diff --git a/EIPS/eip-7637.md b/EIPS/eip-7637.md new file mode 100644 index 0000000000000..8bc356b8e0685 --- /dev/null +++ b/EIPS/eip-7637.md @@ -0,0 +1,104 @@ +--- +eip: 7637 +title: Optimize EOA EXTCODEHASH +description: Modify the output value of EXTCODEHASH for EOA accounts to `0x` +author: Jame (@ZWJKFLC) +discussions-to: https://ethereum-magicians.org/t/eip-7637-extcodehash-optimize/18946 +status: Draft +type: Standards Track +category: Core +created: 2024-02-26 +requires: 1052 +--- + + + +## Abstract + +This proposal is an optimization for [EIP-1052](./eip-1052.md), +For addresses with a balance, but without code, the codehash should still be `0x`. + +When an address `add.code == 0x` and `add.balance != 0`, `add.codehash==0` is required instead of `add.codehash==keccak256("")` + +## Motivation + +EIP-1052 was proposed to save gas fees. However, due to some flaws in the set specifications, in actual applications, due to safety concerns, they will not actually be used. In order for EIP-1052 to be truly useful, it should be optimized. + +If someone uses it based on the proposal of EIP-1052 and does not notice the change when `add.balance != 0`, there may be security issues. + + +## Specification + +The behaviour of `EXTCODEHASH` is changed in the following way: + +1. When calling `EXTCODEHASH`, the codehash of the address with balance but no code is still `0x` + + +## Rationale + +EIP-1052 In order to include the function of `BALANCE`, let the `EXTCODEHASH` of the address without balance be `0x`, and the `EXTCODEHASH` of the address with balance be `keccak256("")`. + +The contract address can be calculated in advance. Whether it is `CREATE` or `CREATE2`, it is possible that the contract is not created but has a balance. For security, You can actually only use `keccak256(add.code) == keccak256("")` or `add.code.length ==0` instead of `add.codehash == 0`,, which makes the original intention of EIP-1052 meaningless. + +For example, uniswap V2 uses stored addresses to determine whether a contract exists. If this `EXTCODEHASH` is optimized, can save a huge amount of gas. + +If someone uses a `add.codehash==0` to determine whether a contract has been created, due to intuition and the lack of details in many documents, they will not think that the codehash of an address with a balance will change from `0x` to `keccak256("")`. If someone maliciously attacks at this time, it will cause some bad effects. + + +## Backwards Compatibility + + +Needs discussion. +It is unclear whether there is a situation where codehash is actually used to determine whether an address has a balance and the codehash is `keccak256("")`. + + +## Reference Implementation + +Code reference for execution-specs + +After modification + +```python +def extcodehash(evm: Evm) -> None: + address = to_address(pop(evm.stack)) + charge_gas(evm, GAS_CODE_HASH) + account = get_account(evm.env.state, address) + if account == EMPTY_ACCOUNT: + codehash = U256(0) + else: + codehash = U256.from_be_bytes(keccak256(account.code)) + if codehash == U256(hexstr="c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470"): + codehash = U256(0) + push(evm.stack, codehash) + evm.pc += 1 +``` + + +Source code + +```python +def extcodehash(evm: Evm) -> None: + address = to_address(pop(evm.stack)) + charge_gas(evm, GAS_CODE_HASH) + account = get_account(evm.env.state, address) + if account == EMPTY_ACCOUNT: + codehash = U256(0) + else: + codehash = U256.from_be_bytes(keccak256(account.code)) + + push(evm.stack, codehash) + evm.pc += 1 +``` + + +## Security Considerations + + +Needs discussion. +It is unclear whether there is a situation where codehash is actually used to determine whether an address has a balance and the codehash is `keccak256("")`. + + +## Copyright + +Copyright and related rights waived via [CC0](../LICENSE.md). +