當我們部署和調用合約的時候,EVM 都在做些什么?
如果你開發過以太坊智能合約,想必你應該熟悉這樣的操作 (此處以remix為例) :
編寫solidity代碼 -> 編譯 -> 部署-> 交互 。合約的編寫與部署似乎并不是一件很麻煩的操作:編寫階段就不說了,Solidity語言大家都應該會;到了編譯階段,本地的 solc 編譯器會把 Solidity 代碼編譯成字節碼(bytecodes);而在部署階段,部署者通過發起一筆特殊交易(to的地址為空)calldata 帶上編譯后的字節碼,等交易上鏈之后,就完成了合約的部署;而合約交互,就是call合約里的某個函數,等待函數的響應和返回,一切就是這樣的簡單。
但是正如開車一樣,當你踩住油門后,車輛開始前進。然而這看似簡單的操作背后是汽油爆燃、活塞往復、數百個齒輪嚙合傳動、輪胎與地面滾動摩擦的復雜行為。部署和調用合約也是如此,它涉及到 EVM 的堆棧操作,內存讀寫,存儲訪問等一系列底層操作。當部署合約時, EVM 把收到的 calldata 翻譯成操作指令,把它們按照給定的長度和參數讀入內存;當調用合約時,EVM 又根據收到的 calldata ,通過函數選擇器來確定調用哪一段代碼,并返回數值。如果只講理論未免過于枯燥,為了便于講解,我們這次用 ethernaut 的一道題目作為例子,詳細了解 EVM 是如何部署和運行合約的,以及如何充當人肉編譯器,徒手編寫智能合約。
以太坊BTC錨定幣總鎖倉量突破160億美元 創歷史新高:金色財經報道,隨著BTC價格來到5.7萬美元上方,以太坊上的BTC錨定幣總鎖倉量也上漲并創下歷史新高。據最新數據顯示,以太坊上的BTC錨定幣總鎖倉量已突破160億美元,本文撰寫時為162.8億美元,總發行量為28.676萬枚,按鎖倉量排名前三的BTC錨定幣分別是:
1、WBTC:發行量208719枚,鎖倉量11,849,380,871美元;
2、HBTC:發行量39906枚,鎖倉量2,265,564,271美元;
3、renBTC:發行量17347枚,鎖倉量984,830,357美元。[2021/10/11 20:20:29]
這個題目是這樣的:我們需要部署一個合約,當我們調用合約 **whatIsTheMeaningOfLife()**函數的時候,它需要返回一個數字 “42”。看起來很簡單對吧?我們分分鐘編寫完畢:
慢著,題目后面還有個小小的附加要求:“所部署的合約大小不超過10個操作碼”。好吧,這個要求的確夠“小”,要知道連合約頭部的 “函數選擇器” 都不止 10 個操作碼好吧?可是“函數選擇器” 是什么,為什么會出現在合約里面呢?帶著你的疑問,繼續向下看。
Synthetix啟動以太坊二層擴容方案Optimistic測試第二階段:據官推消息,合成資產平臺Synthetix宣布已啟動以太坊二層擴容方案Optimistic Ethereum測試的第二階段。在此階段,Synthetix將與Optimistic嘗試從一層(L1)遷移至二層(L2),并擴大可以參與的用戶數量。[2020/10/14]
我們通過 ./solc --asm --bin target.sol 來看看這個合約的最終編譯結果:
608060405234801561001057600080fd5b5060b68061001f6000396000f3fe6080604052348015600f57600080fd5b506004361060285760003560e01c8063650500c114602d575b600080fd5b60336047565b604051603e91906067565b60405180910390f35b6000602a905090565b6000819050919050565b6061816050565b82525050565b6000602082019050607a6000830184605a565b9291505056fea26469706673582212206ef8c7b5177952a701b3b46b69cb3ec296f4c54c946692e8ec901f5e43c1e78a64736f6c63430008110033
以太坊未確認交易9782筆:金色財經報道,據Etherscan.io數據顯示,以太坊未確認交易9782筆。當前挖礦難度2293.53TH,交易處理能力7.72TPS。截至目前以太坊全球均價為214.78美元,日內跌幅2.55%。[2020/3/2]
這么一大坨十六進制數據,就是上述 Solidity 程序編譯之后的字節碼。當我們部署合約時,把這一堆 data 發給以太坊節點,等廣播完成后,合約就部署完畢了。這是 solc 編譯器編譯 Solidity程序得到的代碼,看似雜亂無章的的數據,其實都是和 opcodes 一一對應的。我們來一段一段地看這些代碼:
合約部署代碼:
合約運行代碼:
auxdata:
我們先簡單地把這堆代碼分為合約的部署代碼、運行代碼、auxdata 三部分,如何理解這三種代碼呢?我覺得可以理解為向太空發射衛星:“部署代碼” 就是運載火箭,而“運行代碼”就是衛星。運載火箭只在發射衛星時才起到作用,一旦衛星進入軌道,火箭就廢棄了,只留下衛星在太空中與地球通信。 部署合約也是如此,在部署合約時,部署代碼把一些初始化工作作完之后,就把合約的運行代碼送入EVM,只留下運行代碼在鏈上與用戶進行交互。 (至于auxdata,它是緊跟在runtime代碼后面的43個字節,相當于源碼的指紋,可以用來驗證。這只是數據,并不會被EVM執行。)
分析 | 以太坊空頭勢力出現增長 PMR處于較低水平:據TokenGazer數據分析顯示,截止至5月23日11時,以太坊價格為$244.22,交易量為$10,091.5M,總市值為$25,932.7M,期貨方面,目前Bitfinex和BitMEX總多單量統計數據為$138.8M,總空單量數據為$48.0M,空頭勢力在昨日市場回調中有一定抬頭趨勢;根據 TokenGager 數據監測,目前 ETH 的 PMR 處在較低水平,存在回升潛力。目前,抵押在Maker上的ETH仍在以一定速率減少;目前ERC20代幣總市值約為以太坊總市值的59.03%,環比昨日上升了1.17%;在活躍地址數方面,排名前五的代幣為USDC、DAI、TUSD、LINK、ZRX,連續多日穩定幣應用占據主流位置。[2019/5/23]
那么言歸正傳,我們題目要求我們合約運行代碼的 opcedes 不超過 10 條,那么,這段代碼對應的 opcodes 是多少條呢?答:71 條。(通過查看 Remix : ./artifacts/MagicNum.json 中的 bytecode 里的 opcodes 可以看到。而 deployedBytecode 里的 opcodes 卻是 92 條,因為它的長度是 部署代碼 + 運行代碼 )
以太坊經典團隊2018年的三個明確目標:據cryptogazette,以太坊經典團隊在2018年有三個非常明確的目標:1. 核心投資領域:2018年及以后,ETC將通過ECC的努力進行改造。ECC已經制定了指導方針,以確保所有ETC資金在ETC協議開發,市場營銷和社區舉措進行部署;2. ECC的主要項目:ETC開發。不久之后,ETC將成為令牌項目和dApp的首選;3. 改善營銷并培養強大的社區。[2018/3/17]
那么問題來了,如何把 71 條 opcodes 精簡到 10 條以內呢? 這就需要我們對 EVM 運行智能合約的方式有著一定的了解。如果不了解也沒關系,拿起你手邊的 EVM 指令集 ,我們一起來看看吧:
首先我們要知道,EVM 執行代碼時是按照自上而下的順序執行的,代碼中沒有其他入口點,始終從頂部 (也就是第一行 opcode ) 開始執行。(這點和 Windows 軟件不一樣,PE文件是有固定的入口點的,而且不同的 Windows 版本或不同的 PE 文件 入口點也會有所不同)。也就是說,當我們部署合約時, EVM 會從第一個bytecode開始讀起。
所以我們看字節碼最前面的部分,也就是它的部署代碼:608060405234801561001057600080fd5b5060b68061001f6000396000f3fe
對照 EVM 指令,我們可以識別出這段代碼的含義:
然后我們看合約的運行代碼:
綜合以上可以發現,合約的運行代碼的架構是這樣的:
初始化操作、函數選擇器這些,是 solc 在編譯 Solidity 程序的時候自動生成的。如果我們砍掉這些復雜的東西,直接把我們想要的核心功能編碼上去,不就可以在 10 條以內opcodes 實現既定功能了嗎?
通過分析 圖4 的 whatIsTheMeaningOfLife() 函數調用棧可以得知,讓智能合約返回 “42” ( 十六進制 0x2a) 的關鍵在于 先用 mstore 指令將 0x2a 放入 Memory , 再用 return 指令將內存里的 0x2a 返回即可。至于那些函數名稱和函數簽名,只是高級語言的編譯產物,直接用匯編實現的話,我們直接用這段代碼讀寫內存,完全沒有必要搞那些花里胡哨:
以上代碼相當于構造了一個十分小的合約“運行代碼”。前面我們說過,EVM 執行代碼時是按照自上而下的順序執行的,代碼中沒有其他入口點,始終從頂部 (也就是第一行 opcode ) 開始執行。而且我們編寫的代碼并沒有函數選擇器,也就是說,當外部賬戶調用該它時,無論傳遞給它什么樣的參數、什么樣的函數簽名, EVM 都只會從它的 [00] 處開始執行,老老實實地走到 [09],然后 return 給我們一個 0x20.
但這只是運行代碼,還記得本文開頭說的那三段字節碼嗎?是的,我們還差一個“運載火箭”(部署代碼),把這段運行代碼給發射出去:
部署代碼的結構基本沒怎么變,之前已有解析,此處就不羅嗦了,唯一的區別是把復制到內存的長度由 b6 改為 0a : 608060405234801561001057600080fd5b50600a8061001f6000396000f3fe
然后把他們拼接到一起,記得部署代碼在前、運行代碼在后,最后我們把這段代碼發射出去就 OK了:
你將得到一個超級小巧、只有 10 個字節、無論傳遞什么參數都 只 會 返 回 42 的 “智能合約” (這么說看起來并不智能的樣子……)
全文完。
關于作者:
https://twitter.com/0xNezha
來源:bress
Bress
個人專欄
閱讀更多
金色早8點
Odaily星球日報
潘達看Web3
DeFi之道
區塊律動BlockBeats
比推 Bitpush News
本文轉自公號:老雅痞(laoyapi) 大多數訪問 Horizon Worlds 的游客通常不會在第一個月后返回;“空虛的世界是悲傷的世界”.
1900/1/1 0:00:00原文作者:Sihan, CloudY原文編輯:Vincero, YL, DoctorStrange一、DeSci所解決的問題傳統的科研是以中心化的方式來尋求科研經費以及資源,如國家自然基金.
1900/1/1 0:00:00一GMX巨鯨質押逾17.5萬枚GMX,約合893萬美元:6月9日消息,據 Lookonchain 監測,一 GMX 巨鯨在 3 小時前質押 175,090 枚 GMX(約合 893 萬美元).
1900/1/1 0:00:00來源:老雅痞 導讀 我們之前分析過read 2 earn這種形式,當時在我們的讀者群里,大家就討論過電子書市場怎樣和Web3結合。你看看,這不就來了.
1900/1/1 0:00:00FTX的致命傷是什么?我覺得FTX這個事件還是Luna和三箭資本事件的一個延展。最早門頭溝(MtGox)當年暴雷的時候也有很多研究報告,有人發現MtGox內部有自己專門的交易賬號.
1900/1/1 0:00:00近年來,區塊鏈技術應用和產業已經具備良好的發展基礎,在防偽溯源、供應鏈管理、司法存證、政務數據共享、民生服務等領域涌現了一批有代表性的區塊鏈應用.
1900/1/1 0:00:00