EOSIO開發(八)- 智慧合約基礎概念
什麼是智慧合約
智慧合約的概念早在上世紀90年代就已經被提出來,自從以太坊將其發揚光大以後,智慧合約在各個區塊鏈專案,尤其是公鏈中得到了廣泛應用,EOS也不例外。
用一句話描述智慧合約:
智慧合約(Smart contract )是一種旨在以資訊化方式傳播、驗證或執行合同的計算機協議。智慧合約允許在沒有第三方的情況下進行可信交易,這些交易可追蹤且不可逆轉。
例如小張和小王擲骰子,約定誰的點數大,誰就可以從對方那裡贏得一塊錢。
這個過程可以完全用智慧合約來控制。
- 小張先擲,合約記錄點數。
- 小王后擲,合約記錄點數。
- 合約判斷點數大小,並從小點數賬戶扣除一塊錢給大點數賬戶。
整個過程都由智慧合約自動執行,不需要第三方參與,並且一旦結果確認了就不可反悔。
需要掌握的背景知識
-
C++
雖然C++學起來很麻煩,但是沒辦法,誰讓BM對C++這麼青睞呢。好在開發EOSIO並不需要掌握所有的C++知識,因此我的建議是快速學習,夠用就行。推薦兩本書。一本是《C++語言導學》,讓程式設計師在短時間內快速學習C++的核心知識點。另一本是《C++標準庫》,可以拿來做參考書用。
-
Linux / Mac OS
EOSIO目前只能執行在Linux 或者Mac OS作業系統上。 -
命令列基礎知識
EOSIO提供的一些工具需要通過命令列操作,比如前面文章中經常用到的cleos。
基礎概念
Action
一個智慧合約可以定義多個Action,每個Action代表一次單獨的操作,例如:轉賬、擲骰子、比較點數大小。
對映到程式碼中,可以將Action理解成類中的函式,函式中定義了呼叫Action時需要執行的操作。
智慧合約與賬戶通過Action的方式進行通訊。Action可以單獨執行,也可以和其他Action一起作為一個整體執行。
例如:賬戶小王執行了【還錢】Action,【還錢】Action通知賬戶工商銀行,執行【轉賬】Action,【轉賬】Action又通知賬戶【小李】,執行【簡訊通知】Action。
Transaction
Transaction是一個或多個Action的集合,一個Transaction中的Action要麼全部成功,要麼全部失敗,從這個角度來看,Transaction與資料庫中的“事務”非常像。
在前面Action的例子中,【還錢】Action、【轉賬】Action、【簡訊通知】Action可以都被包含在一個事務中。
下面是包含了多個Action的Transaction例子(關鍵字:actions)。
{
"expiration": "2018-04-01T15:20:44",
"region": 0,
"ref_block_num": 42580,
"ref_block_prefix": 3987474256,
"net_usage_words": 21,
"kcpu_usage": 1000,
"delay_sec": 0,
"context_free_actions": [],
"actions": [{
"account": "eosio.token",
"name": "issue",
"authorization": [{
"actor": "eosio",
"permission": "active"
}],
"data": "00000000007015d640420f000000000004454f5300000000046d656d6f"
},{
"account": "...",
"name": "...",
"authorization": [{
"actor": "...",
"permission": "..."
}],
"data": "..."
}],
"signatures": [""],
"context_free_data": []
}
合約互動模式
EOSIO中提供了兩種智慧合約的互動模式,Inline(內聯)和 Deferred(延遲)。
Inline可以被理解為實時互動模式,在一個Transaction中所有的Action,實時呼叫順序執行。
Deferred可以被理解為延時互動模式,TransactionA中的部分Action沒有被立即執行,而是延遲一段時間後,由TransactionB來執行。
下面用一個具體的示例來說明兩種模式。
假設有一個Employer(僱主)賬戶,希望通過它的payroll Action將工資發放給Employees(僱員)賬戶。
Inline模式
在Inline模式下,所有的Action是被實時順序呼叫的,整個執行過程的時序圖如下所示。
圖中employer::runpayroll
發起了發工資的請求,
而employer::dootherstuff
是僱主執行的其它操作,我們可以不用理會它。
-
第一步,
employer::runpayroll
執行inline actioneosio::token::transfer
,從Employer賬戶傳送給Bank賬戶,並將需要收到工資的Employee賬戶資訊儲存在memo欄位中。 -
第二步,
eosio::token::transfer
action修改了token的轉賬狀態,並將memo欄位的資訊通知給Bank賬戶。 -
第三步,Bank賬戶部署了一個合約,用來監聽
eosio::token::transfer
action的通知。當收到通知後,根據memo欄位的內容通知對應的Employee賬戶。 -
第四步,Employee賬戶同樣部署了合約監聽
eosio::token::transfer
action的聽通知。當收到通知後,執行inline actionbank::doacctpolicy
。 -
第五步,Bank賬戶執行
bank::doacctpolicy
action。
Deferred模式
還是同樣的場景,假設bank::doacctpolicy
不是以inline模式呼叫,而是以deferred模式呼叫,時序圖會改成下面這個樣子。
從時序圖來看,主要的區別:
bank::doacctpolicy
action並沒有立即被執行,而是放到了一個佇列(queue)中。bank::doacctpolicy
action是在延遲一段時間以後,放在Defered Transaction
執行的。
通過前面的描述,我們可以總結出inline模式與deferred模式的主要區別:
- inline模式是實時執行action,而deferred模式是延時執行。
- deferred模式下的action會被放到一個佇列中,後續執行時再從佇列中拿出來。
- inline模式中的action是在同一個Transaction裡,而deferred模式下action被分散到不同的Transaction裡。