2

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?

johndodo
  • 511
  • 3
  • 15

2 Answers2

4

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.

Ismael
  • 30,570
  • 21
  • 53
  • 96
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?

user19510
  • 27,999
  • 2
  • 30
  • 48