7

I want to monitor Ethereum and memorise every contract published on the blockchain (basically the same thing that Etherscan does). How it is possible to do this using NodeJS & web3? How can I determine whether specific transaction was used to publish a new contract?

It is possible to get the input data, but how do I analyze it?

I'm interested NOT in determining whether the address is a contract address, I'm interested in finding specifically CONTRACT CREATION transactions without having to keep all contracts in my database.

3 Answers 3

6

This can be done by checking

  • The transaction's 'to' address, which is zero for contract creation.
  • The 'contractAddress' field from the transaction's receipt.

For example, take a look at the transaction below, notice the 'to' field and 'contractAddress' field.

    > web3.eth.getTransaction("0xf04c0c82bd8e4733e4bcc0ac8e8becf60fad0d99e83883c34887937956a40c3b")

    {
      blockHash:     "0x99efca1a0553673c039a4bdb09f529c0e4feadddf1bdd08753e42a8229774875",
      blockNumber: 90913,
      from: "0x5e0320bb4d82ab8bb5d7291f2c67d1c99abb3c05",
      gas: 1000000,
      gasPrice: 54606694457,
      hash: "0xf04c0c82bd8e4733e4bcc0ac8e8becf60fad0d99e83883c34887937956a40c3b",
      input: "0x60606040526040516020806102518339016040526060805190602001505b806000600050    60003373ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600050819055505b506101ef806100626000396000f30060606040526000357c01000000000000000000000000000000000000000000000000000000009004806390b98a1114610044578063bbd39ac01461007157610042565b005b61005b6004803590602001803590602001506100b3565b6040518082815260200191505060405180910390f35b610082600480359060200150610098565b6040518082815260200191505060405180910390f35b60006000506020528060005260406000206000915090505481565b600081600060005060003373ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000505410156100f557600090506101e9565b81600060005060003373ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282825054039250508190555081600060005060008573ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828282505401925050819055507f16cdf1707799c6655baac6e210f52b94b7cec08adcaf9ede7dfe8649da926146338484604051808473ffffffffffffffffffffffffffffffffffffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff168152602001828152602001935050505060405180910390a1600190506101e9565b92915050560000000000000000000000000000000000000000000000000000000000002710",
      nonce: 6,
      r: "0x524cd0612444308f830c542bdbbc523c5855449103951819028427b9167fd534",
      s: "0x25aa71510d0ca63a1e01d6dad21cfda9755e3792adc3c7554a98c3d5d42fb1c1",
      to: null,
      transactionIndex: 1,
      v: "0x1c",
      value: 0
    }
    > web3.eth.getTransactionReceipt("0xf04c0c82bd8e4733e4bcc0ac8e8becf60fad0d99e83883c34887937956a40c3b")
    {
      blockHash: "0x99efca1a0553673c039a4bdb09f529c0e4feadddf1bdd08753e42a8229774875",
      blockNumber: 90913,
      contractAddress: "0xc4a23a06e6642fa00989b89575f0b9f783259159",
      cumulativeGasUsed: 197451,
      from: "0x5e0320bb4d82ab8bb5d7291f2c67d1c99abb3c05",
      gasUsed: 176451,
      logs: [],
      logsBloom: "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
      root: "0x76ca24aac6c47b5e49b38a227f4892b29aca17cfa273ff57c67ca4f5bd7a37d5",
      to: null,
      transactionHash: "0xf04c0c82bd8e4733e4bcc0ac8e8becf60fad0d99e83883c34887937956a40c3b",
      transactionIndex: 1
    }
2
  • 3
    this won't work when a contract inside another contract creates another contract (internal transaction). It will only work for the first level, but not on the levels down
    – Nulik
    Apr 23, 2020 at 16:00
  • 1
    What can you do with the contractAddress field? Is there some geth RPC call that allows me to read the contract? Or the contract data? Not sure how to continue from here :(
    – David
    May 13, 2021 at 20:16
2

There is no way we can directly determine from the address whether it is a contract address. This is how the contract address is computed: How is the address of an Ethereum contract computed?

There is a web3.js method web.eth.getcode to get the Ethereum Virtual Machine bytecode of the address. In case if it is not a contract then the method would return 0x0. Anything else is a contract.

1

from the Solidity docs:

If the target account is the zero-account (the account with the address 0), the transaction creates a new contract.

Your Answer

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

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