背景概述
在上篇文章中我們了解了合約中隱藏的惡意代碼,本次我們來了解一個非常常見的攻擊手法——搶跑。
前置知識
提到搶跑,大家第一時間想到的一定是田徑比賽,在田徑運動中各個選手的體能素質幾乎相同,起步越早的人得到第一名的概率越大。那么在以太坊中是如何搶跑的呢?
想了解搶跑攻擊必須先了解以太坊的交易流程,我們通過下面這個發送交易的流程圖來了解以太坊上一筆交易發出后經歷的流程:
可以看到圖中一筆交易從簽名到被打包一共會經歷7個階段:
1.使用私鑰對交易內容簽名;
2.選擇GasPrice;
3.發送簽名后的交易;
4.交易在各個節點之間廣播;
5.交易進入交易池;
6.礦工取出GasPrice高的交易;
7.礦工打包交易并出塊。
交易送出之后會被丟進交易池里,等待被礦工打包。礦工從交易池中取出交易進行打包與出塊。根據Eherscan?的數據,目前區塊的Gas限制在3000萬左右這是一個動態調整的值。若以一筆基礎交易21,000Gas來計算,則目前一個以太坊區塊可以容納約1428筆交易。因此當交易池里的交易量大時,會有許多交易沒辦法即時被打包而滯留在池子中等待。這里就衍生出了一個問題,交易池中有那么多筆交易,礦工先打包誰的交易呢?
礦工節點可以自行設置參數,不過大多數礦工都是按照手續費的多少排序。手續費高的會被優先打包出塊,手續費低的則需要等前面手續費高的交易全部被打包完才能被打包。當然進入交易池中的交易是源源不斷的,不管交易進入交易池時間的先后,手續費高的永遠會被優先打包,手續費過低的可能永遠都不會被打包。
那么手續費是怎么來的呢?
我們先看以太坊手續費計算公式:
數據:鎖定在智能合約中的MKR供應占比已創下16個月新高:Glassnode數據顯示,鎖定在智能合約中的MKR供應占比已創下16個月以來的新高,目前為58.287%.[2020/9/21]
TxFee=GasUsed*?GasPrice
其中GasUsed是由系統計算得出的,GasPrice是可以自定義的,所以最終手續費的多少取決于GasPrice設置的多少。
舉個例子:
例如GasPrice設置為10GWEI,GasUsed?為21,000。因此,根據手續費計算公式可以算出手續費為:
10GWEI*21,000=0.00021Ether
在合約中我們常見到Call函數會設置GasLimit,下面我們來看看它是什么東西:
GasLimit可以從字面意思理解,就是Gas限制的意思,設置它是為了表示你愿意花多少數量的Gas在這筆交易上。當交易涉及復雜的合約交互時,不太確定實際的GasUsed,可以設置GasLimit,被打包時只會收取實際GasUsed作為手續費,多給的Gas會退返回來,當然如果實際操作中GasUsed>GasLimit就會發生Outofgas,造成交易回滾。
當然,在實際交易中選擇一個合適的GasPrice也是有講究的,我們可以在ETHGASSTATION上看到實時的GasPrice對應的打包速度:
由上圖可見,當前最快的打包速度對應的GasPrice為2,我們只需要在發送交易時將GasPrice設置為>=2的值就可以被盡快打包。
好了,到這里相信大家已經可以大致猜出搶跑的攻擊方式了,就是在發送交易時將GasPrice調高從而被礦工優先打包。下面我們還是通過一個合約代碼來帶大家了解搶跑是如何完成攻擊的。
合約示例
區塊鏈公司HashCash計劃通過智能合約幫助制藥公司保存臨床試驗記錄:美國區塊鏈公司HashCash Consultants計劃將其區塊鏈技術能力擴展到一家全球制藥公司,以幫助后者通過智能合約進行臨床試驗的安全記錄保存。(Prweb)[2020/7/24]
//?SPDX-License-Identifier:?MITpragmasolidity^0.8.17;contractFindThisHash{??bytes32publicconstanthash=????0x564ccaf7594d66b1eaaea24fe01f0585bf52ee70852af4eac0cc4b04711cd0e2;??constructor()payable{}??functionsolve(stringmemorysolution)public{????require(hash==keccak256(abi.encodePacked(solution)),"Incorrectanswer");????(boolsent,)=msg.sender.call{value:10ether}("");????require(sent,"FailedtosendEther");??}}
攻擊分析
通過合約代碼可以看到?FindThisHash?合約的部署者給出了一個哈希值,任何人都可以通過solve()?提交答案,只要solution的哈希值與部署者的哈希值相同就可以得到10個以太的獎勵。我們這里排除部署者自己拿取獎勵的可能。
我們還是請出老朋友Eve看看他是如何使用搶跑攻擊拿走本該屬于Bob的獎勵的:
1.Alice使用10Ether部署FindThisHash合約;
2.Bob找到哈希值為目標哈希值的正確字符串;
3.Bob調用solve("Ethereum")并將Gas價格設置為15Gwei;
4.Eve正在監控交易池,等待有人提交正確的答案;
5.Eve看到Bob發送的交易,設置比Bob更高的GasPrice,調用solve("Ethereum");
IOTA基金會高級開發人員:以太坊智能合約比IOTA更適合高價值轉移:IOTA基金會高級開發人員將以太坊與IOTA進行了比較,認為以太坊智能合約比IOTA更適合高價值轉移。他進一步指出,有些應用中以太坊智能合約比IOTA更適合,因為IOTA的靈活性在此類應用中成為劣勢。在以太坊這樣的合約中長期持有大筆資金比較安全。他指出,這樣的網絡可以讓你毫無畏懼地依賴它們。Hop表示,與其他區塊鏈同類產品相比,IOTA智能合約協議(ISCP)具有資源豐富、高效且高度靈活的特點。因此,相比之下,IOTA智能合約為更低的交易成本提供了空間。他還透露了IOTA將物聯網(IoT)用于記錄和執行交易的好處。Hop稱贊IOTA的巨大靈活性,同時指出IOTA的智能合約不僅有內置的虛擬機(VM),還允許準確處理SC代碼。這證實了IOTA將適用于未來實施的任何變更或擴展。[2020/5/10]
6.Eve的交易先于Bob的交易被礦工打包;
7.Eve贏得了10個以太幣的獎勵。
這里Eve的一系列操作就是標準的搶跑攻擊,我們這里就可以給以太坊中的搶跑下一個定義:搶跑就是通過設置更高的GasPrice來影響交易被打包的順序,從而完成攻擊。
那么這類攻擊該如何避免呢?
修復建議
在編寫合約時可以使用Commit-Reveal方案:
https://medium.com/swlh/exploring-commit-reveal-schemes-on-ethereum-c4ff5a777db8
SoliditybyExample中提供了下面這段修復代碼,我們來看看它是否可以完美地防御搶跑攻擊。
//SPDX-License-Identifier:MITpragmasolidity^0.8.17;import"github.com/OpenZeppelin/openzeppelin-contracts/blob/release-v4.5/contracts/utils/Strings.sol";contractSecuredFindThisHash{??//Structisusedtostorethecommitdetails??structCommit{????bytes32solutionHash;????uintcommitTime;????boolrevealed;??}??//Thehashthatisneededtobesolved??bytes32publichash=????0x564ccaf7594d66b1eaaea24fe01f0585bf52ee70852af4eac0cc4b04711cd0e2;??//Addressofthewinner??addresspublicwinner;??//Pricetoberewarded??uintpublicreward;??//Statusofgame??boolpublicended;??//Mappingtostorethecommitdetailswithaddress??mapping(address=>Commit)commits;??//Modifiertocheckifthegameisactive??modifiergameActive(){????require(!ended,"Alreadyended");????_;??}??constructor()payable{????reward=msg.value;??}??/*???Commitfunctiontostorethehashcalculatedusingkeccak256(addressinlowercase+solution+secret).???Userscanonlycommitonceandifthegameisactive.??*/??functioncommitSolution(bytes32_solutionHash)publicgameActive{????Commitstoragecommit=commits;????require(commit.commitTime==0,"Alreadycommitted");????commit.solutionHash=_solutionHash;????commit.commitTime=block.timestamp;????commit.revealed=false;??}??/*????Functiontogetthecommitdetails.Itreturnsatupleof(solutionHash,commitTime,revealStatus);?????UserscangetsolutiononlyifthegameisactiveandtheyhavecommittedasolutionHash??*/??functiongetMySolution()publicviewgameActivereturns(bytes32,uint,bool){????Commitstoragecommit=commits;????require(commit.commitTime!=0,"Notcommittedyet");????return(commit.solutionHash,commit.commitTime,commit.revealed);??}??/*????Functiontorevealthecommitandgetthereward.????UserscangetrevealsolutiononlyifthegameisactiveandtheyhavecommittedasolutionHashbeforethisblockandnotrevealedyet.????Itgeneratesankeccak256(msg.sender+solution+secret)andchecksitwiththepreviouslycommitedhash.?????Frontrunnerswillnotbeabletopassthischecksincethemsg.senderisdifferent.????Thentheactualsolutionischeckedusingkeccak256(solution),ifthesolutionmatches,thewinnerisdeclared,????thegameisendedandtherewardamountissenttothewinner.??*/??functionrevealSolution(????stringmemory_solution,????stringmemory_secret)publicgameActive{????Commitstoragecommit=commits;????require(commit.commitTime!=0,"Notcommittedyet");????require(commit.commitTime<block.timestamp,"Cannotrevealinthesameblock");????require(!commit.revealed,"Alreadycommitedandrevealed");????bytes32solutionHash=keccak256(??????abi.encodePacked(Strings.toHexString(msg.sender),_solution,_secret)????);????require(solutionHash==commit.solutionHash,"Hashdoesn'tmatch");????require(keccak256(abi.encodePacked(_solution))==hash,"Incorrectanswer");????winner=msg.sender;????ended=true;????(boolsent,)=payable(msg.sender).call{value:reward}("");????if(!sent){??????winner=address(0);??????ended=false;??????revert("Failedtosendether.");????}??}}
現場 | 薛世淵:與傳統互聯網相比 智能合約能做到“更快”與“更安全”:金色財經現場報道,1月29日,2019區塊鏈產業技術峰會于臺北市舉行。BMW Group區塊鏈工程師薛世淵發表以“推動汽車行業區塊鏈的發展”為主題的演講。他表示,與傳統互聯網相比,智能合約所能做到的是“更快”與“更安全”。 當我們使用電腦的時候,傳統互聯網是將數據都通過中央處理器進行收集和分發,路徑相對復雜。區塊鏈可以實現點對點傳送,效率更高。同時,我們無須懷疑拿到的數據是否真實,是否經過惡意篡改。例如購買二手車時,我們無法知道前車主對這輛車做了什么。但是用區塊鏈記錄駕駛行為,相當于給汽車加了一個護照,我們很容易便能查到這輛車行駛過多少公里,是否發生過事故等等。[2019/1/29]
首先可以看到修復代碼中使用了結構體Commit記錄玩家提交的信息,其中:
commit.solutionHash=_solutionHash=keccak256
commit.commitTime=block.timestamp
commit.revealed=false
下面我們看這個合約是如何運作的:
1.Alice使用十個以太部署SecuredFindThisHash合約;
2.Bob找到哈希值為目標哈希值的正確字符串;
3.Bob計算solutionHash=keccak256(Bob’sAddress+“Ethereum”+Bob’ssecret);
4.Bob調用commitSolution(_solutionHash),提交剛剛算出的solutionHash;
5.Bob在下個區塊調用revealSolution("Ethereum",Bob'ssecret)函數,傳入答案和自己設置的密碼,領取獎勵。
這里我們看下這個合約是如何避免搶跑的,首先在第四步的時候,Bob提交的是這三個值的哈希,所以沒有人知道Bob提交的內容到底是什么。這一步還記錄了提交的區塊時間并且在第五步的revealSolution()?中就先檢查了區塊時間,這是為了防止在同一個區塊開獎被搶跑,因為調用revealSolution()?時需要傳入明文答案。最后使用Bob輸入的答案和密碼驗證與之前提交的solutionHash哈希是否匹配,這一步是為了防止有人不走commitSolution()?直接去調用revealSolution()。驗證成功后,檢查答案是否正確,最后發放獎勵。
分析 | 中國信通院:圖靈完備和圖靈不完備的智能合約之間的區別:中國信息通信研究院與可信區塊鏈推進計劃共同組織編寫了《區塊鏈白皮書》(2018年),白皮書中表示,智能合約可分為圖靈完備和非圖靈完備。影響實現圖靈完備的常見原因包括:循環或遞歸受限、無法實現數組或更復雜的數據結構等。圖靈完備的智能合約有較強的適應性,可以對邏輯較復雜的業務操作進行編程,但有陷入死循環的可能。對比而言,圖靈不完備的智能合約不能進行復雜的邏輯操作,但更加簡單、高效、和安全。[2018/9/6]
所以這個合約真的完美地防止了Eve抄答案嗎?
Ofcoursenot!
咋回事呢?我們看到在revealSolution()?中僅限制了commit.commitTime<block.timestamp?,所以假設Bob在第一個區塊提交了答案,在第二個區塊立馬調用revealSolution("Ethereum",Bob'ssecret)?并設置GasPrice=15Gwei?Eve,通過監控交易池拿到答案,拿到答案后他立即設置GasPrice=100Gwei,在第二個區塊中調用commitSolution()?,提交答案并構造多筆高GasPrice的交易,將第二個區塊填滿,從而將Bob提交的交易擠到第三個區塊中。在第三個區塊中以100Gwei的GasPrice調用revealSolution("Ethereum",Eve'ssecret)?,得到獎勵。
那么問題來了,如何才能有效地防止此類攻擊呢?
很簡單,只需要設置uint256revealSpan?值并在commitSolution()中檢查?require(commit.commitTime+revealSpan>=block.timestamp,"Cannotcommitinthisblock");,這樣就可以防止Eve抄答案的情況。但是在開獎的時候,還是無法防止提交過答案的人搶先領獎。
另外還有一點,本著代碼嚴謹性,修復代碼中的revealSolution()?函數執行完后并沒有將commit.revealed?設為True,雖然這并不會影響什么,但是在編寫代碼的時候還是建議養成良好的編碼習慣,執行完函數邏輯后將開關設置成正確的狀態。
據CoinDesk10月30日消息,許多新興市場和發展中經濟體一直在尋求通過穩定幣和央行數字貨幣解決其金融系統的弱點.
1900/1/1 0:00:00作者|Day 4月份上海升級的完成使得質押的ETH可贖回,進而使LSD賽道變的完整起來。據21Shares研究分析師TomWan發推分析,以太坊信標鏈上的待定驗證者數量已達到3.345萬,創下歷.
1900/1/1 0:00:00CBDC不僅僅是一種金融手段,也和外交有一定的關系。隨著中國深入推動數字人民幣,韓國在考慮使用數字韓元。日本也在考慮自己是否要開始準備CBDC.
1900/1/1 0:00:001.彭博社ETF分析師:Valkyrie申請在美國推出1.25倍杠桿比特幣期貨ETF2.《經濟學人》DeFi主題封面NFT以99.
1900/1/1 0:00:00往期回顧: Rust智能合約養成日記合約狀態數據定義與方法實現Rust智能合約養成日記編寫Rust智能合約單元測試Rust智能合約養成日記Rust智能合約部署.
1900/1/1 0:00:00摘要:據剁椒娛投報道,ChatGPT引發的技術變革快速蔓延,直接沖擊至內容創作領域,甚至將AIGC演變成為內容平臺的一個重要板塊.
1900/1/1 0:00:00