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。
現場 | 觀點:區塊鏈技術需要深入場景才能形成產業:金色財經現場報道,10月15日,華山論劍2020網絡安全大會于西安召開,在大會的區塊鏈安全與應用創新分論壇圓桌討論環節,
基石基金管理合伙人秦少博分享表示,區塊鏈創新型的業務需要承擔比較大的沉默成本,在區塊鏈領域創業需要考量自身能力。區塊鏈技術需要深入場景才能形成產業,過去5年由幣引發的熱潮已經越發理智。把區塊鏈作為技術、生產力討論更合適。不宜與太大的市場概念結合。
中國移動研究院安全技術研究所所長何申分享表示,從通信行業看待區塊鏈,會從系統工程高度去看,當區塊鏈從節點成網形成共識,需要考慮節點的安全。此外,可信是一種保障預期方案,區塊鏈是一種方案,兩種方案的協同,是通信領域的重點。對于區塊鏈透明性帶來的隱私問題可以通過隱私技術解決,但可能在公鏈場景里比較難實現。[2020/10/15]
Args
args 也叫 calldata,是一段只讀的可尋址的保存函數調用參數的空間,與棧不同的地方的是,如果要使用 calldata 里面的數據,必須手動指定偏移量和讀取的字節數。
Memory
Memory 一個簡單的字節數組,主要是在運行期間存儲數據,將參數傳遞給內部函數。基于 32byte 進行尋址和擴展。
前面已經說過 Storage 是每個合約持久化存儲數據的地方其儲存數據的方式是通過插槽來實現的,現在就具體介紹它是怎么實現的:
聲音 | 物美集團創始人張文中:區塊鏈僅靠熱度不能解決問題 須針對場景做深入開發:物美集團創始人張文中近日在接受采訪時表示,新技術對現有技術企業都會有比較大的影響。比如,最近大家談論比較多的區塊鏈對企業影響是必然的。但我們也應該清醒認識到,區塊鏈僅靠熱度不能解決問題,它必須針對所面對的場景做深入開發和挖掘,比如在食品追溯方面,如果能夠追溯源頭,這也能助力實體企業轉型。(聯商網)[2019/11/6]
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);? ?}}
聲音 | 張平文:區塊鏈等已經深入到市民生活的方方面面:月10日至11日,2019世界計算機大會在湖南長沙舉行,中國科學院院士張平文說,計算機包括5G、云計算、大數據、人工智能、區塊鏈等,已經深入到市民生活的方方面面。[2019/9/15]
優化后:
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);? ?}}
聲音 | 中國科學院院士:區塊鏈等已經深入到市民生活的方方面面:9月10日至11日,2019世界計算機大會在湖南長沙舉行,中國科學院院士張平文說,計算機包括5G、云計算、大數據、人工智能、區塊鏈等,已經深入到市民生活的方方面面。(中國新聞網)[2019/9/12]
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);? ?}? ?}
“中國數谷”發布《三年行動計劃》:深入推進區塊鏈等前沿研究探索落地:今日,貴陽國家高新區正式發布《貴陽國家高新區建設“中國數谷之心”三年行動計劃(2018-2020年)》。《三年行動計劃》明確,深入推進物聯網、人工智能、區塊鏈以及大數據+實體經濟等前沿研究探索落地全面推進中國數谷之心建設行動。[2018/4/20]
由于可變長度數組長度不定,一般在編譯可變長度數組時會提前預留存儲空間,所以就會使用狀態變量的位置存儲可變長度數組的長度。
而具體的數據地址會通過計算 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 的健值數據庫,存儲的數據可以通過校驗和來確保一致。但是其也是和智能合約語言進行交互的,當其中一些規則發生沖突很可能就被別有用心的人用來作惡,所以規范的使用智能合約語言是避開漏洞的必要條件。
證監會科技監管局局長姚前表示,隨著現代信息技術革命的興起,技術對貨幣的影響正達到前所未有的狀態,比特幣已經引發了全球大規模的數字貨幣實驗。數字時代已然來臨,數字貨幣時代也必將來臨.
1900/1/1 0:00:00DeFi總市值:1284.71億美元 DeFi總市值數據來源:Coingecko過去24小時去中心化交易所的交易量:33.
1900/1/1 0:00:00現在去哪里投資1萬美元?如今,投資者面臨著一個兩難境地。通貨膨脹正在上升。從高盛到貝萊德,幾乎每家公司都預計到2035年的股票回報率都低于5%。全球大流行已經完全擾亂了市場.
1900/1/1 0:00:00官方消息,JGN成立生態基金,全球投資 DAO!JGN與眾多領先的全球基金合作,成立JGN生態基金,通過 Juggernaut 投資更多優質的加密項目.
1900/1/1 0:00:009月24日, 央行數研所狄剛在“區塊鏈與數字經濟發展論壇”上表示,數字貨幣研究所近年來聚焦區塊鏈的具體實踐.
1900/1/1 0:00:00當前,數字貨幣已成為我國支付體系的重要組成部分。與此同時,由于數字貨幣具有去中心化、匿名性和公開性等屬性,其對國家金融信用資金安全與穩定也造成了一定的影響.
1900/1/1 0:00:00