Fabric: 使用InvokeChaincode实现跨通道数据访问

因为工作中遇到一些问题考虑使用Fabric的跨通道链码调用方法InvokeChaincode()来解决,这篇文章主要是记录以下在Fabric测试网络中InvokeChaincode()的使用过程及遇到的问题。

1 前期准备

1.1 认识InvokeChaincode

  InvokeChaincode的作用是调用指定的链码。而被调用的链码与执行 InvokeChaincode的链码在或不在同一个通道上时,其能发挥的作用不同。具体规则如下:

  • 如果与被调用的链码在同一个通道上,它只是将调用的链码读取集和写入集添加到调用事务中。
  • 如果与被调用的链码在不同的通道上,则只有响应返回给调用的链码;来自被调用链码的任何putState()调用都不会对账本产生任何影响(我的理解是,这种情况下只可以读数据不能写数据)。

另外,InvokeChaincode的参数及其返回值如下:

  • 参数chaincodeName: string类型,目标链码名称。
  • 参数args: [][]byte型,参数列表。
  • 参数channel: string类型,目标链码所在的通道名称。如果channel值为"",则表示当前通道。
  • 返回值peer.Response: peer.Pesponse类型的数据是对peer节点操作的响应结果,通过处理peer.Response类型的数据,可以获取操作执行的状态、事件以及返回的值。也就是说,可以从peer.Response中抽取出目标链码的返回值。peer.Response数据通常包含以下字段:
字段名含义
Status操作的状态码 ,操作成功为200
Payload操作的返回结果,其类型为:[]byte
Message操作的错误信息,仅在出错时有效
TxId操作所在的交易ID
Proposal操作所在的提案
1.2 准备工作

   为了能减少创建节点、通道等这些繁琐的工作,这里将充分利用Fabric中的测试网络test-network。在实现跨通道的数据访问之前,需要先将基本的环境搭建完成。具体包括以下:

  • 使用./network.sh up命令创建peer节点、Orderer节点和cli客户端。
  • 使用./network.sh createChannel -c命令创建两个通道channel1channel2,这两个通道将共用所有的peer和Orderer节点。
  • 配置peer CLI, 将peer CLI绑定到Org1上的peer0节点上。
  • fabric-samples中提供的go语言链码示例部署到channel1中,并使用peer chaincode invoke调用链码的InitLedger方法往链码的world state中写入数据。具体代码如下:
#将asset-transfer-basic/chaincode-go中的链码部署到channel1中
./network.sh deployCC -ccn basic -ccp ../asset-transfer-basic/chaincode-go -ccl go -c channel1
#执行InitLedger()
peer chaincode invoke -o localhost:7050 --ordererTLSHostnameOverride orderer.example.com --tls --cafile "${PWD}/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem" -C channel1 -n basic --peerAddresses localhost:7051 --tlsRootCertFiles "${PWD}/organizations/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt" --peerAddresses localhost:9051 --tlsRootCertFiles "${PWD}/organizations/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt" -c '{"function":"TransferAsset","Args":["asset6","Christopher"]}'
#查询world state中的所有数据
peer chaincode query -C channel1 -n basic -c '{"Args":["GetAllAssets"]}'

Tips:以上这些工作不是本篇的重点,具体过程可以参考其他资料,这里不赘述。

以上准备工作完成后,需要编写新的链码文件的来具体引用InvokeChaincode方法,并将新的链码部署到通道channel2上。

2 实现

2.1 具体实现

  • 先编写链码文件test_invoke.go,具体代码如下:
package chaincodeimport ("github.com/hyperledger/fabric-contract-api-go/contractapi"
)type TestSmartContract struct {contractapi.Contract
}func (s *TestSmartContract) QueryData(ctx contractapi.TransactionContextInterface) (string, error) {//这里为了简单,把要传递给InvokeChaincode()的参数在函数体固定了,实际应用中需要改为从peer chaincode中接收参数chaincodeName := "basic"channelName := "channel1"chaincodeArgs := make([][]byte,1)chaincodeArgs[0]=[]byte("GetAllAssets")response := ctx.GetStub().InvokeChaincode(chaincodeName, chaincodeArgs, channelName)data := response.Payloadreturn string(data), nil
}
  • test_invoke.go文件放到fabric-samples/asset-transfer-basic/chaincode-go/chaincode目录下
  • test_invoke.go文件执行权限。
sudo chmod -R 777 test_invoke.go
  • 修改fabric-samples/asset-transfer-basic/assetTransfer.go文件。将文件中NewChaincode中的参数改为&chaincode.TestSmartContract{}即可。Tips:test_invoke.go文件的主要作用就是定义结构体类型:TestSmartContract。
    在这里插入图片描述
  • 将链码部署到channel2中,这里将这个链码命名为basic_test。
./network.sh deployCC -ccn basic_test -ccp ../asset-transfer-basic/chaincode-go -ccl go -c channel2
  • 接下来在渠道channel2上调用链码basic_test上的QueryData来实现跨通道数据访问。
peer chaincode query -C channel2 -n basic_test -c '{"Args":["QueryData"]}'

结果如下(成功返回了channel1中的world state数据了)。至此,就完成了跨通道的数据访问。
在这里插入图片描述

2.2 补充说明

  在编写test_invoke.go文件时,中途遇到一些错误信息。整理如下:

  • 使用deployCC命令部署链码时若出现错误,一般都是go语言的语法错误,这里直接根据提示信息修改代码即可。
  • 即使 deployCC命令成功了也不代表链码能运行成功。后续链码的编译和执行错误信息可以通道命令docker查看。先运行docker ps -a命令,如果出现如下情况,则说明链码依然有错。
    在这里插入图片描述
    这种情况下,可以通过docker日志来查看具体的错误信息。命令如下:
docker logs --details <CONTAINER-ID>

代码修改之后需要重新使用 deployCC部署。

  • 开始test_invoke.go文件中只有一个名为queryData的方法时遇到这样一种错误: Contracts are required to have at least 1 (none-ignored) public method.
    错误原因:go语言中的方法名如果第一个字母为小写,则说明其他包无法使用这个方法,即为私有。所以这个错误只需要将方法名的首字母大写即可,即QueryData。这里建议,链码中的方法名都尽可能首字母大写。
  • InvokeChaincode方法的返回值类型为peer.Response,如果QueryData直接返回peer.Response,比如采用如下写法:
func (s *TestSmartContract) QueryData(ctx contractapi.TransactionContextInterface) peer.Response {chaincodeName := "basic"channelName := "channel1"chaincodeArgs := make([][]byte,1)chaincodeArgs[0]=[]byte("GetAllAssets")response := ctx.GetStub().InvokeChaincode(chaincodeName, chaincodeArgs, channelName)return response
}

这种写法会提示错误:Cannot use metadata. Metadata did not match schema。为了解决这个错误,在最终的代码中将QueryData的返回值类型改为了(string,error)

参考资料

  1. https://blog.csdn.net/weixin_41946008/article/details/123044664
  2. https://hyperledger-fabric.readthedocs.io/en/latest/test_network.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/139462.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Oracle(15)Managing Users

目录 一、基础知识 1、Users and Security 用户和安全 2、Database Schema 3、Checklist for Creating Users创建用户步骤 二、基础操作 1、创建一个用户 2、OS Authentication 操作系统身份验证 3、Dropping a User 删除用户 4、Getting User Information 获取用户信…

Leetcode100120. 找出强数对的最大异或值 I

Every day a Leetcode 题目来源&#xff1a;100120. 找出强数对的最大异或值 I 解法1&#xff1a;模拟 枚举 2 遍数组 nums 的元素&#xff0c;更新最大异或值。 代码&#xff1a; /** lc appleetcode.cn id100120 langcpp** [100120] 找出强数对的最大异或值 I*/// lc c…

Leetcode—765.情侣牵手【困难】

2023每日刷题&#xff08;二十七&#xff09; Leetcode—765.情侣牵手 并查集置换环思路 参考自ylb 实现代码 class Solution { public:int minSwapsCouples(vector<int>& row) {int n row.size();int len n / 2;vector<int> p(len);iota(p.begin(), p.…

C语言--从键盘输入当月利润I,求应发奖金总数。

题目描述&#xff1a; 企业发放的奖金根据利润提成。利润I低于或等于100000元的&#xff0c;奖金可提成10%; 利润高于100000 元&#xff0c;低于200000元(1000001000000时&#xff0c;超过1000000元的部分按 1%提成。从键盘输入当月利润I,求应发奖金总数。 int main() {int m…

前端面试题 计算机网络

文章目录 ios 7层协议tcp协议和udp协议的区别tcp协议如何确保数据的可靠http和tcp的关系url输入地址到呈现网页有哪些步骤post和get本质区别&#xff0c;什么时候会触发二次预检GET请求&#xff1a;POST请求&#xff1a;触发二次预检&#xff08;CORS中的预检请求&#xff09;&…

c++ 信奥编程 1135:配对碱基链

#include<iostream> #include<cstdio> #include<cstring> using namespace std; int main(){char a[256];int len;int i;gets(a);lenstrlen(a);//计算字符串长度for(i0; i<len; i){ //输出配对碱基if(a[i]A) cout<<"T";if(a[i]T) cout<…

yolo系列报错(持续补充ing)

文章目录 export GIT_PYTHON_REFRESHquiet解决 没有pt权重文件解决 python文件路径报错解决 读取文件列名报错解决 导入不同文件夹出错解决 megengine没有安装解决然后你发现它竟然还没有用 export GIT_PYTHON_REFRESHquiet 设置环境变量 GIT_PYTHON_REFRESH &#xff0c;这个…

【Proteus仿真】【STM32单片机】多路温度控制系统

文章目录 一、功能简介二、软件设计三、实验现象联系作者 一、功能简介 本项目使用Proteus8仿真STM32单片机控制器&#xff0c;使用按键、LED、蜂鸣器、LCD1602、DS18B20温度传感器、HC05蓝牙模块等。 主要功能&#xff1a; 系统运行后&#xff0c;默认LCD1602显示前4路采集的…

python poetry的教程

Poetry Python世界中&#xff0c;Poetry是一个近年来备受瞩目的工具&#xff0c;它为开发者提供了一个灵活且强大的依赖管理解决方案。Poetry可以帮助开发者管理项目的依赖关系&#xff0c;同时提供了一系列的工具和功能&#xff0c;使开发者能够更轻松地创建和管理复杂的项目。…

axios请求的问题

本来不想记录&#xff0c;但是实在没有办法&#xff0c;因为总是会出现post请求&#xff0c;后台接收不到数据的情况,还是记录一下如何的解决的比较好。 但是我使用export const addPsiPurOrder data > request.post(/psi/psiPurOrder/add, data); 下面是封装的代码。后台接…

Ubuntu 创建并发布 Django 项目

Ubuntu 创建并发布 Django 项目 升级操作系统和软件 sudo apt updatesudo apt -y dist-upgrade 安装 python3-pip sudo apt -y install python3-pip安装 django pip install -i https://pypi.tuna.tsinghua.edu.cn/simple djangosudo apt -y install python3-django创建 dj…

2023 年最好的 Android 系统修复/刷机应用程序和软件

任何 Android 设备要顺利运行&#xff0c;其操作系统必须运行良好。幸运的是&#xff0c;对于大多数 Android 用户来说&#xff0c;这是不间断的。设备运行良好&#xff0c;打电话、共享文档等都没有问题。尽管如此&#xff0c;Android 操作系统可能会停止运行。这可能是由于特…

基于机器学习的 ICU 脑血管疾病死亡风险智能预测系统

温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长 Wechat / QQ 名片 :) 1. 项目简介 重症患者或重大手术后的患者在重症监护室&#xff08;ICU&#xff09;内通过多种生命支持系统以维持生理功能。患者在ICU 内会被频繁持续的记录生命体征和实验室测量等多种数据。由于高频…

头歌答案Python——JSON基础

目录 ​编辑 Python——JSON基础 第1关&#xff1a;JSON篇&#xff1a;JSON基础知识 任务描述 第2关&#xff1a;JSON篇&#xff1a;使用json库 任务描述 Python——XPath基础 第1关&#xff1a;XPath 路径表达式 任务描述 第2关&#xff1a;XPath 轴定位 任务描述…

【原型详解】JavaScript原型链:深入了解Prototype,超级详细!!!

&#x1f601; 作者简介&#xff1a;一名大四的学生&#xff0c;致力学习前端开发技术 ⭐️个人主页&#xff1a;夜宵饽饽的主页 ❔ 系列专栏&#xff1a;JavaScript进阶指南 &#x1f450;学习格言&#xff1a;成功不是终点&#xff0c;失败也并非末日&#xff0c;最重要的是继…

Django视图函数和资源

文章目录 1.视图1.1 文件or文件夹1.2 相对和绝对导入urls1.3 视图参数1.4 返回值1.5 响应头1.6 FBV和CBV 2.静态资源2.1 静态文件2.2 媒体文件 1.视图 1.1 文件or文件夹 1.2 相对和绝对导入urls 注意实现&#xff1a;不要再项目根目录做相对导入。 原则&#xff1a; 绝对导入…

【强化学习】18 —— SAC( Soft Actor-Critic)

文章目录 前言最大熵强化学习不同动作空间下的最大熵强化学习基于能量的模型软价值函数最大熵策略 Soft Q-learningSoft Q-IterationSoft Q-Learning近似采样与SVGD伪代码 Soft Actor-Critic伪代码代码实践连续动作空间离散动作空间 参考与推荐 前言 之前的章节提到过在线策略…

iOS移动应用安全加固:保护您的App免受恶意攻击的重要步骤

目录 iOS移动应用安全加固&#xff1a;保护您的App免受恶意攻击的重要步骤 摘要 引言 一、APP加固的概念 二、APP加固方案的比较 三、保护iOS应用的安全 四、总结 参考资料 摘要 本文介绍了移动应用程序&#xff08;App&#xff09;加固的概念和流程&#xff0c;以及市…

【Unity细节】Unity中如何让组件失活而不是物体失活

&#x1f468;‍&#x1f4bb;个人主页&#xff1a;元宇宙-秩沅 hallo 欢迎 点赞&#x1f44d; 收藏⭐ 留言&#x1f4dd; 加关注✅! 本文由 秩沅 原创 &#x1f636;‍&#x1f32b;️收录于专栏&#xff1a;unity细节和bug &#x1f636;‍&#x1f32b;️优质专栏 ⭐【…

Python之Django

web应用程序 # Django框架是一款专门用来开发web应用的框架 # Web应用程序是一种可以通过浏览器访问的应用程序, B/S架构 案例&#xff1a;淘宝网、京东... # 应用程序有两种模式: C/S&#xff1a;客户端/服务器端程序&#xff0c;这类程序一般独立运行 B/S&#xff1a;…