Provable way to whitelist a contract before it is deployed

contract-deploymentcontract-designevmhashsolidity

I would like to prove that a contract, that is going to be deployed, matches specific code and potentially with a specific state too.

For example, Bob say's he is going to deploy a contract that looks like this:

pragma solidity ^0.4.0;

contract SimpleStorage {
    uint storedData;

    function set(uint x) public {
        storedData = x;
    }
}

I'd like to whitelist this contract in my own contract before he deploys it. For example, maybe I keep a mapping of approved address that will be able to call my function. Though, the problem is, I don't know what Bob's SimpleStorage contract address will be.

But I do know that his contract will have this exact code, and that the functions will have ever been called yet (i.e. storedData is empty).

From what I think I know about the EVM, each deployed contract is designated a hash that is used by a Merkel tree. Any state updates to the contract change this hash slightly. I think this might be one method as I could whitelist the hash instead of the address, but I am unsure if this hash can be predicted before deployment.

So maybe the main question are:

  1. Is this understanding of contract hashes correct?

  2. Can you know what contract hash will have before it's deployed? For example, just from how the code looks and assuming no functions have ever been called.

  3. If no for (2), can you deploy it to a testnet, check the hash, and assume it will be the same on mainnet?

Maybe there is a better way of doing this you might be able to point out. For example, maybe I could whitelist Bob's address and trust all the contracts he deploys. But this has the problem that he can deploy any contract and not just SimpleStorage, which would be a vector of attack for my contract.

Would love to hear your thoughts, thank you!

Best Answer

One way to do this is to use the create2 opcode. When using this opcode (e.g. via a contract factory) the address of the contract will depend on the deployment code. The deployment code runs the constructor to initialize the storage and stores the contract code on the blockchain. With this you can calculate the address of the contract ahead of time and use it already for whitelisting.

This process, known as counterfactual deployment, is used by well known Ethereum tools such as the Gnosis Safe or OpenZepplin

Related Topic