Alert Source Discuss
⚠️ Review Standards Track: Core

EIP-7784: GETCONTRACT opcode

Global byte code accessing by its hash

Authors Tim Pechersky (@peersky)
Created 2024-10-07

Abstract

This is a proposal to add a new opcode, GETCONTRACT. The GETCONTRACT opcode would return the address containing the bytecode by its hash.

Motivation

Content addressing by hash is a common pattern in database design. It allows to store and retrieve data by its unique footprint in the storage. This pattern is widely used in the industry and it allows abstracting the actual storage location and allows reusing the same bytecode in multiple contracts.

Today, existing contract discovery relies on addresses, which are non-deterministic and can be obfuscated through proxies. Indexing by bytecode hash provides a deterministic and tamper-proof way to identify and verify contract code, enhancing security and trust in the Ethereum ecosystem.

Consider a security auditor who wants to attest to the integrity of a contract’s code. By referencing bytecode hashes, auditors can focus their audit on the bytecode itself, without needing to assess deployment parameters or storage contents. This method verifies the integrity of a contract’s codebase without auditing the entire contract state.

Additionally, bytecode referencing allows whitelist contracts before deployment, allowing developers to get pre-approval for their codebase without disclosing the code itself, or even pre-setup infrastructure that will change it behavior upon adding some determined functionality on chain.

For developers relying on extensive code reuse, bytecode referencing protects against malicious changes that can occur with address-based referencing through proxies. This builds long-term trust chains extending to end-user applications.

For decentralized application (dApp) developers, a code index can save gas costs by allowing them to reference existing codebase instead of redeploying them, optimizing resource usage. This can be useful for dApps that rely on extensive re-use of same codebase as own dependencies.

This also allows to build new core standards more conveniently, for example, EIP-7702 can use it as dependency, to allow users who want to set up one-time code on their EOAs by referring to GETCONTRACT instead of specifying potentially mutable address based functionality.

Specification

Opcode Definition

  • Mnemonic: GETCONTRACT
  • Opcode Value: 0x4f
  • Input:
    • codehash: A single 32-byte code hash from the stack.
  • Output:
    • address: If the codehash exists in the state, pushes the corresponding contract address onto the stack. Otherwise, pushes 0.
  • Gas Cost: 150
  • Stack Effects: Pops 1 item, pushes 1 item.
  • Error Handling: If the codehash is invalid or the bytecode retrieval encounters an error, the instruction will revert.

Every contract stored in EVM MUST be added to the state trie with the key being the keccak256 hash of the contract’s bytecode, provided it is:

  • not already present
  • The contract did not invoke the SELFDESTRUCT opcode.
  • The EXTCODEHASH return value IS NOT 0xeadcdba66a79ab5dce91622d1d75c8cff5cff0b96944c3bf1072cd08ce018329 (keccak256(0xef01))

Example Usage

function getContractAddress(bytes32 codehash) public view returns (address) {
    address contractAddress;
    assembly {
        contractAddress := GETCONTRACT(codehash)
    }
    return contractAddress;
}

Rationale

Bytecode over Addresses: Bytecode is deterministic and can be verified on-chain, while addresses are opaque and mutable.

Do not re-index: There is small, yet non-zero probability of hash collision attack. Disallowing updates to indexed location of bytecode coupes with this.

Gas cost: This operation is more complex than simple data retrieval, however lookup in the database by hash generally is simpler in complexity.

Security Considerations

Malicious Code: The index does NOT guarantee the safety or functionality of indexed contracts. Users MUST exercise caution and perform their own due diligence before interacting with indexed contracts.

Storage contents of registered contracts: The index only refers to the bytecode of the contract, not the storage contents. This means that the contract state is not indexed and may change over time.

EIP-7702 delegation: Temporary code delegation is disallowed to prevent case of registering a code hash that becomes unavailable. Standard explicitly disallows contracts with bytecode delegated via EIP-7702 from being indexed.

SELFDESTRUCT: Contracts that selfdestruct are not indexed, as they will not have a codehash in the state trie.

Copyright and related rights waived via CC0.

Citation

Please cite this document as:

Tim Pechersky (@peersky), "EIP-7784: GETCONTRACT opcode [DRAFT]," Ethereum Improvement Proposals, no. 7784, October 2024. [Online serial]. Available: https://eips.ethereum.org/EIPS/eip-7784.