比特幣交易所 比特幣交易所
Ctrl+D 比特幣交易所
ads
首頁 > ETH > Info

EVM 深入探討 Part 2_0X0

Author:

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

點擊閱讀:EVM深入探討Part1

導語

在第1部分中,我們探討了EVM如何通過被調用的合約函數知道需要運行哪個字節碼,其中我們了解了調用棧、calldata、函數簽名和EVM操作碼指令。

在第2部分中,我們將開啟內存之旅,全面了解合約的內存以及它在EVM上的工作方式。

此系列我們將引介翻譯noxx的文章深入探討EVM的基礎知識。

內存之旅

我們依然使用第1部分中在remix上為大家演示的示例代碼。

第1部分中我們根據合約編譯后生成的字節碼研究了與功能選擇相關的部分。在本文中,我們將注意力放在字節碼的前5個字節。

這5個字節表示初始化“空閑內存指針”操作。要完全理解這些字節碼的作用,首先需要理解管理支配合約內存的數據結構。

1、內存數據結構

合約內存是一個簡單的字節數組,其中數據存儲可以使用32字節或1字節的數據塊存儲數據,但是讀取時每次只能讀取固定大小的32字節的數據塊。下面的圖片說明了此結構以及合約內存的讀/寫功能。

這個功能是由操作內存的3個操作碼決定的。

MSTORE(x,y):從內存位置“x”開始存儲一個32字節的“y”?值。

MLOAD(x):從內存位置“x”開始將32字節加載到調用棧上。

Polygon zkEVM已修復阻礙L1資產橋接至L2的漏洞,沒有資金面臨風險:5月29日消息,Scroll 區塊鏈安全研究員 iczc 發推稱,在 Polygon zkEVM 中發現一個漏洞,并獲得來自 Web3 漏洞賞金平臺 Immunefi L2 漏洞賞金。該漏洞導致從 L1 橋接至 Polygon zkEVM(L2)的資產無法在 L2 中正確認領,從而阻礙了 L1 至 L2 的資產遷移。

iczc 在處理認領交易(claim tx)預執行結果的代碼邏輯中發現,惡意攻擊者可以通過將 Gas 費設置為非零來繞過對認領交易的「isReverted」預執行檢查,使其可以通過發送大量低成本的 claim 對定序器和驗證器進行 DoS 攻擊,從而增加計算開銷。此外,交易不會在執行后立即從池中刪除。狀態從「待定」更新為「選定」,并繼續存在于 PostgreSQL 數據庫中。目前,只有一個可信的定序器能夠從交易池中獲取交易并執行它們。因此,另一個漏洞是通過發送一個失敗的交易來惡意標記任何存款數。這將導致正確使用存款數的 認領交易被拒絕,因為存款數已經被使用。這使得新用戶無法使用 L2 網絡。Polygon zkEVM 團隊通過刪除認領交易的特定 gas 邏輯,修復了這一漏洞,沒有資金面臨風險。[2023/5/29 9:48:40]

MSTORE8(x,y):在內存位置“x”存儲一個1字節的值“y”。

你可以將內存位置簡單地看作是開始寫入/讀取數據的數組索引。如果想寫入/讀取超過1個字節的數據,只需繼續從下一個數組索引寫入或讀取。

2、EVMPlayground

EVMPlayground有助于鞏固我們這3個操作碼的運行原理、作用以及內存位置的理解。單擊Run和右上角的箭頭進行調試來查看堆棧和內存是如何更改的。

ConsenSys zkEVM上線測試網并更名為Linea:金色財經報道,ConsenSys宣布將Layer 2解決方案ConsenSys zkEVM更名為Linea,目前向所有開發人員、用戶或協議開放測試。Linea使開發人員能夠不受限制地構建可擴展的DApp。

另外,通過MetaMask和Truffle等原生集成,Linea將零知識證明與EVM等效性相結合,為開發人員提供靈活性和可擴展性,而無需ZK技術專業知識。[2023/3/28 13:30:56]

可能會注意到一些奇怪的現象,我只添加了1個字節,為什么多了這么多零呢?

3、內存擴展

當合約寫入內存時,需要為寫入的字節數支付Gas,也就是擴大內存的開銷。如果我們正在寫入一個以前沒有寫入過的內存區域,那么第一次使用它會產生額外的內存擴展開銷。

寫入之前未觸及的內存空間時,內存以32字節為增量擴展。前724個字節,內存擴展呈線性增長,之后呈二次方增長。(由以太坊黃皮書公式326擴大內存的Gas開銷得出,公式為:

,擴展內存時為每個額外的字的開銷。其中a是合約調用中寫入的最大內存位置,以32字節字為單位。用1024字節內存為例,那么a=32。)

在位置32處寫入1個字節之前,我們的內存是32個字節。此時我們開始往未觸及的內存空間寫入內容,結果,內存增加了32個字節,增加到64個字節。內存中所有位置的都初始被定義為0,這也是為什么我們會看到?2200000000000000000000000000000000000000000000000000000000000000?被添加到內存中的原因。

Zilliqa將于4月25日在主網啟動首個EVM完整兼容版本:金色財經報道,Layer1區塊鏈Zilliqa官方博客宣布,將于4月25日在主網啟動首個EVM完整兼容版本。用戶將能夠使用MetaMask等錢包傳輸本機ZIL,并使用Truffle和Hardhat等工具部署Solidity智能合約。據悉,Zilliqa于2022年12月啟動了EVM兼容性測試網,旨在為Zilliqa引入更廣泛的區塊鏈開發者社區。[2023/3/21 13:16:28]

4、內存是一個字節數組

調試過程中,我們可能注意到的第二件事發生在我們從內存位置33(0x21)運行MLOAD時。我們將以下值返回到調用棧。

3300000000000000000000000000000000000000000000000000000000000000

內存讀取可以從一個非32字節元素開始。

內存是一個字節數組,這意味著可以從任何內存位置開始讀取。我們不限于32的倍數。內存是線性的,可以在字節級別進行尋址。內存只能在函數中新建。它可以是新實例化的復雜類型,如數組/結構或從存儲引用的變量中復制。

現在我們對數據結構已有了一定的了解了,接下來讓我們來看空閑內存指針。

5、空閑內存指針

空閑內存指針只是一個指向空閑內存開始位置的指針。它確保智能合約可以跟蹤到哪些內存位置已寫入,哪些未寫入。這可以防止合約覆蓋已分配給另一個變量的某些內存。當一個變量被寫入內存時,合約將首先引用空閑內存指針來確定數據應該存儲在哪里。然后,它通過記錄要寫入新位置的數據量來更新空閑內存指針。這兩個值的簡單相加將產生新的空閑內存開始的位置。

空閑內存指針的位置+數據的字節大小=新空閑內存指針的位置

6、字節碼

就像我們之前所提到的,空閑內存指針是通過這5個操作碼在運行時字節碼的定義的。

Avalanche DEX Pangolin在Evmos上部署:2月22日消息,Avalanche原生多鏈DEX Pangolin在Evmos上推出了代幣交換和流動性合約功能。這一重大部署將Pangolin社區連接到Cosmos支持IBC的跨鏈生態系統中,也會給Evmos帶來更多的流動性。[2023/2/22 12:23:06]

這些操作碼聲明空閑內存指針位于內存中字節0x40處,值為0x80。

Solidity的內存布局保留了4個32字節的插槽:

0x00-0x3f(64bytes):暫存空間,可用于語句之間,即內聯匯編和哈希散列方法。

0x40-0x5f(32bytes):空閑內存指針,當前分配的內存大小,空閑內存的起始位置,初始化為0x80。

0x60-0x7f(32bytes):插槽0,用作動態內存數組的初始值,永遠不應寫入。

我們可以看到,0x40是空閑內存指針的預定義位置。而值0x80只是在4個32字節保留值插槽之后可寫入的第一個內存字節。

7、合約中的內存

為了鞏固我們到目前為止所學到的知識,接下來將看看內存和空閑內存指針是如何在Solidity代碼中更新的。

我們創建MemoryLane合約來進行演示。合約的?memoryLane()?定義了兩個長度分別為5和2的數組,并將uint256類型的1賦值給?b。

要查看合約代碼在EVM中執行的詳細信息可以將其復制到RemixIDE中編譯并部署合約。調用??memoryLane()?后進入DeBug模式來逐步執行操作碼(以上操作可以參考:

波卡生態NFT項目Moonsama團隊計劃推出兼容EVM波卡Layer 2網絡:9月28日消息,基于Kusama平行鏈 Moonriver 的 NFT 項目 Moonsama 的團隊成員 Donnie 在社交媒體發文表示,該團隊計劃與 Aventus 合作,在兩周內推出兼容 EVM 的波卡 Layer 2 網絡,擬采用基于 NFT 的治理機制。[2022/9/28 5:59:19]

https://remix-ide.readthedocs.io/en/latest/tutorial_debug.html)。

將簡化版操作碼提取到EVMPlayground中,可通過這個鏈接查看具體的操作碼及注釋信息。

這里將操作碼分成6個不同的部分依次解讀,刪除了JUMP以及與內存操作無關的操作碼同時將注釋添加了進去方便查看當前在執行什么操作。

1)空閑內存指針初始化

首先,0x80先入棧,這是由Solidity內存布局規定的值,當前內存中沒有任何東西。

最后,我們調用MSTORE,它將第一項從棧0x40彈出以確定在內存中寫入的位置,并將第二個值0x80作為寫入的內容。這樣留下了一個空棧,但已經填充了一部分到內存中。內存由十六進制字符表示,其中每個字符代表4位。例如:在內存中有192個十六進制字符,這意味著我們有96個字節。如果我們回顧Solidity的內存布局會發現,前64個字節將被分配為暫存空間,接下來的32個字節將用于空閑內存指針。

2)內存分配變量“a”和空閑內存指針更新

接下來的部分,我們將跳到每個部分的結束狀態,并簡潔概述。

首先,為變量“a”分配下一個內存,并更新空閑內存指針。編譯器將通過數組大小和默認數組元素大小確定需要多少空間。Solidity中內存數組中的元素都是占據32字節的倍數。當前需要分配的內存為5*32字節,表示為160或0xa0。我們可以看到它被壓入棧中并添加到當前空閑內存指針0x80來獲取新的空閑內存指針值。這將返回0x120,我們可以看到它已被寫入空閑內存指針位置。調用棧將變量“a”的內存位置保存在棧0x80上,以便以后可以在需要時引用它。0xffff代表一個JUMP位置,可以忽略,因為它與內存操作無關。

3)內存初始化變量“a”

已經分配好了內存并且更新了空閑內存指針,接下來需要為變量“a”初始化內存空間。由于該變量只是被聲明并沒有被賦值,它將被初始化為零值。

EVM通過使用了?CALLDATACOPY操作碼來進行操作,其中存在3個變量。

memoryOffset/destOffset?

calldataOffset/offset

size/length

表達式:

memory=msg.data

在這個例子中,memoryOffset(destOffset)?是變量“a”的內存位置。calldataOffset(offset)?是實際calldata的大小,因為并不需要復制任何calldata,所以初始化內存為零。最后,傳入的變量為0xa0。

這是可以看到我們的內存已經擴展到288字節,并且調用棧再次保存了變量的內存位置和以及棧上的JUMP地址。

這與變量“a”的內存分配和空閑內存指針更新相同,只是這次是針對“bytes32memoryb”。內存指針更新為0x160,等于先前的空閑內存指針288加上新變量的大小64。空閑內存指針已在內存中更新為0x160,那么現在在棧上就擁有變量“b”的內存位置。

與變量“a”的內存初始化相同。現在內存已增加到352字節,棧內仍然保存2個變量的內存位置。

最后,我們開始為數組“b”索引0賦值。代碼指出?b?的值應該為1。該值被壓入棧0x01。接下來發生向左移位,但是移位的輸入為0,這意味著我們的值不會改變。接下來,要寫入0x00的數組索引位置被壓入堆棧,并檢查該值是否小于數組0x02的長度。如果不是,則執行跳轉到處理此錯誤狀態的字節碼的不同部分。MUL和ADD操作碼用于確定需要將值寫入內存中的哪個位置以使其對應于正確的數組索引。

0x20(10進制為32)*0x00(10進制為0)=0x00

需要記住,內存數組是32字節的元素,因此該值表示數組索引的起始位置。鑒于我們正在寫入索引0,沒有偏移量,也就是從0x00開始寫入。

0x00+0x120=0x120

ADD用于將此偏移值添加到變量“b”的內存位置。偏移量為0,直接將數據寫入分配的內存位置。最后,MSTORE將值0x01存儲到這個內存位置0x120。

下圖顯示了函數執行結束時的系統狀態。所有棧項都已彈出。請注意,實際上在remix中還有一些項目留在堆棧上,一個JUMP位置和函數簽名,但是它們與內存操作無關,因此在EVMplayground中被省略了。

內存已更新為包含?b=1?賦值,在我們內存的倒數第三行,0值變成了1。可以驗證該值位于正確的內存位置,b?應占用位置0x120-0x13f。

我們現在對合約內存的工作原理有了一定程度的了解。在后續需要編寫代碼時,將為我們提供很好理解與幫助。當你跳過一些合同操作碼,看到某些內存位置不斷彈出(0x40),現在就知道他們的確切含義了。

在本系列下一篇文章中,我們將在EVM深入探討系列第3部分深入探討合約存儲的工作原理,了解存儲插槽包裝,揭開存儲插槽的神秘面紗。

Tags:0X0OFFFFSSET0X0價格HALO NFT OFFICIALFFS價格LSETH幣

ETH
漏洞早已存在數月?Temple DAO遭受攻擊損失230萬美元事件分析_COM

北京時間2022年10月11日21:11:11,CertiKSkynet天網檢測到項目TempleDAO遭到黑客攻擊,損失約230萬美元.

1900/1/1 0:00:00
金色早報 | 美國9月CPI同比上漲8.2% 連續7個月破8_區塊鏈

頭條 ▌美國9月CPI同比上漲8.2%,連續7個月破810月13日美國中期選舉前最后一份CPI數據出爐,9月CPI同比上漲8.2%,預估為8.1%,前值為8.3%;連續7個月位于8%以上.

1900/1/1 0:00:00
速覽Arbitrum首屆波哥大黑客松獲獎項目_BIT

原文作者:Arbitrum原文編譯:angelilu,ForesightNews在哥倫比亞波哥大舉行的第一屆Arbitrum黑客馬拉松已經正式落下帷幕.

1900/1/1 0:00:00
頭等艙:Aptos投研報告_CLE

華爾街日報:2019年至今SBF一直在接受多動癥和抑郁癥的治療:2月6日消息,FTX曾聘請心理醫生George Lerner博士作為教練,每周在巴哈馬為FTX工作32小時.

1900/1/1 0:00:00
「穩定幣二戰」打響 版圖重塑進行時_USDC

作者:Azuma;編輯:郝方舟主戰場、局部戰場、邊緣戰場,局勢分別如何。“第二次穩定幣大戰已然打響.

1900/1/1 0:00:00
區塊鏈行為報告:加密貨幣采用率上升 Reddit指明方向_區塊鏈

來源:Dappradar作者:SaraGherghelas本報告分析了影響區塊鏈行業2022年第三季度的最重要的行為趨勢。盡管宏觀經濟形勢存在不確定性,但Web3開發人員仍在繼續建設.

1900/1/1 0:00:00
ads