以太坊價格 以太坊價格
Ctrl+D 以太坊價格
ads

LID:智能合約解構(2):創建與運行時間代碼解析

Author:

Time:1900/1/1 0:00:00

本文是系列文章的第二部分。如果您還沒有閱讀本文的前言,請先看一下,第一部分·引言我們正在解構一個簡單的solidity智能合約的EVM字節碼。今天,讓我們開始用“分而治之”的策略來拆解智能合約的復雜代碼吧。我在介紹性的前言中說過,這個反匯編的代碼其實非常低級,但與原始字節碼相比會比較易讀。請確保已在遵循了我在前言中介紹的操作,把BasicToken的代碼在remix編譯器中進行了部署。免責聲明:本文中提供的所有說明均受我自己對transaction運作方式的解釋,不代表以太坊官方意見。現在,讓我們聚焦在JUMP、JUMPI、JUMPDES、RETURN和STOP操作嗎,并忽略所有其他的操作。每當我們發現不是其中之一的操作碼時,我們就忽略它,并跳到下一條指令,不要被他們干預。當EVM執行代碼時,是自上而下的順序,代碼中沒有其他入口點,始終從頂部開始執行。JUMP和JUMPI可以讓代碼跳轉。JUMP獲取堆棧中的最上面的值,并將執行移動到該位置的指令。但是,目標位置必須包含JUMPDEST操作碼,否則執行將失敗。這樣做的唯一目的是:JUMPDEST將位置標記為有效的跳轉目標。JUMPI也完全相同,但堆棧的第二個位置一定不能有“0”,否則就沒有跳轉。所以這是一個有條件的跳轉,STOP是讓智能合約完全停止的指令,RETURN則是暫停智能合約的執行,但返回EVM內存的一部分數據,這很方便。所以,讓我們開始解釋代碼時考慮到所有這些。在Remix的調試器中,將“transaction”的滑塊滑到最左邊。你可以使用StepInto按鈕并按照說明進行操作。前面的指令可以忽略,直接到第11條指令,我們找到了第一條JUMPI。如果它沒有跳轉,它將繼續通過指令12到15并最終進入REVERT,接著將停止執行。但如果跳轉,它將跳過這些指令到位置16。指令16是一個JUMPDEST。繼續單步執行操作碼,直到“transaction”滑塊一直向右。剛剛發生了很多等等,但只有在68的位置才能找到RETURN操作碼。這很奇怪。如果您考慮一下,本智能合約的控制流程將始終在指令15或68結束。我們剛剛完成它并確定沒有其他可能的流程,那么剩下的指令是什么?。我們剛剛遍歷的指令集就是所謂的合約的“創建代碼”。它永遠不會成為智能合約代碼本身的一部分,但僅在創建智能合約的交易期間由EVM執行一次。我們很快就會發現,這段代碼負責設置創建的合約的初始狀態,以及返回其運行時代碼的副本。剩下的497條指令,正如我們所見,執行流程永遠不會達到的,正是這些代碼將成為已部署智能合約的一部分。接下來,我們對代碼進行第一次拆分:把創建時的代碼與運行時的代碼區分開。創建部分

央行數字人民幣智能合約預付資金管理產品“元管家”正式發布:9月8日消息,人民銀行數字貨幣研究所8日在2022第二屆中國(北京)數字金融論壇上發布了數字人民幣智能合約預付資金管理產品-“元管家”。“元管家”在數字人民幣的錢包上部署智能合約,在預付消費服務場景提供防范商戶挪用資金、保障用戶權益的解決方案。(財聯社)[2022/9/8 13:15:57]

現在,我們將深入研究代碼的創建部分。圖1.解構BasicToken.sol的創建時EVM字節碼這是本文中要理解的最重要的概念。創建代碼在事務中執行,該事務返回運行時代碼的副本,該副本是智能合約的實際代碼。正如我們將看到的,構造函數是創建代碼的一部分,而不是運行時代碼的一部分。智能合約的構造函數是創建代碼的一部分;一旦部署,它將不會出現在智能合約的代碼中。這種魔力是如何發生的?這就是我們現在要逐步分析的內容。好的。所以現在我們的問題被簡化為理解這些與創建時代碼相對應的70條指令。讓我們重新采用自上而下的方法,這次了解所有指令,而不是跳過任何指令。首先,讓我們關注使用PUSH1和MSTORE操作碼的指令0到2。圖2.空閑內存指針EVM字節碼結構PUSH1只需將一個字節壓入堆棧頂部,而MSTORE從堆棧中抓取最后兩個項并將其中一個存儲在內存中:mstore(0x40,0x80)|||Whattostore.Wheretostore.(inmemory)注意:上面的代碼片段是Yul-ish代碼。注意它是如何從左到右消耗堆棧中的元素,總是首先消耗堆棧頂部的元素。這是將數字0x80存儲在位置0x40的位置。在我們現在討論的問題中,不用去管它,如果必須有一個原因,我后面會解釋。現在,在Remix的Debugger選項卡中打開Stack以及Memory的面板,以便在逐步查看這些指令時可以可視化。你可能想知道:指令1和3發生了什么?PUSH是唯一由兩個或多個字節組成的EVM指令。所以,PUSH80是兩條指令。所以我們揭開了謎底:指令1是0x80,而指令3的0x40。接下來我會說明從5到15的指令。圖3.non-payable檢查EVM字節碼結構。在這里,又有一大堆的新的操作碼:CALLVALUE,DUP1,ISZERO,PUSH2,和REVERT。CALLVALUE推送創建事務中涉及的wei的數量,DUP1復制堆棧中的第一個元素,如果堆棧的最高值為零,ISZERO則將1推送到堆棧,PUSH2就像PUSH1,但它將兩個字節推送到堆棧,而REVERT則是停止執行。那么這里發生了什么?在Solidity中,我們可以像這樣編寫這個匯編:ifrevert;這段代碼實際上不是我們原始Solidity源的一部分,而是由編譯器注入的,因為我們沒有將構造函數聲明為payable。在Solidity的最新版本中,未明確聲明為payable的函數不能接收以太。返回到匯編代碼,在指令11的JUMPI將跳過指令12到15,如果沒有相關的以太幣,則跳轉到16。否則,REVERT將以兩個參數執行為0。好的!讓我們中場休息一下,來杯咖啡。如果您想要另一種方式來可視化我們剛剛完成的工作,請嘗試使用我構建的這個簡單工具:solmap。它允許您實時編譯Solidity代碼,然后單擊EVM操作碼以突出顯示相關的Solidity代碼。反匯編與Remix有點不同,但你應該能夠通過比較來理解它。咖啡時間到!準備繼續前進了嗎?接下來是指令16到37。請繼續使用Remix的調試器。。圖4.EVM字節碼結構,用于從智能合約字節碼末尾附加的代碼中檢索構造函數參數前四個指令讀取位置在存儲器中的任何內容0x40,并將其推送到堆棧。如果你能回憶起來,那應該是數字0x80。下面是推0x20到堆棧,并拷貝該值,壓棧0x0217,最后拷貝第四個值,這應該是0x80。在查看這樣的EVM指令時,可以暫時不了解發生了什么。別擔心,它會時不時出現在你的腦海。在指令28,執行了CODECOPY,它接受三個參數:目標內存位置,用來存儲復制代碼,從中復制的指令編號,以及要復制的代碼的字節數。因此,在這種情況下,0x80從位于代碼中的字節位置開始。如果查看整個反匯編代碼,有566條指令。為什么這段代碼試圖復制最后32個字節的代碼呢?實際上,在部署包含參數的構造函數的合約時,參數作為原始十六進制數據附加到代碼的末尾。在這種情況下,構造函數接受一個uint256參數,因此所有這些代碼所做的就是將參數從附加在代碼末尾的值復制到內存中。這些32條指令作為反匯編代碼沒有意義,但是它們用原始的十六進制表示:0x0000000000000000000000000...0000000000000000000002710。當然,這是我們在部署智能合約時傳遞給構造函數的十進制值10000!你可以一步一步地在Remix中重復這一部分,確保您了解剛剛發生的事情。最終結果應該是0x00..002710的位置,看到在內存中的數字0x80。好,開始下一部分之前,我建議來一杯威士忌休息一下。威士忌時光!為什么建議你來一杯威士忌,因為從這里開始,都是下坡路了。下一組指令是29到35,更新內存地址0x40的值0x80到值0xa0,可以看到,它們將值偏移了0x20字節。現在我們可以開始理解指令0到2了。Solidity追蹤稱為“空內存指針”的東西:即內存中我們可以用來存儲東西的地方,保證沒有人會覆蓋它。因此,由于我們將數字10000存儲在舊的空閑內存位置,我們通過向前移動32個字節來更新空閑存儲器指針。即使是經驗豐富的Solidity開發人員在看到“空閑內存指針”或代碼時也會感到困惑,mload(0x40,0x80),這些只是說,“每當我們寫一個新條目時,我們將從這一點開始寫入內存并保留偏移記錄”。Solidity中的每個函數,當編譯為EVM字節碼時,將初始化此指針。在0x00到0x40之間的內存有什么,你可能不知道。沒有。Solidity保留的一段內存,計算哈希值,我們很快就會看到,這對于映射和其他類型的動態數據是必需的。現在,在指令37中,MLOAD從存儲器讀取位置0x40并基本上將我們10000的值從內存下載到堆棧中,在那里它將是新的,并且可以在下一組指令中使用的。這是由Solidity生成的EVM字節碼中的常見模式:在執行函數體之前,函數的參數被加載到堆棧中,以便即將到來的代碼可以使用它們-這正是接下來會發生的事情。讓我們繼續說明38至55。圖5.構造函數的主體EVM代碼。這些指令只不過是構造函數的主體:也就是Solidity代碼:totalSupply_=_initialSupply;balances=_initialSupply;前四條指令非常明顯,首先,0被壓入堆棧,然后堆棧中的第二項被復制,然后數字0被復制并被推送到堆棧,這是存儲中的位置槽totalSupply_。現在,SSTORE可以使用這些值,并且仍然保持10000個以下以備將來使用:sstore(0x00,0x2710)|||Whattostore.Wheretostore.(instorage)瞧!我們將數字10000存儲在變量中totalSupply_。是不是很神奇??一定要在Remix的Debugger選項卡中可視化這個值。你可以在存儲完全加載的面板中找到它。下一組指令有點棘手,但基本上會處理在balances映射中存儲10000的密鑰msg.sender。在繼續之前,請確保您了解Solidity文檔的這一部分,該文檔說明了如何在內存中保存映射。簡而言之,它將連接映射值的槽與使用的鍵,然后用SHA3操作碼取摘要并使用它作為在內存中的目標位置。最后,存儲只是一個簡單的字典或哈希表。繼續執行指令43至45,將msg.sender地址存儲在內存中,然后在指令46至50中,將值1存儲在內存位置0x20。最后,SHA3操作碼計算從位置0x00到位置0x40的內存中的任何內容的Keccak256散列-即映射的插槽/位置與所使用的鍵的串聯。這正是值10000將存儲在我們的映射中的位置:sstore(hash...,0x2710)|||Whattostore.Wheretostore.此時,構造函數的主體已完全執行。所有這些起初可能有點壓倒性,但它是存儲在Solidity中工作的基本部分。如果你沒有得到它,我建議你跟著Remix的調試器重復幾次,保持堆棧和內存面板。另外,請隨時提出以下問題。此模式在Solidity生成的EVM字節碼中普遍使用,您將很快學會輕松識別它。最后,它只是計算在內存中保存映射的某個鍵的值的位置。圖6.運行時代碼復制結構在指令56至65中,我們再次執行代碼復制。只有這一次,我們不會將代碼的最后32個字節復制到內存中;我們從位置0x0046開始復制0x01d1字節到位置0的內存。這是要復制的一大塊代碼!如果您再次將滑塊一直向右滑動,您將注意到位置70正好在我們的創建時EVM代碼之后,執行停止的地方。運行時字節碼包含在那些465個字節中。這是代碼的一部分,它將作為智能合約的運行時代碼保存在區塊鏈中,該代碼將是每次有人或某事與智能合約交互時執行的代碼。。這正是指令66到69所做的:返回我們復制到內存的代碼。圖7.運行時代碼返回EVM字節碼結構。RETURN抓取復制到內存的代碼并將其交給EVM。如果此創建代碼在對0x0地址的事務的上下文中執行,則EVM將執行代碼并將返回值存儲為創建的智能合約的運行時代碼。到現在為止,我們的BasicToken代碼將創建和部署智能合約實例,并準備好使用其初始狀態和運行時代碼。如果退后一步并查看圖2,您將看到我們分析的所有EVM字節碼結構都是通用的,除了以紫色突出顯示的那個:也就是說,它們將是由Solidity編譯器生成的創建時字節碼。構造函數與構造函數的區別僅在于紫色部分-構造函數的實際體。獲取嵌入在字節碼末尾的參數的結構,以及復制運行時代碼并將其返回的結構,可以被認為是樣板代碼和通用EVM操作碼結構。您現在應該能夠查看任何構造函數,在按指令學習之前,您應該對構成它的組件有一個大概的了解。在本系列的下一篇文章中,我們將介紹實際的運行時代碼,首先介紹如何在不同的入口點與智能合約的EVM代碼進行交互。現在,給自己一個當之無愧的輕拍,因為你剛剛消化了系列中最困難的部分。你還應該具有強大的能力來讀取和調試EVM字節碼,理解通用結構,最重要的是,了解創建時和運行時EVM字節碼之間的區別。這就是使得合約的構造函數在Solidity中如此特殊的原因。我們將在下一篇的系列文章中繼續解構!*本文由AlejandroSantander首發于medium,由獵豹區塊鏈安全翻譯并整理*獵豹區塊鏈安全以金山霸的技術為依托,結合人工智能、nlp等技術,為區塊鏈用戶提供合約審計、情感分析等生態安全服務。Ratingtoken官網https://www.ratingtoken.net/?from=z

數據:中心化交易所及智能合約中的以太坊供應量變化呈鮮明對比:Glassnode數據顯示,2020年以來,中心化交易所(CEX)及智能合約中的以太坊供應量變化呈現鮮明對比。前者逐步下降,供應量占比自14.50%左右已跌至11.50%附近;后者逐步上升,自11.50%左右攀升至15%上方,且在8月末完成了對前者的超越。[2020/9/19]

Nervos 首席架構師 Jan:智能合約開發者仍屬小眾群體,應該擁抱傳統開發人員:CoinDesk共識大會中文版分會場于北京時間5月12日13-14點在線上舉行,Nervos首席架構師謝晗劍(Jan Xie)在大會中表示,Nervos目前的主要目標是完善CKB的開發者體驗。

與 C、C++和JavaScript社區相比,智能合約開發人員仍然是很小的一個群體。新的智能合約平臺想要成為主流,一個更實際的方法是擁抱傳統的開發人員,讓他們可以使用任何他們已經熟悉的編程語言,而不是創建一種新的語言并強迫他們使用。Nervos構建了一個與RISC-V完全兼容的虛擬機,GCC/LLVM支持的任何編程語言都可以用來在Nervos上編寫智能合約。

這樣的設計實現了讓更多的開發者加入到Nervos網絡中來進行開發,同時也讓Nervos開發者社區更加強大。目前,Nervos已開啟了Grants計劃和孵化器CK Labs計劃,旨在擁抱更多優秀的開發人員。[2020/5/12]

聲音 | EOSLaoMao:將盡快部署示例 DAPP 和 eosio.assert 智能合約:據 IMEOS 報道,根據 EOS LaoMao 團隊消息:1. 我們將在下個版本更新 App 圖標(來自 BlockOne 的建議)2. 目前 EOS 主網尚無 DAPP 支持 EOS Authenticator 協議。3. 我們將聯合 Kylin 測試網絡的 BP 一起,盡快部署示例 DAPP 和 eosio.assert 智能合約。[2019/6/4]

金色財經現場報道 八分量創始人兼CEO阮安邦:區塊鏈及智能合約仍存在部分問題:金色財經現場報道,在2018大數據產業峰會上,八分量創始人兼CEO阮安邦表示,區塊鏈及智能合約仍存在部分問題,首先鏈外運算不可信,除非完整的運算流程均由智能合約編寫,數據在鏈外流傳的任一環節的安全問題都會導致全局可信性的喪失;限定性借口,即便圖靈完備,所支持的接口與功能依舊遠少于存量應用程序;移植重構,無法與存量應用程序兼容,需完全移植,大量重構;完全冗余,智能合約的所有操作均需要在全網絡節點完全重做,造成極大的資源浪費與性能損失;低效共識,共識效率極低,且共識操作價值極低,極大的資源浪費與新能損失。[2018/4/19]

Tags:SOLSOLIDDITLIDAbsoluteSOLID幣Quieroganar AuditsBLID價格

幣安app官網下載
KEN:以社會契約論看比特幣:一個關鍵Bug能殺死比特幣嗎?

編者按:英國家ThomasHobbes認為自我保存和追求幸福是人的本性,但在人人為敵的“自然狀態”中不能夠實現。人們為了擺脫這種狀態,便訂立契約,國家由此產生.

1900/1/1 0:00:00
ITC:解讀澳本聰和他的 Bitcoin SV “兩年小目標”

“澳本聰”克雷格?S?懷特博士是BitcoinSV的最大支持者,也是吳忌寒的“死對頭”,這一點毋庸置疑.

1900/1/1 0:00:00
ECA:權力的游戲:起底EOS核心仲裁論壇

“12名陪審員,1名大法官的陪審制大家都熟悉,但1名陪審員,21名大法官的陪審制應該沒人見過。EOS治理中的仲裁制度似乎更接近于后者。”編者按:本文來自碳鏈價值,作者:李畫,星球日報經授權發布.

1900/1/1 0:00:00
TEN:背靠“韓國豆瓣+愛奇藝”的「Contents Protocol」,想借助token重新制定影視數據收入分配規則

我曾在《已經有6000萬月活用戶的去中心化內容平臺「Contentos」是如何做增量的?》中總結過大同小異的“區塊鏈+內容”故事:一是把積分換成token、鼓勵優質內容生產和傳播的“各種stee.

1900/1/1 0:00:00
PLANET:星球日報 | 研究報告顯示多數頂級交易所偽造交易量;吳忌寒回應“比特大陸控制BSV價格”的猜測;日本政府新增虛擬貨幣“公司稅法”

頭條 研究報告:多數頂級交易所都在偽造交易量區塊鏈透明度研究所最近報告指出,CoinMarketCap上排名前25的交易所每天的總成交量為25億美元,而實際的成交量僅有3.24億美元.

1900/1/1 0:00:00
CAR:2018年“熊王”易主,比特幣力壓A股

本文來自:肖磊看市,作者:肖磊,星球日報經授權轉發。2018年即將過去,回顧這一年,投資市場可謂驚心動魄,中國股市上證綜指以3314點開盤,一月份上漲至最高的3587點,而后一路下跌,至年末收盤.

1900/1/1 0:00:00
ads