5?月?16?日,迅雷發(fā)布了星域云和迅雷鏈開放平臺(tái)。關(guān)于迅雷鏈開放平臺(tái)、如何基于迅雷鏈開發(fā)智能合約,以及開發(fā)合約的注意事項(xiàng),來鑫有著最直接和專業(yè)的理解。

迅雷鏈的優(yōu)勢(shì)

目前,迅雷區(qū)塊鏈已實(shí)現(xiàn)智能合約每秒百萬次調(diào)用。在迅雷鏈基礎(chǔ)上,已搭建起了區(qū)塊鏈技術(shù)應(yīng)用的開放平臺(tái),企業(yè)和個(gè)人開發(fā)者可以輕松將業(yè)務(wù)上鏈。作為區(qū)塊鏈?3.0?的代表,迅雷鏈開放平臺(tái)相比于其他主鏈具備很多優(yōu)勢(shì):

1.技術(shù)優(yōu)勢(shì):百萬級(jí)并發(fā)處理能力、秒級(jí)確認(rèn)快速可靠,適合企業(yè)?ToC?應(yīng)用的大規(guī)模使用;

2.成本優(yōu)勢(shì):成功接入的應(yīng)用首年?gas?成本將全部由迅雷網(wǎng)心承擔(dān),從根本上解決開發(fā)者的成本之憂;

3.流量?jī)?yōu)勢(shì):共享?4?億?+?用戶基礎(chǔ),共享鏈克生態(tài)的百萬量級(jí)活躍人群,塑造標(biāo)桿產(chǎn)品對(duì)接迅雷核心推廣資源;

4.投融資優(yōu)勢(shì):聯(lián)手知名投資機(jī)構(gòu),投資孵化。

迅雷鏈開放平臺(tái)運(yùn)行流程和接入

為了方便開發(fā)者調(diào)試,迅雷鏈提供沙盒環(huán)境,開發(fā)者在完成本地測(cè)試后,先在沙盒環(huán)境測(cè)試,在沙盒環(huán)境開發(fā)者可以申請(qǐng)給測(cè)試賬號(hào)充值,調(diào)用接口部署合約,并執(zhí)行合約進(jìn)行邏輯測(cè)試。測(cè)試完成后使用沙盒環(huán)境中的合約地址到迅雷鏈開放平臺(tái)提交發(fā)布申請(qǐng)。開發(fā)者在開放平臺(tái)提交的合約代碼必須和測(cè)試環(huán)境一致。

迅雷鏈官方審核開發(fā)者應(yīng)用合規(guī)后,反饋開發(fā)者審核通過,開發(fā)者手動(dòng)執(zhí)行發(fā)布到鏈上,將區(qū)塊鏈應(yīng)用邏輯里使用的合約地址替換為合約在線上區(qū)塊鏈發(fā)布后的地址。

關(guān)于合約的開發(fā)有哪些注意事項(xiàng)

迅雷鏈底層兼容?EVM,所以推薦開發(fā)者使用S????ty?語(yǔ)言開發(fā)智能合約。智能合約,實(shí)際上就是存儲(chǔ)了代碼的區(qū)塊鏈賬戶,其他賬戶都可以通過給這個(gè)賬戶發(fā)送交易實(shí)現(xiàn)合約調(diào)用,以改變合約內(nèi)存儲(chǔ)的狀態(tài)變量。下面是一個(gè)簡(jiǎn)單的商品買賣合約代碼。

 

 

上面的合約,實(shí)現(xiàn)了一個(gè)簡(jiǎn)單的商品買賣合約,賣家部署合約并放入雙倍商品價(jià)格的保證金,買家通過向合約發(fā)送交易調(diào)用?confirmPurchase?方法,并轉(zhuǎn)入雙倍商品價(jià)格的鏈克,來鎖定交易,買賣雙方在交易確認(rèn)后,買家再次通過向合約發(fā)送交易調(diào)用?confirmReceived?方法,確認(rèn)交易狀態(tài),合約向買家轉(zhuǎn)入一倍商品價(jià)格的鏈克,向賣家轉(zhuǎn)入剩余的全部鏈克,交易結(jié)束。

合約中限定了狀態(tài)、調(diào)用者等?modifier,保證交易流程的正確。合約的狀態(tài)變量記錄了買賣雙方的賬戶、商品的價(jià)格、交易的狀態(tài)等信息,通過向合約發(fā)送交易調(diào)用合約內(nèi)方法,來改變合約內(nèi)部的狀態(tài)變量值,最后這些交易在區(qū)塊鏈同步出去,實(shí)現(xiàn)了合約代表的交易需求的去中心化。

合約通過?Solidity?語(yǔ)言編寫,是當(dāng)前的合約編寫最流行的語(yǔ)言之一。這門語(yǔ)言受?C++,Python?和Javascript?語(yǔ)言的影響,設(shè)計(jì)的目的是能在以太坊虛擬機(jī)(EVM)上運(yùn)行。Solidity?是靜態(tài)類型語(yǔ)言,支持繼承、庫(kù)和復(fù)雜的用戶定義類型等特性。詳細(xì)?API?可參考

http://solidity.readthedocs.io/en/develop/index.html

通過truffle的智能合約的開發(fā)流程

truffle?是一套?Solidity?開發(fā)框架,集成了本地區(qū)塊鏈環(huán)境,可快速編譯、部署、調(diào)試合約代碼。詳情可參考?http://truffleframework.com/docs/

1.首先安裝?truffle,依賴?nodejs,使用?npm -g truffle?命令安裝。新建合約項(xiàng)目文件目錄,使用truffle init命令初始化合約工程。

2.新建合約文件?contract/SimpleStorage.sol

3.添加?migrate?代碼,新建文件?migrations/2_deploy_contract.js。后面會(huì)介紹這段代碼的作用。

4.執(zhí)行?truffle compile?編譯合約,編譯后的合約在?build?文件夾下。每個(gè)合約有一個(gè)對(duì)應(yīng)的?json?文件,內(nèi)含部署所需的?bytecode,abiCode

5.執(zhí)行?truffle migrate?移植部署合約

6.執(zhí)行?truffle develop,開啟本地區(qū)塊鏈環(huán)境,對(duì)已部署的合約進(jìn)行測(cè)試

合約是通過?EVM(以太坊虛擬機(jī))?來運(yùn)行的,最終部署在區(qū)塊鏈上,同步到區(qū)塊鏈的交易中,生成合約賬戶。

truffle develop?命令可以生成一個(gè)本地區(qū)塊鏈,并生成?10?個(gè)區(qū)塊鏈賬戶,每個(gè)賬戶有?100?的余額。migrate?是?truffle?命令,可以通過執(zhí)行?migrations?下的腳本,將合約部署到指定的區(qū)塊鏈上。truffle.js可以配置部署和連接的區(qū)塊鏈。上面第三步腳本實(shí)現(xiàn)的功能就是將?SimpleStorage?合約部署到區(qū)塊鏈上,依賴的是?truffle?封裝的功能。

truffle develop?生成的控制臺(tái)環(huán)境,是本地區(qū)塊鏈環(huán)境,內(nèi)置?web3,并將?migration?里部署的合約實(shí)例化到上下文中,可以直接調(diào)用。

以太坊remix實(shí)現(xiàn)合約的部署和調(diào)用

除了使用?truffle?框架開發(fā)智能合約,還可以通過以太坊提供的?[remix](http://remix.ethereum.org/)快速實(shí)現(xiàn)合約的部署和調(diào)用。(由于某些網(wǎng)絡(luò)原因,可能出現(xiàn)頁(yè)面部分?js?不能完全加載)

remix?提供了合約的編譯運(yùn)行環(huán)境,并可以再控制臺(tái)看到合約每條交易的詳細(xì)信息,如輸入輸出參數(shù),簽名后的方法?data,交易?hash?等信息。支持調(diào)試。

1.使用?compile detail,可以看到合約編譯詳情。包括?bytecode,abi?和使用?web3.js?快速部署的方法。

2.使用run來create合約,控制臺(tái)可查看創(chuàng)建合約的交易。

remix功能豐富,提供有本地區(qū)塊鏈環(huán)境和線上etherum連接選擇,支持單步調(diào)試,并可以看到詳細(xì)的堆棧內(nèi)容和assembly code。簡(jiǎn)單的合約直接通過remix部署和測(cè)試十分便捷。但是如果有依賴合約需要導(dǎo)入等方式實(shí)現(xiàn)的,不能很好的支持。也可以支持通過websocket連接本地項(xiàng)目。

智能合約有哪些安全注意事項(xiàng)?

由于智能合約是通過發(fā)送交易部署在區(qū)塊鏈上的去中心化應(yīng)用,這種性質(zhì)就決定了合約一旦部署和調(diào)用操作成功,就不能回退。而合約中所保存狀態(tài)和轉(zhuǎn)移的資產(chǎn),都具有重要的價(jià)值和意義,所以如果合約代碼出現(xiàn)?bug,往往都會(huì)產(chǎn)生十分嚴(yán)重的后果。下面介紹一些合約開發(fā)過程中需要注意到的部分安全事項(xiàng)。

1.設(shè)置函數(shù)可視性和合理的?modifier?權(quán)限

有對(duì)外交互的函數(shù)通常設(shè)置為?public?或?external,內(nèi)部函數(shù)設(shè)置為?private?或?internal。另外,一般使用相應(yīng)的?modifier?限制函數(shù)操作的角色權(quán)限。這些都可以有效減少安全問題。

2. send?調(diào)用可能失敗,需要檢測(cè)?send?結(jié)果然后再確定是否進(jìn)行下面的狀態(tài)改變。

 

通常的操作邏輯可能會(huì)使,向某個(gè)賬戶發(fā)送一筆交易,然后改變合約內(nèi)的某些數(shù)據(jù)狀態(tài)。但是如果未對(duì)?send?函數(shù)調(diào)用的結(jié)果做檢測(cè),可能會(huì)出現(xiàn)?send?失敗,但是后續(xù)狀態(tài)依然被改變的結(jié)果,導(dǎo)致狀態(tài)不一致。

下面例子展示(但并不是一個(gè)安全的合約例子):

如果msg.sender.send失敗,但合約并未拋出異常繼續(xù)執(zhí)行,將導(dǎo)致?balances[msg.sender]?為?0,但msg.sender?并沒有轉(zhuǎn)入對(duì)應(yīng)的?balance。所以需要對(duì)?send?的結(jié)果檢測(cè),并使用?throw?異常的方法,回滾已改變的狀態(tài)值。

3.循環(huán)可能導(dǎo)致?gas?被消耗完而引起合約執(zhí)行失敗

循環(huán)變量可能依賴外部輸入,如果循環(huán)的次數(shù)過多,將會(huì)導(dǎo)致?gas?消耗遞增,直至超過?gasLimit,從而使得合約執(zhí)行失敗,回滾狀態(tài)值,但是對(duì)應(yīng)的?gas?卻已經(jīng)消耗不能退回。

4.調(diào)用堆棧深度限制

EVM?調(diào)用堆棧限制最深?1024?層,從資源交易占用角度看這是必須的。同時(shí)也意味著,如果嵌套調(diào)用的數(shù)量達(dá)到?1024,合約執(zhí)行將會(huì)失敗。攻擊者可以遞歸調(diào)用一個(gè)合約?1023?次,然后再調(diào)用合約函數(shù),造成失敗一些?send?之類的失敗,如上述第一條。

5.溢出漏洞

溢出,就是一個(gè)數(shù)字增加到它的最大值以上。Solidity?可以處理多達(dá)?256?位的數(shù)字(高達(dá)?2的256次方-1),所以遞增?1?會(huì)得?0。最佳實(shí)踐是通過?zeppelin-solidity?提供的?safeMath?來處理數(shù)值計(jì)算。

 

上面是?openzeppelin?實(shí)現(xiàn)的?safeMath?的乘法運(yùn)算。如果乘法運(yùn)算溢出,則?c/a?的結(jié)果不會(huì)等于b。以此保證運(yùn)算的正確性。

6.可重入攻擊?(DAO)

在使用?call?來發(fā)送?value?時(shí),檢測(cè)外部條件順序的不合理或調(diào)用者設(shè)置?call?或?send?對(duì)應(yīng)?fallback惡意轉(zhuǎn)賬,都可能導(dǎo)致狀態(tài)不一致和金額的損失。

避免?DAO?攻擊最佳實(shí)踐就是使用?transfer?來實(shí)現(xiàn)轉(zhuǎn)賬,并使用?require?檢測(cè)結(jié)果。

在合約?A?執(zhí)行?to.call.value?時(shí),如果?to?地址是合約地址,將會(huì)觸發(fā)?to?的?fallback?函數(shù)來接收value。如果在?to?合約的?fallback?里遞歸調(diào)用了?A?合約的?withdraw?時(shí),就是?DAO?攻擊。

7. selfdestruct?的執(zhí)行參數(shù)如果是合約地址,將不會(huì)執(zhí)行合約的?fallback

如果一個(gè)合約?A?的?selfdestrcut(sender)?的?sender?是一個(gè)合約地址?B,B?合約將不會(huì)使用?fallback?來接收?A?的?selfdestruct?帶來的轉(zhuǎn)賬。由此可能產(chǎn)生繞過合約邏輯的風(fēng)險(xiǎn)。

8.短地址攻擊

短地址攻擊是針對(duì)基于?ERC20?類型的?token transfer?時(shí)的問題。在調(diào)用?transfer (address addr, uint amount)?時(shí),實(shí)際發(fā)送交易的是?abi?編碼后的16進(jìn)制代碼,其中每個(gè)參數(shù)長(zhǎng)度是固定的,如果長(zhǎng)度不足會(huì)自動(dòng)補(bǔ)?0。漏洞即源于此,如果?addr?的最后是以?0?結(jié)尾的,而攻擊者少輸入最后的?0,amount?編碼高位補(bǔ)?0,導(dǎo)致?amount?編譯值比實(shí)際輸入值大。從而實(shí)現(xiàn)轉(zhuǎn)移超出實(shí)際應(yīng)該?transfer?的數(shù)量的?token。實(shí)踐中,需要在?transfer?方法檢查長(zhǎng)度來限制此類問題。

合約的安全實(shí)踐需要持續(xù)的關(guān)注和更新,并做好合約的審計(jì)和升級(jí),必要情況下可設(shè)置一些緊急停止或轉(zhuǎn)移合約功能的方法,以備不時(shí)之需。

文/來鑫
分享到

songjy

相關(guān)推薦