Input data (or method) for nft contract transfers

Is it possible to extend the output of the REST API /nft/{address}/transfers with the input data or method as etherscan does so I can figure out if and which function of a contract was used (and which one) to transfer nfts in a certain collection contract?

I would like to know more than just the OpenSea transactions. I would like to look at a certain nft collection contract and figure out which transfers occurred through any market or swap contract. For instance this swap https://etherscan.io/tx/0xc1fe9d8e0263420f863b67ced6c2fe6c68042e815dcfa87f60ea143f0a4e506f The current output does not allow me to figure out what kind of transaction this was and differentiate it from the initiation transaction where the BAYC was moved to the escrow contract, which is https://etherscan.io/tx/0x694861e8e08c5862270daf7b40385b0f39af39fcb7558dd146b850d15ebe0418 . I’d rather not resort to filtering on price or some other heuristic.

The more marketplaces we will get, the more messy it will be to be able to track all these different market contracts. So I want to build with the nft collections as starting points since most users don’t think in terms of OpenSea transfers and LooksRare transfers (or whatever other markets will pop-up), but rather collection-centric.

So in an ideal world the API would show the input data in decoded form as etherscan does with their method column and in raw input data form to figure out the arguments of the called function (so from your side input data is probably easiest as a first step). So that would require 2 extra response fields (methods and input data). I think this would allow for much more applications where devs can figure out how nft collections are used (as pure investments, as loan collateral, being swapped for assets, etc.)

Thanks in advance for looking at this!

can you give a more exact example (like actual data) of how the output is now and what you would want to be added?

sure, so lets say that for the above I want to make a dashboard for BAYC transfers (sales or otherwise). But I want to make it robust to new marketplaces popping up every couple weeks. So I look at the transfers of the BAYC contract because any transfer of a BAYC token needs to pass through that contract independent of new marketplace or whatever. So I can use the /nft/0xbc4ca0eda7647a8ab7c2061c2e118a18a936f13d/transfers endpoint. So I run:

curl -X 'GET' \
  'https://deep-index.moralis.io/api/v2/nft/0xbc4ca0eda7647a8ab7c2061c2e118a18a936f13d/transfers?chain=eth&format=decimal' \
  -H 'accept: application/json' \
  -H 'X-API-Key: xxxxxxxxxxxxxxx

and get back (I only show ‘results’ here):

{
      "block_number": "14055741",
      "block_timestamp": "2022-01-22T13:37:18.000Z",
      "block_hash": "0xd4a2b9e0b5589a954cb38831b35276d229c7475d434b363f09cc50a4c1444eb1",
      "transaction_hash": "0xc1fe9d8e0263420f863b67ced6c2fe6c68042e815dcfa87f60ea143f0a4e506f",
      "transaction_index": 37,
      "log_index": 24,
      "value": "92005000000000000000",
      "contract_type": "ERC721",
      "transaction_type": "Single",
      "token_address": "0xbc4ca0eda7647a8ab7c2061c2e118a18a936f13d",
      "token_id": "2406",
      "from_address": "0xc310e760778ecbca4c65b6c559874757a4c4ece0",
      "to_address": "0x18632c33ce3dcffdeb51ecbcd8cabe415ce6fec0",
      "amount": "1",
      "verified": 1,
      "operator": null
    },
    {
      "block_number": "14055718",
      "block_timestamp": "2022-01-22T13:31:20.000Z",
      "block_hash": "0x39f587c9c5d4f5eae89bd6818a1c831b3165bcf6213fedcd11259b7be44ed62a",
      "transaction_hash": "0x694861e8e08c5862270daf7b40385b0f39af39fcb7558dd146b850d15ebe0418",
      "transaction_index": 107,
      "log_index": 92,
      "value": "5000000000000000",
      "contract_type": "ERC721",
      "transaction_type": "Single",
      "token_address": "0xbc4ca0eda7647a8ab7c2061c2e118a18a936f13d",
      "token_id": "2406",
      "from_address": "0x55ef96bd356ffce421e12dcca303071752526b37",
      "to_address": "0xc310e760778ecbca4c65b6c559874757a4c4ece0",
      "amount": "1",
      "verified": 1,
      "operator": null
    },
    {
      "block_number": "14055441",
      "block_timestamp": "2022-01-22T12:34:14.000Z",
      "block_hash": "0x77decea3d7ccdebd3456f9ad06cb88542079a9e6af9ec120f69745505a9c421e",
      "transaction_hash": "0xecdb2dca46d1cd05682c0aee4c04087c2b839b606d8c6383cd8bddddbd2a83f5",
      "transaction_index": 262,
      "log_index": 253,
      "value": "94206900000000000000",
      "contract_type": "ERC721",
      "transaction_type": "Single",
      "token_address": "0xbc4ca0eda7647a8ab7c2061c2e118a18a936f13d",
      "token_id": "3059",
      "from_address": "0x4353583f5793f1fd7231558ff933c6ee07c1124f",
      "to_address": "0xd4f072b18c7a31d50bbf1df729b68e9ace7bc0d9",
      "amount": "1",
      "verified": 1,
      "operator": null
    },

From this I can’t automatically figure out if the middle transaction (transferring a BAYC for 0.05 eth) was a fat finger error, or that this was part of a bigger transaction with a swap contract, or I would need to resort to some heuristics that will probably not be accurate and have a bunch of edge-cases.

If I look up the transaction hash in the /transaction/{transaction_hash} however,

curl -X 'GET' \
  'https://deep-index.moralis.io/api/v2/transaction/0x694861e8e08c5862270daf7b40385b0f39af39fcb7558dd146b850d15ebe0418?chain=eth' \
  -H 'accept: application/json' \
  -H 'X-API-Key: xxxxxxxxxxxx'

I get

{
  "hash": "0x694861e8e08c5862270daf7b40385b0f39af39fcb7558dd146b850d15ebe0418",
  "nonce": "210",
  "transaction_index": "107",
  "from_address": "0x55ef96bd356ffce421e12dcca303071752526b37",
  "to_address": "0xc310e760778ecbca4c65b6c559874757a4c4ece0",
  "value": "5000000000000000",
  "gas": "674281",
  "gas_price": "106851965633",
  "input": "0xc041abb1000000000000000000000000000000000000000000000000000000000000000000000000000000000000000055ef96bd356ffce421e12dcca303071752526b37000000000000000000000000000000000000000000000000000000000000000000000000000000000000000018632c33ce3dcffdeb51ecbcd8cabe415ce6fec0000000000000000000000000000000000000000000000004fcc1a89027f000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000016000000000000000000000000000000000000000000000000000000000000002c000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000bc4ca0eda7647a8ab7c2061c2e118a18a936f13d00000000000000000000000058874d2951524f7f851bbbe240f0c3cf0b992d7900000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e0000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000966000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
  "receipt_cumulative_gas_used": "5025761",
  "receipt_gas_used": "439921",
  "receipt_contract_address": null,
  "receipt_root": null,
  "receipt_status": "1",
  "block_timestamp": "2022-01-22T13:31:20.000Z",
  "block_number": "14055718",
  "block_hash": "0x39f587c9c5d4f5eae89bd6818a1c831b3165bcf6213fedcd11259b7be44ed62a",
  "transfer_index": [
    14055718,
    107
  ],
  "logs": [
    {
      "log_index": "91",
      "transaction_hash": "0x694861e8e08c5862270daf7b40385b0f39af39fcb7558dd146b850d15ebe0418",
      "transaction_index": "107",
      "address": "0xbc4ca0eda7647a8ab7c2061c2e118a18a936f13d",
      "data": "0x",
      "topic0": "0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925",
      "topic1": "0x00000000000000000000000055ef96bd356ffce421e12dcca303071752526b37",
      "topic2": "0x0000000000000000000000000000000000000000000000000000000000000000",
      "topic3": "0x0000000000000000000000000000000000000000000000000000000000000966",
      "block_timestamp": "2022-01-22T13:31:20.000Z",
      "block_number": "14055718",
      "block_hash": "0x39f587c9c5d4f5eae89bd6818a1c831b3165bcf6213fedcd11259b7be44ed62a",
      "transfer_index": [
        14055718,
        107,
        91
      ]
    },
    {
      "log_index": "92",
      "transaction_hash": "0x694861e8e08c5862270daf7b40385b0f39af39fcb7558dd146b850d15ebe0418",
      "transaction_index": "107",
      "address": "0xbc4ca0eda7647a8ab7c2061c2e118a18a936f13d",
      "data": "0x",
      "topic0": "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef",
      "topic1": "0x00000000000000000000000055ef96bd356ffce421e12dcca303071752526b37",
      "topic2": "0x000000000000000000000000c310e760778ecbca4c65b6c559874757a4c4ece0",
      "topic3": "0x0000000000000000000000000000000000000000000000000000000000000966",
      "block_timestamp": "2022-01-22T13:31:20.000Z",
      "block_number": "14055718",
      "block_hash": "0x39f587c9c5d4f5eae89bd6818a1c831b3165bcf6213fedcd11259b7be44ed62a",
      "transfer_index": [
        14055718,
        107,
        92
      ]
    },
    {
      "log_index": "93",
      "transaction_hash": "0x694861e8e08c5862270daf7b40385b0f39af39fcb7558dd146b850d15ebe0418",
      "transaction_index": "107",
      "address": "0xc310e760778ecbca4c65b6c559874757a4c4ece0",
      "data": "0x00000000000000000000000000000000000000000000000000000000000017d200000000000000000000000018632c33ce3dcffdeb51ecbcd8cabe415ce6fec0",
      "topic0": "0x20c004714deaf94f3e80538ac812eb372a6d40711070cd585f447f9ef76d525d",
      "topic1": "0x00000000000000000000000055ef96bd356ffce421e12dcca303071752526b37",
      "topic2": "0x0000000000000000000000000000000000000000000000000000000061eb4900",
      "topic3": "0x0000000000000000000000000000000000000000000000000000000000000000",
      "block_timestamp": "2022-01-22T13:31:20.000Z",
      "block_number": "14055718",
      "block_hash": "0x39f587c9c5d4f5eae89bd6818a1c831b3165bcf6213fedcd11259b7be44ed62a",
      "transfer_index": [
        14055718,
        107,
        93
      ]
    }
  ]
}

Here from the input and logs I can figure out that it was actually a contract interaction and which functions were called. From that I can see that it was actually a ‘swapEvent’.

So if this could be included in the output for /nft/0xbc4ca0eda7647a8ab7c2061c2e118a18a936f13d/transfers then I wouldn’t have to do all these extra calls and I think lots of people will be able to use this.

Hope this is clear!

I think that I understand now, you could propose it on roadmap: https://roadmap.moralis.io/

Hey @intothemeta, I’m new to web3. I want to ask how u decode the input/log are “SWAP”? I know that these are hashes and they represent something but I’m not sure how to begin. Thank you in advance.

Hi,

You need the abi (kinda like source code) of the contract that the interaction took place with. Then you can decode the input data to show which function was called in the transaction. Sadly from there on it would be a manual task to classify contract functions to their utility, since the makers of smart-contracts can call functions whatever they like. The atomicMatch function on the OpenSea contract for instance is initiates a sale. But they could have named this whatever.

Hope this helps,
Kind regards,
Meta