5

I am trying to create a password in the constructor when deploying a smart contract.

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.4;

contract passwordContract {
bytes32 password;
address owner;

constructor(uint32 _password) {
    owner = msg.sender;
    password = keccak256(abi.encodePacked(_password,msg.sender));
}

modifier onlyOwner() {
    require(msg.sender == owner, "only owner");
    _;
}

function getPassword() external view onlyOwner returns(bytes32) {
    return password;
}


// can anyone call this function, but need a password in parameter.
function canCallAnyOne(bytes32 _password) public {
    require(_password == password,"wrong password");
    // do something
}
}

As in the example above, put the password in the function's parameter so that only those who know the password can run the function.

I have two questions.

  1. When deploying a smart contract, can the miner figure out the password?

  2. I would like to create a function like the one above. Can anyone advise a better way?

1
  • 4
    It is absolutely NOT safe to generate any sort of password or private key in a smart contract. Commented Aug 18, 2022 at 10:44

4 Answers 4

8

It's absolutely not safe!

You could create and save a hash of the password off-chain and save it in the smart contract. But this is no good anyways because of the Frontrunning attack. When a user sends a transaction with the "password" to access the functionality in the smart contract, the transaction will sit in the mempool waiting to be mined, and attackers and miners will see the password and will be able to create another transaction with higher gas price than yours so it has more priority and will probably be mined and executed before yours.

Also, there is nothing really private in a smart contract or blockchain. You could declare the password variable as:

bytes32 private password;

and it wouldn't make any good, because any value in a smart contract storage can be accessed directly, with something like:

await web3.eth.getStorageAt(yourSmartContractAddress, indexOfTheStateVariable);

In your case, since your password variable is the first declared, its index in storage would be 0:

await web3.eth.getStorageAt(yourSmartContractAddress, 0);
3

I won't duplicate what others have said (this is unsafe). But I will suggest a possible alternative. Rather than using a password, use a digital signature. An ECDSA signature is not susceptible to front-running, and does not require the contract to know any secrets. This question covers implementing a digital signature in Solidity.

1

bytes32 password; is accessible by anyone, so no, it's absolutely NOT safe. A good workaround is to hash the password, store the hash in your smart contract and when the user inputs the password to your smart contract, hash it and compare it to the stored hash, if the hashes are equal, that means the user entered the correct password (but it's only a one time use tho, as soon as the real password has been submitted, anyone has access to it)

2
  • 2
    This is a bad idea, because the password is leaked as soon as the transaction enters the mempool, which makes it vulnerable to a frontrunning attack.
    – blues
    Commented Aug 19, 2022 at 14:50
  • @blues very true, thanks for pointing it out :)
    – Foxxxey
    Commented Aug 19, 2022 at 22:43
1

This is definitely not safe, I don't think any expansion is needed on top of the other answers provided.

The key problems are: All memory in the EVM is visible to everyone. Transactions are put into a queue and not executed immediately, allowing anything you do to be seen before it happens (and people to pay more gas to jump in front of you using the information they now know).

A potentially more viable solution here would be to hardcode a Wallet address and treat the recovery password for that Wallet as the password. I.e. if you know the password you can recover the keys required to generate a transaction that can call that function.

Curious what you are trying to achieve here with this password based approach.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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