EVM 是一個輕量級的虛擬機,其設計初衷就是提供一種可以忽略硬件、操作系統等兼容性的虛擬的執行環境供以太坊網絡運行智能合約。
簡單來說 EVM 是一個完全獨立的沙盒,在 EVM 中運行的代碼是無法訪問網絡、文件系統和其他進程的,以此來避免錯誤的代碼能讓智能合約毀滅或者影響外部環境。
在此基礎上,知道創宇區塊鏈安全實驗室帶大家一起深入理解 EVM 的存儲機制和安全問題。
可以看到 EVM 存儲數據分為兩類:
存儲在 code 和 storage 里的數據是 non-volatile (不容易丟失的)
存儲在 stack,args,memory 里數據是volatile(容易丟失的)
Code
code 部署合約時儲存 data 字段也就是合約內容的空間,即專門存儲智能合約的二進制源碼的空間
Storage
Storage 是一個可以讀寫修改的持久存儲的空間,也是每個合約持久化存儲數據的地方。Storage 是一個巨大的 map,一共 2^256 個插槽 (slot),每個插糟有 32byte,合約中的“狀態變量”會根據其具體類型分別保存到這些插槽中。
Stack
stack 即所謂的“運行棧",用來保存 EVM 指令的輸入和輸出數據。可以免費使用,沒有 gas 消耗,用來保存函數的局部變量,數量被限制在 16 個。stack 的最大深度為 1024 ,其中每個單元是 32 byte。
云南省委宣傳部副部長:深入推進區塊鏈與各行業領域的深度融合:8月25日,云南省委宣傳部副部長、省新聞出版(版權)局局長楊潤,市委常委、市委宣傳部部長徐曉梅率隊到五華區調研“區塊鏈 ”大文創產業建設情況。云南省區塊鏈中心成立了產業聯盟,數十家國內外企業加入,以商招商的產業氛圍日漸濃厚。中心成立一年以來,以成熟領先的區塊鏈技術助力數字云南發展。上線云南區塊鏈平臺,為企業快速部署應用提供極大便利。楊潤表示,五華區要按照“以應用換市場、以市場換產業”思路,以區塊鏈技術應用為突破口,強化政策引領,加大招商引資力度,引進國內外優秀企業落地園區,聚焦場景應用,深入推進區塊鏈與各行業領域的深度融合,把五華區打造成區塊鏈技術應用試驗場、產業發展聚集區。(五華區委宣傳部)[2021/8/30 22:46:23]
Args
args 也叫 calldata,是一段只讀的可尋址的保存函數調用參數的空間,與棧不同的地方的是,如果要使用 calldata 里面的數據,必須手動指定偏移量和讀取的字節數。
Memory
Memory 一個簡單的字節數組,主要是在運行期間存儲數據,將參數傳遞給內部函數。基于 32byte 進行尋址和擴展。
前面已經說過 Storage 是每個合約持久化存儲數據的地方其儲存數據的方式是通過插槽來實現的,現在就具體介紹它是怎么實現的:
工行業務總監:區塊鏈等技術在金融行業得到深入應用:工商銀行信息科技業務總監呂仲濤在接受記者采訪時表示,從技術基礎上看,中國正在躋身全球金融科技發展的“第一梯隊”,人工智能、大數據、區塊鏈等新技術在金融行業得到深入應用,很多銀行都在積極建設新技術平臺。從實踐運用上看,各行也紛紛加強金融科技的頂層設計和實施運用。他表示,經此一疫,各行業將加快生產要素、生產關系的重組升級和生產方式的變革突破,推動產業互聯網建設,進而推動金融服務供需關系的重塑。(經濟參考報)[2020/5/21]
1.對于大小在 32 字節以內的變量(常量),以其定義的順序作為它的索引值來存儲。即第一個變量的索引為 key(0),第二個變量的索引為 key(1)...
2.對于連續較小的值,可能被優化存儲在同一個位置,比如:合約中前四個狀態變量都是 uint64 類型的,則四個狀態變量的值會被打包成一個 32 字節的值存儲在 0 位置。
未優化:
pragma solidity ^0.4.11;contract C {? ?uint256 a = 12;? ?uint256 c = 12;? ?uint256 b = 12;? ?uint256 d = 12;? ?function m() view public returns(uint256,uint256,uint256,uint256){? ? ? ?return (a,b,c,d);? ?}}
動態 | 人民日報:深入實施國家大數據戰略 應突破區塊鏈等十大技術瓶頸:9月14日訊,人民日報發文表示,深入實施國家大數據戰略,應集中力量協同攻關,突破大數據的十大技術瓶頸,包括數據供給層面的區塊鏈技術、數據交換技術,數據處理層面的大數據存儲管理技術、分布式計算技術、編程語言技術,數據分析層面的大數據基礎算法、機器學習、數據智能技術,大數據應用層面的大數據可視化、真偽判定技術。[2018/9/14]
優化后:
pragma solidity ^0.4.11;contract C {? ?uint64 a = 12;? ?uint64 c = 12;? ?uint64 b = 12;? ?uint64 d = 12;? ?function m() view public returns(uint64,uint64,uint64,uint64){? ? ? ?return (a,b,c,d);? ?}}
對于大小在 32 字節以內的結構體同樣也是順序存儲,例如結構體變量索引定義在位置 0,結構體內部有兩個成員,則這兩個成員的依序為 0 和 1。
pragma solidity ^0.4.11;contract C {struct Info {? ?uint256 a ;? ?uint256 b ;}? ?function m() ?external returns(uint256,uint256){? ? ? ?Info storage info;? ? ? ?info.a = 12 ;? ? ? ?info.b = 24 ;? ? ? ?return(info.a,info.b);? ?}}
動態 | SAP與蘇寧將在區塊鏈等領域開展深入研究:在“第9屆中德經濟技術合作論壇”上,中國國務院總理李克強與德國總理默克爾,共同見證了SAP與蘇寧控股集團的戰略合作簽約。根據合作協議,未來,雙方將聯合開展技術創新和行業實踐,在人工智能、機器學習、區塊鏈、物聯網等領域開展課題研究,共同促進數字經濟發展。[2018/7/10]
map 存儲位置是通過 keccak256 (bytes32(key) + bytes32(position) ) 計算得到的,position 表示 key 對應 storage 類型變量存儲的位置。
pragma solidity ^0.4.11;contract Test {?mapping(uint256 => uint256) knownsec;?function go() public {? ? ?knownsec[0x60] = 0x40;?}}
同上,只要在 32 字節以內也是順序存儲,不過在編譯時編譯器會進行邊界檢查防止越界。
pragma solidity ^0.4.11;contract C {? ?uint256 a = [12,24,48] ;? ?? ?function m() public view returns(uint256,uint256,uint256){? ? ? ?return (a,a,a);? ?}? ?}
財政部副部長朱光耀:G20正在深入討論對數字經濟征稅:財政部副部長朱光耀在中國發展高層論壇上表示,數字經濟還處在發展的過程中,要以科普、推動的態度來推進數字經濟發展。像任何事物一樣,也要關注數字經濟的其他影響,包括稅收征管、反洗錢監管措施等要跟上。他還透露G20正在深入討論對數字經濟征稅。[2018/3/24]
由于可變長度數組長度不定,一般在編譯可變長度數組時會提前預留存儲空間,所以就會使用狀態變量的位置存儲可變長度數組的長度。
而具體的數據地址會通過計算 keccak256 (bytes32(position)) 算得數組首地址,再加數組長度偏移量獲得具體的元素。
pragma solidity ^0.4.11;contract C {? ?uint256[] a = [12,24,48] ;? ?? ?function m() public view returns(uint256,uint256,uint256){? ? ? ?return (a,a,a);? ?}? ?}
如果長度小于等于31字節 :
1.對于定長字節數組則是同定長數組一樣;
2.對于可變字節數組和字符串,會在存儲值位置補0一直到32字節,并用補0的最后一個字節存儲字符串的編碼長度。
pragma solidity ^0.4.4;contract A{? ?string public name0 = "knownsec";?? ?bytes8 public name=0x6b6e6f776e736563;? ?bytes public g ;? ?? ?function test() public {? ? ? ?g.push(0xAA);? ? ? ?g.push(0xBB);? ? ? ?g.push(0xCC);? ?}? ?function go() public view returns(bytes){? ? ? ?return g;? ?}}
當節數組和字符串長度大于31字節時
1.變量位置存儲編碼長度,并且編碼長度公式更換為編碼長度 = 字符數 * 2 + 1
2.真實存儲值第一個位置通過公式 keccak256(bytes32(position)) 獲取,剩余值在獲取到的位置順序存儲,同樣在最后存儲位置補0到32字節。
string public name = "knownsecooooooooooooooooooooooooo";
前面已經講到EVM的存儲結構及存儲機制,現在我們再來探討其安全問題。
漏洞原理:
在官方手冊中提到結構體,數組和映射的局部變量默認是放在 storage 中的,而 solidity 語言中函數中設置的局部變量的默認類型取決于它們本身的類型。
因此如果在函數內部設置以上 storage 類型變量卻沒有進行初始化,他們就相當于存儲指針指向合約中的其他變量,當我們對其進行改變時改變的就是其指向的變量。漏洞合約,目的修改 owner 為自己地址:
pragma solidity ^0.4.0;contract testContract{? ?bool public unlocked = false;? ?address public owner = 0xCA35b7d915458EF540aDe6068dFe2F44E8fa733c;struct Person {? ?bytes32 name;? ?address mappedAddress;}? ?function test(bytes32 _name , address ?_mappedAddress) public{? ? ? ?Person person;? ? ? ?person.name = _name;? ? ? ?person.mappedAddress = _mappedAddress;? ? ? ?require(unlocked);? }}
漏洞合約分析:
可以看到該合約在函數部分創建新的結構體時沒有進行初始化,由此我們可以利用該函數進行對owner的修改。不過使用該函數我們還要通過require驗證,不過這也不難因為狀態變量unlocked也同樣在我們可控的范圍內。
具體操作:
調用test函數分別傳入向_name 傳入:0x0000000000000000000000000000000000000000000000000000000000000001(真值)
_mappedAddress 傳入:0xfB89eCb0188cb83c220aADDa1468C1635208e821(個人地址)
傳參前:
傳參后:
可以看到已經成功更改了地址。
可以看到 EVM 的存儲器就是一個 key=>value 的健值數據庫,存儲的數據可以通過校驗和來確保一致。但是其也是和智能合約語言進行交互的,當其中一些規則發生沖突很可能就被別有用心的人用來作惡,所以規范的使用智能合約語言是避開漏洞的必要條件。
新華社北京10月8日電題:組織“買手”、平臺撮合、出售套現……斬斷虛擬貨幣“洗白”贓款的“黑手”新華社“新華視點”記者吳雨、吳光于、朱國亮近日,中國人民銀行等十部門發文.
1900/1/1 0:00:001.Flow一周年發展回顧一年前的今天,CoinList向13000名投資者銷售了Flow代幣,在社區銷售和荷蘭拍賣中募集超過1800萬美元.
1900/1/1 0:00:00近日,澳大利亞參議院發布了關于該國區塊鏈監管狀況的最終報告,長達 168 頁,為政策制定者提供了如何最好地利用新興區塊鏈的路線圖行業.
1900/1/1 0:00:00本文由高承實原創,授權金色財經首發。——在CCF YOCSEF鄭州“區塊鏈技術未來應用的主戰場在哪?”上的發言從金融角度,區塊鏈在數字金融領域的發展也難言成功,比如數字人民幣系統就基本沒有采用區.
1900/1/1 0:00:00金色財經? 區塊鏈10月10日訊? “精靈寶可夢”風格游戲Axie Infinity最近風靡全球,玩家可以在這款游戲中培育一種名為Axie的生物,并將其每三個分為一組投入戰斗.
1900/1/1 0:00:00流動性是任何發達金融市場的首要目標之一。問題本質上是,“我想讓X交易盡可能便宜,我需要有人在另一邊。”這不僅適用于交換代幣,也適用于借貸、衍生品和結構性產品.
1900/1/1 0:00:00