EIP-1052 EXTCODEHASH opcode
Final · EVM & execution · EIP status Final · created 2018-05-02
Adds a new instruction, EXTCODEHASH (0x3f), that directly returns the keccak256 hash of a contract's code. It lets you cheaply check another contract's code without copying the entire code.
Why it is needed
Sometimes a contract needs to check what code resides at an address before trusting and calling another contract. For example, it may check whether the counterparty's code matches one of a pre-approved list of implementations, or automatically approve a contract whose code matches one that has already passed code analysis. Before this EIP, performing such a check required copying the counterparty's entire code using the EXTCODECOPY instruction. In practice only a hash serving as a fingerprint of the code is needed, yet the larger the code, the greater the copying cost, wasting gas (the unit used to compute computation fees). This EIP removes that waste by adding a new instruction, EXTCODEHASH, that directly returns just the keccak256 hash instead of the entire code.
What changes
Today
- Checking another contract's code requires copying the entire code with EXTCODECOPY
- Even when only a hash comparison is needed, the gas cost grows with code size
- It is hard to distinguish an account with no code from an account that does not exist at all
After EIP-1052
- A single EXTCODEHASH call directly yields the keccak256 hash of the code
- The check costs a fixed 400 gas regardless of code size
- The return value also distinguishes whether the account does not exist versus exists but has no code
Who is affected
- Smart contract developers: A whitelist pattern that checks for approved implementations by hash can be implemented at far lower cost.
- Client teams: The EVM must implement the new opcode 0x3f and follow the return rules for each account state.
- Users: Gas consumption drops for apps using code-verification logic, indirectly lowering their fee burden.
In depth
Instruction definition and behavior
The new opcode EXTCODEHASH uses number 0x3f. It pops one argument from the stack, zeroes the upper 96 bits, interprets the remaining 160 bits as an address, and pushes onto the stack the keccak256 hash of that address's account code. Since it returns only the hash rather than the code itself, it fits uses where a hash alone suffices, such as code-identity checks or existence checks.
Three return values depending on account state
If the account does not exist, or is empty per EIP-161, it pushes 0. If the account exists but has no code, it pushes c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470, the keccak256 hash of empty data. If the account has code, it pushes the hash of that code. This design, which distinguishes a codeless account from a nonexistent one, matches how accounts are represented in the state trie. As a result, smart contracts can also use it to check whether a given account exists.
The 400 gas cost and its rationale
The gas cost of EXTCODEHASH is 400. It was set to the same cost as BALANCE because the work required for execution is an account lookup, just like the BALANCE opcode. Unlike copying the entire code with EXTCODECOPY, the cost does not scale with code size, which makes checking the code of large contracts especially gas-efficient.
Address argument interpretation rule
Only the last 20 bytes of the stack argument matter; the first 12 bytes are ignored. This matches how BALANCE (0x31), EXTCODESIZE (0x3b), and EXTCODECOPY (0x3c) handle addresses. The test cases also confirm this rule by specifying that if EXTCODEHASH of address A is X, then EXTCODEHASH of A + 2**160 must also be X.
Edge cases covered by the test cases
The source document presents 10 test cases. A codeless account must return the empty-data hash c5d246..., while a nonexistent account must return 0. A precompiled contract returns either c5d246... or 0. It also covers edge cases such as an account that was selfdestructed within the current transaction, one whose selfdestruct was reverted, one created within the current transaction, one whose creation was reverted, one that initially did not exist but later became an empty account, and an empty account slated for removal under state-clearing rules.
Compatibility and specification status
Since this adds a new opcode that did not exist before, there are no backward-compatibility issues. The status of the source document is Final, meaning the specification is settled and will not change further.