header-langage
简体中文
繁體中文
English
Scan to Download the APP
Partnered With:

How to decode ethereum smart contract data and process the details in bulk?

Read this article in 18 Minutes
Once we have the tools, the decoding process is relatively simple
Decoding Ethereum Smart Contract Data
Original author: Yifei Huang, Sequoia Capital
ChinaDeFi




As we discussed in a previous article, smart contract transactions are similar to back-end API calls in smart contract-driven Web3 applications. Details of each smart contract transaction and resulting application state change are recorded in data elements called transactions, calls, and logs. The transaction data element represents function calls (EOA, to be more precise) initiated by the user, the call data element represents other function calls initiated by the smart contract during the transaction, and the log data element represents events that occur during the execution of the transaction.


Using these data elements, it is possible to describe state changes that occur on the application and blockchain as a result of transactions in a very fine manner. When you aggregate and analyze all the transactions, tracking, and logging of a decentralized Web3 application, you can provide a holistic and insightful view of the user population and their activities within the product. However, doing so is challenging because many of the salient details are recorded as hexadecimal encoded strings. For example, a transaction using Uniswap to exchange a pair of tokens on the Ethereum network (this particular record can be viewed on Etherscan):




If you looked at the transaction on Etherscan, you might have noticed that it decoded the original record and provided a good context to help us understand the transaction details. While this is very helpful, it is not intended to answer questions that require converting and aggregating data, such as what is the total transaction value of all Uniswap users, or what is the three-month retention rate of Uniswap users. To answer these questions, we need to be able to collect all the records, decode them, and process the details in bulk. We'll detail how to do this in the next article.


Decoding the deal


If we check the original data record, we can see that the transaction is initiated by eoaare perfectly legal in the 0 x3c02cebb49f6e8f1fc96158099ffa064bbfee38b, Sent to the intelligent contracts associated with Uniswap v2 router address 0 x7a250d5630b4cf539739df2c5dacb4c659f2488d. However, the relevant request details are encoded as a long hexadecimal string in the input field.


Before we discuss how to extract human-readable data from input, it would be instructive to talk about its structure. The leading 0x indicates that the string is hexadecimal, so it is irrelevant to the actual information content. After that, every 2 hexadecimal characters represent a byte. The first four bytes, in this case 38ED1739, are the hash signature of the function being called. The remaining bytes are hashes of arguments passed to the function. This means that the length of the input string can vary depending on the particular function being called and the parameters required.


To decode this hexadecimal string, we need to reference the application binary interface or ABI. This is a JSON object that contains all function and event interface definitions (that is, names and types) for a given smart contract. The ABI's function is to find and match hash signatures in transaction data with human-readable interface definitions. An EXAMPLE ABI looks like this:


Partial view of the Uniswap V2 router ABI


The ABI is usually found on block browsers like Etherscan, along with the contract source code. This is the ABI link for the Uniswap V2 router contract.


Once we have an ABI, we can write to decode transactions:




There are a few things to note in the sample code:


1. This code is designed to process a large number of transactions in batches. It assumes that the data already exists in local storage (rather than being fetched in real time from the blockchain) and is well suited for distributed processing frameworks like PySpark.


2.@lru_cache(maxsize=None) - We cache contract object creation to reduce the overhead of repeating the same calculation over a large number of transactions. This assumes decoding for a small number (thousands) of different smart contracts.


3. It uses the open source Web3 package method decode_function_input to extract data based on templates provided in the ABI. However, the data returned by this method is usually non-serializable (such as byte arrays) and sometimes loses human-readable keys. Therefore, it is very helpful (and may even be necessary) to use the utility method to perform the post-extraction convert_to_HEX to convert the data into a serializable JSON object and attach human-understandable keys where missing. This makes it easier to persist and reuse decoded data.


4. The same code can be used to decode trace data elements. This is because they are simply internal transactions initiated by smart contracts.


Use the code above to get the decoded input data


function called: swapExactTokensForTokens arguments: { "amountIn": 2500000000, "amountOutMin": 194024196127819599854524737, "path": [ "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48", "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2", "0x528B3e98c63cE21C6f680b713918E0F89DfaE555" ], "to": "0x3c02cebB49F6e8f1FC96158099fFA064bBfeE38B", "deadline": 1634603299}


So it's easier for us to understand.


1. The call is to a method called SwapexactTokensforTokens. The user is putting in 2.5 billion starting tokens, And it is expected that the aim of return at least 194024196127819599854524737 units Token. These numbers may seem astronomical, but keep in mind that Token units are usually expressed as 1/10^n, where n is approximately 18. N is sometimes called the decimal value of Token.


2. The PATH array describes the tokens exchanged in this transaction. Each array element is the address of the Token contract. The first is USDC(a stablecoin pegged to the DOLLAR), the second is Wrapped Eth(Ethereum with an ERC20 interface) and the third is DXO(a deep-space gaming currency).


3. Putting 1 and 2 together, we can infer that the user requests to exchange 2,500 USDC (which has a decimal value of 6) and about 194 million DXO (which has a decimal value of 18). Since this special pair exchange cannot be obtained directly, the transaction will be mediated through an intermediate Token (WETH).


Decoding the log


The transaction also fires seven events during execution, which can be obtained by querying the tables in Google's Public Dataset on Ethereum or viewed with Etherscan. The two most notable records that correspond to the exchange requested by the user are:


log_index: 47 transaction_hash: 0x87a3bc85da972583e22da329aa109ea0db57c54a2eee359b2ed12597f5cb1a64 transaction_index: 37 address: 0xb4e16d0168e52d35cacd2c6185b44281ec28c9dc  data: 0x000000000000000000000000000000000000000000000000000000009502f900000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 00093f8f932b016b1c topics: [ '0xd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d822', '0x0000000000000000000000007a250d5630b4cf539739df2c5dacb4c659f2488d', '0x000000000000000000000000242301fa62f0de9e3842a5fb4c0cdca67e3a2fab'] block_timestamp: 2021-10-19 00:00:18 block_number: 13444845 block_hash: 0xe9ea4fc0ef9a13b1e403e68e3ff94bc94e472132528fe8f07ade422b84a43afc


There are


log_index: 50 transaction_hash: 0x87a3bc85da972583e22da329aa109ea0db57c54a2eee359b2ed12597f5cb1a64 transaction_index: 37 address: 0x242301fa62f0de9e3842a5fb4c0cdca67e3a2fab data: 0x0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000093f8f 932b016b1c000000000000000000000000000000000000000000a137bb41b9113069a51e190000000000000000000000000000000000000000000000 000000000000000000 topics: [ '0xd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d822', '0x0000000000000000000000007a250d5630b4cf539739df2c5dacb4c659f2488d', '0x0000000000000000000000003c02cebb49f6e8f1fc96158099ffa064bbfee38b']  block_timestamp: 2021-10-19 00:00:18 block_number: 13444845 block_hash: 0xe9ea4fc0ef9a13b1e403e68e3ff94bc94e472132528fe8f07ade422b84a43afc


Again, the related details are encoded as hexadecimal strings in topics and data fields. As in the case of Transaction, it is useful for INPUT to browse the structure of these data fields. Topics is an array where the first element represents the hash signature of the event interface definition. Any other element in the Topics array is usually the blockchain address involved in the event, which may or may not exist depending on the context. Data represents the event parameter value, whose length varies according to the event definition. As in the case of transactions, we need to refer to the contract ABI in order to convert it into a human-readable form.


Keen readers will notice that the above log xb4e16d0168e52d35cacd2c6185b44281ec28c9dc address 0 and 0 x242301fa62f0de9e3842a5fb4c0cdca67e3a2fab eoaare perfectly legal Initially called the Router v2 0 x7a250d5630b4cf539739df2c5dacb4c659f2488d different contract. The two addresses correspond to the Uniswap V2 contract of the USDC-weth and DXO-weth Token pair. These contracts are responsible for holding the liquidity of their respective trading pairs and actually exchanging them. The Router contract with which the user initially interacts acts as a coordinator and initiates an internal transaction (trace) to the appropriate pairing contract. Therefore, to decode these events, we also need a pair of contract ABIs. The following is an example of a decoding log:




Similar to the code for transaction decoding, the sample code is optimized for bulk decoding use cases and is used with something like PySpark to handle a large number of logging events. Run above rate of return:


event emitted: Swap arguments: { "sender": "0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D", "to": "0x242301FA62f0De9e3842A5Fb4c0CdCa67e3A2Fab", "amount0In": 2500000000, "amount1In": 0, "amount0Out": 0, "amount1Out": 666409132118600476}


There are


event emitted: Swap arguments: { "sender": "0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D", "to": "0x3c02cebB49F6e8f1FC96158099fFA064bBfeE38B", "amount0In": 0, "amount1In": 666409132118600476, "amount0Out": 194900241391490294085918233, "amount1Out": 0 }


We can think of these two actual swaps as events that occurred after the initial request for the path -- USDC > WETH > DXO. We can see that the router contract (ending with 488D) is the sender of the two events, acting as the coordinator. Usdc-weth to contract (ending with C9DC) change 2.5 billion UNITS of USDC to 666,409,132,118,600,476 units of WETH, and then transfer the resulting WETH to DXO-weth to contract (ending with 2Fab). DXO - WETH contract will WETH replacement of 666409132118600476 units to 194900241391490294085918233 units of DXO, It is sent back to the user as originally requested (EOA ends at E38B).


conclusion


As this example shows, once we have the tools, the decoding process is relatively simple, but knowing what to decode and how to interpret the resulting data is not. Depending on the specific question we're trying to answer, some features and events are more relevant than others. To analyze economic activity and user behavior in web3 applications, it is important to understand how specific smart contracts work and to identify key functions and events involved in metrics of interest. This is best done through a combination of actually using the product, checking data consumption on block browsers like Etherscan, and reading the smart contract source code. This is the key condition to develop the correct decoding and analysis strategy.


The original link


Welcome to join the official BlockBeats community:

Telegram Subscription Group: https://t.me/theblockbeats

Telegram Discussion Group: https://t.me/BlockBeats_App

Official Twitter Account: https://twitter.com/BlockBeatsAsia

举报 Correction/Report
Choose Library
Add Library
Cancel
Finish
Add Library
Visible to myself only
Public
Save
Correction/Report
Submit