當前位置:首頁 > 物聯(lián)網 > 區(qū)塊鏈
[導讀] 1.智能合約的源起 區(qū)塊鏈技術自比特幣誕生之日起便受到了廣泛的關注。最初,區(qū)塊鏈僅僅作為記錄用戶交易的底層賬本,不支持用戶訂制其它功能。 比特幣為了實現(xiàn)交易,即用戶間轉賬的功能,

1.智能合約的源起

區(qū)塊鏈技術自比特幣誕生之日起便受到了廣泛的關注。最初,區(qū)塊鏈僅僅作為記錄用戶交易的底層賬本,不支持用戶訂制其它功能。

比特幣為了實現(xiàn)交易,即用戶間轉賬的功能,設計了一套基于棧的簡單腳本語言。這套語言不支持循環(huán),不具備圖靈完備性,僅限于比特幣客戶端內部使用,且只圍繞交易這一項功能,一般被稱之為“Bitcoin Script”。

如果大家去查看比特幣區(qū)塊鏈中的每一筆交易記錄,那么會發(fā)現(xiàn)交易內容其實是一串字節(jié)碼,這串字節(jié)碼就是Bitcoin Script。比特幣對Bitcoin Script書寫的交易代碼的格式進行了限制,這種做法保證了交易的合法性與資金的安全性,但犧牲了整個系統(tǒng)的可編程性與靈活性。

一般情況下,一套語言能實現(xiàn)成千上萬種功能,如果設計一套語言只是實現(xiàn)了一個功能,未免有些可惜?;蛟SVitalik Buterin正是發(fā)現(xiàn)了區(qū)塊鏈中腳本語言的可能性,于是他在以太坊中把語言請到了舞臺中央,供用戶創(chuàng)建與調用,這也成為了以太坊最具魅力的特性——智能合約。

與比特幣的Bitcoin Script對應,以坊中腳本語言名字叫EVM語言(Ethereum Virtual Machine Code)。EVM語言也是基于棧的語言,但它是圖靈完備的語言,且以太坊設計了專門的虛擬機EVM來為其提供運行環(huán)境,這和Bitcoin Script有明顯的區(qū)別。

2.智能合約的使用以交易為接口

為了明確系統(tǒng)的功能,以太坊擴充了交易的概念。在比特幣中,交易一般指用戶之間的轉賬操作,在以太坊中,交易除了轉賬,還包括創(chuàng)建或者調用智能合約。因此可以說EVM語言也是為了交易而存在,但它服務的交易的內容廣泛得多。

我們先補充一些必要的概念。以太坊中賬戶分為外部賬戶與合約賬戶,外部賬戶就是用戶使用的賬戶,其中包括了用戶的私鑰和錢包等重要信息;合約賬戶用來存放一個智能合約,通常是由外部賬戶創(chuàng)建的。

用戶發(fā)送到以太坊區(qū)塊鏈上的每一筆交易中都包含幾個關鍵字段:“from”表示交易發(fā)起者,“to”表示交易接收者,“value”表示交易金額,“data”表示附帶的信息。

上文提及的三種操作的交易格式如下:

1) 普通轉賬操作:“from A, to B, value C”表示從外部賬戶A向外部賬戶B轉賬,轉賬金額為C;

2) 智能合約創(chuàng)建操作:“from A, to (空), value C, data D”表示外部賬戶A創(chuàng)建一個智能合約,向該合約賬戶里轉賬C, 合約的代碼為D;

3) 智能合約調用操作:“from A, to E, data F”表示外部賬戶A調用合約賬戶E的智能合約,本次調用傳入的參數為F。

3一筆交易的處理流程

下面我們來分析一筆交易在以太坊區(qū)塊鏈中是如何被處理與執(zhí)行的。

這部分在以太坊的源碼中十分清晰,因此我們跟隨源碼里的函數調用流程來進行說明。以太坊Go版本源碼地址:https://github.com/ethereum/go-ethereum。

首先先定位,我們可以從core/blockchain.go中找到執(zhí)行的core/state_processor.go中Process()方法,在Process()方法中可以找到如下一行代碼:

receipt, _,err:= ApplyTransaction(p.config, p.bc, nil, gp, statedb, header, tx, usedGas, cfg)

根據這個函數名字我們知道已經找到了執(zhí)行交易的入口。

3.1 創(chuàng)建EVM虛擬機

瀏覽在core/state_processor.go中的ApplyTransacTIon()方法,可發(fā)現(xiàn)如下三行關鍵代碼:

context := NewEVMContext(msg, header, bc, author)

vmenv := vm.NewEVM(context, statedb, config, cfg)

_, gas, failed, err := ApplyMessage(vmenv, msg, gp)

第一行是創(chuàng)建新的EVM的執(zhí)行上下文環(huán)境,第二行是創(chuàng)建新的EVM,第三行是用新創(chuàng)建的EVM來處理交易消息。由此可知,每一筆交易在執(zhí)行之前以太坊都會創(chuàng)建一個EVM虛擬機來負責該交易的執(zhí)行。

繼續(xù)瀏覽core/state_transiTIon.go中的ApplyMessage()方法,發(fā)現(xiàn)該方法只有一行代碼:

return NewStateTransiTIon(evm, msg, gp).TransiTIonDb()

繼續(xù)看core/state_transition.go中的TransitionDb()方法,發(fā)現(xiàn)方法中有一個重要的分支:

if contractCreation {

ret, _, st.gas, vmerr = evm.Create(sender, st.data, st.gas, st.value)

} else {

st.state.SetNonce(msg.From(), st.state.GetNonce(sender.Address())+1)

ret, st.gas, vmerr = evm.Call(sender, st.to(), st.data, st.gas, st.value)

}

這段代碼的意思是先判斷是不是創(chuàng)建合約的操作,如果是,則調用Create()方法,如果不是,則調用Call()方法。由此可知,交易的三種操作中,創(chuàng)建合約使用的方法是Create(),而調用合約與轉賬使用的方法是Call()。

接下來我們分別看一下這兩個方法。

3.2 智能合約的創(chuàng)建

先看core/vm/evm.go中的Create()方法。該方法只有兩行代碼:

contractAddr=crypto.CreateAddress(caller.Address(),evm.StateDB.GetNonce(caller.Address()))

return evm.create(caller, &codeAndHash{code: code}, gas, value, contractAddr)

第一行是根據外部賬戶的地址和nonce值計算將要創(chuàng)建的合約賬戶的地址,這個nonce參數用來記錄該外部賬戶已創(chuàng)建的合約的數目。

第二行是將創(chuàng)建的合約賬戶地址和其它參數一起傳給同文件中的create()方法。

繼續(xù)看create()方法可看到如下三行代碼:

nonce := evm.StateDB.GetNonce(caller.Address())

evm.StateDB.SetNonce(caller.Address(), nonce+1)

contractHash := evm.StateDB.GetCodeHash(contractAddr)

第一行是獲取想創(chuàng)建合約的外部賬戶的nonce值。

第二行是將該nonce的值加一后寫回去,第三行是計算合約地址的哈希值確保不會發(fā)生地址沖突。

在計算出合約地址后,可看到下面一行代碼:

evm.StateDB.CreateAccount(contractAddr)

這行代碼是根據合約地址創(chuàng)建出了合約賬戶。合約賬戶創(chuàng)建完后,可看到下面一行代碼:

evm.Transfer(evm.StateDB, caller.Address(), contractAddr, value)

創(chuàng)建者從外部賬戶向合約賬戶轉賬,金額為value。至此,合約賬戶創(chuàng)建工作完成了。

接下來需要創(chuàng)建合約對象并把合約代碼跑起來:

contract:=NewContract(caller, AccountRef(contractAddr), value, gas) contract.SetCallCode(&contractAddr, crypto.Keccak256Hash(code), code)

第一行是創(chuàng)建合約對象,第二行是將用戶定義的智能合約代碼綁定到該合約對象上。

合約對象創(chuàng)建完后,用下面一行代碼運行該合約:

ret, err = run(evm, contract, nil)

可能有人會疑惑:創(chuàng)建完合約為什么要運行一遍?

這主要有兩方面的原因:其一,系統(tǒng)需保證合約代碼是能正確運行的,這樣在以后的調用中才不會出錯;其二,系統(tǒng)需要通過運行才能計算出消耗的gas數量,進而完成對外部賬戶的創(chuàng)建合約操作的扣費。其實在create()方法中還有檢查棧深度、創(chuàng)建快照、出錯后回滾、gas計算等代碼,因它們不涉及到本文的主要內容,故略過。

3.3 轉賬與智能合約的調用

然后我們看core/vm/evm.go中的Call()方法,該方法負責合約調用和轉賬兩種交易操作。

Call()方法中不需要創(chuàng)建新的地址,只需要:

to = AccountRef(addr)

該行代碼獲取交易接收方的地址。之后可看到下面一行代碼:

evm.Transfer(evm.StateDB, caller.Address(), to.Address(), value)

交易發(fā)起者向交易接收方轉賬value金額。接下來的代碼和Create()相像:

contract := NewContract(caller, to, value, gas)

contract.SetCallCode(&addr,evm.StateDB.GetCodeHash(addr),evm.StateDB.GetCode(addr))

第一行創(chuàng)建合約對象,第二行將接收者地址上的智能合約代碼綁定到合約對象上。如果是轉賬操作,接收者地址上沒有代碼,因此綁定的代碼是空,之后的運行會很快結束。綁定完成后,使用run()方法運行該合約完成調用:

ret, err = run(evm, contract, input)

在Call()方法中同樣還有檢查棧深度、創(chuàng)建快照、出錯會滾、gas計算等代碼,留給感興趣的讀者自行閱讀。

Create()與Call()中最后執(zhí)行都調用了core/vm/evm.go中的run()方法,而run()方法中可發(fā)現(xiàn):

return interpreter.Run(contract, input, readOnly)

接下來定位到core/vm/interpreter.go中的Run()方法。該方法是EVM中解釋器的運行流程,核心邏輯為循環(huán)取出合約的代碼,查表解析出具體的操作碼,再查表計算出需要消耗的gas數目,然后調用操作碼相應的處理函數執(zhí)行。

核心代碼如下:

for atomic.LoadInt32(&in.evm.abort) == 0 {

op = contract.GetOp(pc)

operation := in.cfg.JumpTable[op]

cost, err = operation.gasCost(in.gasTable, in.evm, contract, stack, mem, memorySize)

res, err := operation.execute(&pc, in, contract, mem, stack)

}

至此,一筆交易的運行就結束了。

4. 結語

綜上所述,我們能了解到以太坊設計的三種交易背后能給予用戶極大的自由度,也充分發(fā)揮了EVM語言及其虛擬機的功能。

用戶通過Solidity等語言編寫智能合約,然后編譯成EVM語言,再打包成交易的格式發(fā)送到區(qū)塊鏈上運行。以太坊得益于這種模式帶來的可編程的特性,引領區(qū)塊鏈技術進入了2.0時代。

然而,現(xiàn)在智能合約由于EVM的棧深度與gas消耗的限制,多數都是簡單且袖珍的程序。即使現(xiàn)在這樣的程序已經足夠滿足需求,但未來必將面臨更多更加復雜化的交易場景。

如何去應對這些場景,需要廣大開發(fā)者們繼續(xù)努力。

本站聲明: 本文章由作者或相關機構授權發(fā)布,目的在于傳遞更多信息,并不代表本站贊同其觀點,本站亦不保證或承諾內容真實性等。需要轉載請聯(lián)系該專欄作者,如若文章內容侵犯您的權益,請及時聯(lián)系本站刪除。
換一批
延伸閱讀

9月2日消息,不造車的華為或將催生出更大的獨角獸公司,隨著阿維塔和賽力斯的入局,華為引望愈發(fā)顯得引人矚目。

關鍵字: 阿維塔 塞力斯 華為

加利福尼亞州圣克拉拉縣2024年8月30日 /美通社/ -- 數字化轉型技術解決方案公司Trianz今天宣布,該公司與Amazon Web Services (AWS)簽訂了...

關鍵字: AWS AN BSP 數字化

倫敦2024年8月29日 /美通社/ -- 英國汽車技術公司SODA.Auto推出其旗艦產品SODA V,這是全球首款涵蓋汽車工程師從創(chuàng)意到認證的所有需求的工具,可用于創(chuàng)建軟件定義汽車。 SODA V工具的開發(fā)耗時1.5...

關鍵字: 汽車 人工智能 智能驅動 BSP

北京2024年8月28日 /美通社/ -- 越來越多用戶希望企業(yè)業(yè)務能7×24不間斷運行,同時企業(yè)卻面臨越來越多業(yè)務中斷的風險,如企業(yè)系統(tǒng)復雜性的增加,頻繁的功能更新和發(fā)布等。如何確保業(yè)務連續(xù)性,提升韌性,成...

關鍵字: 亞馬遜 解密 控制平面 BSP

8月30日消息,據媒體報道,騰訊和網易近期正在縮減他們對日本游戲市場的投資。

關鍵字: 騰訊 編碼器 CPU

8月28日消息,今天上午,2024中國國際大數據產業(yè)博覽會開幕式在貴陽舉行,華為董事、質量流程IT總裁陶景文發(fā)表了演講。

關鍵字: 華為 12nm EDA 半導體

8月28日消息,在2024中國國際大數據產業(yè)博覽會上,華為常務董事、華為云CEO張平安發(fā)表演講稱,數字世界的話語權最終是由生態(tài)的繁榮決定的。

關鍵字: 華為 12nm 手機 衛(wèi)星通信

要點: 有效應對環(huán)境變化,經營業(yè)績穩(wěn)中有升 落實提質增效舉措,毛利潤率延續(xù)升勢 戰(zhàn)略布局成效顯著,戰(zhàn)新業(yè)務引領增長 以科技創(chuàng)新為引領,提升企業(yè)核心競爭力 堅持高質量發(fā)展策略,塑強核心競爭優(yōu)勢...

關鍵字: 通信 BSP 電信運營商 數字經濟

北京2024年8月27日 /美通社/ -- 8月21日,由中央廣播電視總臺與中國電影電視技術學會聯(lián)合牽頭組建的NVI技術創(chuàng)新聯(lián)盟在BIRTV2024超高清全產業(yè)鏈發(fā)展研討會上宣布正式成立。 活動現(xiàn)場 NVI技術創(chuàng)新聯(lián)...

關鍵字: VI 傳輸協(xié)議 音頻 BSP

北京2024年8月27日 /美通社/ -- 在8月23日舉辦的2024年長三角生態(tài)綠色一體化發(fā)展示范區(qū)聯(lián)合招商會上,軟通動力信息技術(集團)股份有限公司(以下簡稱"軟通動力")與長三角投資(上海)有限...

關鍵字: BSP 信息技術
關閉
關閉