中移链(基于EOS)实战:如何调用RPC接口组装交易、签名、上链以及查询上链结果

2023-11-10 09:59

本文主要是介绍中移链(基于EOS)实战:如何调用RPC接口组装交易、签名、上链以及查询上链结果,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

id:BSN_2021
公众号:BSN研习社
红枣科技何来亮

背景:今年3月开放联盟链“中移链”在区块链服务网络(BSN[1])中完成适配并上线发布,吸引了大批开发者,部分开发者提出了一些共性问题

目的:本篇文章是为了让读者了解如何在中移链(基于EOS)上调用RPC接口组装交易、签名、上链以及查询上链结果

适用对象:适用于BSN开放联盟链--中移链(基于EOS)开发者

1. 准备

•需要现在bsn[2]创建项目和创建一个账户,可以参考:https://bsnbase.com/static/tmpFile/bzsc/openper/7-3-6.html

•可以获取到eos 端点:https://opbningxia.bsngate.com:18602/api/aecb28acfd154cfeb90d0b6a8ecab1e7/rpc     

•eos账户/合约地址:helailiang14

•为账户购买足够的资源(cpu、net、ram)

•安装EOSIO开发环境:需要安装cleos和keosd, 可以参考:https://developers.eos.io/welcome/latest/getting-started-guide/local-development-environment/installing-eosio-binaries •部署eos合约: hello.cpp


#include <eosio/eosio.hpp>
#include <eosio/transaction.hpp>using namespace eosio;
// 通过[[eosio::contract]]标注这个类是一个合约
class [[eosio::contract]] hello : public contract
{
public:using contract::contract;// 在构造函数进行表对象的实例化, 标准合约构造函数,receiver也就是我们的合约账号(一般情况下),code就是我们的action名称,ds就是数据流// get_self() 合约所在的账号  get_code() 当前交易请求的action方法名 get_datastream() 当前数据流hello(name receiver, name code, datastream<const char *> ds) : contract(receiver, code, ds), friend_table(get_self(), get_self().value){}// 用[[eosio::action]]标注这个方法是一个合约action就行// 注意:action的名称要求符合name类型的规则[[eosio::action]] void hi(name user){print("Hello, ", user);print("get_self,", get_self().value);// print("get_code,", get_code().value);uint32_t now = current_time_point().sec_since_epoch();auto friend_itr = friend_table.find(user.value);// 数据不存在 if (friend_itr == friend_table.end()) {// 第一个参数就是内存使用的对象,第二个参数就是添加表对象时的委托方法。friend_table.emplace(get_self(), [&](auto &f) {f.friend_name = user;f.visit_time = now;});}else{// 第一个参数是传递需要修改的数据指针,第二个参数是内存使用的对象,第二个参数就是表对象修改时的委托方法friend_table.modify(friend_itr, get_self(), [&](auto &f) {f.visit_time = now;});}}[[eosio::action]] void nevermeet(name user){print("Never see you again, ", user);auto friend_itr = friend_table.find(user.value);check(friend_itr != friend_table.end(), "I don't know who you are.");// 只有一个参数,就是要删除的对象指针friend_table.erase(friend_itr);}[[eosio::action]] void meetagain(){uint32_t now = current_time_point().sec_since_epoch();auto time_idx = friend_table.get_index<"time"_n>();auto last_meet_itr = time_idx.begin();check(last_meet_itr != time_idx.end(), "I don't have a friend.");time_idx.modify(last_meet_itr, get_self(), [&](auto &f) {f.visit_time = now;});}private:// 定义一个结构体,然后用[[eosio::table]]标注这个结构体是一个合约表。在结构体里定义一个函数名primary_key,返回uint64_t类型,作为主键的定义struct [[eosio::table]] my_friend{name friend_name;uint64_t visit_time;uint64_t primary_key() const { return friend_name.value; }double by_secondary() const { return -visit_time; }};// 定义表名和查询索引  "friends"_n就是定义表名,所以使用了name类型,之后my_friend是表的结构类typedef eosio::multi_index<"friends"_n, my_friend> friends;friends friend_table;
};

2. rpc调用流程

1. 将交易信息由JSON格式序列化为BIN格式字符串


curl   -X POST   'https://opbningxia.bsngate.com:18602/api/{您的开放联盟链项目ID/rpc/v1/chain/abi_json_to_bin' \
-d '{"code": "helailiang14","action": "hi","args": {"user": "helloworld"}
}'
------------------
return{"binargs":"00408a97721aa36a"}

  2. 获取当前最新的区块编号


curl   GET 'https://opbningxia.bsngate.com:18602/api/{您的开放联盟链项目ID/rpc/v1/chain/get_info'------------------
return{"server_version":"11d35f0f","chain_id":"9b4c6015f8b73b2d7ee3ebd92d249a1aba06a614e9990dcf54f7cf2e3d5172e1","head_block_num":15134328,"last_irreversible_block_num":15134262,"last_irreversible_block_id":"00e6ee360b5e7680a526ddea45db1be15c4be2cd2389020688218fe765be6db7","head_block_id":"00e6ee7889523875a28284effecdd1199cc960adb14c14c36cd1bd52afed6824","head_block_time":"2022-04-27T09:08:08.500","head_block_producer":"prod.b","virtual_block_cpu_limit":200000000,"virtual_block_net_limit":1048576000,"block_cpu_limit":199900,"block_net_limit":1048576,"server_version_string":"v3af0a20","fork_db_head_block_num":15134328,"fork_db_head_block_id":"00e6ee7889523875a28284effecdd1199cc960adb14c14c36cd1bd52afed6824","server_full_version_string":"v3af0a20","last_irreversible_block_time":"2022-04-27T09:07:35.500"
}

获取到head_block_num : 15134328
引用
获取 head_block_id:00e6ee7889523875a28284effecdd1199cc960adb14c14c36cd1bd52afed6824
引用
获取 chain_id: 9b4c6015f8b73b2d7ee3ebd92d249a1aba06a614e9990dcf54f7cf2e3d5172e1 

 3. 根据区块编号获取区块详情


curl   -X POST 'https://opbningxia.bsngate.com:18602/api/{您的开放联盟链项目ID/rpc/v1/chain/get_block' \
-d '{"block_num_or_id": "15130610"
}'
------------------
return{"timestamp": "2022-04-27T09:08:08.500","producer": "prod.b","confirmed": 0,"previous": "00e6ee77f2655528739622d2c9235026d4f10138b9821e46ea35165cb086d12d","transaction_mroot": "0000000000000000000000000000000000000000000000000000000000000000","action_mroot": "665584b582b234bf58d3708b31da20e14d266713e3bc6ce79ea3187cc2ffa5a4","schedule_version": 2,"new_producers": null,"producer_signature": "SIG_K1_KiYCDLMgE6gE1nNqQQL2jEEF3VVd6iaspAePvvJMjKwgg2Yf6GiTYcznrkymAdtZUAUFh28N8r9RzX936cASKDB6JW6ga3","transactions": [],"id": "00e6ee7889523875a28284effecdd1199cc960adb14c14c36cd1bd52afed6824","block_num": 15134328,"ref_block_prefix": 4018438818
}

获取到timestamp :  2022-04-27T09:08:08

     4. 签署交易

使用EOSIO提供的签名工具实现签名:启动keosd后,才会提供签名服务

 


curl -X POST POST 'http://192.168.1.46:8800/v1/wallet/sign_transaction' \
-d '[{"expiration": "2022-04-27T10:08:08","ref_block_num": 61048,"ref_block_prefix": 4018438818,"max_net_usage_words": 0,"max_cpu_usage_ms": 0,"delay_sec": 0,"context_free_actions": [],"actions": [{"account": "helailiang14","name": "hi","authorization": [{"actor": "helailiang14","permission": "active"}],"data": "00408a97721aa36a"}],"transaction_extensions": [],"signatures": [],"context_free_data": []},["EOS6F6PRkSaPyijTDBYskFbsxpGz53JMTFbEhua94fQEyf7pAMc7Y"],"9b4c6015f8b73b2d7ee3ebd92d249a1aba06a614e9990dcf54f7cf2e3d5172e1"
]'
------------------
return :{"expiration":"2022-04-27T10:08:08","ref_block_num":61048,"ref_block_prefix":4018438818,"max_net_usage_words":0,"max_cpu_usage_ms":0,"delay_sec":0,"context_free_actions":[],"actions":[{"account":"helailiang14","name":"hi","authorization":[{"actor":"helailiang14","permission":"active"}],"data":"00408a97721aa36a"}],"transaction_extensions":[],"signatures":["SIG_K1_K2AzV2Pk4SP3PQhcdQ1bYgGZgr7PUUcJkAGowvncFV1ngrZufeCQpveAUBRYvNA5uyxFk2hKiot3Mu7FCW5rqqeoU5SVTo"],"context_free_data":[]
}

expiration 过期时间。这里将timestamp加上了60分钟.

ref_block_num:  由第二步返回的head_block_id 16进制的 然后字段截取前八位低4位 转10进制, ee78 ==> 61048

ref_block_prefix:由第二步返回的head_block_id 16进制的 然后字段截取16到24 然后两个字节反转(a28284ef反转为ef8482a2) 转10进制, ef8482a2 ==>  4018438818

account 合约名称,即部署合约的账户

name 调用的合约方法。

actor 调用者。签名者

data :第一步生成的bin字符串

permission 使用的权限类型

EOS6F6PRkSaPyijTDBYskFbsxpGz53JMTFbEhua94fQEyf7pAMc7Y :签署此交易的公钥。实际上是由钱包中对应的私钥来签

9b4c6015f8b73b2d7ee3ebd92d249a1aba06a614e9990dcf54f7cf2e3d5172e1: 是第二步获取的chain_id

signatures:  签名结果SIG_K1_K2AzV2Pk4SP3PQhcdQ1bYgGZgr7PUUcJkAGowvncFV1ngrZufeCQpveAUBRYvNA5uyxFk2hKiot3Mu7FCW5rqqeoU5SVTo

 5. 打包交易

使用 cleos convert pack_transaction将交易报文转换成 packed 格式


cleos convert pack_transaction  '{
"expiration":"2022-04-27T10:08:08","ref_block_num":61048,"ref_block_prefix":4018438818,"max_net_usage_words": 0,"max_cpu_usage_ms": 0,"delay_sec": 0,"context_free_actions": [],"actions": [{"account": "helailiang14","name": "hi","authorization": [{"actor": "helailiang14","permission": "active"}],"data": "00408a97721aa36a"}],"transaction_extensions": []
}'------------------
return:{"signatures": [],"compression": "none","packed_context_free_data": "","packed_trx": "0816696278eea28284ef000000000140029bc64567a26a000000000000806b0140029bc64567a26a00000000a8ed32320800408a97721aa36a00"
}

packed_trx: 为交易报文的 packed 格式

      6. 提交交易


curl -X POST 'https://opbningxia.bsngate.com:18602/api/{您的开放联盟链项目ID/rpc/v1/chain/push_transaction' \
-d '{"signatures": ["SIG_K1_K2AzV2Pk4SP3PQhcdQ1bYgGZgr7PUUcJkAGowvncFV1ngrZufeCQpveAUBRYvNA5uyxFk2hKiot3Mu7FCW5rqqeoU5SVTo"],"compression": "none","packed_context_free_data": "","packed_trx": "0816696278eea28284ef000000000140029bc64567a26a000000000000806b0140029bc64567a26a00000000a8ed32320800408a97721aa36a00"
}'------------------
return:{"transaction_id":"a69d03f6b1bab4bd8908124eef5e59d3e47df4063e697a07487308cde63a9f79","processed":{"id":"a69d03f6b1bab4bd8908124eef5e59d3e47df4063e697a07487308cde63a9f79","block_num":15136664,"block_time":"2022-04-27T09:27:36.500","producer_block_id":null,"receipt":{"status":"executed","cpu_usage_us":272,"net_usage_words":13},"elapsed":272,"net_usage":104,"scheduled":false,"action_traces":[{"action_ordinal":1,"creator_action_ordinal":0,"closest_unnotified_ancestor_action_ordinal":0,"receipt":{"receiver":"helailiang14","act_digest":"31ff1ecb2b0b0c89911b74c7930f08ecfefbd24ba59ef30a905d44068d2d8910","global_sequence":15199315,"recv_sequence":2,"auth_sequence":[["helailiang14",4]],"code_sequence":1,"abi_sequence":1},"receiver":"helailiang14","act":{"account":"helailiang14","name":"hi","authorization":[{"actor":"helailiang14","permission":"active"}],"data":{"user":"helloworld"},"hex_data":"00408a97721aa36a"},"context_free":false,"elapsed":63,"console":"Hello, helloworldget_self,7683817463629939264","trx_id":"a69d03f6b1bab4bd8908124eef5e59d3e47df4063e697a07487308cde63a9f79","block_num":15136664,"block_time":"2022-04-27T09:27:36.500","producer_block_id":null,"account_ram_deltas":[],"account_disk_deltas":[],"except":null,"error_code":null,"return_value_hex_data":"","inline_traces":[]}],"account_ram_delta":null,"except":null,"error_code":null}
}

signatures:  为第4步签名的结果

packed_trx: 为第5步的报文转换结果

      7. 查询表数据


curl -X POST 'https://opbningxia.bsngate.com:18602/api/{您的开放联盟链项目ID/rpc/v1/chain/get_table_rows' \
-d'{"code": "helailiang14","table": "friends","scope": "helailiang14","json": true
}'
------------------
return:{"rows":[{"friend_name":"helloworld","visit_time":1651051656}],"more":false,"next_key":"","next_key_bytes":""
}

 数据[helloworld]已经写到table中

References

[1] BSN: https://bsnbase.com/
[2] bsn: https://bsnbase.com/p/home/Openalliance/projectManagement

这篇关于中移链(基于EOS)实战:如何调用RPC接口组装交易、签名、上链以及查询上链结果的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/381940

相关文章

MyBatis编写嵌套子查询的动态SQL实践详解

《MyBatis编写嵌套子查询的动态SQL实践详解》在Java生态中,MyBatis作为一款优秀的ORM框架,广泛应用于数据库操作,本文将深入探讨如何在MyBatis中编写嵌套子查询的动态SQL,并结... 目录一、Myhttp://www.chinasem.cnBATis动态SQL的核心优势1. 灵活性与可

RabbitMQ工作模式中的RPC通信模式详解

《RabbitMQ工作模式中的RPC通信模式详解》在RabbitMQ中,RPC模式通过消息队列实现远程调用功能,这篇文章给大家介绍RabbitMQ工作模式之RPC通信模式,感兴趣的朋友一起看看吧... 目录RPC通信模式概述工作流程代码案例引入依赖常量类编写客户端代码编写服务端代码RPC通信模式概述在R

Java Spring 中的监听器Listener详解与实战教程

《JavaSpring中的监听器Listener详解与实战教程》Spring提供了多种监听器机制,可以用于监听应用生命周期、会话生命周期和请求处理过程中的事件,:本文主要介绍JavaSprin... 目录一、监听器的作用1.1 应用生命周期管理1.2 会话管理1.3 请求处理监控二、创建监听器2.1 Ser

C/C++和OpenCV实现调用摄像头

《C/C++和OpenCV实现调用摄像头》本文主要介绍了C/C++和OpenCV实现调用摄像头,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一... 目录准备工作1. 打开摄像头2. 读取视频帧3. 显示视频帧4. 释放资源5. 获取和设置摄像头属性

Mybatis嵌套子查询动态SQL编写实践

《Mybatis嵌套子查询动态SQL编写实践》:本文主要介绍Mybatis嵌套子查询动态SQL编写方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录前言一、实体类1、主类2、子类二、Mapper三、XML四、详解总结前言MyBATis的xml文件编写动态SQL

Apache 高级配置实战之从连接保持到日志分析的完整指南

《Apache高级配置实战之从连接保持到日志分析的完整指南》本文带你从连接保持优化开始,一路走到访问控制和日志管理,最后用AWStats来分析网站数据,对Apache配置日志分析相关知识感兴趣的朋友... 目录Apache 高级配置实战:从连接保持到日志分析的完整指南前言 一、Apache 连接保持 - 性

Java中的Closeable接口及常见问题

《Java中的Closeable接口及常见问题》Closeable是Java中的一个标记接口,用于表示可以被关闭的对象,它定义了一个标准的方法来释放对象占用的系统资源,下面给大家介绍Java中的Clo... 目录1. Closeable接口概述2. 主要用途3. 实现类4. 使用方法5. 实现自定义Clos

MQTT SpringBoot整合实战教程

《MQTTSpringBoot整合实战教程》:本文主要介绍MQTTSpringBoot整合实战教程,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考... 目录MQTT-SpringBoot创建简单 SpringBoot 项目导入必须依赖增加MQTT相关配置编写

在Java中基于Geotools对PostGIS数据库的空间查询实践教程

《在Java中基于Geotools对PostGIS数据库的空间查询实践教程》本文将深入探讨这一实践,从连接配置到复杂空间查询操作,包括点查询、区域范围查询以及空间关系判断等,全方位展示如何在Java环... 目录前言一、相关技术背景介绍1、评价对象AOI2、数据处理流程二、对AOI空间范围查询实践1、空间查

MySQL基本查询示例总结

《MySQL基本查询示例总结》:本文主要介绍MySQL基本查询示例总结,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧... 目录Create插入替换Retrieve(读取)select(确定列)where条件(确定行)null查询order by语句li