# 浣跨敤Rust杩涜鏅鸿兘鍚堢害寮€鍙�

璇昏€呭璞★細鏈珷鑺備富瑕佹弿杩颁娇鐢≧ust杩涜ChainMaker鍚堢害缂栧啓鐨勬柟娉曪紝涓昏闈㈠悜浜庝娇鐢≧ust杩涜ChainMaker鐨勫悎绾﹀紑鍙戠殑寮€鍙戣€呫€�

**姒傝**
1銆佽繍琛屾椂铏氭嫙鏈虹被鍨嬶紙runtime_type锛夛細 WASMER
2銆佷粙缁嶄簡鐜渚濊禆
3銆佷粙缁嶄簡寮€鍙戞柟寮忓強sdk鎺ュ彛
4銆佹彁渚涗簡涓€涓ず渚嬪悎绾�

## 鐜渚濊禆

浣跨敤Rust寮€鍙戠敤浜嶤hainMaker鐨剋asm鍚堢害,闇€瑕佸畨瑁匯ust寮€鍙戠幆澧冿紝骞跺皢 wasm32-unknown-unknown锛堢洰鏍囧钩鍙帮級鍔犲叆鍒癛ust寮€鍙戠幆澧冪殑宸ュ叿閾句腑銆�

rust 瀹夎鍙婃暀绋嬭鍙傝€冿細[rust 瀹樼綉](https://www.rust-lang.org/)

瀹夎鎸囦护濡備笅锛�

```sh
# 瀹夎 Rust
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
# 璁� Rust 鐨勭幆澧冨彉閲忕敓鏁� 
source "$HOME/.cargo/env"
# 鍔犲叆 wasm32-unknown-unknown
rustup target add wasm32-unknown-unknown
```


## 缂栧啓Rust鏅鸿兘鍚堢害

### 鎼缓寮€鍙戠幆澧�
1锛夋帹鑽愪娇鐢� GoLand闆嗘垚寮€鍙戠幆澧� + Rust鎻掍欢

2锛変笅杞� contracts-rust 绀轰緥宸ョ▼
```shell
git clone git@git.chainmaker.org.cn:contracts/contracts-rust.git -b v2.3.0
```

3锛夎繘鍏ヤ笅杞界殑Rust宸ョ▼
```shell
cd contracts-rust/fact
```

### 浠g爜缂栧啓瑙勫垯

**瀵归摼鏆撮湶鏂规硶鍐欐硶涓猴細**

- #[no_mangle] 琛ㄧず鏂规硶鍚嶇紪璇戝悗鏄浐瀹氱殑锛屼笉鍐欎細鐢熸垚 _ZN4rustfn1_34544tert54grt5 绫讳技鐨勬贩娣嗗悕
- pub extern "C"
- method_name(): 涓嶅彲甯﹀弬鏁帮紝鏃犺繑鍥炲€�

```rust
#[no_mangle]// no_mangle娉ㄨВ锛岃〃鏄庡澶栨毚闇叉柟娉曞悕绉颁笉鍙彉
pub extern "C" fn init_contract() { // pub extern "C" 闆嗘垚C
    let ctx = &mut sim_context::get_sim_context();
    // do something 
    ctx.ok("contract init success.".as_bytes());
}
```

**鍏朵腑init_contract銆乽pgrade鏂规硶蹇呴』鏈変笖瀵瑰鏆撮湶**

- init_contract锛氬垱寤哄悎绾︿細鎵ц璇ユ柟娉�
- upgrade锛� 鍗囩骇鍚堢害浼氭墽琛岃鏂规硶

```rust
// 瀹夎鍚堢害鏃朵細鎵ц姝ゆ柟娉曘€侰hainMaker涓嶅厑璁哥敤鎴风洿鎺ヨ皟鐢ㄨ鏂规硶銆�
#[no_mangle]
pub extern "C" fn init_contract() {
    let ctx = &mut sim_context::get_sim_context();
    // do something
    ctx.ok("contract init success.".as_bytes());
}

// 鍗囩骇鍚堢害鏃朵細鎵ц姝ゆ柟娉曘€侰hainMaker涓嶅厑璁哥敤鎴风洿鎺ヨ皟鐢ㄨ鏂规硶銆�
#[no_mangle]
pub extern "C" fn upgrade() {
    let ctx = &mut sim_context::get_sim_context();
    // do something
    ctx.ok("contract upgrade success.".as_bytes());
}
```

**鑾峰彇涓庨摼浜や簰鐨勪笂涓嬫枃sim_context**

1銆佸湪`Cargo.toml`涓紩鍏ュ浜� contract-sdk-rust 椤圭洰鐨勪緷璧�
```toml
[dependencies]
contract_sdk_rust = { git = "https://git.chainmaker.org.cn/chainmaker/contract-sdk-rust", tag = "v2.3.0" }
```

2銆佸湪浣跨敤鏃跺紩鍏im_context

```rust
use contract_sdk_rust::sim_context;
use contract_sdk_rust::sim_context::SimContext;
use contract_sdk_rust::easycodec::*;

fn method_name() {
    // 鑾峰彇涓婁笅鏂�
    let ctx = &mut sim_context::get_sim_context();
    
}
```

### 瀛樿瘉鍚堢害绀轰緥婧愮爜灞曠ず

**瀛樿瘉鍚堢害绀轰緥锛歠act.rs** 瀹炵幇濡備笅涓や釜鍔熻兘

1銆佸瓨鍌ㄦ枃浠跺搱甯屽拰鏂囦欢鍚嶇О鍜屾椂闂淬€�

2銆侀€氳繃鏂囦欢鍝堝笇鏌ヨ璇ユ潯璁板綍

```rust
use contract_sdk_rust::sim_context;
use contract_sdk_rust::sim_context::SimContext;
use contract_sdk_rust::easycodec::*;

// 瀹夎鍚堢害鏃朵細鎵ц姝ゆ柟娉曪紝蹇呴』
#[no_mangle]
pub extern "C" fn init_contract() {
    sim_context::log("init_contract");
    let ctx = &mut sim_context::get_sim_context();
    
    // 瀹夎鏃剁殑涓氬姟閫昏緫锛屽唴瀹瑰彲涓虹┖
    
    ctx.ok("contract init success.".as_bytes());
}

// 鍗囩骇鍚堢害鏃朵細鎵ц姝ゆ柟娉曪紝蹇呴』
#[no_mangle]
pub extern "C" fn upgrade() {
    sim_context::log("upgrade");
    let ctx = &mut sim_context::get_sim_context();
    
    // 鍗囩骇鏃剁殑涓氬姟閫昏緫锛屽唴瀹瑰彲涓虹┖

    ctx.ok("contract upgrade success".as_bytes());
}

struct Fact {
    file_hash: String,
    file_name: String,
    time: i32,
    ec: EasyCodec,
}

impl Fact {
    fn new_fact(file_hash: String, file_name: String, time: i32) -> Fact {
        let mut ec = EasyCodec::new();
        ec.add_string("file_hash", file_hash.as_str());
        ec.add_string("file_name", file_name.as_str());
        ec.add_i32("time", time);
        Fact {
            file_hash,
            file_name,
            time,
            ec,
        }
    }

    fn get_emit_event_data(&self) -> Vec<String> {
        let mut arr: Vec<String> = Vec::new();
        arr.push(self.file_hash.clone());
        arr.push(self.file_name.clone());
        arr.push(self.time.to_string());
        arr
    }

    fn to_json(&self) -> String {
        self.ec.to_json()
    }

    fn marshal(&self) -> Vec<u8> {
        self.ec.marshal()
    }

    fn unmarshal(data: &Vec<u8>) -> Fact {
        let ec = EasyCodec::new_with_bytes(data);
        Fact {
            file_hash: ec.get_string("file_hash").unwrap(),
            file_name: ec.get_string("file_name").unwrap(),
            time: ec.get_i32("time").unwrap(),
            ec,
        }
    }
}

// save 淇濆瓨瀛樿瘉鏁版嵁
#[no_mangle]
pub extern "C" fn save() {
    // 鑾峰彇涓婁笅鏂�
    let ctx = &mut sim_context::get_sim_context();

    // 鑾峰彇浼犲叆鍙傛暟
    let file_hash = ctx.arg_as_utf8_str("file_hash");
    let file_name = ctx.arg_as_utf8_str("file_name");
    let time_str = ctx.arg_as_utf8_str("time");

    // 鏋勯€犵粨鏋勪綋
    let r_i32 = time_str.parse::<i32>();
    if r_i32.is_err() {
        let msg = format!("time is {:?} not int32 number.", time_str);
        ctx.log(&msg);
        ctx.error(&msg);
        return;
    }
    let time: i32 = r_i32.unwrap();
    let fact = Fact::new_fact(file_hash, file_name, time);

    // 浜嬩欢
    ctx.emit_event("topic_vx", &fact.get_emit_event_data());

    // 搴忓垪鍖栧悗瀛樺偍
    ctx.put_state(
        "fact_ec",
        fact.file_hash.as_str(),
        fact.marshal().as_slice(),
    );
}

// find_by_file_hash 鏍规嵁file_hash鏌ヨ瀛樿瘉鏁版嵁
#[no_mangle]
pub extern "C" fn find_by_file_hash() {
    // 鑾峰彇涓婁笅鏂�
    let ctx = &mut sim_context::get_sim_context();

    // 鑾峰彇浼犲叆鍙傛暟
    let file_hash = ctx.arg_as_utf8_str("file_hash");

    // 鏍¢獙鍙傛暟
    if file_hash.len() == 0 {
        ctx.log("file_hash is null");
        ctx.ok("".as_bytes());
        return;
    }

    // 鏌ヨ
    let r = ctx.get_state("fact_ec", &file_hash);

    // 鏍¢獙杩斿洖缁撴灉
    if r.is_err() {
        ctx.log("get_state fail");
        ctx.error("get_state fail");
        return;
    }
    let fact_vec = r.unwrap();
    if fact_vec.len() == 0 {
        ctx.log("None");
        ctx.ok("".as_bytes());
        return;
    }

    // 鏌ヨ
    let r = ctx.get_state("fact_ec", &file_hash).unwrap();
    let fact = Fact::unmarshal(&r);
    let json_str = fact.to_json();

    // 杩斿洖鏌ヨ缁撴灉
    ctx.ok(json_str.as_bytes());
    ctx.log(&json_str);
}
```



### 鍚堢害SDK鎺ュ彛鎻忚堪
闀垮畨閾炬彁渚汻ust鍚堢害涓庨摼浜や簰鐨勭浉鍏虫帴鍙o紝浠g爜瀛樺湪鍗曠嫭鐨勯」鐩紙https://git.chainmaker.org.cn/chainmaker/contract-sdk-rust锛変腑銆傚啓鍚堢害鏃跺彲鐩存帴鎸囧畾渚濊禆锛屽苟杩涜寮曠敤锛屽叿浣撲俊鎭彲鍙傝€冩枃绔犳湯灏�"鎺ュ彛鎻忚堪绔犺妭"銆�


### 缂栬瘧绀轰緥鍚堢害

```shell
cd contracts_rust/fact/
cargo build --release --target=wasm32-unknown-unknown
```

鐢熸垚鍚堢害鐨勫瓧鑺傜爜鏂囦欢鍦�

```shell
contracts_rust/fact/target/wasm32-unknown-unknown/release/fact.wasm
```

#### 绀轰緥鍚堢害妗嗘灦鎻忚堪

```shell
contract-sdk-rust$ tree -I target

鈹溾攢鈹€ Cargo.lock # 渚濊禆鐗堟湰淇℃伅
鈹溾攢鈹€ Cargo.toml # 椤圭洰閰嶇疆鍙婁緷璧栵紝鍙傝€冿細https://rustwasm.github.io/wasm-pack/book/cargo-toml-configuration.html
鈹溾攢鈹€ README.md  # 缂栬瘧鐜璇存槑
鈹溾攢鈹€ src
鈹�   鈹溾攢鈹€ fact.rs			# 瀛樿瘉绀轰緥浠g爜
鈹�   鈹斺攢鈹€ lib.rs          # 绋嬪簭鍏ュ彛
```

### 閮ㄧ讲璋冪敤鍚堢害
缂栬瘧瀹屾垚鍚庯紝灏嗗緱鍒颁竴涓猔.wasm`鏍煎紡鐨勫悎绾︽枃浠讹紝鍙皢涔嬮儴缃插埌鎸囧畾鍒伴暱瀹夐摼涓婏紝瀹屾垚鍚堢害閮ㄧ讲銆�
閮ㄧ讲鍚堢害鐨勪娇鐢ㄦ暀绋嬪彲璇﹁锛歔閮ㄧ讲绀轰緥鍚堢害](./閮ㄧ讲绀轰緥鍚堢害.md)銆�

## 杩唬鍣ㄤ娇鐢ㄧず渚�

[鐐瑰嚮姝ゅ鏌ョ湅鎺ュ彛璇存槑](#new_iterator_interface)

浣跨敤绀轰緥濡備笅锛�

```rust
#[no_mangle]
pub extern "C" fn how_to_use_iterator() {
    let ctx = &mut sim_context::get_sim_context();

    // 鏋勯€犳暟鎹�
    ctx.put_state("key1", "field1", "val".as_bytes());
    ctx.put_state("key1", "field2", "val".as_bytes());
    ctx.put_state("key1", "field23", "val".as_bytes());
    ctx.put_state("key1", "field3", "val".as_bytes());
    // 浣跨敤杩唬鍣紝鑳芥煡鍑烘潵  field1锛宖ield2锛宖ield23 涓夋潯鏁版嵁
    let r = ctx.new_iterator_with_field("key1", "field1", "field3");
    if r.is_ok() {
        let rs = r.unwrap();
        // 閬嶅巻
        while rs.has_next() {
            // 鑾峰彇涓嬩竴琛屽€�
            let row = rs.next_row().unwrap();
            let key = row.get_string("key").unwrap();
            let field = row.get_bytes("field");
            let val = row.get_bytes("value");
            // do something
        }
        // 鍏抽棴娓告爣
        rs.close();
    }

    ctx.put_state("key2", "field1", "val".as_bytes());
    ctx.put_state("key3", "field2", "val".as_bytes());
    ctx.put_state("key33", "field2", "val".as_bytes());
    ctx.put_state("key4", "field3", "val".as_bytes());
    // 鑳芥煡鍑烘潵 key2锛宬ey3锛宬ey33 涓夋潯鏁版嵁
    ctx.new_iterator("key2", "key4");
    // 鑳芥煡鍑烘潵 key3锛宬ey33 涓ゆ潯鏁版嵁
    ctx.new_iterator_prefix_with_key("key3");
    // 鑳芥煡鍑烘潵  field2锛宖ield23 涓夋潯鏁版嵁
    ctx.new_iterator_prefix_with_key_field("key1", "field2");
    
    
    ctx.put_state_from_key("key5","val".as_bytes());
    ctx.put_state_from_key("key56","val".as_bytes());
    ctx.put_state_from_key("key6","val".as_bytes());
    // 鑳芥煡鍑烘潵 key5锛宬ey56 涓ゆ潯鏁版嵁
    ctx.new_iterator("key5", "key6");
}
```





## Rust SDK API鎻忚堪 <span id="api"></span>

### 涓嬭浇 contract-sdk-rust 椤圭洰浠g爜
```shell
git clone  --depth=1 https://git.chainmaker.org.cn/chainmaker/contract-sdk-rust -b v2.3.0
```

### 椤圭洰鏂囦欢璇存槑
```shell
tree -I target 

鈹溾攢鈹€ Cargo.lock # 渚濊禆鐗堟湰淇℃伅
鈹溾攢鈹€ Cargo.toml # 椤圭洰閰嶇疆鍙婁緷璧栵紝鍙傝€冿細https://rustwasm.github.io/wasm-pack/book/cargo-toml-configuration.html
鈹溾攢鈹€ Makefile   # build涓€涓獁asm鏂囦欢
鈹溾攢鈹€ README.md  # 缂栬瘧鐜璇存槑
鈹溾攢鈹€ src
鈹�   鈹溾攢鈹€ easycodec.rs                # 搴忓垪鍖栧伐鍏风被
鈹�   鈹溾攢鈹€ lib.rs                      # 绋嬪簭鍏ュ彛
鈹�   鈹溾攢鈹€ sim_context.rs              # 鍚堢害SDK涓昏鎺ュ彛鍙婂疄鐜�
鈹�   鈹溾攢鈹€ sim_context_bulletproofs.rs # 鍚堢害SDK鍩轰簬bulletproofs鐨勮寖鍥磋瘉鏄庢帴鍙e疄鐜�
鈹�   鈹溾攢鈹€ sim_context_paillier.rs     # 鍚堢害SDK鍩轰簬paillier鐨勫崐鍚屾€佽繍绠楁帴鍙e疄鐜�
鈹�   鈹溾攢鈹€ sim_context_rs.rs           # 鍚堢害SDK sql鎺ュ彛瀹炵幇
鈹�   鈹斺攢鈹€ vec_box.rs                  # 鍐呭瓨绠$悊绫�
```

### 鍐呯疆閾句氦浜掓帴鍙�

鐢ㄤ簬閾句笌SDK鏁版嵁浜や簰銆�

```rust
// 鐢宠size澶у皬鍐呭瓨锛岃繑鍥炶鍐呭瓨鐨勯鍦板潃
pub extern "C" fn allocate(size: usize) -> i32 {}
// 閲婃斁鏌愬湴鍧€
pub extern "C" fn deallocate(pointer: *mut c_void) {}
// 鑾峰彇SDK杩愯鏃剁幆澧�
pub extern "C" fn runtime_type() -> i32 { 0 }
```


### 鐢ㄦ埛涓庨摼浜や簰鎺ュ彛

```rust

/// SimContext is a interface with chainmaker interaction
pub trait SimContext {
    // common method
    fn call_contract(
        &self,
        contract_name: &str,
        method: &str,
        param: EasyCodec,
    ) -> Result<Vec<u8>, result_code>;
    fn ok(&self, value: &[u8]) -> result_code;
    fn error(&self, body: &str) -> result_code;
    fn log(&self, msg: &str);
    fn arg(&self, key: &str) -> Result<Vec<u8>, String>;
    fn arg_as_utf8_str(&self, key: &str) -> String;
    fn args(&self) -> &EasyCodec;
    fn get_creator_org_id(&self) -> String;
    fn get_creator_pub_key(&self) -> String;
    fn get_creator_role(&self) -> String;
    fn get_sender_org_id(&self) -> String;
    fn get_sender_pub_key(&self) -> String;
    fn get_sender_role(&self) -> String;
    fn get_block_height(&self) -> u64;
    fn get_tx_id(&self) -> String;
    fn emit_event(&mut self, topic: &str, data: &Vec<String>) -> result_code;
    // paillier
    fn get_paillier_sim_context(&self) -> Box<dyn PaillierSimContext>;
    // bulletproofs
    fn get_bulletproofs_sim_context(&self) -> Box<dyn BulletproofsSimContext>;
    // sql
    fn get_sql_sim_context(&self) -> Box<dyn SqlSimContext>;

    // KV method
    fn get_state(&self, key: &str, field: &str) -> Result<Vec<u8>, result_code>;
    fn get_state_from_key(&self, key: &str) -> Result<Vec<u8>, result_code>;
    fn put_state(&self, key: &str, field: &str, value: &[u8]) -> result_code;
    fn put_state_from_key(&self, key: &str, value: &[u8]) -> result_code;
    fn delete_state(&self, key: &str, field: &str) -> result_code;
    fn delete_state_from_key(&self, key: &str) -> result_code;

    /// new_iterator range of [startKey, limitKey), front closed back open
    fn new_iterator(
        &self,
        start_key: &str,
        limit_key: &str,
    ) -> Result<Box<dyn ResultSet>, result_code>;

    /// new_iterator_with_field range of [key+"#"+startField, key+"#"+limitField), front closed back open
    fn new_iterator_with_field(
        &self,
        key: &str,
        start_field: &str,
        limit_field: &str,
    ) -> Result<Box<dyn ResultSet>, result_code>;

    /// new_iterator_prefix_with_key_field range of [key+"#"+field, key+"#"+field], front closed back closed
    fn new_iterator_prefix_with_key_field(
        &self,
        key: &str,
        field: &str,
    ) -> Result<Box<dyn ResultSet>, result_code>;

    /// new_iterator_prefix_with_key range of [key, key], front closed back closed
    fn new_iterator_prefix_with_key(&self, key: &str) -> Result<Box<dyn ResultSet>, result_code>;
}


pub trait SqlSimContext {
    fn execute_query_one(&self, sql: &str) -> Result<EasyCodec, result_code>;
    fn execute_query(&self, sql: &str) -> Result<Box<dyn ResultSet>, result_code>;

    /// #### ExecuteUpdateSql execute update/insert/delete sql
    /// ##### It is best to update with primary key
    ///
    /// as:
    ///
    /// - update table set name = 'Tom' where uniqueKey='xxx'
    /// - delete from table where uniqueKey='xxx'
    /// - insert into table(id, xxx,xxx) values(xxx,xxx,xxx)
    ///
    /// ### not allow:
    /// - random methods: NOW() RAND() and so on
    fn execute_update(&self, sql: &str) -> Result<i32, result_code>;

    /// ExecuteDDLSql execute DDL sql, for init_contract or upgrade method. allow table create/alter/drop/truncate
    ///
    /// ## You must have a primary key to create a table
    /// ### allow:     
    /// - CREATE TABLE tableName
    /// - ALTER TABLE tableName
    /// - DROP TABLE tableName   
    /// - TRUNCATE TABLE tableName
    ///
    /// ### not allow:
    /// - CREATE DATABASE dbName
    /// - CREATE TABLE dbName.tableName
    /// - ALTER TABLE dbName.tableName
    /// - DROP DATABASE dbName   
    /// - DROP TABLE dbName.tableName   
    /// - TRUNCATE TABLE dbName.tableName
    /// not allow:
    /// - random methods: NOW() RAND() and so on
    ///
    fn execute_ddl(&self, sql: &str) -> Result<i32, result_code>;
}


pub trait PaillierSimContext {
    // Paillier method
    fn add_ciphertext(
        &self,
        pubkey: Vec<u8>,
        ciphertext1: Vec<u8>,
        ciphertext2: Vec<u8>,
    ) -> Result<Vec<u8>, result_code>;
    fn add_plaintext(
        &self,
        pubkey: Vec<u8>,
        ciphertext: Vec<u8>,
        plaintext: &str,
    ) -> Result<Vec<u8>, result_code>;
    fn sub_ciphertext(
        &self,
        pubkey: Vec<u8>,
        ciphertext1: Vec<u8>,
        ciphertext2: Vec<u8>,
    ) -> Result<Vec<u8>, result_code>;
    fn sub_plaintext(
        &self,
        pubkey: Vec<u8>,
        ciphertext: Vec<u8>,
        plaintext: &str,
    ) -> Result<Vec<u8>, result_code>;
    fn num_mul(
        &self,
        pubkey: Vec<u8>,
        ciphertext: Vec<u8>,
        plaintext: &str,
    ) -> Result<Vec<u8>, result_code>;
}
/// BulletproofsSimContext is the trait that wrap the bulletproofs method
pub trait BulletproofsSimContext {
    /// Compute a commitment to x + y from a commitment to x without revealing the value x, where y is a scalar
    ///
    /// # Arguments
    ///
    /// * `commitment` - C = xB + rB'
    /// * `num` - the value y
    ///
    /// # return
    ///
    /// * `return1` - the new commitment to x + y: C' = (x + y)B + rB'
    ///
    fn pedersen_add_num(&self, commitment: Vec<u8>, num: &str) -> Result<Vec<u8>, result_code>;

    /// Compute a commitment to x + y from commitments to x and y, without revealing the value x and y
    ///
    /// # Arguments
    ///
    /// * `commitment1` - commitment to x: Cx = xB + rB'
    /// * `commitment2` - commitment to y: Cy = yB + sB'
    ///
    /// # return
    ///
    /// * `return1` - commitment to x + y: C = (x + y)B + (r + s)B'
    ///
    fn pedersen_add_commitment(
        &self,
        commitment1: Vec<u8>,
        commitment2: Vec<u8>,
    ) -> Result<Vec<u8>, result_code>;

    /// Compute a commitment to x - y from a commitment to x without revealing the value x, where y is a scalar
    ///
    /// # Arguments
    ///
    /// * `commitment1` - C = xB + rB'
    /// * `num` - the value y
    ///
    /// # return
    ///
    /// * `return1` - the new commitment to x - y: C' = (x - y)B + rB'
    fn pedersen_sub_num(&self, commitment: Vec<u8>, num: &str) -> Result<Vec<u8>, result_code>;

    /// Compute a commitment to x - y from commitments to x and y, without revealing the value x and y
    ///
    /// # Arguments
    ///
    /// * `commitment1` - commitment to x: Cx = xB + rB'
    /// * `commitment2` - commitment to y: Cy = yB + sB'
    ///
    /// # return
    ///
    /// * `return1` - commitment to x - y: C = (x - y)B + (r - s)B'
    fn pedersen_sub_commitment(
        &self,
        commitment1: Vec<u8>,
        commitment2: Vec<u8>,
    ) -> Result<Vec<u8>, result_code>;

    /// Compute a commitment to x * y from a commitment to x and an integer y, without revealing the value x and y
    ///
    /// # Arguments
    ///
    /// * `commitment1` - commitment to x: Cx = xB + rB'
    /// * `num` - integer value y
    ///
    /// # return
    ///
    /// * `return1` - commitment to x * y: C = (x * y)B + (r * y)B'
    fn pedersen_mul_num(&self, commitment: Vec<u8>, num: &str) -> Result<Vec<u8>, result_code>;

    /// Verify the validity of a proof
    ///
    /// # Arguments
    ///
    /// * `proof` - the zero-knowledge proof proving the number committed in commitment is in the range [0, 2^64)
    /// * `commitment` - commitment bindingly hiding the number x
    ///
    /// # return
    ///
    /// * `return1` - true on valid proof, false otherwise
    fn verify(&self, proof: Vec<u8>, commitment: Vec<u8>) -> Result<Vec<u8>, result_code>;
}

```



get_state

```rust
// 鑾峰彇鍚堢害璐︽埛淇℃伅銆傝鎺ュ彛鍙粠閾句笂鑾峰彇绫诲埆 鈥渒ey鈥� 涓嬪睘鎬у悕涓� 鈥渇ield鈥� 鐨勭姸鎬佷俊鎭€�
// @param key: 闇€瑕佹煡璇㈢殑key鍊�
// @param field: 闇€瑕佹煡璇㈢殑key鍊间笅灞炴€у悕涓篺ield
// @return: 鏌ヨ鍒扮殑value鍊硷紝鍙婇敊璇唬鐮� 0: success, 1: failed
fn get_state(&self, key: &str, field: &str) -> Result<Vec<u8>, result_code>;
```

get_state_from_key

```rust
// 鑾峰彇鍚堢害璐︽埛淇℃伅銆傝鎺ュ彛鍙互浠庨摼涓婅幏鍙栫被鍒负key鐨勭姸鎬佷俊鎭�
// @param key: 闇€瑕佹煡璇㈢殑key鍊�
// @return1: 鏌ヨ鍒扮殑鍊�
// @return2:  0: success, 1: failed
fn get_state_from_key(&self, key: &str) -> Result<Vec<u8>, result_code>;
```

put_state

```rust
// 鍐欏叆鍚堢害璐︽埛淇℃伅銆傝鎺ュ彛鍙妸绫诲埆 鈥渒ey鈥� 涓嬪睘鎬у悕涓� 鈥渇iled鈥� 鐨勭姸鎬佹洿鏂板埌閾句笂銆傛洿鏂版垚鍔熻繑鍥�0锛屽け璐ュ垯杩斿洖1銆�
// @param key: 闇€瑕佸瓨鍌ㄧ殑key鍊�
// @param field: 闇€瑕佸瓨鍌ㄧ殑key鍊间笅灞炴€у悕涓篺ield
// @param value: 闇€瑕佸瓨鍌ㄧ殑value鍊�
// @return: 0: success, 1: failed
fn put_state(&self, key: &str, field: &str, value: &[u8]) -> result_code;
```

put_state_from_key

```rust
// 鍐欏叆鍚堢害璐︽埛淇℃伅銆�
// @param key: 闇€瑕佸瓨鍌ㄧ殑key鍊�
// @param value: 闇€瑕佸瓨鍌ㄧ殑value鍊�
// @return: 0: success, 1: failed
fn put_state_from_key(&self, key: &str, value: &[u8]) -> result_code;
```

delete_state

```rust 
// 鍒犻櫎鍚堢害璐︽埛淇℃伅銆傝鎺ュ彛鍙妸绫诲埆 鈥渒ey鈥� 涓嬪睘鎬у悕涓� 鈥渘ame鈥� 鐨勭姸鎬佷粠閾句笂鍒犻櫎銆�
// @param key: 闇€瑕佸垹闄ょ殑key鍊�
// @param field: 闇€瑕佸垹闄ょ殑key鍊间笅灞炴€у悕涓篺ield
// @return: 0: success, 1: failed
fn delete_state(&self, key: &str, field: &str) -> result_code;
```

delete_state_from_key

```rust
// 鍒犻櫎鍚堢害璐︽埛淇℃伅銆傝鎺ュ彛鍙妸绫诲埆 鈥渒ey鈥� 涓嬪睘鎬у悕涓� 鈥渘ame鈥� 鐨勭姸鎬佷粠閾句笂鍒犻櫎銆�
// @param key: 闇€瑕佸垹闄ょ殑key鍊�
// @return: 0: success, 1: failed
fn delete_state_from_key(&self, key: &str) -> result_code;
```

call_contract

```rust
// 璺ㄥ悎绾﹁皟鐢�
// @param contract_name: 鍚堢害鍚嶇О
// @param method: 鍚堢害鏂规硶
// @param EasyCodec: 鍚堢害鍙傛暟
fn call_contract(&self, contract_name: &str, method: &str, param: EasyCodec) -> Result<Vec<u8>, result_code>;
```

args

```rust
// @return: EasyCodec
fn args(&self) -> &EasyCodec;
```

arg

```rust
// 璇ユ帴鍙e彲杩斿洖灞炴€у悕涓� 鈥渒ey鈥� 鐨勫弬鏁扮殑灞炴€у€笺€�
// @param key: 鑾峰彇鐨勫弬鏁板悕
// @return: 鑾峰彇鐨勫弬鏁板€� 鎴� 閿欒淇℃伅銆傚綋鏈紶璇ey鐨勫€兼椂锛屾姤閿檖aram not found
fn arg(&self, key: &str) -> Result<Vec<u8>, String>;
```

ok

```rust
// 璇ユ帴鍙e彲璁板綍鐢ㄦ埛鎿嶄綔鎴愬姛鐨勪俊鎭紝骞跺皢鎿嶄綔缁撴灉璁板綍鍒伴摼涓娿€�
// @param body: 鎴愬姛杩斿洖鐨勪俊鎭�
fn ok(&self, value: &[u8]) -> result_code;
```

error

```rust
// 璇ユ帴鍙e彲璁板綍鐢ㄦ埛鎿嶄綔澶辫触鐨勪俊鎭紝骞跺皢鎿嶄綔缁撴灉璁板綍鍒伴摼涓娿€�
// @param body: 澶辫触淇℃伅
fn error(&self, body: &str) -> result_code;
```

log

```rust
// 璇ユ帴鍙e彲璁板綍浜嬩欢鏃ュ織銆傛煡鐪嬫柟寮忎负鍦ㄩ摼閰嶇疆鐨刲og.yml涓紝寮€鍚痸m:debug鍗冲彲鐪嬪埌绫讳技锛歸asmer log>> + msg
// @param msg: 浜嬩欢淇℃伅
fn log(&self, msg: &str);
```

get_creator_org_id

```rust
// 鑾峰彇鍚堢害鍒涘缓鑰呮墍灞炵粍缁嘔D
// @return: 鍚堢害鍒涘缓鑰呯殑缁勭粐ID
fn get_creator_org_id(&self) -> String;
```

get_creator_role

```rust
// 鑾峰彇鍚堢害鍒涘缓鑰呰鑹�
// @return: 鍚堢害鍒涘缓鑰呯殑瑙掕壊
fn get_creator_role(&self) -> String;
```

get_creator_pub_key

```rust
// 鑾峰彇鍚堢害鍒涘缓鑰呭叕閽�
// @return: 鍚堢害鍒涘缓鑰呯殑鍏挜鐨凷KI
fn get_creator_pub_key(&self) -> String;
```

get_sender_org_id

```rust
// 鑾峰彇浜ゆ槗鍙戣捣鑰呮墍灞炵粍缁嘔D
// @return: 浜ゆ槗鍙戣捣鑰呯殑缁勭粐ID
fn get_sender_org_id(&self) -> String;
```

get_sender_role

```rust
// 鑾峰彇浜ゆ槗鍙戣捣鑰呰鑹�
// @return: 浜ゆ槗鍙戣捣鑰呰鑹�
fn get_sender_role(&self) -> String;
```

get_sender_pub_key()

```rust
// 鑾峰彇浜ゆ槗鍙戣捣鑰呭叕閽�
// @return 浜ゆ槗鍙戣捣鑰呯殑鍏挜鐨凷KI
fn get_sender_pub_key(&self) -> String;
```

get_block_height

```rust
// 鑾峰彇褰撳墠鍖哄潡楂樺害
// @return: 褰撳墠鍧楅珮搴�
fn get_block_height(&self) -> i32;
```

get_tx_id

```rust
// 鑾峰彇浜ゆ槗ID
// @return 浜ゆ槗ID
fn get_tx_id(&self) -> String;
```

emit_event

```rust
// 鍙戦€佸悎绾︿簨浠�
// @param topic: 鍚堢害浜嬩欢涓婚
// @data: 鍚堢害浜嬩欢鏁版嵁锛寁ertor涓簨浠舵暟鎹釜鏁颁笉鍙ぇ浜�16锛屼笉鍙皬浜�1
fn emit_event(&mut self, topic: &str, data: &Vec<String>) -> result_code;
```

<span id="new_iterator_interface">new_iterator</span>

```rust
/// new_iterator range of [startKey, limitKey), front closed back open
// 鏂板缓key鑼冨洿杩唬鍣紝key鍓嶉棴鍚庡紑锛屽嵆锛歴tart_key <= dbkey < limit_key
// @param start_key: 寮€濮嬬殑key
// @param limit_key: 缁撴潫鐨刱ey
// @return: 缁撴灉闆嗘父鏍�
fn new_iterator(&self,start_key: &str,limit_key: &str) -> Result<Box<dyn ResultSet>, result_code>;

/// new_iterator_with_field range of [key+"#"+startField, key+"#"+limitField), front closed back open
// 鏂板缓field鑼冨洿杩唬鍣紝key闇€鐩稿悓锛宖ield鍓嶉棴鍚庡紑锛屽嵆锛歬ey = dbdbkey and start_field <= dbfield < limit_field
// @param key: 鍥哄畾key
// @param start_field: 寮€濮嬬殑field
// @param limit_field: 缁撴潫鐨刦ield
// @return: 缁撴灉闆嗘父鏍�
fn new_iterator_with_field(&self, key: &str, start_field: &str, limit_field: &str) -> Result<Box<dyn ResultSet>, result_code>;

/// new_iterator_prefix_with_key range of [key, key], front closed back closed
// 鏂板缓鎸囧畾key鍓嶇紑鍖归厤杩唬鍣紝key闇€鍓嶇紑涓€鑷达紝鍗砫bkey.startWith(key)
// @param key: key鍓嶇紑
// @return: 缁撴灉闆嗘父鏍�
fn new_iterator_prefix_with_key(&self, key: &str) -> Result<Box<dyn ResultSet>, result_code>;

/// new_iterator_prefix_with_key_field range of [key+"#"+field, key+"#"+field], front closed back closed
// 鏂板缓鎸囧畾field鍓嶇紑鍖归厤杩唬鍣紝key闇€鐩稿悓锛宖ield鍓嶇紑涓€鑷达紝鍗砫bkey = key and dbfield.startWith(field)
// @param key: key鍓嶇紑
// @return: 缁撴灉闆嗘父鏍�
fn new_iterator_prefix_with_key_field(&self, key: &str, field: &str) -> Result<Box<dyn ResultSet>, result_code>;

```