13

I'd like to get a list of all transactions which are sent to specific contract or method of contract. What kind of way do we have to implement it?

7

If the contract is under your control, you can simply emit a log whenever you want and then watch for log events.

If the contract is not under your control or it's a plain account, you have no officially supported way to do that (it's not a needed feature to create distributed apps). You need to gather/analyze the data yourself from the blockchain.

  • Are there any tools to gather and analyze the blockchain? – Satoshi Nakanishi Feb 17 '16 at 4:43
  • You can check out ethslurp (ethslurp.com). It does exactly this, but we're still working on picking up 'internal transactions.' – Thomas Jay Rush Nov 16 '16 at 3:45
8

If you have a contract address you can filter the transactions to that address

var filter = eth.filter({fromBlock:0, toBlock:'latest', address: "0x.."});
filter.get(function (err, transactions) {
  transactions.forEach(function (tx) {
    var txInfo = eth.getTransaction(tx.transactionHash);
    /* Here you have
    txInfo.gas;
    txInfo.from;
    txInfo.input;
    */
  });
});
  • 1
    So that means you need to parse all blocks and transactions from the genesis block, right? – Satoshi Nakanishi Jun 5 '16 at 8:45
  • I tried this with a sample contract with less than 10 transaction in tesnet, and it was pretty fast. I'm just learning, I don't know how it will perform in a contract with a lot of transactions. Also don't know if geth and/or web3.js do optimizations when filtering. But you can always narrow the block range. – Ismael Jun 5 '16 at 9:26
  • 1
    I learned that ethereum uses bloom filters github.com/ethereum/wiki/wiki/Design-Rationale#trie-usage so it doesn't parse all block to filter by addresses or topics – Ismael Jun 6 '16 at 17:45
  • 1
    @tinybike In my test I was only interested in transaction that were sent to my contract. AFAICT it include all transactions that were sent to the contract, even the invalid ones (ie out of gas), but doesn't include "internal transactions" (ie transactions sent to my contract originated from another contract). – Ismael Jun 14 '16 at 18:10
  • 2
    Technically, filtering on events does work in all cases. It is conceivable that a smart contract may have functions that accept ether but do not emit an event (it would be poor design to do this, but it's conceivable). Because of this the only way is to parse every block looking for calls into the contract. For regular accounts (non-contracts) this is even more obvious. Regular accounts cannot emit events. – Thomas Jay Rush Nov 16 '16 at 3:48
1

Apart from the above mentioned methods, this is one which I have personally implemented and it works like a charm:

  • You read all transactions in the block with web3.getBlock(<blockNumber>, true). The true flag helps you in fetching all transactions associated with the block.
  • Once you have all transactions, process them one by one and get the details of the transaction using web3.getTransaction(<TransactionHash>). This web3 call will give the details about the transaction i.e. to/from address, eth transferred(if any), nonce, etc. You can filter the transactions by using the to/from address i.e. if they belong to you.
  • To get more details on the transaction, you can also use web3.getTransactionReceipt(<transactionHash>). This will also provide you logs of the events fired during that particular transactions. The events logs can be decoded using the ABI of the contract and using the logParser. This will help you to get all string (human readable) output instead of the hashes which are given out by the blockchain.

PS: you can start the above from the first block or start from a particular block from which transactions started happening over a particular contract.

I hope this helps

0

Or if you're lazy like me and need it in JSON Format right away, use the etherscan API - just replace the values accordingly.

https://envionapi.backand.com:443/1/objects/action/ethereum_contract_webhook_object/?authorization=basic+YOURAUTHKEY&name=transactionsByBlocks&parameters={"contract_address":"YOURADDRESS", "block_min" :  THESTARTBLOCK, "block_max" : THEENDBLOCK }

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.