區塊鏈研究實驗室 深入解析Solidity合約

2021-09-11 07:06:02 字數 2749 閱讀 4510

這次主要討論solidity背後的運作原理,到底乙個solidity合約經過編譯到部署上鏈之間的過程是如何運作的,以及後續呼叫合約時的流程,知道得越多就越能寫出安全可靠的合約。

我們都知道乙個solidity程式**寫完之後,必須將它編譯成byte code,才能透過交易部署至鏈上,變成所謂的智慧型合約。我們以下面的etherdice.sol為例子。

當etherdice.sol經過編譯之後,會產出下面的一長串byte code,這些可以透過evm assbemly來一步步解析,但用肉眼很難看出到底是如何運作的,至少我不行。

以執行的方式來看,這些bytecode可以先分成固定的三個部分,如下:

合約部署上鏈之後,在使用合約內的某個函式時,其流程又是如何運作的?這就歸runtime部分的byte code來負責了。如下圖,runtime可以分成幾個固定的部分,其中最常用到的就屬 functionselector ,它主要負責逐一比對想要呼叫的function signature是否有存在byte code中,若有就執行,否則就會執行fallback function。若合約連fallbackfunction都沒實作,則交易就會被revert。

簡單介紹完合約部署上鏈及呼叫函式的流程之後,讓我們來看看對於etherdice合約的攻防思路,就會變得相當容易理解。

1.小明的發財夢

2.etherdice的漏洞

阿財是個業餘的bug hunter,平時最大的嗜好就是挖bug賺獎金。又是個沒局的夜晚,阿財跟平常一樣獨自坐在計算機前看文章,信箱突然登登一聲,一封主旨為new bounty posted的email出現在螢幕的角落,阿財馬上點開信中的鏈結,想要搶快挖bug。經驗豐富的阿財只看etherdice的合約名稱就馬上知道可能的漏洞在哪邊,果不其然,又是乙個想發財的新手,這下撿到寶了。

骰子遊戲中最重要的random number**居然是使用區塊的timestamp,只要寫個攻擊的合約,透過合約來呼叫etherdice的bet,就可以事先計算block.timestamp % 6的結果再來下注,就每賭必贏啦!!阿財很迅速的完成攻擊合約,並寫下建議的修補方式,就提交bug了。

3.修補etherdice的漏洞

小明才剛躺在床上都還沒睡著,手機就傳來email的通知,沒想到居然這麼快就被找到bug,經過測試確認之後,dicehack.sol的確是可以成功壓中每一筆下注。他一邊喃喃自語solidified不愧是全球最大的solidity bug bounty**,效率真高,這錢花的實在值得,一邊著手修補漏洞。

防禦的概念是這樣的,只要能判斷發出交易的address是一般的 externally owned account (eoa,也就是由使用者控制金鑰的賬戶),還是 contract account,就可以擋下由dicehack.sol發出的交易,這樣就沒問題啦。

合約部署上鏈後,會將runtime部分儲存起來,透過判斷某個address是否擁有runtime的bytecode就可知它是否為contract address。幸好,solidity支援inline assembly,可以直接在solidity程式**內使用extcodesize取出儲存的byte code長度,若長度為0就表示是eoa發出的,否則就是合約。

小明修改完程式**之後,再跑一次dicehack.sol,果然成功擋下,看到螢幕上跳出 robot is not allowed!! 訊息,嘴角不禁微微抽動。這下終於可以高枕無憂,離他的發財夢也不遠了。

4.道高一尺魔高一丈

一切都在阿財的預料之中,但令他感到意外的是這個新手居然馬上就修補好漏洞,這樣的熱血青年實在令人讚賞,沈思幾秒之後,阿財心裡默默說出,好吧,這次就放過你了。於是著手提交第二個bug,並附上他早就預備好的第二支攻擊合約。

攻擊思路是這樣的,solidity經過編譯之後,主要有creation及runtime兩個部分的byte code,首先執行creation,此時,runtime程式**尚未儲存,這樣extcodesize(addr)的回傳值一定會是0。因此只要把攻擊程式**寫在合約的constructor裡面,就可以繞過偵測機制,發動攻擊。

這次阿財並沒有說明防禦的方法,因為他希望這位熱血青年能夠繼續鑽研技術,用自己的方式找出答案。其實他這麼做都是為了增加取暖人數,畢竟幣圈正值寒冬,能多一人是一人。

區塊鏈研究實驗室除錯大揭秘!

除錯solidity 非常困難。隨著時間的流逝,諸如ganache,remix和solidity test helpers之類的工具使它變得更容易,但仍然存在bug。使用ganache進行除錯的gui將有助於減輕許多這些痛苦,並允許開發人員視覺化地處理和除錯合同。現在有一種方法可以做到這一點!本教程...

區塊鏈研究實驗室 以太坊上的廣義狀態通道

狀態通道是可用於分布式應用程式的基礎技術。它們可以用於與一組已定義的參與者進行任何互動,例如付款或類似象棋或撲克的遊戲。通道化 這些應用程式使其成本大大降低,並減少了當今區塊鏈應用程式中不可接受的高延遲,從而實現了使用者預期的類似網路的響應時間。儘管如此,在當今的以太坊應用中,狀態通道的利用率仍然很...

區塊鏈研究實驗室 智慧型合約資料下溢攻擊案例分析

儘管dao合同並未成為下溢攻擊的受害者,但我們可以利用現有的babydao合同 來更好地了解這種過於常見的攻擊方式。首先我們了解uint256是什麼。uint256是256位的無符號整數 無符號,只有正整數 以太坊虛擬機器被設計為使用256位作為其字大小,或者由計算機的cpu一次處理的位數。由於ev...