如何編寫與部署新的智慧合約

作者: Yongxin Xu
在上一篇文章中,我介紹了自動販賣機 DApp 的模型,以及為這個應用程式定義、名為「aggregate transaction」的新智慧合約(交易協定)。此後,我持續編寫智慧合約並建立鏈下模擬器。因此,本文將簡要介紹編寫及部署新智慧合約的步驟,並分享使用 ArcBlock Forge Framework 的心得。
首先快速回顧 aggregate transaction。前幾篇文章提到,我的 DApp 是自動販賣機業務的可信任帳本。區塊鏈在其中的作用,是確保帳本中的所有資料可靠,也就是不可竄改。因此,DApp 只需要區塊鏈完成帳單資料的記錄。為滿足這項需求,我需要編寫新的智慧合約,換句話說,就是定義一種名為「aggregate transaction」的新交易類型。每當產生帳單,自動販賣機的錢包帳戶便會傳送 aggregate transaction,將所有相關資訊寫入鏈上。交易成功送出後,相關各方的利潤金額會自動更新至各自的錢包帳戶。一旦所有資訊都上鏈,便無法造假,帳本也就能始終保持可信。


以下是編寫與部署新智慧合約的步驟:
第一,建立自訂鏈。
Forge Framework 提供的 Forge CLI 能輕鬆建立自訂鏈。使用 forge start 命令即可在本機建立並啟動節點。
第二,編寫新的智慧合約。
建立新智慧合約需要編寫以下四個檔案:
- protocol.proto
protocol.proto用來定義交易的資料結構。換句話說,它告訴鏈這種交易長什麼樣子,以及包含哪些資訊。在 Forge Framework 中,一筆交易由外層 transaction 與 inner transaction 兩層組成。簡單來說,外層包含所有交易類型的共通資訊,例如傳送者與傳送時間;內層則包含各交易類型特有的資訊。因此,protocol.proto實際上定義的是內層的結構與內容。


- protocol.yml
protocol.yml透過建立 pipeline,告訴鏈如何處理這個新智慧合約。基本上,Forge Node 會分三個步驟處理每筆交易。
- Check。Forge Node 收到交易後,會先快速檢視整筆交易,確認是否有欄位未填等明顯問題。
- Verify。相較於 check,這是更徹底的檢查。通過驗證的交易會被認定為對鏈完全有效。
若要理解 check 與 verify 的差異,可以想像機場安檢。通常先檢查身分證件與登機證,確認資訊是否有問題,再通過全身掃描器偵測違禁品。只有完成安檢後才能登機。
- Update。最後一步是在交易通過驗證後,更新整條鏈的狀態。 > Forge Framework 提供許多預先定義的「pipe」,讓開發者能像堆積木一樣建立 pipeline;開發者也可以自行編寫自訂 pipe。例如,不同交易類型會更新鏈上不同的資料,因此通常需要為最後的 update 步驟自訂 pipe。

- protocol.ex
protocol.ex用來編寫自訂 pipe,使用的程式語言是 Elixir。雖然 Elixir 對我們而言可能很陌生,但程式背後的邏輯並不複雜。關於如何使用 Elixir 編程,請參閱相關參考資料。 - config.yml
config.yml包含整個智慧合約的基本資訊,供鏈參考。它會指定前述三個檔案及目前版本號。每次修改智慧合約時,都必須更新版本號。若部署修訂版時忘記更新,鏈便不會替我們更新任何內容。

第三,部署新的智慧合約。
Forge CLI 提供了簡便的智慧合約部署方式。只需依照文件中的指示,就能輕鬆部署新的智慧合約。
第四,測試新的智慧合約。
我們可以在 Forge remote console 中使用 Elixir SDK 測試新智慧合約,而且 Elixir SDK 非常容易使用。不過 Python 是我的最愛,因此這裡要展示如何以 Python SDK 測試新智慧合約。主要有三個步驟:
- 編譯新的智慧合約。可使用 Google 提供的 Protocol Buffer Compiler,將
protocol.proto編譯成支援 python 的檔案。
protoc -I=$SRC_DIR --python_out=$DST_DIR $SRC_DIR/protocol.proto- 建立錢包帳戶。如上一篇文章所述,錢包是鏈上所有交易的發起者或接收者。只要知道另一個人的錢包地址,就能在鏈上與其互動。因此,我要為 aggregate transaction 的發起者——自動販賣機,以及接收者——相關各方建立錢包帳戶。使用以下命令即可透過 Python-SDK 建立錢包,也能輕鬆查看錢包地址與餘額。
from forge_sdk import ForgeConn
f = ForgeConn('127.0.0.1:28210')
rpc = f.rpc
vm = rpc.create_wallet(moniker='vending_machine', passphrase='vm1234')
addr = vm.wallet.address
rpc.get_account_balance(address)- 最後,傳送交易。我可以使用以下命令傳送 aggregate transaction。傳送後,鏈會傳回一個雜湊值,我們可藉此驗證交易是否已成功送上鏈。
itx = protos.AggregateTx(sku=sku, value=value, time=time, operator=op.wallet.address, manufacturer=ma.wallet.address, supplier=su.wallet.address, location=lo.wallet.address)
itx2 = utils.encode_to_any(type_url="fg:t:aggregate", data=itx)
rpc.send_itx(tx=itx2, wallet=vm.wallet, token=vm.token, nonce=0)
rpc.is_tx_ok('[return-hash]')
以上就是編寫與部署新智慧合約的步驟。如果沒有問題,DApp 的鏈上部分基本上就完成了。接下來可以專注於我們最熟悉的鏈下部分。
透過 Forge Framework 部署智慧合約後,我最大的感受是,使用 forge framework 自訂自己的鏈真的非常簡單。Forge Framework 替我們解決了複雜的底層區塊鏈技術。也就是說,當我們只想製作 DApp 時,它會屏蔽那些不需要了解的高深知識,大幅降低建構 DApp 的難度,並提供可遵循的範本。下次我計畫向大家展示自動販賣機 DApp,以及完成鏈下部分的過程。我也非常期待應用程式最後的樣貌。此外,經過三週的學習與實作,我累積了許多經驗,對區塊鏈技術及其如何改變生活也有更深入的理解。這些內容會在下一篇文章與大家分享。下次見!