鏈聞 ChainNews
EOS 智能合約是由一系列 action 組成,每個 action 代表一條合約條款,實現了條款中的具體規則。智能合約的執行基於 C/S 通信架構,本文從代碼角度描述了智能合約的製作智能合約、部署智能合約和調用智能合約三個部分。

什麼是智能合約

在解釋智能合約前,我們先來看看傳統合約的形態。合約的本質是由一系列條款組成,每個條款由若干條規則組成,通過向條款中輸入固定的參數,會輸出固定的結果。傳統合約需要由雙方共同參與簽署確認,同時需要第三方見證人公證後,才具有法律效應,確保合約按照既定的規則執行。這裏的第三方通常是具有法律效力的公證方,同時必須是能夠精準理解合約條款的專業機構,可以避免雙方產生糾紛。比如,在租賃合同中,需要由房東和租客雙方共同簽署,而中介則扮演了第三方見證人。

隨着信息技術的發展,紙質的合約逐漸被電子合約替代。電子合約是用程序代碼來實現合約條款,當外部條件滿足後,自動執行相應的規則,避免人工參與,提高合約執行效率。比如,信用卡自動還款、股票委託交易等,都採用了電子合約方式。

雖然電子合約實現了合約的自動化執行,但是仍然需要一個第三方仲裁機構參與,比如銀行、股票交易所。這些機構相互獨立,而且需要協作處理大量的清算、交割任務。這導致了中心化的仲裁模式產生了瓶頸。

智能合約 = 電子合約 + 去中心化仲裁 + 合約間交互

智能合約是對電子合約的進一步優化,去除了中心化的第三方仲裁機構,由區塊鏈上所有節點產生的共識,作爲合約執行依據。大大減少人工參與工作,進一步提升了合約的執行效率。智能合約本質就是部署在區塊鏈上的一段可執行代碼,可以被查詢或者調用。智能合約可以與人進行交互,也可以和其它智能合約交互,合約的執行過程完全不需要額外的人工參與。

EOS 智能合約分析

EOS 智能合約是由一系列 action 組成,每個 action 代表一條合約條款,實現了條款中的具體規則。智能合約的執行基於 C/S 通信架構,分爲製作智能合約、部署智能合約和調用智能合約三部分。

製作智能合約

智能合約的代碼放在 eos/contracts/ 目錄下,每個智能合約對應一個獨立目錄,主要包含 cpp 文件、hpp 文件、abi 文件,例如,token 合約目錄結構如下:

其中,hpp 頭文件主要包含類定義、全局變量、宏定義等等;cpp 源文件主要包含合約函數的實現細節;abi 文件全名叫做「Application Binary Interface」(應用程序二進制接口),通過 abi 接口轉換層,用戶可以通過 JSON 格式直接調用智能合約裏面的 action 函數。

部署智能合約

用戶需要將智能合約 C++代碼編譯成 WASM 格式(一種面向 web 的二進制格式,也是區塊鏈唯一能夠識別的格式),例如,編寫一個用來打印 hello world 的智能合約:

hello/hello.cpp:

其中,每個智能合約必須實現一個 apply() 函數,用來將 action 請求映射到具體的處理函數,具體的實現細節封裝在 EOSIO_ABI 宏裏面。這樣,開發者只需要專注合約業務邏輯的開發,而不必關注底層技術細節,簡化了智能合約開發的工作。

將合約代碼變成 WASM 格式,用於存儲在區塊鏈上:

#eosiocpp -o hello.wast hello.cpp
生成 abi 文件,爲其它用戶提供一個友好的 action 調用接口:

#eosiocpp -g hello.abi hello.cpp
Generated hello.abi

abi 文件內容:

通過客戶端工具 cleos,將智能合約發送給服務器,由服務器持久化部署在區塊鏈上,隨後可以被其它用戶調用執行該合約:

調用智能合約

由客戶端通過 cleos 命令發送 action 請求給服務器。服務器會根據 action 請求信息,去區塊鏈上找到對應的智能合約代碼,並將代碼加載到內存中執行,最後將執行結果返回給客戶端,下面的命令調用了 hello.code 智能合約的 hi 函數,並將「user」作爲參數傳入:
#cleos push action hello.code hi \'[\”user\”]\’ -p user

hello.code <= hello.code::hi {\”user\”:\”user\”}

Hello, user

Action 處理流程

cleos 會將一組 action 封裝成一個 transaction 數據包發送給服務器。這裏借用了數據庫事務的概念,一個 transaction 代表一個事務,在事務內的 action 要麼全部執行,要麼都不執行,必須保證事務的原子性。Transaction 可以包含一個 action,也可以包含多個 action,用 json 格式表示,例如:

服務器接收到大量的 action 請求,然後將 action 派發到對應的智能合約。每個智能合約都會實現一個 apply() 函數,用來處理各個 action 請求。apply() 函數包含 3 個參數,receiver 表示處理請求的賬號,code 表示合約名稱,action 表示 action 名稱,例如:

action 在運行之前,EOSIO 會爲 action 創建一個運行環境,也叫做 Action 「Apply」 Context,提供程序運行所需的 CPU 和內存資源,具體的資源申請量取決與賬戶持有的股權比例,也就是 EOS 代幣。

每個服務器都有一個 action 處理函數集合副本,當客戶端發起 action 請求後,所有服務器會在本地運行 action 處理函數,並相互校驗結果,最後將確認結果返回給客戶端,具體流程如下:

智能合約的通信模型

智能合約中所謂的智能概念,就是智能合約不但可以和人交互通信,而且可以和其它智能合約進行交互通信。例如,當本次智能合約的 transaction 中可以調用其它智能合約的 action 來完成一些工作,或者在未來某個時刻觸發其它智能合約的 transaction。

EOSIO 支持兩種基本的通信模型,inline 和 deferred。其中,inline 模型是指在當前的 transaction 中完成對其它智能合約 action 的調用,可以簡單的認爲是 transaction 的嵌套調用,內部的 action 失敗會導致 transaction 整體做回退。Deferred 模型是指延遲一段時間,或者滿足一定條件後才執行,也就是說不能保證一定被執行到。

更多精彩內容,關注鏈聞 ChainNews 公衆號(id:chainnewscom),或者來微博@ 鏈聞 ChainNews 與我們互動!轉載請註明版權和原文鏈接!

來源鏈接:www.8btc.com