如何在本體網絡上編寫WebAssembly智能合約? 第 1 部分:生鏽

如何在本體網絡上編寫WebAssembly智能合約? 第 1 部分:生鏽

本體Wasm技術降低了將具有復雜業務邏輯的dApp智能合約遷移到區塊鏈的成本,從而極大地豐富了dApp生態。

現在 本體 Wasm 同時支持 Rust 和 C++ 開發。 Rust語言對Wasm的支持更好,生成的字節碼更簡單,可以進一步降低合約調用的成本。 所以, 如何使用Rust在本體網絡上開發合約?

使用 Rust 開發 WASM 合約

創建合約

貨物 是一款不錯的Rust開發項目創建和包管理工具,幫助開發者更好的組織代碼和第三方庫的交互。 要創建新的 Ontology Wasm 合約,只需運行以下命令:

如何在本體網絡上編寫WebAssembly智能合約? 第 1 部分:生鏽

它生成的項目結構:

如何在本體網絡上編寫WebAssembly智能合約? 第 1 部分:生鏽

Cargo.toml文件用於設置項目基本信息和依賴庫信息。 文件的 [lib] 部分必須設置為 crate-type = ["cdylib"]。 lib.rs 文件用於編寫合約邏輯代碼。 此外,還需要在 Cargo.toml 配置文件的 [dependencies] 部分添加依賴參數:

如何在本體網絡上編寫WebAssembly智能合約? 第 1 部分:生鏽

通過這種依賴,開發者可以調用與本體區塊鏈交互的接口和序列化參數等工具。

合約錄入功能

每個程序都有一個input函數,比如我們平時看到的main函數,但是合約沒有main函數。 當使用 Rust 開發 Wasm 合約時,默認的 invoke 函數被用作輸入函數來使用合約。 在將 Rust 源代碼編譯成虛擬機可以執行的字節碼時,Rust 中的函數名稱會不清楚。 為了防止編譯器產生冗餘代碼,減少合約的大小,invoke函數添加了#[no_mangle]註解。

invoke函數是如何獲取參數來執行交易的?

ontio_std 庫提供了一個 runtime::input() 函數來獲取執行交易的參數。 開發人員可以使用 ZeroCopySource 反序列化生成的字節數組。 其中讀取的第一個字節數組是調用方法的名稱,後面是方法參數。

合約執行的結果如何返回?

ontio_std 庫提供的 runtime::ret 函數返回方法執行的結果。

完成的調用函數如下所示:

如何在本體網絡上編寫WebAssembly智能合約? 第 1 部分:生鏽

序列化和反序列化合約數據

在開發合約的過程中,開發者總是會遇到序列化和反序列化的問題,具體是如何在數據庫中存儲一個struct數據類型,以及如何反序列化從數據庫讀取的一個字節數組得到一個struct數據類型。

ontio_std 庫為數據序列化和反序列化提供解碼器和編碼器接口。 結構的字段還實現了解碼器和編碼器接口,以便可以對結構進行序列化和反序列化。 序列化各種數據類型時,需要 Sink 類的實例。 Sink類的一個實例有一個set-type字段buf,存放的是byte類型的數據,所有序列化後的數據都存放在buf中。

對於固定長度的數據(如:byte、u16、u32、u64等),直接將數據轉為byte數組,然後存入buf; 對於非固定長度的數據,必須先序列化length,再序列化Ddata(例如未知大小的無符號整數,包括u16、u32或u64等)。

反序列化恰恰相反。 對於每一種序列化方法,都有一種對應的反序列化方法。 反序列化需要使用 Source 類的實例。 此類實例有兩個字段 buf 和 pos。 buf用來存放要反序列化的數據,pos用來存放當前讀取的位置。 讀取特定類型的數據時,如果知道其長度,則可以直接讀取,對於未知長度的數據——先讀取長度,再讀取內容。

訪問和更新鏈中數據

本體-wasm-cdt-rust - 封裝了一個對鏈中數據進行操作的操作方法,方便開發者實現對鏈中數據的增刪改查操作,如下:

  • 數據庫::獲取(鍵) - 用於向鏈上請求數據,key請求AsRef接口的實現;
  • 數據庫::放(鍵,值) - 用於在網絡上存儲數據。 Key請求AsRef接口的實現,value請求Encoder接口的實現;
  • 數據庫::刪除(鍵) - 用於從鏈中移除數據,key請求AsRef接口的實現。

合同測試

當合約的方法實現時,我們需要訪問鏈上的數據,需要合適的虛擬機來執行合約的字節碼,所以一般需要將合約部署在鏈上進行測試。 但是這種測試方法是有問題的。 為了方便開發者測試合約,ontio_std 庫提供了一個 mock 模塊用於測試。 該模塊提供了電路中數據的模擬,方便開發者對合約中的方法進行單元測試。 具體例子可見 這裡.

合約調試

console::debug(msg) 在調試合約時顯示調試信息。 msg 信息將添加到節點日誌文件中。 前提條件是在本地本體測試節點運行時將日誌文件級別設置為調試模式。

runtime::notify(msg) 在調試合約時輸出適當的調試信息。 此方法將存儲輸入到鏈中的信息,並且可以使用 getSmartCodeEvent 方法從鏈中查詢。

該文章由 Hashrate&Shares 的編輯特別為 OntologyRussia 翻譯。

你是開發者嗎? 加入我們的技術社區 不和. 另外,看看 開發者中心 在我們的網站上,您可以在其中找到開發人員工具、文檔等。

本體論

來源: www.habr.com

添加評論