日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

调用wasm_PDX Utopia区块链协议栈使用Solidity调用wasm智能合约

發布時間:2023/12/15 编程问答 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 调用wasm_PDX Utopia区块链协议栈使用Solidity调用wasm智能合约 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

在這個瞬息萬變的世界中,智能合約已成為所有平臺中強有力的服務。Solidity是一種趨勢,PDX Utopia區塊鏈協議棧使用Solidity調用wasm智能合約。

什么是Solidity?

Solidity是一種語法類似JavaScript的高級語言。它被設計成以編譯的方式生成以太坊虛擬機代碼,這種語言的突出優點是安全。

Solidity語言是靜態類型語言,支持繼承、庫和復雜的用戶定義類型,可以使用Solidity語言創建區塊鏈上運行的投票、眾籌、錢包等各種類型的智能合約。

以太坊合約中的Solidity

合約是以太坊去中心化應用程序的基本構建模塊。所有變量和函數都是合約的一部分,這是所有項目的起點。一個名為MyFirst的空合約看起來像這樣:

version pragma ^0.4.19;contract MyFirst{}

Solidity文件的布局

源文件可以包含任意數量的合約定義,包括指令和pragma指令。

注釋

就像任何其他語言一樣,Solidity可以使用單行和多行注釋。

// This is a single-line comment./*This is amulti-line comment*/

Solidity中的值類型

以下類型也稱為值類型,因為這些類型的變量將始終按值傳遞。

Solidity數據結構

Solidity提供三種類型的數據結構:

使用Solidity調用wasm智能合約

定義 ABI

>在 `hello-wasm-abi/src/abi.rs` 中定義了 Contract 對象,包含了 `hello-wasm` 樣例中的

>`put/get/getcounter` 三個方法的 `ABI` 描述,注意,我們還不能直接用 `JSON` 來描述 `ABI`;

>必須使用 `pdxabi::Contract` 來定義聲明。

建議通過以下三步來生成 ABI :

1. 使用 `solidity` 編寫 `contract interface`;

2. 使用 `remix` 編譯 `contract interface` 得到對應的 `ABI` 描述;

3. 參照 `ABI` 描述文件編寫 `pdxabi::Contract`;

部署 wasm 合約后可以使用合約地址和 contract interface 在 remix 里對合約進行實例化,方便測試。

Solidity Contract Interface

在 [Remix IDE](http://remix.ethereum.org/#optimize=false&version=soljson-v0.5.3+commit.10d17f24.js&evmVersion=null&appVersion=0.7.7) 中編寫合約接口,并編譯solidity。

pragma solidity ^0.5.3;contract hello_wasm_abi { function getcounter() public view returns(uint256); function get(string memory key) public view returns(string memory); function put(string memory key,string memory val) public payable;}???????????????

JSON ABI

編譯合約接口可以得到對應的 `ABI JSON` 描述,提供合約地址和此 `JSON ABI` 文檔。

`DAPP` 開發者即可實例化 `hello_wasm_abi` 合約,并使用其中的三個函數:

json[ { "constant": false, "inputs": [ { "name": "key", "type": "string" }, { "name": "val", "type": "string" } ], "name": "put", "outputs": [], "payable": true, "stateMutability": "payable", "type": " function" }, { "constant": true, "inputs": [ { "name": "key", "type": "string" } ], "name": "get", "outputs": [ { "name": "", "type": "string" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, "inputs": [], "name": "getcounter", "outputs": [ { "name": "", "type": "uint256" } ], "payable": false, "stateMutability": "view", "type": "function" }]

pdxabi::Contract

根據 `JSON ABI` 描述實例化 `pdxabi::Contract` 對象,用來對合約的 `input/output` 進行序列化和反序列化。

rustpub fn get_contract_abi() -> pdxabi::Contract { let mut functions: HashMap = HashMap::new(); let fn_put = pdxabi::Function { constant: false, name: String::from("put"), inputs: Vec::from(vec![ pdxabi::Param { name: String::from("key"), kind: pdxabi::param_type::ParamType::String }, pdxabi::Param { name: String::from("val"), kind: pdxabi::param_type::ParamType::String }, ]), outputs: Vec::default(), }; let fn_get = pdxabi::Function { constant: true, name: String::from("get"), inputs: Vec::from(vec![ pdxabi::Param { name: String::from("key"), kind: pdxabi::param_type::ParamType::String }, ]), outputs: Vec::from(vec![ pdxabi::Param { name: String::default(), kind: pdxabi::param_type::ParamType::String }, ]), }; let fn_getcounter = pdxabi::Function { constant: true, name: String::from("getcounter"), inputs: Vec::default(), outputs: Vec::from(vec![ pdxabi::Param { name: String::default(), kind: pdxabi::param_type::ParamType::Uint(256) }, ]), }; functions.insert(fn_put.clone().name, fn_put.clone()); functions.insert(fn_get.clone().name, fn_get.clone()); functions.insert(fn_getcounter.clone().name, fn_getcounter.clone()); pdxabi::Contract { constructor: None, functions: functions, events: HashMap::default(), fallback: false, signers: HashMap::default(), }}

使用 `ABI`

>在 hello-wasm-abi 合約中:

```rustextern crate wasm_bindgen;extern crate ewasm_api;??use wasm_bindgen::prelude::*;use ewasm_api::types::*;use ewasm_api::pdx::utils::*;

倒入處理 abi 的開發庫

use ewasm_api::pdxabi;

pdxabi::Contract 定義的對象放在 abi 模塊中:

pub mod abi;??const COUNTER_KEY: Bytes32 = Bytes32{ bytes: [255; 32] };??fn inc_counter() { let old_v = ewasm_api::storage_load(&COUNTER_KEY); let old_i = bytes_to_uint(&old_v.bytes[..]); let new_i = old_i + 1; let val = u32_to_bytes32(new_i as u32); let value = Bytes32 { bytes: val }; ewasm_api::storage_store(&COUNTER_KEY, &value);}? ?fn get_counter() -> Vec { let v = ewasm_api::storage_load(&COUNTER_KEY); Vec::from(&v.bytes[..])}??fn put_data(k: String, v: String){ ewasm_api::pdx::storage_store(k.as_bytes(), v.as_bytes());}??fn get_data(k: String) -> Vec { ewasm_api::pdx::storage_load(k.as_bytes())}??#[wasm_bindgen]pub fn main() { inc_counter(); let input = ewasm_api::calldata_acquire(); if !input.is_empty() {

從 input 獲取方法簽名,按照 ABI 規范,input 的前 4 個 byte 為方法簽名。

let fn_sig = &Vec::from(&input[..4]);

根據方法簽名獲取 function 對象。

let function = contract.function_by_sig(fn_sig).expect("error_fn_sig");

通過 function.name 來匹配相應的 handler。

match function.name.as_str() { "getcounter" => { // function getcounter() public view returns(uint256);

調用 get_counter 得到返回值,轉換成 uint

let rtn = ewasm_api::pdx::utils::bytes_to_uint(get_counter().as_slice());

此方法沒有輸入值,只有輸出,通過 function.encode_output 序列化輸出 。

let data = function.encode_output(&[pdxabi::Token::Uint(rtn.into())]).unwrap();

將結果返回給合約調用者。

ewasm_api::finish_data(data.as_slice()); } "get" => { // function get(string memory key) public view returns(string memory);

此方法有定義輸入 string key , 先用 function.decode_input 解析 input, 得到輸入列表 。

let tokens = function.decode_input(input.as_slice()).expect("error_put_input");

接口中 input 只定義了一個參數,所以 key = tokens[0]。

let key = tokens.get(0).expect("error_put_key");

調用 get_data(key) 函數,得到 val 的字節數組。

let val = get_data(key.clone().to_string().unwrap());

接口描述輸出值為 string,所以要將 val 轉換為 string。

let rtn = String::from_utf8(val).expect("error_get_val");

使用 function.encode_output 對返回值進行序列化。

let data = function.encode_output(&[pdxabi::Token::String(rtn)]).expect("error_get_output");

將結果返回給合約調用者。

ewasm_api::finish_data(data.as_slice()); } "put" => { // function put(string memory key,string memory val) public payable;

此方法有定義輸入 [string key,string val] , 先用 function.decode_input 解析 input, 得到輸入列表。

let tokens = function.decode_input(input.as_slice()).expect("error_put_input");

接口中定義了兩個參數,分別對應 key = tokens[0] , val = tokens[1]。

let key = tokens.get(0).expect("error_put_key"); let val = tokens.get(1).expect("error_put_val");

調用 put_data(key,val)。

put_data(key.clone().to_string().unwrap(), val.clone().to_string().unwrap());

結束調用,此方法沒有返回值。

ewasm_api::finish() } _ => ewasm_api::finish()

如果方法匹配失敗,則直接返回不做任何處理。

} }}

部署與使用

* 部署合約方式與 `hello-wasm` 樣例相同,可以參照

[README.md](https://github.com/PDXbaap/ewasm-rust-demo/blob/master/README.md) 中關于`部署`的描述:

* 調用合約:部署成功后會得到 `Contract Address` ,如果使用 `web3` 系列 `SDK` 可以使用 `JSON ABI` + `Contract Address` 來實例化合約,并進行調用,如果使用 `remix IDE` 進行測試調用,可以使用 `Solidity Contract Interface` + `Contract Address` 來實例化合約并調用關于 web3 提供的 SDK 和 remix IDE 的詳細資料請參閱 web3 基金會的相關資料。

Solidity 調用 Wasm 合約

用 `sol` 合約來調用 `wasm` 合約,與 `sol` 調用 `sol` 方式相同,假設已經部署過 `hello-wasm-abi` 這個合約,并得到合約地址 `0xda3ce11d916ffba4a1289cef66a7f142ec5a0f74`,通過 `hello-wasm-abi` 合約接口和地址,即可實例化這個合約,之后用法與 `sol` 調用 `sol` 一致。

例如:

soliditypragma solidity ^0.5.3;

hello-wasm-abi 合約接口

contract hello_wasm_abi { function getcounter() public view returns(uint256); function get(string memory key) public view returns(string memory); function put(string memory key,string memory val) public payable;}

使用 hello-wasm-abi 合約的 solidity 合約

contract foobar { function fetch(address addr,string memory key) public view returns(string memory) {

第一個參數 addr 為 wasm 合約地址,通過接口和地址實例化合約對象。

hello_wasm_abi hello = hello_wasm_abi(addr);

調用 wasm 合約方法

return hello.get(key); } function set(address addr,string memory key,string memory val) public payable { hello_wasm_abi hello = hello_wasm_abi(addr); hello.put(key,val); }??}

部署 `foobar` 合約后,使用 `hello-wasm-abi` 的合約地址:

`0xda3ce11d916ffba4a1289cef66a7f142ec5a0f74` 作為第一個參數分別調用 `fetch` 和 `set` 方法,完成對 `hello-wasm-abi` 合約的 `get` 和 `put` 的調用。

總結

以上是生活随笔為你收集整理的调用wasm_PDX Utopia区块链协议栈使用Solidity调用wasm智能合约的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。