In Ethernaut level 8 you are given this contract to hack:

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;

The password which is passed into the contract through the constructor arguments is easily found; By going to the creation transaction in Etherscan and reading the init input code in text. Or by:

web3.eth.getStorageAt(contractAddress, 1,  function(error, result) {password = result}))

Is there a way to encode these arguments (bytes32 _password) and make it so no one can retrieve them via etherscan or web3?


You will never really be able to truly hide data where your equality check is essentially a == b.

Most systems that rely on such password based functionality would use hashes to hide the value.

Instead of setting the password directly, you set password to keccak256(password). Then, when you want to unlock the contract, you make a transaction with the actual password as data, and the contract will calculate the keccak256(input), and then verify that it matches the hash previously provided.

Of course, this then reveals the password in the unlocking tx. To avoid this, you can pass in a new hash (_newpassword) when unlocking. If the unlock is successful, update the password hash to this new one, and the next time you wish to unlock, provide the password for this hash (along with a third one to set it to).

| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.