原標題:《解碼以太坊智能合約數據》
正如我們在之前的文章中所討論的,智能合約交易類似于智能合約驅動的web3應用程序中的后端API調用。每個智能合約交易和結果應用程序狀態更改的細節都記錄在稱為交易、調用和日志的數據元素中。交易數據元素表示用戶發起的函數調用(更準確地說是EOA),調用數據元素表示智能合約在交易中發起的其他函數調用,而日志數據元素表示交易執行期間發生的事件。
使用這些數據元素,可以非常精細地描述由于交易而在應用程序和區塊鏈上發生的狀態更改。當對一個去中心化的web3應用程序的所有交易、跟蹤和日志進行匯總分析時,可以提供用戶群及其在產品中的活動的整體和深刻的觀點。然而,這樣做是有挑戰性的,因為許多顯著的細節都被記錄為十六進制編碼字符串。例如,在以太坊網絡上使用Uniswap交換一對代幣的交易(該特定記錄可以在Etherscan上查看):
如果在Etherscan上查看交易,就可能已經注意到,它已經解碼了這個原始記錄,并提供了很好的上下文來幫助我們理解交易細節。雖然這非常有幫助,但它并不是為了回答那些需要轉換和匯總數據的問題,例如,所有Uniswap用戶的總交易價值是多少,或者Uniswap用戶3個月的留存率是多少。為了回答這些問題,我們需要能夠收集所有記錄,對其進行解碼,并批量處理相關細節。我們將在接下來的文章中詳細介紹如何做到這一點。
解碼交易
如果我們檢查原始數據記錄,我們可以看到交易是由EOA發起的0x3c02cebb49f6e8f1fc96158099ffa064bbfee38b,發送到與Uniswapv2路由器關聯的智能合約地址0x7a250d5630b4cf539739df2c5dacb4c659f2488d。但是,相關請求詳細信息在input字段中被編碼為一個長十六進制字符串。
在我們討論如何從input中提取人類可讀的數據之前,先談談它的結構將會很有指導意義。前導0x表示該字符串是十六進制的,因此它與實際的信息內容無關。之后,每2個十六進制字符代表一個字節。前四個字節,在本例中是38ed1739,是被調用函數的哈希簽名。其余字節是傳遞給函數的參數的哈希值。這意味著輸入字符串的長度可以根據所調用的特定函數和所需的參數而變化。
為了解碼這個十六進制字符串,我們需要引用應用程序二進制接口或ABI。這是一個json對象,包含給定智能合約的所有函數和事件接口定義(即名稱和類型)。ABI的功能是查找將交易數據中的散列簽名與人類可讀的接口定義進行匹配。ABI示例如下所示:
Uniswapv2路由器ABI的部分視圖
ABI通常可以在像Etherscan這樣的區塊瀏覽器上找到,以及合約源代碼。這是Uniswapv2路由器合約的ABI鏈接。
一旦我們有了ABI,我們就可以編寫來解碼交易:
importtracebackimportsysfromfunctoolsimportlru_cachefromweb3importWeb3fromweb3.autoimportw3fromweb3.contractimportContractfromweb3._utils.eventsimportget_event_datafromweb3._utils.abiimportexclude_indexed_event_inputs,get_abi_input_names,get_indexed_event_inputs,normalize_event_input_typesfromweb3.exceptionsimportMismatchedABI,LogTopicErrorfromweb3.typesimportABIEventfrometh_utilsimportevent_abi_to_log_topic,to_hexfromhexbytesimportHexBytesimportjsonimportredefdecode_tuple(t,target_field):output=dict()foriinrange(len(t)):ifisinstance(t,(bytes,bytearray)):output]=to_hex(t)elifisinstance(t,(tuple)):output]=decode_tuple(t,target_field)else:output]=treturnoutputdefdecode_list_tuple(l,target_field):output=lforiinrange(len(l)):output=decode_tuple(l,target_field)returnoutputdefdecode_list(l):output=lforiinrange(len(l)):ifisinstance(l,(bytes,bytearray)):output=to_hex(l)else:output=lreturnoutputdefconvert_to_hex(arg,target_schema):"""utilityfunctiontoconvertbytecodesintohumanreadableandjsonserializabledatastructures"""output=dict()forkinarg:ifisinstance(arg,(bytes,bytearray)):output=to_hex(arg)elifisinstance(arg,(list))andlen(arg)>0:target===k]iftarget=='tuple':target_field=targetoutput=decode_list_tuple(arg,target_field)else:output=decode_list(arg)elifisinstance(arg,(tuple)):target_field=foraintarget_schemaif'name'inaanda==k]output=decode_tuple(arg,target_field)else:output=argreturnoutput,{"inputs":,"name":"WETH","outputs":,"stateMutability":"view","type":"function"},{"inputs":,"name":"addLiquidity","outputs":,"stateMutability":"nonpayable","type":"function"},{"inputs":,"name":"addLiquidityETH","outputs":,"stateMutability":"payable","type":"function"},{"inputs":,"name":"factory","outputs":,"stateMutability":"view","type":"function"},{"inputs":,"name":"getAmountIn","outputs":,"stateMutability":"pure","type":"function"},{"inputs":,"name":"getAmountOut","outputs":,"stateMutability":"pure","type":"function"},{"inputs":","name":"path","type":"address"}],"name":"getAmountsIn","outputs":","name":"amounts","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":","name":"path","type":"address"}],"name":"getAmountsOut","outputs":","name":"amounts","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":,"name":"quote","outputs":,"stateMutability":"pure","type":"function"},{"inputs":,"name":"removeLiquidity","outputs":,"stateMutability":"nonpayable","type":"function"},{"inputs":,"name":"removeLiquidityETH","outputs":,"stateMutability":"nonpayable","type":"function"},{"inputs":,"name":"removeLiquidityETHSupportingFeeOnTransferTokens","outputs":,"stateMutability":"nonpayable","type":"function"},{"inputs":,"name":"removeLiquidityETHWithPermit","outputs":,"stateMutability":"nonpayable","type":"function"},{"inputs":,"name":"removeLiquidityETHWithPermitSupportingFeeOnTransferTokens","outputs":,"stateMutability":"nonpayable","type":"function"},{"inputs":,"name":"removeLiquidityWithPermit","outputs":,"stateMutability":"nonpayable","type":"function"},{"inputs":","name":"path","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"swapETHForExactTokens","outputs":","name":"amounts","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":","name":"path","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"swapExactETHForTokens","outputs":","name":"amounts","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":","name":"path","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"swapExactETHForTokensSupportingFeeOnTransferTokens","outputs":,"stateMutability":"payable","type":"function"},{"inputs":","name":"path","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"swapExactTokensForETH","outputs":","name":"amounts","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":","name":"path","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"swapExactTokensForETHSupportingFeeOnTransferTokens","outputs":,"stateMutability":"nonpayable","type":"function"},{"inputs":","name":"path","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"swapExactTokensForTokens","outputs":","name":"amounts","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":","name":"path","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"swapExactTokensForTokensSupportingFeeOnTransferTokens","outputs":,"stateMutability":"nonpayable","type":"function"},{"inputs":","name":"path","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"swapTokensForExactETH","outputs":","name":"amounts","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":","name":"path","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"swapTokensForExactTokens","outputs":","name":"amounts","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"stateMutability":"payable","type":"receive"}]'output=decode_tx('0x7a250d5630b4cf539739df2c5dacb4c659f2488d','0x38ed1739000000000000000000000000000000000000000000000000000000009502f900000000000000000000000000000000000000000000a07e38bf71936cbe39594100000000000000000000000000000000000000000000000000000000000000a00000000000000000000000003c02cebb49f6e8f1fc96158099ffa064bbfee38b00000000000000000000000000000000000000000000000000000000616e11230000000000000000000000000000000000000000000000000000000000000003000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2000000000000000000000000528b3e98c63ce21c6f680b713918e0f89dfae555',sample_abi)print('functioncalled:',output)print('arguments:',json.dumps(json.loads(output),indent=2))
國際刑警組織正在調查如何監督元宇宙犯罪:金色財經報道,國際刑警組織(INTERPOL)正在調查如何在元宇宙中監督犯罪。然而,國際刑警組織的一名高級官員認為,定義“元宇宙犯罪”存在一些問題。據BBC報道,國際刑警組織秘書長Jurgen Stock透露,該組織打算監督元宇宙中的犯罪活動。Stock強調了“老練和專業”的罪犯適應新技術工具進行犯罪的能力。
此前2022年10月消息,國際刑警組織推出專門為全球執法部門設計的元宇宙INTERPOL Metaverse,該元宇宙允許注冊用戶參觀法國里昂的國際刑警組織總秘書處總部的虛擬場景,甚至可以通過其Avatar與其他官員進行互動以及為全球執法部門提供沉浸式培訓課程。(Cointelegraph)[2023/2/6 11:50:10]
在示例代碼中有幾點需要注意:
此代碼設計用于批量處理大量交易。它假設數據已經存在于本地存儲中(而不是從區塊鏈實時獲取),并且非常適合像PySpark這樣的分布式處理框架。
這樣我們就更容易理解了。
該調用是對名為swapexacttokensfortokens的方法的調用,用戶正在放入25億單位的起始代幣,并期望至少返回194,024,196,127,819,599,854,524,737單位的目標代幣。這些數字看起來可能是天文數字,但請記住,代幣單位通常用1/10^n表示,其中n大約是18。N有時被稱為代幣的十進制值。該path數組描述了在此交易中交換的代幣。每個數組元素都是代幣合約的地址。第一個是USDC(一種與美元掛鉤的穩定幣),第二個是WrappedEth(帶有ERC20接口的以太坊),第三個是DXO(一種深空游戲貨幣)。將1和2放在一起,我們可以推斷用戶請求交換2,500USDC(USDC的十進制值為6)和大約1.94億DXO(DXO的十進制值為18)。由于這種特殊的成對交換不能直接獲得,交易將通過WETH的中間代幣進行調解。解碼日志
該交易在執行過程中還觸發了7個事件,可以通過logs在以太坊上查詢Google的PublicDataset中的表獲得,也可以通過Etherscan查看。與用戶所要求的交換相對應的兩個最顯著的記錄是:
log_index:47transaction_hash:0x87a3bc85da972583e22da329aa109ea0db57c54a2eee359b2ed12597f5cb1a64transaction_index:37?address:0xb4e16d0168e52d35cacd2c6185b44281ec28c9dcdata:0x000000000000000000000000000000000000000000000000000000009502f90000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000093f8f932b016b1ctopics:?block_timestamp:2021-10-1900:00:18block_number:13444845block_hash:0xe9ea4fc0ef9a13b1e403e68e3ff94bc94e472132528fe8f07ade422b84a43afc
還有
log_index:50transaction_hash:0x87a3bc85da972583e22da329aa109ea0db57c54a2eee359b2ed12597f5cb1a64transaction_index:37?address:0x242301fa62f0de9e3842a5fb4c0cdca67e3a2fabdata:0x0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000093f8f932b016b1c000000000000000000000000000000000000000000a137bb41b9113069a51e190000000000000000000000000000000000000000000000000000000000000000topics:?block_timestamp:2021-10-1900:00:18block_number:13444845block_hash:0xe9ea4fc0ef9a13b1e403e68e3ff94bc94e472132528fe8f07ade422b84a43afc
伏泰昊:JUST主動思考如何在波場上建立完善的DeFi體系:據最新消息顯示,波場大航海時代4.0全球線上發布會正在進行中,JUST項目負責人伏泰昊在發布會中表示:“JUST旨在打造基于波場TRON的穩定幣借貸平臺,一個好的金融產品離不開下面應用層的穩定輸入與輸出,會有多個協議與應用的交叉集合,長期來看,JST代幣作為整個治理體系的代幣,我們會提供多種底層借貸協議和報價協議等,為用戶提供全面的金融服務。作為DeFi明星項目,JUST不僅致力于開拓波場的穩定幣市場,也在主動思考如何在波場上建立完善的DeFi體系。”[2020/7/7]
同樣,相關詳細信息在topics和data字段中編碼為十六進制字符串。與transaction的情況一樣,input瀏覽這些數據字段的結構是有益的。topics是一個數組,其中第一個元素表示事件接口定義的哈希簽名。topics數組中的任何其他元素通常是事件中涉及的區塊鏈地址,根據具體上下文可能存在,也可能不存在。data表示事件參數值,其長度根據事件定義而不同。與交易的情況一樣,我們需要引用合約ABI,以便將其轉換為人類可讀的形式。
敏銳的讀者會注意到上面日志中的合約地址0xb4e16d0168e52d35cacd2c6185b44281ec28c9dc和0x242301fa62f0de9e3842a5fb4c0cdca67e3a2fab與用戶EOA最初調用的Routerv2合約0x7a250d5630b4cf539739df2c5dacb4c659f2488d不同。這兩個地址對應USDC-WETH和DXO-WETH代幣對的Uniswapv2對合約。這些合約負責持有各自交易對的流動性,并實際進行交換。用戶最初與之交互的Router合約作為一個協調器,并向適當的配對合約發起內部交易(跟蹤)。因此,為了解碼這些事件,我們還需要一對合約ABI。解碼日志示例如下:
fromweb3._utils.eventsimportget_event_datareturntopic2abievent_abi=topic2abi]evt_name=event_abidata=get_event_data(w3.codec,event_abi,log)target_schema=event_abidecoded_data=convert_to_hex(data,target_schema)return(evt_name,json.dumps(decoded_data),json.dumps(target_schema))exceptException:return('decodeerror',traceback.format_exc(),None)else:return('nomatchingabi',None,None)pair_abi=',"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":,"name":"Approval","type":"event"},{"anonymous":false,"inputs":,"name":"Burn","type":"event"},{"anonymous":false,"inputs":,"name":"Mint","type":"event"},{"anonymous":false,"inputs":,"name":"Swap","type":"event"},{"anonymous":false,"inputs":,"name":"Sync","type":"event"},{"anonymous":false,"inputs":,"name":"Transfer","type":"event"},{"constant":true,"inputs":,"name":"DOMAIN_SEPARATOR","outputs":,"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":,"name":"MINIMUM_LIQUIDITY","outputs":,"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":,"name":"PERMIT_TYPEHASH","outputs":,"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":,"name":"allowance","outputs":,"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":,"name":"approve","outputs":,"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":,"name":"balanceOf","outputs":,"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":,"name":"burn","outputs":,"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":,"name":"decimals","outputs":,"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":,"name":"factory","outputs":,"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":,"name":"getReserves","outputs":,"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":,"name":"initialize","outputs":,"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":,"name":"kLast","outputs":,"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":,"name":"mint","outputs":,"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":,"name":"name","outputs":,"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":,"name":"nonces","outputs":,"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":,"name":"permit","outputs":,"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":,"name":"price0CumulativeLast","outputs":,"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":,"name":"price1CumulativeLast","outputs":,"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":,"name":"skim","outputs":,"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":,"name":"swap","outputs":,"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":,"name":"symbol","outputs":,"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":,"name":"sync","outputs":,"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":,"name":"token0","outputs":,"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":,"name":"token1","outputs":,"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":,"name":"totalSupply","outputs":,"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":,"name":"transfer","outputs":,"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":,"name":"transferFrom","outputs":,"payable":false,"stateMutability":"nonpayable","type":"function"}]'output=decode_log('0x000000000000000000000000000000000000000000000000000000009502f90000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000093f8f932b016b1c',,pair_abi)print('eventemitted:',output)print('arguments:',json.dumps(json.loads(output),indent=2))
聲音 | 海爾集團董事局主席:如何利用區塊鏈改變企業未來:海爾集團董事局主席、首席執行官張瑞敏在近期參加的活動時提出:產品會被場景替代,行業將被生態覆蓋。海爾以區塊鏈為載體,以分布式賬本彼此間分享基于物聯網的數據資源,一方面不斷優化用戶體驗,一方面所有生態攸關方均得到增值,多方共贏。海爾依據自身優勢在區塊鏈領域展開了3個方向的探索:第一,以先發優勢,參與制定區塊鏈標準;第二,以延伸效應,賦能產業生態;第三,以區塊鏈思維,變革組織結構。(IT168)[2019/11/19]
與交易解碼的代碼類似,示例代碼針對批量解碼用例進行了優化,并與類似PySpark的東西一起使用,以處理大量日志事件。運行以上收益率:
eventemitted:Swaparguments:{"sender":"0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D","to":"0x242301FA62f0De9e3842A5Fb4c0CdCa67e3A2Fab","amount0In":2500000000,"amount1In":0,"amount0Out":0,"amount1Out":666409132118600476}
還有
eventemitted:Swaparguments:{"sender":"0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D","to":"0x3c02cebB49F6e8f1FC96158099fFA064bBfeE38B","amount0In":0,"amount1In":666409132118600476,"amount0Out":194900241391490294085918233,"amount1Out":0}
我們可以認為這兩個確實swap是path在初始請求之后發生的事件——USDC>WETH>DXO。我們可以看到路由器合約(以488D結尾)是兩個事件中的發送方,充當協調者。USDC-WETH對合約(以c9dc結尾)將25億單位USDC換成666,409,132,118,600,476單位WETH,然后將產生的WETH轉移到DXO-WETH對合約(結束2Fab)。DXO-WETH合約將666,409,132,118,600,476單位的WETH置換為194,900,241,391,490,294,085,918,233單位的DXO,并按照最初的要求將其發送回用戶(EOA結束于E38B)。
結束語
正如本例所示,一旦我們有了工具,解碼的過程就相對簡單了,但知道要解碼什么以及如何解釋結果數據就不是那么簡單了。根據我們嘗試回答的具體問題,某些功能和事件比其他功能和事件更相關。為了分析web3應用程序中的經濟活動和用戶行為,了解特定智能合約的工作方式并確定感興趣的指標中涉及的關鍵功能和事件非常重要。這最好是通過實際使用該產品、在像Etherscan這樣的區塊瀏覽器上檢查數據消耗以及閱讀智能合約源代碼的組合來實現。這是制定正確的解碼和分析策略的關鍵條件。
Source:https://towardsdatascience.com/decoding-ethereum-smart-contract-data-eed513a65f76
聲音 | Brendan 發推特表達如何實現成功:據 IMEOS 報道,Block.one CEO Brendan Blumer 發推特表示,成功通常是有具備充分理由讓社區聽從你,并實際提供他們(社區)想要的東西來實現。[2018/10/1]
金色財經現場報道 360官方人員現場展示如何攻擊EOS漏洞:金色財經現場報道,EOS區塊鏈平臺漏洞媒體溝通會上,360官方人員現場展示了是如何攻擊的,攻擊展示圖片見下圖。[2018/5/29]
11月4日,在2021騰訊數字生態大會上,騰訊云區塊鏈聯合騰訊研究院共同發布《鏈計算:構建信任網絡,致力無邊界協同》白皮書.
1900/1/1 0:00:00據中國網報道,國家發展改革委定于11月16日上午10:00召開11月份例行新聞發布會,國家發展改革委新聞發言人介紹有關情況,并回答記者提問.
1900/1/1 0:00:00巴比特訊,11月8日,以太坊二層解決方案zkSync開發公司MatterLabs宣布完成5000萬美元B輪融資,AndreessenHorowitz領投.
1900/1/1 0:00:00據CoinGape10月30日消息,Ripple發布第三季度XRP市場報告,自愿提供透明度和定期更新公司對加密市場狀況的看法,如季度銷售更新、與XRP相關的公告和對上一季度市場發展的評論.
1900/1/1 0:00:00巴比特訊,10月29日,加密貨幣風險基金CollabCurrency宣布完成6000萬美元的新基金募資,將繼續投資早期加密項目。CollabCurrency還在推出的新網站上列出其投資組合.
1900/1/1 0:00:00鏈集市?·讓區塊鏈落地更簡單 《區塊鏈行業觀察》專欄·第60?篇作者丨Abhinav?Chugh 圖片丨來源于網絡 區塊鏈技術為在各方之間建立信任奠定了基礎,但是還未發揮其潛力.
1900/1/1 0:00:00