飛魚2星評價
2020-04-26 14:25:55
智能合約是很容易受到攻擊的——合約上存在的bug、用戶的錢包的漏洞、或者設(shè)置上的疏忽,都會導致被攻擊。如果您使用了智能合約,則必須準備好應急預案,在大多數(shù)情況下,唯一有效的解決方案是部署新的智能合約實例,并且將所有數(shù)據(jù)遷移到該實例中。
如果你計劃開發(fā)可升級的智能合約,遷移過程將的最大風險是在升級機制的過程中。
本篇文章將帶你了解智能合約遷移的工作原理。
*本文由Trailofbits團隊首發(fā)于blog,由獵豹區(qū)塊鏈安全團隊翻譯與編輯*
(譯文鏈接:https://blog、trailofbits.com/2018/10/29/how-contract-migration-works/)
1. 你需要智能合約遷移
即使是沒有任何漏洞的智能合約,用戶也可能會因為私鑰的丟失而被盜。在這類攻擊中,即使智能合約具備了可升級的機制,也可能無法修復已部署的智能合約,因此需要部署并正確初始化合約的新實例,以便為用戶恢復功能,所有開發(fā)人員必須在智能合約設(shè)計階段就集成遷移功能,并且必須準備好折中方案進行遷移。
遷移有兩個步驟:
1)恢復要遷移的數(shù)據(jù)
2)將數(shù)據(jù)寫入新合約
讓我們來看看細節(jié)、成本和運營后果。
2.如何執(zhí)行遷移
第1步:數(shù)據(jù)恢復
需要從區(qū)塊鏈中的特定區(qū)塊來讀取數(shù)據(jù),如果是從事件(黑客或故障)中恢復,需要在事件發(fā)生之前,使用阻止或過濾攻擊者的操作。
如果可能,先暫停合同,這對用戶更加透明,并防止了黑客攻擊不懂遷移的用戶。
數(shù)據(jù)恢復將取決于您的數(shù)據(jù)結(jié)構(gòu):
對于簡單類型的公共變量(例如uint或address),通過getter的檢索值是微不足道的。對于私有變量,您可以依賴事件,也可以計算變量的內(nèi)存偏移量,然后使用getStorageAt函數(shù)檢索。由于元素的數(shù)量是已知的,因此陣列也很容易恢復。
映射的情況就有點復雜了,不存儲映射的鍵,需要恢復它們才能訪問這些值。為簡化離線跟蹤,我們建議在映射中存儲值時發(fā)出事件。
對于ERC20智能合約來說,可以通過跟蹤轉(zhuǎn)移事件的地址找到所有持有者的列表,這個過程很難。
我們準備了兩個方案來幫你:
首先,可以掃描區(qū)塊鏈并自行檢索持有者; 在第二種情況下,可以依賴以太網(wǎng)區(qū)塊鏈公開的Google BigTable存檔。
如果您不熟悉web3 API以從區(qū)塊鏈中提取信息,則可以使用ethereum-etl,它提供了一組腳本來簡化數(shù)據(jù)提取。
如果您沒有同步區(qū)塊鏈,則可以使用Google BigQuery API。圖1顯示了如何通過BigQuery收集給定令牌的所有地址:
圖1:使用Google BigQuery恢復地址0x41424344處令牌的所有Transfer事件
BigQuery提供對塊編號的訪問,因此可以調(diào)整此查詢以將事務返回到特定塊。
一旦恢復了所有持有者的地址,就可以離線查詢balanceOf功能以恢復與每個持有者相關(guān)的余額。過濾余額為空的帳戶。
現(xiàn)在我們知道如何檢索要遷移的數(shù)據(jù),我們就可以將數(shù)據(jù)寫入新合約。
第2步:數(shù)據(jù)寫入
收集數(shù)據(jù)后,就要創(chuàng)建新的智能合約了。
對于簡單的變量,可以通過智能合約的構(gòu)造函數(shù)來設(shè)置值。
如果數(shù)據(jù)無法保存在單個中,則情況會稍微復雜和昂貴。每個交易都包含在一個區(qū)塊中,該區(qū)塊限制了其交易可以使用的gas總量(所謂的Gas Limit”)。如果交易的gas成本接近或超過此限制,礦工將不會再打包。因此,如果要遷移大量數(shù)據(jù),則必須將遷移拆分為多個任務。
解決方案是在智能合約中添加初始化狀態(tài),只有所有者才能更改狀態(tài)變量,用戶無法執(zhí)行任何操作。
對于ERC20令牌,該過程將采取以下步驟:
1)在初始化狀態(tài)下部署契約,
2)遷移余額,
3)將合約的狀態(tài)轉(zhuǎn)移到生產(chǎn)狀態(tài)。
4)初始化狀態(tài)可以使用Pausable功能和指示初始化狀態(tài)的布爾值來實現(xiàn)。
為了降低成本,可以使用批量傳輸功能實現(xiàn)余額的遷移,該功能允許您在單個事務中設(shè)置多個帳戶:
在遷移合約時,會出現(xiàn)兩個主要問題:
遷移成本和對交易所有什么影響。
3.遷移成本
數(shù)據(jù)的恢復是在鏈外完成的,因此是免費的。Ethereum-etl可以在本地使用。谷歌的BigQuery API提供足夠的免費信用來支付其使用。
但是,發(fā)送到網(wǎng)絡的每個事務和新合同存儲的每個字節(jié)都有成本。
使用圖2的batchTransfer功能,轉(zhuǎn)移200個賬戶的成本約為2.4M gas,平均gas價格(10 Gwei)的5.04美元(ETH以今天的價格計算)。粗略地說,遷移一個數(shù)據(jù)需要0.025美元。
如果我們看看按市值排名的前五大ERC20代幣的持有人數(shù):
4.交易所
部署新合約可能會對運營產(chǎn)生影響。對于基于token的合同來說,在遷移期間與交換機協(xié)作非常重要,以確保將列出新合約,并且將丟棄之前的合約。
幸運的是,前面的標識遷移事件,表明交流有可能進行合作。
智能合約遷移與可升級智能合約
可升級的合約有幾個缺點:
· 需要詳細的EVM和Solidity的專業(yè)知識,基于委托調(diào)用的代理要求開發(fā)人員掌握EVM和Solidity是必要的。
· 增·加了復雜性和代碼大小,合約更難審查,更有可能會有bug和安全問題。
· 增加了要處理的密鑰數(shù)量,合約將需要多個授權(quán)用戶(所有者,升級者)。授權(quán)用戶越多,攻擊面越大。
· 每筆交易的gas費用增加。合約變得比沒有升級機制的同一版本更具競爭力。
· 他們鼓勵在部署后解決問題。如果開發(fā)人員知道無法輕松更新合同,他們往往會更徹底地測試和審查合約。
· 它們減少了用戶對合約的信任。用戶需要信任合約的所有者,這會阻止真正分散的系統(tǒng)。
· 只有在存在強有力的論據(jù)時,合約才應具有可升級機制,例如:
· 合約需要經(jīng)常更新。如果要定期修改合約,則定期遷移的成本可能高到足以證明可升級性機制的合理性。
· 合約要求固定地址。合約的遷移需要使用新地址,這可能會破壞與第三方的交互(例如與其他合同的交互)。
· 合約遷移實現(xiàn)了升級帶來的好處,但缺點很少。升級相對于遷移的主要優(yōu)點是升級成本更低。然而,這種成本并不能證明所有的缺點。
5.小貼士
在合同部署之前準備遷移過程、使用事件來促進數(shù)據(jù)跟蹤。
如果要購買可升級版的合約,則還必須準備遷移程序,因為您的密鑰可能會受到損害,或者您的合約可能會遭受錯誤且不可逆轉(zhuǎn)的操縱。
智能合約帶來了新的發(fā)展模式,它們的不可變性要求用戶重新思考他們構(gòu)建應用程序的方式,并要求徹底的設(shè)計和開發(fā)過程。
飛飛8885星評價
2020-04-26 14:26:44
智能合約(smart contract)由尼克?薩博在1994年提出。由于缺少可信的執(zhí)行環(huán)境,智能合約當時并未產(chǎn)生實際應用。比特幣底層技術(shù)區(qū)塊鏈天生可以為智能合約提供可信的執(zhí)行環(huán)境,以太坊進而首次成就了基于區(qū)塊鏈的智能合約平臺,以太坊的白皮書《以太坊:下一代智能合約和去中心化應用平臺》。
智能合約的本質(zhì)
智能保證執(zhí)行安全,并減少交易成本。智能合約允許在沒有第三方的情況下進行可信交易,且交易可追蹤、不可逆轉(zhuǎn)。智能合約是以信息化方式傳播、驗證或執(zhí)行合同的計算機協(xié)議。智能合約程序不是單純自動執(zhí)行的程序。它本身就是系統(tǒng)的有效參與者。它是運行在可復制、共享的賬本上的計算機程序,可以處理信息,接收、儲存和發(fā)送價值。
智能合約漏洞
去中心化執(zhí)行的智能合約由于代碼開源,會導致安全漏洞更容易被利用卻可能無法迅速修復。2016年6月The DAO的智能合約漏洞造成損失5000萬美元的損失,開發(fā)者未能就漏洞及時做出回應。最終通過回滾數(shù)據(jù)塊、以太坊硬分叉挽回損失,卻嚴重損害區(qū)塊鏈的去中心化屬性。
以太坊智能合約中的問題包括合約編程Solidity、編譯器錯誤、以太坊虛擬機錯誤、對區(qū)塊鏈網(wǎng)絡的攻擊、程序錯誤的不變性以及其他尚無文檔記錄的攻擊。
智能合約的用途
區(qū)塊鏈技術(shù)的去中心化賬本功能可以被用來創(chuàng)建、確認、轉(zhuǎn)移各種不同類型的資產(chǎn)及合約。幾乎所有類型的金融交易都可以被改造成在區(qū)塊鏈上使用,包括股票、私募股權(quán)、眾籌、債券和其他類型的金融衍生品如期貨、期權(quán)等。
智能合約工作原理
用戶承諾雙方的權(quán)利和義務編寫為電子化的機器語言,參與者分別用各自的私鑰簽名。簽名后的智能合約傳入?yún)^(qū)塊鏈網(wǎng)絡中。合約通過P2P的方式在區(qū)塊鏈全網(wǎng)中擴散,驗證節(jié)點會將收到的合約先保存到內(nèi)存中,等待觸發(fā)對該份合約的共識和處理。共識時間到了,驗證節(jié)點會把最近一段時間內(nèi)保存的所有合約打包成一個合約集合,并算出這個合約集合的哈希值,組裝成區(qū)塊結(jié)構(gòu),擴散到全網(wǎng);其他驗證節(jié)點收到后,與自己保存的合約集合對比教驗,同時發(fā)送一份自己認可的合約集合給其他驗證節(jié)點;通過多輪的發(fā)送和比較,所有驗證節(jié)點最終在規(guī)定的時間內(nèi)對最新的合約集合達成一致。
每個區(qū)塊包含以下信息:當前區(qū)塊的Hash值、前一區(qū)塊的Hash值、達成共識時的時間戳、以及其他描述信息;已經(jīng)達成共識的合約集。
智能合約執(zhí)行過程
智能合約定期檢查自動機狀態(tài),逐條遍歷每個合約內(nèi)包含的狀態(tài)機、事務以及觸發(fā)條件;將條件滿足的事務推送到待驗證的隊列中,進行簽名驗證,確保事務的有效性,等待多數(shù)驗證節(jié)點達成共識,成功執(zhí)行并通知用戶;未滿足觸發(fā)條件的事務將繼續(xù)存放在區(qū)塊鏈上。
事務執(zhí)行成功后,智能合約自帶的狀態(tài)機會判斷所屬合約的狀態(tài),當合約包括的所有事務都順序執(zhí)行完后,狀態(tài)機會將合約的狀態(tài)標記為完成,并從最新的區(qū)塊中移除該合約;反之將標記為進行中,繼續(xù)保存在最新的區(qū)塊中等待下一輪處理,直到處理完畢。