1

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:]
'7316d007c2dfd30ff33536803bc07e747818e2c1'

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.

anomit
  • 13
  • 2

1 Answers1

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"
user19510
  • 27,999
  • 2
  • 30
  • 48