0

Knowing the hash of a transaction that created the contract, how do I get the address of created contract?

For instance:

curl -X POST -H "Content-Type: application/json" --data '{"jsonrpc":"2.0","method":"eth_getTransactionByHash","params":["0x622b3d3b880666e2447458c09e87f50a2f45f72d87d8bcb0e5924ccb73d92e59"],"id":1}' http://10.10.10.10:8545 | python -m json.tool
{
    "id": 1,
    "jsonrpc": "2.0",
    "result": {
        "blockHash": "0x0375c57448e43a56e3c0e8e5bbeb744bda0cf6cde246e521d0dc9271fb17ce22",
        "blockNumber": "0x40342b",
        "from": "0xd534d9f6e61780b824afaa68032a7ec11720ca12",
        "gas": "0x4c4b40",
        "gasPrice": "0xee6b2800",
        "hash": "0x622b3d3b880666e2447458c09e87f50a2f45f72d87d8bcb0e5924ccb73d92e59",
        "input": "0x6060604052341561000f57600080fd5b6040516040806111498339810160405280805191
...
000000000000000000010db6b405c4cff3185926f5bda140703a77c5",
        "nonce": "0x0",
        "r": "0xea3abf44bb80534553042f11d0465be54a2f3f5910c861c154a397f677549161",
        "s": "0x5bf893f90270dd9aa0092ce15b13c7a8ea9c541c13190e9ed874f7d3841ce0d1",
        "to": null,
        "transactionIndex": "0xd",
        "v": "0x26",
        "value": "0x0"
    }
}

From Etherscan I know the address is 0xb5fe93ccfec708145d6278b0c71ce60aa75ef925, but how do I get this address via JSON RPC?

1

You can use eth_getTransactionReceipt, the returned json has a field named contractAddress that contains the address of the created contract.

The example from the wiki

Request:

curl -X POST -H "Content-Type: application/json" --data '{"jsonrpc":"2.0","method":"eth_getTransactionReceipt","params":["0xb903239f8543d04b5dc1ba6579132b143087c68db1b2168786408fcbce568238"],"id":1}'

Result:

{
"id":1,
"jsonrpc":"2.0",
"result": {
     transactionHash: '0xb903239f8543d04b5dc1ba6579132b143087c68db1b2168786408fcbce568238',
     transactionIndex:  '0x1', // 1
     blockNumber: '0xb', // 11
     blockHash: '0xc6ef2fc5426d6ad6fd9e2a26abeab0aa2411b7ab17f30a99d3cb96aed1d1055b',
     cumulativeGasUsed: '0x33bc', // 13244
     gasUsed: '0x4dc', // 1244
     contractAddress: '0xb60e8dd61c5d32be8058bb8eb970870f07233155' // or null, if none was created
     logs: [{
         // logs as returned by getFilterLogs, etc.
     }, ...],
     status: '0x1'
  }
}

This will not work when the contract is create indirectly by another contract, ie for example if you are using the factory pattern.

1

I don't believe there's any way to get the JSON RPC API to tell you the address, but the address of a contract is programmatically determined from the transaction sender's address and nonce. The transaction hash gives you both of those pieces of information. You need to RLP-encode them and then take the last 20 bytes of the keccak-256 hash. Pseudocode:

keccak256(rlp(address, nonce))[-20:]

Code using pyethereum:

>>> ethereum.utils.mk_contract_address(0xd534d9f6e61780b824afaa68032a7ec11720ca12, 0).hex()
'b5fe93ccfec708145d6278b0c71ce60aa75ef925'

A little more explicitly:

>>>  binascii.hexlify(ethereum.utils.sha3(ethereum.utils.rlp.encode([0xd534d9f6e61780b824afaa68032a7ec11720ca12, 0]))[-20:])
b'b5fe93ccfec708145d6278b0c71ce60aa75ef925'

Code using just pysha3 and a bit of manual RLP-encoding:

>>> binascii.hexlify(sha3.keccak_256(binascii.unhexlify(b'd6' + b'94' + b'd534d9f6e61780b824afaa68032a7ec11720ca12' + b'80')).digest()[-20:])
b'b5fe93ccfec708145d6278b0c71ce60aa75ef925'

Explanation:

  • d6 = 0xc0 + 20 (length of the address) + 1 (length of the encoded nonce)
  • 80 = 0x80 + 0 (length of nonce) — For a nonce of 1, you would use 01 instead (the encoding of a single byte with the value 1)

See also: How is the address of an Ethereum contract computed?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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