Search code examples
pythonethereumblockchain

How is the address of an Base Chain contract computed?


I tried two different methods to compute contracts on Base Chain , and I've deployed a contract on Base Chain to validate.

def predict_contract_address(deployer_address, nonce):
    encoded = Web3.solidity_keccak(['address', 'uint256'], [deployer_address, nonce])
    contract_address = Web3.to_checksum_address(encoded[-20:])
    return contract_address

This method returning 0xc989DF16dc2026D73f018158cEad7AAf3508Dd3e which is not matching the actual address. The following is second method:

def pca(deployer_address, nonce):
    return to_checksum_address(keccak(rlp.encode([deployer_address, nonce]))[-20:])

This method returning address 0xdEca8F8D505Ba2BF3B9d4120f66B3Ec9e49393fb according to the guideline which is also wrong. Both using nonce 0 for calculation. Tx Hash of actual contract deployment - 0x1c2e239387c9e6609f1e82900080ab9606e42d5c33074d1e95431817698152e0


Solution

  • The contract address is determined by the sender's address and nonce. When a contract is created, its address is computed by taking the Keccak-25 has of RLP-encoded list of the creator's address and his nonce, and then taking the rightmost 20 bytes of this hash.

    To compute it:

    from ewb3 import Web3
    import rlp
    from eth_hash.auto import keccak
    def compute_contract_address(deployer_address, nonce):
        encoded = rlp.encode([bytes.fromhex(deployer_address[2:]), nonce])
        hashed = keccak(encoded)
        contract_address = hashed[-20:]
        contract_address = Web3.toChecksumAddress(contract_address.hex())
        return contract_address
    

    Please make sure that deployer_address is passed as a hexadecimal string and nonce is passed as an integer.