賓建偉,相里朋,包小敏
(工業(yè)和信息化部電子第五研究所,廣東 廣州 511370)
區(qū)塊鏈作為一種創(chuàng)新技術(shù),顛覆了原有的商業(yè)邏輯和運(yùn)行規(guī)則。區(qū)塊鏈的分布式賬本技術(shù)和共識(shí)機(jī)制,構(gòu)建了低成本的互信機(jī)制,建立了“去中心化”的交易體系,實(shí)現(xiàn)了價(jià)值的直接傳遞,有助于提高運(yùn)營(yíng)效率、實(shí)現(xiàn)業(yè)務(wù)場(chǎng)景的創(chuàng)新[1]。在金融領(lǐng)域,區(qū)塊鏈技術(shù)不僅可以為支付、數(shù)字資產(chǎn)交易和智能合約保險(xiǎn)等新興金融商業(yè)模式提供底層技術(shù)支撐,同時(shí),借助區(qū)塊鏈構(gòu)建低成本的生態(tài)信任體系,可大大地降低金融交易成本、提高金融運(yùn)行效率。故近年來(lái)區(qū)塊鏈的發(fā)展非常迅速[2]。
區(qū)塊鏈一開始就應(yīng)用于數(shù)字貨幣、金融領(lǐng)域,其安全性要求更高于其他技術(shù)。區(qū)塊鏈的本質(zhì)是一個(gè)去中心化的數(shù)據(jù)庫(kù),將數(shù)據(jù)信息采用分布式方法記錄,在安全性方面,較傳統(tǒng)實(shí)現(xiàn)了質(zhì)的突破;但是區(qū)塊鏈仍面臨著大量的安全風(fēng)險(xiǎn)[3]。
區(qū)塊鏈的安全風(fēng)險(xiǎn)包括網(wǎng)絡(luò)與存儲(chǔ)層安全風(fēng)險(xiǎn)、數(shù)據(jù)與算法層安全風(fēng)險(xiǎn)、共識(shí)與合約層安全風(fēng)險(xiǎn)和應(yīng)用支撐層安全風(fēng)險(xiǎn)。其中,網(wǎng)絡(luò)與存儲(chǔ)層安全風(fēng)險(xiǎn)等與傳統(tǒng)的安全風(fēng)險(xiǎn)類似;而共識(shí)與合約層安全風(fēng)險(xiǎn)是區(qū)塊鏈獨(dú)有的風(fēng)險(xiǎn),該風(fēng)險(xiǎn)主要是針對(duì)共識(shí)和智能合約(Smart contract)這兩項(xiàng)核心技術(shù)的攻擊,包括“51%”攻擊、女巫攻擊、雙花攻擊和DDoS攻擊,以及針對(duì)共識(shí)和智能合約邏輯漏洞實(shí)施的攻擊等[4]。本文將對(duì)智能合約的安全風(fēng)險(xiǎn)進(jìn)行分析,并提出智能合約的安全代碼要求。
區(qū)塊鏈?zhǔn)怯梅植际綌?shù)據(jù)庫(kù)識(shí)別、傳播和記載信息的智能化對(duì)等網(wǎng)絡(luò),也被稱為價(jià)值互聯(lián)網(wǎng)。區(qū)塊鏈技術(shù)作為一種使數(shù)據(jù)庫(kù)安全而不需要行政機(jī)構(gòu)授信的解決方案首先被應(yīng)用于比特幣。自稱日裔美國(guó)黑客的中本聰于2008年在《比特幣白皮書》中提出“區(qū)塊鏈”概念,并在2009年創(chuàng)立了比特幣社會(huì)網(wǎng)絡(luò),開發(fā)出第一個(gè)區(qū)塊,即“創(chuàng)世區(qū)塊”[5]。
智能合約(Smart contract)的使用是第二代區(qū)塊鏈技術(shù)與第一代的顯著區(qū)別,智能合約這個(gè)術(shù)語(yǔ)在區(qū)塊鏈之前就已出現(xiàn),至少可以追溯到1995年,由多產(chǎn)的跨領(lǐng)域法律學(xué)者、受到廣泛贊譽(yù)的密碼學(xué)家尼克·薩博(Nick Szabo)所提出,他在發(fā)表于自己網(wǎng)站的幾篇文章中提到了智能合約理念,定義如下:“一個(gè)智能合約是一套以數(shù)字形式定義的承諾(Promises),包括合約參與方可以在上面執(zhí)行這些承諾的協(xié)議?!?/p>
智能合約理念幾乎與互聯(lián)網(wǎng)(World Wide Web)同時(shí)出現(xiàn),從本質(zhì)上講,這些自動(dòng)合約的工作原理類似于其他計(jì)算機(jī)程序的if-then語(yǔ)句,是一種旨在以信息化方式傳播、驗(yàn)證或執(zhí)行合同的計(jì)算機(jī)協(xié)議。智能合約允許在沒(méi)有第三方的情況下進(jìn)行可信交易,這些交易可追蹤且不可逆轉(zhuǎn)。當(dāng)一個(gè)預(yù)先編好的條件被觸發(fā)時(shí),智能合約則執(zhí)行相應(yīng)的合同條款。
在計(jì)算機(jī)上進(jìn)行智能合約的實(shí)際應(yīng)用時(shí),需要控制實(shí)物資產(chǎn)保證其有效地執(zhí)行合約;同時(shí)要做到,執(zhí)行合約條款時(shí)能獲取到第三方審核的合約方信息,即需要解決信息傳遞與信任問(wèn)題。
在無(wú)法建立信任關(guān)系的互聯(lián)網(wǎng)上,區(qū)塊鏈技術(shù)依靠密碼學(xué)和巧妙的分布式算法,無(wú)需借助任何第三方中心機(jī)構(gòu)的介入,用數(shù)學(xué)的方法使參與者達(dá)成共識(shí),保證交易記錄的存在性、合約的有效性和身份的不可抵賴性,由此解決了互聯(lián)網(wǎng)上的信任和價(jià)值傳遞問(wèn)題,為智能合約的廣泛應(yīng)用提供了絕佳的溫床。第二代區(qū)塊鏈開源項(xiàng)目——以太坊(Ethereum)即使用了智能合約,以太坊提供了圖靈完備的腳本語(yǔ)言Solidity、Serpent與沙盒環(huán)境的以太坊虛擬機(jī)(EVM:Ethereum Virtual Machine),以供用戶編寫和運(yùn)行智能合約。一個(gè)旨在推動(dòng)區(qū)塊鏈跨行業(yè)應(yīng)用的開源項(xiàng)目——Hyperledge,由Linux基金會(huì)在2015年12月主導(dǎo)發(fā)起,它也支持智能合約,Hyperledger Fabric的智能合約被稱為Chaincode,其選用Docker容器作為沙盒環(huán)境,Docker容器中帶有一組經(jīng)過(guò)簽名的基礎(chǔ)磁盤映像及Go與Java語(yǔ)言運(yùn)行所需的SDK,以運(yùn)行Go與Java語(yǔ)言編寫的Chaincode。智能合約使很多不同類型的程序和操作得以自動(dòng)化,最明顯的體現(xiàn)之處在于支付環(huán)節(jié)及付款時(shí)的步驟操作。2016年底由智能合約聯(lián)盟(SCA)與數(shù)字商務(wù)商會(huì)(CDC)聯(lián)合發(fā)布的“Smart Contracts:12 Use Cases for Business & Beyond”(《智能合約:12種商業(yè)及其他使用案例》)白皮書介紹了數(shù)字身份、抵押、供應(yīng)鏈和癌癥研究等12項(xiàng)智能合約的商業(yè)使用案例,而目前智能合約已在金融、醫(yī)療等多個(gè)領(lǐng)域中得以實(shí)際應(yīng)用[6]。
區(qū)塊鏈的本質(zhì)是一個(gè)去中心化的數(shù)據(jù)庫(kù)。在運(yùn)行的過(guò)程中,區(qū)塊鏈將數(shù)據(jù)信息采用分布式方式記錄,并且由所有的參與者共同記錄。這些數(shù)據(jù)信息會(huì)被存儲(chǔ)在所有的節(jié)點(diǎn)之中,不是像傳統(tǒng)數(shù)據(jù)庫(kù)一樣,僅僅存在于唯一的中心化機(jī)構(gòu)。因此,在安全性方面,較傳統(tǒng)實(shí)現(xiàn)了質(zhì)的突破。但區(qū)塊鏈仍面臨著大量的安全風(fēng)險(xiǎn)。
智能合約作為區(qū)塊鏈的核心技術(shù)極大地提升了其應(yīng)用前景。但是,由于區(qū)塊鏈具有不可更改和不可撤銷的特點(diǎn),如果智能合約代碼中存在漏洞,那么這些漏洞將為區(qū)塊鏈的應(yīng)用帶來(lái)極大的安全隱患[7]。Ivica Nikolic等人通過(guò)對(duì)近100萬(wàn)份的智能合約進(jìn)行研究,就發(fā)現(xiàn)其中相當(dāng)多的智能合約存在漏洞。2018年,以太坊也曾因?yàn)橹悄芎霞s安全問(wèn)題而不得不出現(xiàn)了硬分叉,分叉的結(jié)果給以太坊社區(qū)帶來(lái)了極大的爭(zhēng)議和混亂,黑客盜取了價(jià)值約5 000萬(wàn)美元的以太幣,當(dāng)時(shí)為了挽回大部分人的損失,采取了硬分叉的策略,用新的長(zhǎng)的鏈來(lái)代替被攻擊的鏈,這樣黑客的盜取就沒(méi)有價(jià)值(參考上述舉例)。但是,當(dāng)時(shí)社區(qū)的部分支持者認(rèn)為這是一個(gè)去中心化的社區(qū),不應(yīng)該由一個(gè)人來(lái)決定未來(lái)。所以愿意扛下被黑客攻擊后的損失,以保證社區(qū)的去中心化。因此,社區(qū)之間產(chǎn)生了矛盾,就出現(xiàn)了硬分叉之后的兩條鏈:以太經(jīng)典(ETC)和現(xiàn)在的以太坊(ETH)。
智能合約是一段運(yùn)行在區(qū)塊鏈網(wǎng)絡(luò)中的代碼,它完成用戶所賦予的業(yè)務(wù)邏輯。以以太坊體系的代幣為例,其業(yè)務(wù)邏輯是代幣發(fā)幣和交易。以太坊在設(shè)計(jì)之初,將智能合約設(shè)計(jì)成了一旦部署就不能修改的模式。這種設(shè)計(jì)有可能是為了提高智能合約的可信性。
然而,只要是由人編寫的程序,就一定會(huì)出現(xiàn)錯(cuò)誤和缺陷。以太坊這種設(shè)計(jì)本身就違背了程序設(shè)計(jì)的一般規(guī)律,在智能合約出現(xiàn)漏洞的時(shí)候可能會(huì)造成無(wú)法彌補(bǔ)的損失。由于智能合約本質(zhì)上是部署和運(yùn)行在區(qū)塊鏈上的程序,在沒(méi)有標(biāo)準(zhǔn)的合約模板或編寫規(guī)范的情況下,很難要求程序員都能夠?qū)懗鲎罴褜?shí)踐的代碼,一些邏輯不嚴(yán)謹(jǐn)?shù)拇a會(huì)造成智能合約的業(yè)務(wù)邏輯存在安全隱患[8]。目前智能合約出現(xiàn)的漏洞有20多種,其中主要的漏洞類型如下所述。
a)重入攻擊
重入漏洞是最著名的以太坊智能合約漏洞,曾導(dǎo)致了以太坊的分叉(The DAO hack)。Solidity中的call.value()函數(shù)在被用來(lái)發(fā)送Ether的時(shí)候會(huì)消耗它接收到的所有g(shù)as,當(dāng)調(diào)用call.value()函數(shù)發(fā)送Ether的操作發(fā)生在實(shí)際減少發(fā)送者賬戶的余額之前時(shí),就會(huì)存在重入攻擊的風(fēng)險(xiǎn)。
b)數(shù)值溢出
智能合約中的算數(shù)問(wèn)題是指整數(shù)溢出和整數(shù)下溢。Solidity最多能處理256位的數(shù)字(2^256-1),最大數(shù)字增加1會(huì)溢出得到0。同樣,當(dāng)數(shù)字為無(wú)符號(hào)類型時(shí),0減去1會(huì)下溢得到最大數(shù)字值。
整數(shù)溢出和下溢不是一種新類型的漏洞,但它們?cè)谥悄芎霞s中尤其危險(xiǎn)。溢出情況會(huì)導(dǎo)致不正確的結(jié)果,特別是如果可能性未被預(yù)期,則可能會(huì)影響程序的可靠性和安全性。
c)訪問(wèn)控制
訪問(wèn)控制缺陷是所有的程序中都可能存在的安全風(fēng)險(xiǎn),智能合約也同樣會(huì)存在類似問(wèn)題,著名的Parity Wallet智能合約就受到過(guò)該問(wèn)題的影響。
返回值調(diào)用驗(yàn)證此問(wèn)題多出現(xiàn)在和轉(zhuǎn)幣相關(guān)的智能合約中,故又被稱作為靜默失敗發(fā)送或未經(jīng)檢查發(fā)送。在Solidity中存在transfer()、send()、call.value()等轉(zhuǎn)幣方法,都可以用于向某一地址發(fā)送Ether,其區(qū)別在于:transfer發(fā)送失敗時(shí)會(huì)throw,并且進(jìn)行狀態(tài)回滾;只會(huì)傳遞2 300 gas供調(diào)用,防止重入攻擊;send發(fā)送失敗時(shí)會(huì)返回false;只會(huì)傳遞2 300 gas供調(diào)用,防止重入攻擊;call.value發(fā)送失敗時(shí)會(huì)返回false;傳遞所有的可用gas進(jìn)行調(diào)用(可通過(guò)傳入gas_value參數(shù)進(jìn)行限制),不能有效地防止重入攻擊。
如果在代碼中沒(méi)有檢查以上send和call.value轉(zhuǎn)幣函數(shù)的返回值,合約會(huì)繼續(xù)執(zhí)行后面的代碼,可能由于Ether發(fā)送失敗而導(dǎo)致意外的結(jié)果。
d)錯(cuò)誤使用隨機(jī)數(shù)
智能合約中可能需要使用隨機(jī)數(shù),雖然Solidity提供的函數(shù)和變量可以訪問(wèn)智能合約審計(jì)報(bào)告明顯難以預(yù)測(cè)的值,如block.number和block.timestamp,但是它們通常或者比看起來(lái)更公開,或者受到礦工的影響,即這些隨機(jī)數(shù)在一定程度上是可預(yù)測(cè)的,所以惡意用戶通??梢詮?fù)制它并依靠其不可預(yù)知性來(lái)攻擊該功能。
e)事務(wù)順序依賴
由于礦工總是通過(guò)代表外部擁有地址(EOA)的代碼來(lái)獲取gas費(fèi)用,因此用戶可以指定更高的費(fèi)用以便更快地開展交易。由于以太坊區(qū)塊鏈?zhǔn)枪_的,每個(gè)人都可以看到其他人未決交易的內(nèi)容。這就意味著,如果某個(gè)用戶提交了一個(gè)有價(jià)值的解決方案,惡意用戶可以竊取該解決方案并以較高的費(fèi)用復(fù)制其交易,以搶占原始的解決方案。
f)拒絕服務(wù)攻擊
在以太坊的世界中,拒絕服務(wù)是致命的,遭受該類型攻擊的智能合約可能永遠(yuǎn)無(wú)法恢復(fù)正常工作狀態(tài)。導(dǎo)致智能合約拒絕服務(wù)的原因可能有很多種,包括在作為交易接收方時(shí)的惡意行為,人為增加計(jì)算功能所需的gas而導(dǎo)致gas耗盡,濫用訪問(wèn)控制訪問(wèn)智能合約的private組件,利用混淆和疏忽等。
g)邏輯設(shè)計(jì)缺陷
邏輯設(shè)計(jì)缺陷主要是指與業(yè)務(wù)設(shè)計(jì)相關(guān)的安全問(wèn)題。
h)假充值漏洞
在代幣合約的transfer函數(shù)對(duì)轉(zhuǎn)賬發(fā)起人(msg.sender)的余額檢查用的是if判斷方式,當(dāng)balances[msg.sender]<value時(shí)進(jìn)入else邏輯部分并returnfalse,最終沒(méi)有拋出異常,我們認(rèn)為僅if/else這種溫和的判斷方式在transfer這類敏感函數(shù)場(chǎng)景中是一種不嚴(yán)謹(jǐn)?shù)木幋a方式。
i)增發(fā)代幣漏洞
主要指初始化代幣總量后,代幣合約中是否存在可能使代幣總量增加的函數(shù)。
j)凍結(jié)賬戶繞過(guò)
主要指代幣合約中在轉(zhuǎn)移代幣時(shí),是否存在未校驗(yàn)代幣來(lái)源賬戶、發(fā)起賬戶和目標(biāo)賬戶是否被凍結(jié)的操作。
在歷次的安全事故中,因智能合約的漏洞引發(fā)了安全問(wèn)題并占了較大的比重。根據(jù)智能合約檢測(cè)結(jié)果,總結(jié)了主要的智能合約的安全漏洞類型,按照占比進(jìn)行排序,如表1所示。
表1 智能合約安全漏洞分布
智能合約的操作對(duì)象大多為數(shù)字資產(chǎn),其主要負(fù)責(zé)將業(yè)務(wù)邏輯以代碼的形式實(shí)現(xiàn)、編譯和部署,并按照既定的規(guī)則或者觸發(fā)條件自動(dòng)地執(zhí)行,所以具有形式多樣性和差異性,因此,與其他區(qū)塊鏈安全問(wèn)題相比,智能合約安全性問(wèn)題往往會(huì)引發(fā)較大的經(jīng)濟(jì)損失且更加不可控[9]。
除少部分聯(lián)盟鏈中支持智能合約在部署之后進(jìn)行更新外,大多數(shù)智能合約通常具有發(fā)布即生效、不可更改等特點(diǎn),同時(shí),現(xiàn)階段能夠運(yùn)行智能合約的區(qū)塊鏈項(xiàng)目一般都處在早起階段并且具有很強(qiáng)的實(shí)驗(yàn)性質(zhì),智能合約可能存在的安全隱患不斷地被發(fā)現(xiàn),相關(guān)項(xiàng)目面臨的安全威脅也在不斷地變化,因此,要應(yīng)對(duì)智能合約的安全漏洞問(wèn)題,需要在智能合約上線之前,對(duì)其進(jìn)行全面深入的安全驗(yàn)證,從智能合約開發(fā)階段就秉持一個(gè)全新的工程思維,盡可能地對(duì)安全隱患有所準(zhǔn)備,本著一定的安全原則進(jìn)行合約代碼的編寫,如“當(dāng)智能合約出現(xiàn)錯(cuò)誤時(shí),停止合約”“管理賬戶的資金風(fēng)險(xiǎn)(包括限制轉(zhuǎn)賬速率、限制最大轉(zhuǎn)賬額度等)”等。致力于在智能合約開發(fā)階段規(guī)避這些安全隱患,通過(guò)對(duì)智能合約已經(jīng)出現(xiàn)的安全問(wèn)題案例進(jìn)行分析,以以太坊智能合約開發(fā)體系Solidity為例,整理出了智能合約開發(fā)中需要注意的重點(diǎn)內(nèi)容,具體如下所述。
a)嚴(yán)格控制表征權(quán)限的變量和表示
訪問(wèn)控制權(quán)限是安全領(lǐng)域的防護(hù)重點(diǎn)之一。在智能合約中,針對(duì)權(quán)限,主要考慮是否為合約所有者、在合約內(nèi)部還是外部、是否滿足用戶添加的權(quán)限要求。其實(shí)現(xiàn)依賴函數(shù)修飾符、判斷語(yǔ)句等,通常會(huì)有變量或標(biāo)識(shí)來(lái)表征。因此,必須對(duì)用于表征權(quán)限的變量和表示進(jìn)行嚴(yán)格的控制,即這些敏感變量也應(yīng)該通過(guò)函數(shù)修飾符進(jìn)行權(quán)限控制,從而保證權(quán)限閉環(huán),讓攻擊者無(wú)機(jī)可乘。具體地說(shuō),對(duì)于標(biāo)識(shí)權(quán)限的變量,往往有對(duì)應(yīng)的函數(shù)對(duì)其進(jìn)行修改以實(shí)現(xiàn)一些預(yù)期功能。對(duì)這些函數(shù),必須控制訪問(wèn)權(quán)限(通過(guò)函數(shù)修飾符或assert、if-else等實(shí)現(xiàn))。
b)盡量避免外部調(diào)用
調(diào)用不受信任的外部合約可能會(huì)引發(fā)一系列意外的風(fēng)險(xiǎn)和錯(cuò)誤,外部調(diào)用可能在其合約和它所依賴的其他合約內(nèi)執(zhí)行惡意代碼。因此,在實(shí)現(xiàn)業(yè)務(wù)邏輯中時(shí),多花一些時(shí)間和精力重復(fù)實(shí)現(xiàn)其他合約已經(jīng)實(shí)現(xiàn)的業(yè)務(wù)邏輯,避免直接調(diào)用不受信任的外部合約可以直接規(guī)避相關(guān)的安全風(fēng)險(xiǎn),與合約引入惡意代碼攻擊所造成的損失相比,重復(fù)“造輪子”很有必要。
c)仔細(xì)權(quán)衡“send()”“transfer()”和“call.value()”
在以太坊網(wǎng)絡(luò)中進(jìn)行轉(zhuǎn)賬Ether時(shí),需要仔細(xì)權(quán)衡“someAddress.send()”“someAddress.transfer()”和“someAddress.call.value()()”之間的差別。由于觸發(fā)機(jī)制的不同,與someAddress.call.value()()相 比,someAddress.send()和someAddress.transfer()能 保 證 可 重 入 安 全,someAddress.call.value()()將會(huì)發(fā)送指定數(shù)量的Ether并且觸發(fā)對(duì)應(yīng)代碼的執(zhí)行,而被調(diào)用的外部智能合約代碼將享有所有剩余的gas,通過(guò)這種方式轉(zhuǎn)賬是很容易有可重入漏洞的,非常不安全。
d)使用assert()強(qiáng)制不變性
當(dāng)斷言條件不滿足時(shí)果斷地觸發(fā)斷言保護(hù),比如不變的屬性發(fā)生了變化。例如:代幣在以太坊上的發(fā)行比例,在代幣的發(fā)行合約里可以通過(guò)這種方式得到解決。斷言保護(hù)經(jīng)常需要和其他技術(shù)組合使用,比如:當(dāng)斷言被觸發(fā)時(shí)先掛起合約然后升級(jí)。
e)正確使用assert()和require()
在Solidity0.4.10中assert()和require()被加入。require(condition)被用來(lái)驗(yàn)證用戶的輸入,如果條件不滿足便會(huì)拋出異常,應(yīng)當(dāng)使用它驗(yàn)證所有用戶的輸入。assert(condition)在條件不滿足時(shí)也會(huì)拋出異常,但是最好只用于固定變量:內(nèi)部錯(cuò)誤或你的智能合約陷入無(wú)效的狀態(tài)。遵循這些范例,使用分析工具來(lái)驗(yàn)證永遠(yuǎn)不會(huì)執(zhí)行這些無(wú)效操作碼:意味著代碼中不存在任何不變量,并且代碼已經(jīng)正式驗(yàn)證。
f)權(quán)衡Abstract合約和Interfaces
Interfaces和Abstract合約都是用來(lái)使智能合約能更好地被定制和重用。Interfaces是在Solidity0.4.11中被引入的,和Abstract合約很像但是不能定義方法只能申明。Interfaces存在一些限制比如不能夠訪問(wèn)storage或者從其他Interfaces那繼承,通常這些使Abstract合約更實(shí)用。盡管如此,Interfaces在實(shí)現(xiàn)智能合約之前的設(shè)計(jì)智能合約階段仍然有很大的用處。另外,需要注意的是,如果一個(gè)智能合約從另一個(gè)Abstract合約繼承而來(lái),那么它必須實(shí)現(xiàn)所有Abstract合約內(nèi)的申明并未實(shí)現(xiàn)的函數(shù),否則它也會(huì)成為一個(gè)Abstract合約。
g)使Fallback函數(shù)盡量簡(jiǎn)單明了
Fallback函數(shù)在合約執(zhí)行消息發(fā)送沒(méi)有攜帶參數(shù)(或當(dāng)沒(méi)有匹配的函數(shù)可供調(diào)用)時(shí)將會(huì)被調(diào)用,一些攻擊隱藏在Fallback函數(shù)中調(diào)用的外部合約,而Fallback函數(shù)邏輯不清導(dǎo)致遞歸時(shí)同樣會(huì)造成gas的大量損失,因此盡量讓Fallback函數(shù)簡(jiǎn)單明了,避免正常業(yè)務(wù)邏輯執(zhí)行受阻而調(diào)用Fallback時(shí)引入安全風(fēng)險(xiǎn)。
h)明確標(biāo)明函數(shù)和狀態(tài)變量的可見性
明確標(biāo)明函數(shù)和狀態(tài)變量的可見性。函數(shù)可以聲明為external,public,internal或private。分清楚它們之間的差異。例如:external可能已夠用而不是使用public。對(duì)于狀態(tài)變量,external是不可能的。明確標(biāo)注可見性將使得更容易避免關(guān)于誰(shuí)可以調(diào)用該函數(shù)或訪問(wèn)變量的錯(cuò)誤假設(shè)。
i)保持智能合約的簡(jiǎn)潔
在智能合約的開發(fā)中,清晰明了往往比性能提升更重要,復(fù)雜的智能合約往往存在更多的安全隱患,因此,為了提升智能合約的安全性,首先應(yīng)確保智能合約的邏輯簡(jiǎn)潔,堅(jiān)持通過(guò)內(nèi)部模塊化和功能調(diào)用的編碼風(fēng)格實(shí)現(xiàn)合約邏輯,同時(shí)需盡量地使用被廣泛驗(yàn)證過(guò)的合約和工具,如不要自己寫一個(gè)隨機(jī)數(shù)生成器。
智能合約作為以信息化方式傳播、驗(yàn)證和執(zhí)行合同的計(jì)算機(jī)協(xié)議,為區(qū)塊鏈技術(shù)的發(fā)展和落地提供了更靈活的工具,然而,作為一種全新的技術(shù)應(yīng)用,區(qū)塊鏈智能合約面臨的安全問(wèn)題同樣嚴(yán)峻。任何信息系統(tǒng)的安全維護(hù)都不是一勞永逸的,對(duì)智能合約的安全維護(hù)同樣如此,通過(guò)對(duì)已出現(xiàn)的安全事故案例進(jìn)行分析和總結(jié),形成了一套智能合約安全開發(fā)規(guī)范,可以有效地指導(dǎo)開發(fā)人員在進(jìn)行智能合約設(shè)計(jì)時(shí)規(guī)避安全風(fēng)險(xiǎn);同時(shí),鑒于越來(lái)越多的區(qū)塊鏈項(xiàng)目支持合約在部署后進(jìn)行修改和更新,實(shí)時(shí)跟蹤新出現(xiàn)的智能合約漏洞,保持智能合約的動(dòng)態(tài)檢查同樣重要。