Contracts Decoding

This article will focus on a particular type of table that is used to store events from smart contracts. This functionality could be very useful for you if you:

  • Want to track and analyze the behavior of a smart contract to ensure that it is functioning as intended?
  • Need to monitor specific events that occur within a smart contract to trigger other actions or updates in your application?
  • Want to retrieve data from a smart contract and store it in a more structured and accessible format for further analysis?
  • Need to comply with regulatory requirements or perform audits on smart contracts to ensure compliance with regulations and agreements?
  • Want to create a dashboard or visualization to monitor the state and behavior of a smart contract in real-time?

Footprint offers a user-friendly solution for working with smart contracts by providing decoded data in easily readable tables. Our approach involves utilizing the ABI for smart contracts so that instead of navigating the raw transactions, logs, and traces associated with smart contract activity, we decode this information and organize it into user-friendly tables. As new events in the new transactions are emitted, the data is decoded and added as a row to the corresponding table.

What is decoding?

Smart contracts on any EVM blockchain are typically written in high-level programming languages such as Solidity or Vyper. In order to be executed in the EVM environment, the smart contract code must be compiled into EVM bytecode. Once deployed, the bytecode is associated with an address on the respective blockchain and stored permanently in the blockchain's state storage.

To interact with a deployed smart contract, which is represented as bytecode, we need a way to call the functions defined in the high-level language. This translation of function names and arguments into bytecode is accomplished through the use of an Application Binary Interface (ABI). The ABI precisely documents the names, types, and arguments of the functions in the smart contract, which allows for interaction with the contract using a format that is somewhat human-readable.

In this section, we will examine an event log from a RabbitHole project event that was recorded in a smart contract. The raw, undecoded version of the event can be seen on Etherscan in the following form:

https://etherscan.io/tx/0x9790c03dff59e50372bd1c50fd0f9b0223de40c46019875b9a0c4897ad74a291#eventlog

If we search for this transaction in the ethereum_logs table of the Footprint database, the resulting dataset will include the encoded bytecode in the same form as shown on Etherscan:

https://www.footprint.network/chart/Logs-of-0x9790c03dff59e50372bd1c50fd0f9b0223de40c46019875b9a0c4897ad74a291-fp-39514

The encoded bytecode format is not useful for data analysis purposes. However, by leveraging the contract's ABI, we can decode this bytecode into readable data. Given that the table has already been decoded in Footprint, we can query the table to obtain the decoded information:

https://www.footprint.network/chart/Decoded-0x9790c03dff59e50372bd1c50fd0f9b0223de40c46019875b9a0c4897ad74a291-fp-39515

This decoded information is incredibly useful for analyzing the transaction. For the Transfer event log of an ERC721 token, the structure is always:

Transfer(address from, address to, uint256 value)

Since an event log only has three indexed fields, the data field is used to store information about the number of token transferred in this transaction. Since topic1 is always the Keccak-256 hash of the signature of the event, we only need to decode topic2, topic3, and data to obtain the decoded information.

Submit smart contract

A request to decode a contract can be submitted through a form provided on the Footprint Analytics website:

https://www.footprint.network/submit/contract/

The contract submission form is a several steps process. Initially, we request the contract's blockchain and address.

This step serves two purposes. Firstly, it allows us to check for potential duplicate contracts and any pending submissions. Secondly, it enables us to automate parts of the submission process by retrieving metadata from relevant third-party sources and Footprint.

Upon clicking Next we request additional contract information required for decoding:

If the contract was found through other third-party sources, you only need to provide the project name. Once you submit the required information, the process is complete and you will be able to see your submission in https://www.footprint.network/submit/contract.

However, it is important to note that we conduct a manual quality assurance review, which involves referencing the tables mentioned earlier in https://docs.footprint.network/docs/smart-contracts-decoding#related-tables:

📘

Related tables

After conducting a contract check on our end and approving the submission, the data will be transferred to the official {chain}_decoded_events table. The waiting period may vary depending on the situation.

You can find the mentioned table via the search bar:

In our database, event topics are stored as JSON objects (see https://www.footprint.network/chart/Decoded-0x9790c03dff59e50372bd1c50fd0f9b0223de40c46019875b9a0c4897ad74a291-fp-39515). The most straightforward method to extract the values from the object is by utilizing the following SQL code:

SELECT *,
       json_value(decoded_data, 'strict $.tokenId') AS tokenId
FROM "footprint"."ethereum_decoded_events"
WHERE ("footprint"."ethereum_decoded_events"."contract_address" = '0xec3a9c7d612e0e0326e70d97c9310a5f57f9af9e'
       AND "footprint"."ethereum_decoded_events"."transaction_hash" = '0x9790c03dff59e50372bd1c50fd0f9b0223de40c46019875b9a0c4897ad74a291')

Self-parsing Contracts

If you want to get immediate access to the results of parsing a contract, such as for exploratory data analysis, we also provide a self-service method for parsing a contract.

You can find the bronze logs related table via the search bar

We define a function "udf_decode_event" that to parse the data from the logs table and The SQL example is as follows:

  select
    address ,
    transaction_hash ,
    udf_decode_event(
  '{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Transfer","type":"event"}', 
  "data" ,topics) AS decoded_data 
  from ethereum_logs where address ='0x60e4d786628fea6478f785a6d7e704777c86a7c6' and  transaction_hash ='0xd48ffa07cf7c20d98600fcc8f6de9d2a619e93252ad89143c769cb3c783acfdb'
    and block_timestamp > date '2023-10-07'

The result of parsing “decoded_data” is JSON objects(see https://www.footprint.network/chart/Self-Parsing-Contract-Example-fp-45040). So you can also get the value you want by extracting Json as before.

:fireworks: By reaching this point, you have gained an understanding of this feature and are now capable of enhancing your analysis process with greater thoroughness.