To begin with, I have already gone through the approach outlined in the following thread: How is the address of an Ethereum contract computed?

I wanted to test if the approach actually works. On my local testnet (Parity client), I deployed a contract through a transaction 0x23ca2b2dccc2635d6cd12a90438751949b9c5074b21ad27bb99e3facfdf73051

The relevant information from getTransactionByHash :

    "jsonrpc": "2.0",
    "result": {
        "from": "0x004ec07d2329997267ec62b4166639513386f32e",        
         "nonce": "0x8e",
    } }

and from getTransactionReceipt

    "jsonrpc": "2.0",
    "result": {
        "blockHash": "0x255bed2220ca551aed77ab3075faf4388d74f6cb2f8ba45cb03d8f1f2ea4b43e",
        "blockNumber": "0x220",
        "contractAddress": "0x8d7bb25141ff9c4c77e9e208b6bf4d1d3ca684b0" }}

So the deployed contract address is 0x8d7bb25141ff9c4c77e9e208b6bf4d1d3ca684b0 . And I wanted to verify if the code I write to automate a piece of contract deployment functionality is correct so I can return the deterministically expected contract address on the chain.

import rlp 
from sha3 import keccak_256 
sender = "0x004ec07d2329997267ec62b4166639513386f32e" 
nonce = int("0x8e", 16)
dd = keccak_256(rlp.encode([sender.encode('utf-8'),nonce])).hexdigest()[24:]

The computed address according to the given formula isn't what I expected it to be.

I am confused about:

  1. The correct data types of the arguments to be passed to rlp.encode(). I encoded the sender address because pyrlp 1.0.1 doesn't accept strings.
  2. Am I using the right cryptographic keccak function?

Any guidance or pointers will be really appreciated.

1 Answer 1


The mistake is treating the sending account as a string. It's a hexadecimal representation of some bytes. You can use bytes.fromhex to convert it. Otherwise I think your code is fine. This code works:

import rlp
from sha3 import keccak_256

# Convert from hex to bytes. Be sure to drop the leading 0x.
sender = bytes.fromhex("004ec07d2329997267ec62b4166639513386f32e")

# The nonce is just a number.
nonce = 0x8e

# Last 20 bytes means the last 40 characters in hexadecimal
contract_address = keccak_256(rlp.encode([sender, nonce])).hexdigest()[-40:]

assert contract_address == "8d7bb25141ff9c4c77e9e208b6bf4d1d3ca684b0"

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.