En el nivel 8 de Ethernaut se te otorga este contrato para hackear:
pragma solidity ^0.4.18;
contract Vault {
bool public locked;
bytes32 private password;
function Vault(bytes32 _password) public {
locked = true;
password = _password;
}
function unlock(bytes32 _password) public {
if (password == _password) {
locked = false;
}
}
}
La contraseña que se pasa al contrato a través de los argumentos del constructor se encuentra fácilmente; Al ir a la transacción de creación en Etherscan y leer el código de entrada de inicio en el texto. O por:
web3.eth.getStorageAt(contractAddress, 1, function(error, result) {password = result}))
¿Hay alguna manera de codificar estos argumentos (bytes32 _password) y hacer que nadie pueda recuperarlos a través de etherscan o web3?
Nunca podrá realmente ocultar datos donde su control de igualdad es esencialmente a == b
.
La mayoría de los sistemas que dependen de dicha funcionalidad basada en contraseña utilizarían hash para ocultar el valor.
En lugar de establecer la contraseña directamente, establece password
en keccak256(password)
. Luego, cuando desee desbloquear el contrato, realice una transacción con la contraseña real como datos, y el contrato calculará el keccak256(input)
, y luego verificará que coincida con el hash proporcionado anteriormente.
Por supuesto, esto revela la contraseña en el tx de desbloqueo. Para evitar esto, puede pasar un nuevo hash ( _newpassword
) al desbloquear. Si el desbloqueo es exitoso, actualice el hash de contraseña a este nuevo, y la próxima vez que desee desbloquear, proporcione la contraseña para este hash (junto con un tercero para configurarlo).