智能合約的技術(shù)運(yùn)作原理解析
在上一篇《從一筆交易來(lái)看ETH與BTC之異同》中,我們從一筆交易來(lái)概略說(shuō)明了ETH與BTC轉(zhuǎn)帳交易的不同之處,本篇文章我們要來(lái)談以太坊智能合約。不會(huì)談到實(shí)作部分,而是希望能從實(shí)際應(yīng)用場(chǎng)景切入來(lái)說(shuō)明,讓閱讀完本文的讀者都能充分理解智能合約的技術(shù)運(yùn)作原理。
好!那本文便開(kāi)始啰!我們直接開(kāi)門(mén)見(jiàn)山地來(lái)談?wù)劊?/p>
何謂智能合約?
智能合約本質(zhì)上是一段部署 ( Deploy,即發(fā)布) 到區(qū)塊鏈上的程式碼,因?yàn)閰^(qū)塊鏈上的程式碼(嚴(yán)格來(lái)說(shuō)是二進(jìn)位碼)可以被檢視,所以具備公開(kāi)透明的特性。智能合約被部署到鏈上后會(huì)產(chǎn)生一個(gè)合約地址,永久存在于鏈上的區(qū)塊之中。以下用Pelith開(kāi)發(fā)部署之CryptoCow智能合約為范例做解說(shuō)。
如何部署智能合約?
我們從智能合約的誕生談起。
開(kāi)發(fā)者將程式碼開(kāi)發(fā)完成后,要透過(guò)發(fā)送一筆接收地址為“0x0”開(kāi)頭的交易(一般交易的接收地址為0x開(kāi)頭,后面接一串字),并在交易的 Input Data內(nèi)放上開(kāi)發(fā)完成的程式碼。礦工看到接收地址為0x0的交易就會(huì)知道交易的發(fā)送者想要部署智能合約,隨后便會(huì)將Input Data內(nèi)的程式碼部署到區(qū)塊鏈上,并生成一個(gè)合約地址。
然而我們會(huì)發(fā)現(xiàn)Input Data充滿(mǎn)了看不懂的文字,似乎跟我們印象中的程式碼不太一樣,原因是在以太坊上儲(chǔ)存的合約邏輯是以Bytecode 的形式,所以開(kāi)發(fā)者以Solidity開(kāi)發(fā)的原始碼必須先被編譯成Bytecode 才能部署上鏈。
目前大多數(shù)開(kāi)發(fā)者使用的開(kāi)發(fā)工具,如:Remix 本身都具備編譯的功能,開(kāi)發(fā)者開(kāi)發(fā)完原始碼后只要一鍵進(jìn)行編譯的動(dòng)作便能取得Bytecode 。
至此,我們來(lái)整理一下部署智慧合約上鏈的流程:
1. 開(kāi)發(fā)者以Solidity 編寫(xiě)完成合約
2. 原始碼編譯為Bytecode
3. 放入交易的Input Data 中
4. 接收地址部分留空(0x0)
5. 節(jié)點(diǎn)(礦工) 判定為要發(fā)送合約上鏈
6. 礦工執(zhí)行,并部署上鏈生成智慧合約
7. 合約擁有自己的「合約地址」,永久存在鏈上
什么是合約地址?
在合約生成之后,會(huì)創(chuàng)造出一個(gè)合約地址,讓合約(Contract Account)和個(gè)人帳戶(hù)(Externally Owned Account)一樣都有一個(gè)地址,會(huì)紀(jì)錄追蹤nonce(帳戶(hù)的交易次數(shù))和balance(帳戶(hù)余額)。
不過(guò)合約因?yàn)槭恰副弧箘?chuàng)造出來(lái)的,不像個(gè)人帳戶(hù)一樣可以「主動(dòng)操作」來(lái)發(fā)送交易給別人,所以我們?nèi)绻褂弥腔酆霞s的功能,必須要以個(gè)人帳戶(hù)發(fā)送一筆「接收地址為合約地址」的交易,來(lái)主動(dòng)觸發(fā)合約,讓合約執(zhí)行動(dòng)作。
因此,任何一筆交易的起點(diǎn)都必須是個(gè)人帳戶(hù)。
接著,我們來(lái)實(shí)際看看一筆和智能合約互動(dòng)的交易,下方是一筆很常見(jiàn)的操作合約交易,內(nèi)容是將一顆透過(guò)智能合約創(chuàng)造出來(lái)的ERC-20 代幣,從一個(gè)地址轉(zhuǎn)移到另一個(gè)地址中。而這些操作,必須透過(guò)交易發(fā)起者將這些操作以程式原始碼撰寫(xiě),編譯后放到Input Data 中。
上方紅框中其實(shí)是Etherscan 解碼(Decode)后呈現(xiàn)的樣式,而Solidity 原始碼編譯后其實(shí)是長(zhǎng)得像下列這樣,以hex(16進(jìn)位制)的方式表示。
對(duì)照上下兩種不同表現(xiàn)形式的圖,我們可以發(fā)現(xiàn)下圖紅底線(xiàn)的部分(0x93316cdf)在上圖中被以 MethodID 標(biāo)示出來(lái)。其實(shí)0x后的前8碼表示的是 我們要呼叫合約中的什么 function(在智慧合約撰寫(xiě)時(shí)我們會(huì)規(guī)劃有哪些功能是可以使用的),后面接的則是該功能的其它參數(shù)。
而這個(gè) MethodID(0x93316cdf)其實(shí)也有許多其它的別名,這邊列舉一些比較常聽(tīng)到的:HashID、FuncTIon Hash、FuncTIon Signature 等。
因此,知道這個(gè)之后,未來(lái)我們?cè)诓僮鱀APP 時(shí),便能去檢視背后的操作,也可以直接上以太坊區(qū)塊鏈瀏覽器Etherscan 去追蹤交易(TransacTIon),看是否智慧合約真的有按照DAPP 應(yīng)用程式介面顯示的狀態(tài)去執(zhí)行功能。
如果不確定這個(gè)MethodID是什么功能或會(huì)做什么,可以到Ethereum FuncTIon Signature Database 上查詢(xún):
把0x93316cdf 貼上并搜尋后,便能得知這個(gè)MethodID 對(duì)應(yīng)的是什么function,可以再以這個(gè)function 到智慧合約的程式碼中去確認(rèn)到底操作了什么。
結(jié)論
智能合約是一段部署到區(qū)塊鏈上的程式碼,可以有各式各樣的功能。因?yàn)閰^(qū)塊鏈公開(kāi)透明的特性,所以可以被任何人檢視和驗(yàn)證。
合約部署完成后會(huì)生成「合約帳戶(hù)」,有自己的合約地址。但所有的交易與操作都必須「?jìng)€(gè)人帳戶(hù)」發(fā)起,去呼叫合約中的function來(lái)執(zhí)行。
想要確認(rèn)操作合約的交易到底做了什么,可以檢視Input Data內(nèi)0x后的前八碼 MethodID,并查詢(xún)這是什么 function,再到合約帳戶(hù)中去檢視原始碼來(lái)確認(rèn)。





