娃哈哈10星評價(jià)
2020-04-23 15:28:29
近年來,智能合約成為了區(qū)塊鏈安全的重災(zāi)區(qū),從The DAO到BEC,SocialChain,Hexagon,再到EOS漏洞,智能合約安全漏洞頻現(xiàn)令不少開發(fā)者和企業(yè)對區(qū)塊鏈望而卻步。
12月8日,在迅雷鏈技術(shù)沙龍第六站現(xiàn)場,迅雷鏈底層研發(fā)工程師胡登啟系統(tǒng)剖析了智能合約安全問題,分析了智能合約中存在的典型漏洞和預(yù)防措施,并總結(jié)了在合約編程過程中需要注意的幾大安全原則,在現(xiàn)場聽眾間引起了熱烈反響。
區(qū)塊鏈虛擬機(jī)工作原理
關(guān)于虛擬機(jī)的運(yùn)行原理,胡登啟以EVM為例,講解了虛擬機(jī)底層是如何實(shí)現(xiàn)的,讓開發(fā)者對虛擬機(jī)有了更全面的認(rèn)識。
首先,區(qū)塊鏈的虛擬機(jī)應(yīng)該包含以下6個(gè)特性:
1.安全:這也是最重要的,即代碼在沙盒中運(yùn)行,一旦發(fā)生錯(cuò)誤,可以回滾掉所有更新;
2.結(jié)果明確:結(jié)果確定且沒有歧義,在區(qū)塊鏈的所有節(jié)點(diǎn)執(zhí)行該邏輯,得到的結(jié)果一定是保持一致的;
3.簡單:操作碼低級,結(jié)構(gòu)簡單;
4.具備特定的能力:虛擬機(jī)能處理加密運(yùn)算,比如支持橢圓曲線算法,能訪問交易與鏈狀態(tài),獲取blockhash,tx相關(guān)內(nèi)容等等;
5.易于優(yōu)化:支持即時(shí)編譯(JIT)等;
6.節(jié)省空間:虛擬機(jī)組件緊湊,便于集成到區(qū)塊鏈服務(wù)中。
通過分析EVM虛擬機(jī),胡登啟總結(jié)了通用區(qū)塊鏈虛擬機(jī)應(yīng)該是如何運(yùn)作的:
1.首先開發(fā)者會使用 c.c++、或者 solidity等高級語言編寫一個(gè)合約,一般情況下這里包含了很多的復(fù)雜的業(yè)務(wù)邏輯;
2.通過編譯器llvm,或者solidity編譯器,將包含服務(wù)業(yè)務(wù)邏輯的源代碼編譯成與機(jī)器無關(guān)的中間代碼,也就是我們所說的字節(jié)碼;
3.虛擬機(jī)在運(yùn)行時(shí),首先要通過代碼加載器,將字節(jié)碼讀入內(nèi)存,初始化基礎(chǔ)的內(nèi)存變量;
4.然后由虛擬機(jī)的執(zhí)行引擎將一條一條的字節(jié)碼指令翻譯成對應(yīng)機(jī)器平臺的底層指令執(zhí)行;
5.執(zhí)行引擎在執(zhí)行指令的過程中會使用到臨時(shí)變量、堆棧區(qū)存儲空間,或者讀寫外部文件等,這里統(tǒng)稱為運(yùn)行時(shí)數(shù)據(jù)區(qū)。
區(qū)塊鏈虛擬機(jī)的執(zhí)行流程
一個(gè)通用的虛擬機(jī)執(zhí)行流程可以抽象成下面這個(gè)過程:
1.首先將字節(jié)碼加載到內(nèi)存的代碼段,初始化運(yùn)行環(huán)境,這時(shí)程序計(jì)數(shù)器初始化為0。如上圖所示,這里有個(gè)循環(huán)體,循環(huán)判斷的結(jié)束條件是:是否要終止執(zhí)行?如果判斷標(biāo)記為false,則獲取pc執(zhí)行的操作碼,否則退出執(zhí)行,返回結(jié)果;
2.獲取到pc操作碼后,會校驗(yàn)參數(shù),比如參數(shù)是否足夠,有沒有超過堆棧的最大可用空間等;
3.接下來會執(zhí)行具體的指令;
4.指令結(jié)束后,計(jì)數(shù)器加一,繼續(xù)循環(huán),直到程序設(shè)置了終止標(biāo)記位。
迅雷鏈支持圖靈完備的EVM虛擬機(jī),胡登啟以一個(gè)簡單的solidity合約為例,為現(xiàn)場開發(fā)者分析了EVM虛擬機(jī)是如何運(yùn)行的。
EVM虛擬機(jī)的執(zhí)行主流程是在Run函數(shù)里面的,在循環(huán)里面首先會獲取對應(yīng)的操作碼,將操作碼關(guān)聯(lián)到對應(yīng)的指令,這個(gè)指令在執(zhí)行之前會進(jìn)行一些數(shù)據(jù)的校驗(yàn)。執(zhí)行指令完之后,可以判斷繼續(xù)執(zhí)行指令還是返回退出。
如上圖所示,這個(gè)合約只有一個(gè)Add函數(shù),計(jì)算2個(gè)uint8變量的和。
通過solidity編譯器,將合約編譯成bytecode、 虛擬機(jī)會將bytecode轉(zhuǎn)換成對應(yīng)的opcode。opcode被表示為預(yù)定義的標(biāo)識符。比如 0x60 對應(yīng)的opcode是 PUSH1, 0x52 對應(yīng)的opcode是 MSTORE、
而上面提到的被預(yù)定義的標(biāo)識符,其實(shí)就是操作碼。EVM中將操作碼大致分為四類:
第一類是算術(shù)運(yùn)算,包括最基礎(chǔ)的加減乘除運(yùn)算指令;
第二類是邏輯運(yùn)算,包括與、或、非、等于、不等于、大于、小于等;
第三類是與區(qū)塊鏈狀態(tài)相關(guān)指令,具體是指區(qū)塊信息如coinbase、區(qū)塊時(shí)間戳、區(qū)塊序號等,還有交易相關(guān)的,如交易的發(fā)送者,交易轉(zhuǎn)賬金額等指令;
第四類是跟存儲相關(guān)的指令,比如讀取虛擬機(jī)運(yùn)行時(shí)內(nèi)存數(shù)據(jù),或者存儲數(shù)據(jù)到區(qū)塊鏈狀態(tài)中。
每一個(gè)操作碼都對應(yīng)一個(gè)操作指令。操作指令定義了操作碼具體要執(zhí)行怎樣的操作,操作消耗的gas值,操作需要的參數(shù)與返回值的個(gè)數(shù),還有操作需要額外空間。同時(shí)操作指令中還定義了一些標(biāo)記位,比如終止運(yùn)算、跳轉(zhuǎn)、是否出錯(cuò)、是否應(yīng)該返回等。
胡登啟通過展示最簡單的加法操作指令為例,為大家分析了指令結(jié)構(gòu)。EVM虛擬機(jī)每個(gè)操作指令都會消耗一定的gas值,這么做的目的一方面是為了避免開發(fā)者編寫無限循環(huán)的代碼,另一方面是為了給打包交易的節(jié)點(diǎn)一點(diǎn)獎(jiǎng)勵(lì)。
智能合約開發(fā)的安全準(zhǔn)則
不過胡登啟指出,EVM只是區(qū)塊鏈虛擬機(jī)的一種實(shí)現(xiàn)方式,而且現(xiàn)行的智能合約還是一個(gè)在不斷發(fā)展的技術(shù),要想運(yùn)用好這個(gè)技術(shù)并不容易。
事實(shí)上,在實(shí)踐過程中,合約被爆出了各種安全漏洞,這些漏洞可能給項(xiàng)目發(fā)行方造成巨大的損失。因?yàn)閰^(qū)塊鏈?zhǔn)侨ブ行幕淖灾蜗到y(tǒng),往往發(fā)現(xiàn)漏洞后,發(fā)行方很難去修復(fù)這個(gè)漏洞,只能任由黑客肆意的攻擊。因此要求開發(fā)者在編寫智能合約時(shí),做更加全面的安全測試,盡量避免包含漏洞的代碼發(fā)布到區(qū)塊鏈系統(tǒng)中。
胡登啟通過分析智能合約中存在的典型漏洞,向現(xiàn)場聽眾展示了智能合約安全問題的重要性,并為開發(fā)者編寫智能合約提供了一些參考。
比如,他以今年年初轟動一時(shí)的美鏈BEC合約漏洞為例,講述了智能合約安全的重要性。BEC是美鏈公司發(fā)布的token,于今年2月上線交易, 4月22日該合約被爆出重大漏洞,導(dǎo)致其token市值幾乎歸零。
其智能合約中有個(gè)批量轉(zhuǎn)賬的接口,參數(shù)是地址數(shù)組和轉(zhuǎn)賬token值。如上圖的第218行代碼,這里有個(gè)乘法運(yùn)算,用以計(jì)算一次交易中轉(zhuǎn)移token的總值,計(jì)算結(jié)果使用uint256類型保存。有過c或者c++開發(fā)經(jīng)驗(yàn)的同學(xué)可能會看出,這里存在整數(shù)溢出的問題。
黑客正是利用了這個(gè)漏洞,進(jìn)行BEC token的巨額增發(fā),最終導(dǎo)致其價(jià)值接近歸零。
胡登啟以此作為反面教材,告誡開發(fā)者,在合約開發(fā)中進(jìn)行任何數(shù)學(xué)運(yùn)算時(shí),都推薦使用SafeMath庫,這樣可以避免溢出的漏洞。比較諷刺的一點(diǎn)是,BEC合約的其他代碼都使用了SafeMath庫,唯獨(dú)漏了這一處??梢姶a測試一定要充分,漏了一個(gè)點(diǎn),可能造成巨大損失。
通過對另外數(shù)起知名安全漏洞案例的分析,胡登啟總結(jié)了智能合約開發(fā)的3條安全準(zhǔn)則:
1.開發(fā)者應(yīng)深入的理解區(qū)塊鏈系統(tǒng)的運(yùn)行原理。
2.希望開發(fā)者熟練掌握一門合約語言的特性。
3.要做全面的代碼測試,不能有僥幸心理。
胡登啟最后表示,區(qū)塊鏈智能合約還是一門比較年輕的技術(shù),需要在開發(fā)者的不斷實(shí)踐中去完善與提升。因此在目前階段,開發(fā)者進(jìn)行智能合約編程時(shí),尤其需要注意規(guī)避漏洞,以保證合約具備足夠的安全性。
楚風(fēng)2星評價(jià)
2020-04-23 15:28:53
什么是虛擬機(jī)?
傳統(tǒng)的虛擬機(jī)指的是,通過軟件模擬的,具備完整硬件系統(tǒng)功能,并運(yùn)行在隔離環(huán)境下的完整計(jì)算機(jī)系統(tǒng),比如VMware、Java虛擬機(jī)等。勝超比較喜歡用VMware虛擬機(jī),可以在一臺電腦多安裝幾個(gè)系統(tǒng),更重要的是,不怕被黑客攻擊,因?yàn)樘摂M機(jī)是在隔離環(huán)境下運(yùn)行的。
什么是以太坊虛擬機(jī)?
以太坊虛擬機(jī)的英文全稱為“Ethereum Virtual Machine”,簡稱為EVM,這個(gè)EVM就是建立在以太坊區(qū)塊鏈上的代碼運(yùn)行環(huán)境,是一個(gè)完全獨(dú)立的沙盒,合約代碼可對外完全隔離并在EVM內(nèi)部運(yùn)行,其主要作用是處理以太坊系統(tǒng)內(nèi)的智能合約。
什么是圖靈完備的?
以太坊就是圖靈完備的,開發(fā)者可以使用Solidity語言創(chuàng)建運(yùn)行于EVM上的應(yīng)用程序。所謂圖靈完備,就是一切可計(jì)算的問題都能計(jì)算,這樣的虛擬機(jī)或者編程語言就叫圖靈完備的,圖靈完備通常指具有無限存儲能力的通用物理機(jī)器或編程語言。與圖靈完備相反的是圖靈不完備,比如比特幣的腳本系統(tǒng),就是圖靈不完備的,而一些智能合約系統(tǒng),就是圖靈完備的,圖靈不完備更安全些,而圖靈完備更智能些!