本體技術視點 | Wasm重磅登陸Ontology主網!Wasm合約開發必讀入門教程(4)

買賣虛擬貨幣
日前的政策利好將區塊鏈推向了前所未有風口,“把區塊鏈作為核心技術自主創新重要突破口,加快推動區塊鏈技術和產業創新發展”成為了區塊鏈行業最新的工作指示。我們感到十分興奮,因為我們一直都在正確的道路上持續前行,為這一場區塊鏈技術攻堅戰厲兵秣馬。而就在本體 Ontology 2.0 釋出前夕,Ontology v1.8.0於10月29日重磅釋出。經過數月在測試網上的穩定執行,Wasm 功能也正式登陸了主網。在往期的技術視點中,我們已推出多部 Ontology Wasm 相關教程,社羣夥伴們紛紛表示受益匪淺。本期我們將介紹如何基於 Wasm合約使用 Runtime API,相信你會有所收穫。Runtime API 簡述

Ontology Wasm 合約開發工具庫 ontology-wasm-cdt-rust 裡面 Runtime 模組封裝了合約與 Ontology 鏈互動的 API 方法。透過這些 API 方法,合約可以獲得鏈上的資料,或者將合約中的資料儲存到鏈上,以下是這些 API 方法的簡單描述。

接下來,我們來具體講述下這些 API 的使用方法。在此之前,開發者可以從 GitHub 上 clone 下來我們的合約模板,然後在lib.rs檔案中新增合約邏輯程式碼。

Runtime API 使用方法

首先,開發者僅需要透過下面的方式將 Runtime 模組引入到當前合約中:

use ontio_std::runtime;
然後就可以透過 Runtime 引用以上所有的 API 介面。

1. timestamp() 

timestamp()方法獲得當前的時間戳,即返回撥用該函式的 Unix 時間,單位為秒。呼叫示例:

let t = runtime::timestamp();
一個簡單的示例程式碼如下:

#![no_std]
extern crate ontio_std as ostd;
use ostd::abi::{Sink, Source};
use ostd::prelude::*;
use ostd::runtime;

fn hello() -> u64 {
runtime::timestamp()//取得當前時間戳
}

#[no_mangle]
fn invoke() {
let input = runtime::input();//獲得輸入方法名和方法引數
let mut source = Source::new(&input);//構造反序列化例項
let action = source.read().unwrap_or_default();//讀取方法名
let mut sink = Sink::new(16);//構造序列化例項
match action {
"hello" => {
sink.write(hello());//將hello()返回的結果序列化
}
_ => panic!("unsupported action!")
}
runtime::ret(sink.bytes());//將序列化後的結果返回給呼叫方
}

在下面的 API 方法講述中,我們將省略具體例子,只介紹 API 方法的作用。小夥伴們可以採用類似於上述例子的程式碼進行試驗。

2. block_height

block_height函式獲得當前區塊鏈網路的區塊高度,呼叫示例:

let t = runtime::block_height();

3. address

address 獲得當前合約的地址,呼叫示例:
let t = runtime::address();

4. caller

caller 獲得呼叫方的合約地址,主要用於跨合約呼叫的場景,比如合約 A 呼叫合約 B 的應用場景, 在合約 B 中就可以呼叫該方法獲得呼叫方合約 A 的地址:

let t = runtime::caller();

5. entry_address

entry_address 獲得入口合約地址,比如有這樣的應用場景,合約 A 透過合約 B 呼叫合約 C的方法,此時,在合約 C 中就可以透過該方法拿到合約 A 的地址,呼叫示例:
let t = runtime::entry_address();

6. current_blockhash

current_blockhash 獲得當前區塊的 hash,示例如下:

let t = runtime::current_blockhash();

7. current_txhash

current_txhash獲得當前交易的 hash,示例如下:
let t = runtime::current_txhash();

8. sha256

sha256計算輸入引數的 hash256值:

let h = runtime::sha256("test");

9. check_witness

check_witness(from)校驗是否含有該地址的簽名:

· 驗證當前的函式呼叫者是不是含有 from 的簽名 。若是(即簽名驗證透過),則函式返回 true;

· 檢查當前函式呼叫者是不是一個合約。若是合約,且是從該合約發起去執行函式,返回 true。即,驗證 from 是不是caller的返回值。其中,caller()函式可以得到呼叫當前智慧合約的合約雜湊值。

assert!(runtime::check_witness(from));

10. notify

notify函式將合約中事件推送到全網,並將其內容儲存到鏈上,呼叫方法如下:

runtime::notify("notify".as_bytes())

在合約中推送事件時,可以自定義一個事件函式,加上#[event]註解即可。我們的工具庫中提供了該屬性巨集,需要透過use ostd::macros::event;引入。示例如下:

use ostd::macros::event;
mod notify {
use super::*;
#[event]
pub fn transfer(from: &Address, to: &Address, amount: U128) {}
}
fn transfer(from: &Address, to: &Address, amount: U128) -> bool {
...
notify::transfer(from, to, amount);
}

11. panic

panic方法可以在合約執行發生致命錯誤的時候立即終止交易的執行,然後回滾當前的交易。該方法在跨合約呼叫的場景很重要,比如在如下的應用場景中,合約 A 中的方法 a 呼叫合約 B 中的方法 b,其中合約 A 的 a 方法在呼叫合約 B 的 b 方法之前會儲存一些資料到鏈上,但是在呼叫合約 B 的 b 方法時,發生了致命的錯誤,需要回滾合約 A 中 a 方法執行過程中儲存的資料,此時就需要在合約 B 的 b 方法中應用panic方法實現該功能。

runtime::panic("test");

結語

本文主要講解了 Runtime 模組的 API,該模組提供了與鏈互動的功能,其中 notify 用於合約中推送事件,開發者可以使用自定義事件的方式推送事件,而不是直接使用 notify 方法。use ostd::macros::event屬性巨集提供了更加友好的事件推送機制。在跨合約呼叫的過程中,panic方法在異常處理中具有非常重要的。下一期我們將介紹如何實現 Wasm 合約與 NeoVM 合約及 Native 合約之間的相互呼叫,歡迎大家關注學習。

Ontology 率先支援 Wasm 合約將會大大提高混合虛擬機器的效能,也將吸引眾多不同語言的技術開發者加入本體社羣,共同推進區塊鏈技術的研發,豐富本體強大的技術生態。同時,基於本體強大的技術研發團隊,也可將現有的優秀技術整合到本體生態上來,為合約開發者增加更多選項。歡迎各位技術夥伴與我們共同前行!

免責聲明:

  1. 本文版權歸原作者所有,僅代表作者本人觀點,不代表鏈報觀點或立場。
  2. 如發現文章、圖片等侵權行爲,侵權責任將由作者本人承擔。
  3. 鏈報僅提供相關項目信息,不構成任何投資建議

推荐阅读

;