Hyperledger Fabric——balance transfer(四)安装和实例化chaincode
详细解析blance transfer示例的安装(install)和实例化(Instantiate)链码(chaincode)的过程。安装chaincode会根据本地的链码文件生成chaincode镜像,实例化chaincode则会启动该镜像,使链码在docker容器中运行。
安装chaincode
1.首先看app.js中的路由函数
app.post('/chaincodes', async function(req, res) {
var peers = req.body.peers; // 目标节点列表
var chaincodeName = req.body.chaincodeName; // chaincode名称
var chaincodePath = req.body.chaincodePath; // chaincode路径
var chaincodeVersion = req.body.chaincodeVersion; // chaincode版本
var chaincodeType = req.body.chaincodeType; // chaincode类型 Eg. golong
/*
省略了参数校验
*/
// 安装chaincode
let message = await install.installChaincode(peers, chaincodeName, chaincodePath, chaincodeVersion, chaincodeType, req.username, req.orgname)
res.send(message);
});
2.再来看install-chaincode.js
var installChaincode = async function(peers, chaincodeName, chaincodePath,
chaincodeVersion, chaincodeType, username, org_name) {
logger.debug('\n\n============ Install chaincode on organizations ============\n');
helper.setupChaincodeDeploy();
let error_message = null;
try {
// 创建该组织对应的client,该client中包含用户信息_userContext
var client = await helper.getClientForOrg(org_name, username);
// admin transactionID
tx_id = client.newTransactionID(true);
// 打包请求参数
var request = {
targets: peers,
chaincodePath: chaincodePath,
chaincodeId: chaincodeName,
chaincodeVersion: chaincodeVersion,
chaincodeType: chaincodeType
};
// 调用SDK中的installChaincode()方法,根据request生成交易提案
// 然后通过sendPeersProposal()方法提交给所有背书节点,该方法获得提案响应的集合
// 最终返回 生成的交易提案 和 收集到的提案响应集合(内含背书签名)
// 之后将两者会作为交易的内容发送给orderer服务
let results = await client.installChaincode(request);
var proposalResponses = results[0]; // 背书响应集合
var proposal = results[1]; // 交易提案
// 检查提案响应是否均存在且合格
var all_good = true;
for (var i in proposalResponses) {
let one_good = false;
if (proposalResponses && proposalResponses[i].response &&
proposalResponses[i].response.status === 200) {
one_good = true;
logger.info('install proposal was good');
} else {
logger.error('install proposal was bad %j',proposalResponses.toJSON());
}
all_good = all_good & one_good;
}
if (all_good) {
logger.info('Successfully sent install Proposal and received ProposalResponse');
} else {
error_message = 'Failed to send install Proposal or receive valid response. Response null or status is not 200'
logger.error(error_message);
}
}
这一步完成后会生成chiancode
镜像,内部包含chaincode
源码go文件编译生成的可执行文件。
实例化chaincode
1.首先看app.js中的路由函数
app.post('/channels/:channelName/chaincodes', async function(req, res) {
var peers = req.body.peers;
var chaincodeName = req.body.chaincodeName;
var chaincodeVersion = req.body.chaincodeVersion;
var channelName = req.params.channelName;
var chaincodeType = req.body.chaincodeType;
var fcn = req.body.fcn;
var args = req.body.args;
// 实例化chaincode
let message = await instantiate.instantiateChaincode(peers, channelName, chaincodeName, chaincodeVersion, chaincodeType, fcn, args, req.username, req.orgname);
res.send(message);
});
2.再来看instantiate-chaincode.js
var instantiateChaincode = async function(peers, channelName, chaincodeName, chaincodeVersion, functionName, chaincodeType, args, username, org_name) {
var error_message = null;
try {
// 创建该组织名对应的client,并为其分配了用户对象
var client = await helper.getClientForOrg(org_name, username);
// 获取channel对象
var channel = client.getChannel(channelName);
// 获取基于msp管理员的TransactionID,这表示实例化链码的交易提案
// 需要用到组织管理员的身份进行签名
var tx_id = client.newTransactionID(true);
// 这个transaction ID 会用来登记(register)事件监听
var deployId = tx_id.getTransactionID();
// 构造请求结构
var request = {
targets : peers,
chaincodeId: chaincodeName,
chaincodeType: chaincodeType,
chaincodeVersion: chaincodeVersion,
args: args,
txId: tx_id
};
if (functionName)
request.fcn = functionName;
let results = await channel.sendInstantiateProposal(request, 60000);
// 返回的 交易提案 和 提案相应
var proposalResponses = results[0];
var proposal = results[1];
// 检查提案响应中是否包含正确的背书签名
var all_good = true;
for (var i in proposalResponses) {
let one_good = false;
if (proposalResponses && proposalResponses[i].response &&
proposalResponses[i].response.status === 200) {
one_good = true;
logger.info('instantiate proposal was good');
} else {
logger.error('instantiate proposal was bad');
}
all_good = all_good & one_good;
}
// 等待channel的eventHub通知我们交易被peer节点提交
var promises = [];
let event_hubs = channel.getChannelEventHubsForOrg();
#event_hubs.forEach((eh) => {
#let instantiateEventPromise = new Promise((resolve, reject) => {
#let event_timeout = setTimeout(() => {
let message = 'REQUEST_TIMEOUT:' + eh.getPeerAddr();
logger.error(message);
eh.disconnect();
}, 60000);
// 注册交易事件监听
#eh.registerTxEvent(deployId, (tx, code, block_num) => {
clearTimeout(event_timeout);
}, (err) => {
clearTimeout(event_timeout);
logger.error(err);
reject(err);
},
{unregister: true, disconnect: true}
);
eh.connect();
});
promises.push(instantiateEventPromise);
});
// 构造交易请求,包含交易id、交易提案、提案响应
var orderer_request = {
txId: tx_id, // 组织admin进行签名的交易id
proposalResponses: proposalResponses,
proposal: proposal
};
// 发送交易请求到Orderer节点,内部通过调用orderer.sendBroadcast(envelope)实现
var sendPromise = channel.sendTransaction(orderer_request);
} else {
error_message = util.format('Failed to send Proposal and receive all good ProposalResponse');
logger.debug(error_message);
}
} catch (error) {
logger.error('Failed to send instantiate due to error: ' + error.stack ? error.stack : error);
error_message = error.toString();
}
};
测试
安装
chaincode
curl -s -X POST \
http://localhost:4000/chaincodes \
-H "authorization: Bearer <Token>" \
-H "content-type: application/json" \
-d '{
"peers": ["peer0.org1.example.com","peer1.org1.example.com"],
"chaincodeName":"mycc",
"chaincodePath":"github.com/example_cc/go",
"chaincodeType": "golang",
"chaincodeVersion":"v0"
}'结果:
{"success":true,"message":"Successfully install chaincode"}
实例化
chaincode
curl -s -X POST \
http://localhost:4000/channels/mychannel/chaincodes \
-H "authorization: Bearer <token>" \
-H "content-type: application/json" \
-d '{
"peers": ["peer0.org1.example.com","peer1.org1.example.com"],
"chaincodeName":"mycc",
"chaincodeVersion":"v0",
"chaincodeType": "golang",
"args":["a","100","b","200"]
}'结果:
{"success":true,"message":"Successfully instantiate chaingcode in organization Org1 to the channel 'mychannel'"}
Hyperledger Fabric——balance transfer(四)安装和实例化chaincode的更多相关文章
- Hyperledger Fabric——balance transfer(一)启动示例
Blacne transfer是Hyperledger fabric Node SDK的一个示例应用,主要使用了SDK中fabric-client 和 fabric-ca-client 模块中的API ...
- Hyperledger Fabric——balance transfer(六)查询
balance transfer 提供了很多查询接口,包括链码查询,根据区块号查询区块数据,根据交易ID查询交易信息,查询链上的区块数,查询已安装或已实例化的链码,查询通道. 源码解析 1.调用链码查 ...
- Hyperledger Fabric——balance transfer(五)执行交易
链码安装和实例化之后就可以调用chaincode执行交易,下面分析简单的账户转账操作是如何完成的. 源码分析 1.首先看app.js的路由函数 app.post('/channels/:channel ...
- Hyperledger Fabric——balance transfer(三)创建和加入Channel
详细解析blance transfer示例的创建通道(Channel)和加入节点到通道的过程. 创建Channel 1.首先看app.js的路由函数 var createChannel = requi ...
- Hyperledger Fabric——balance transfer(二)注册用户
详细分析blance transfer示例的用户注册(register)与登录(enroll)功能. 源码分析 1.首先分析项目根目录的app.js文件中关于用户注册和登录的路由函数.注意这里的tok ...
- Hyperledger Fabric v1.1.0安装记录(国内源版)
1. 安装虚拟机 虚拟机软件采用:VirtualBox 操作系统选择:Ubuntu 14.04 内存:4G CPU:2核 硬盘:20G 2.(可选)更改 ...
- Hyperledger Fabric (1.0)环境部署 chaincode【转】
三.测试Fabric 其实我们在前面运行./network_setup.sh up的时候系统已经运行了一个Example02的ChainCode测试,部署上去的ChainCodeName是mycc,所 ...
- Ubuntu16.04下安装Hyperledger Fabric 1.0.0
系统环境 * Ubuntu: 16.04 * Go: 1.9.2 * NodeJS: v6.12.0 * Docker: 17.09.0-ce * HyperLedger Fabric: 1.0.0 ...
- Hyperledger Fabric Chaincode for Operators——实操智能合约
什么是Chaincode(智能合约)? chaincode是一个程序,它是使用Go语言编写的,最终在Java等其他编程语言中实现了指定的接口.chaincode运行在一个被背书peer进程独立出来的安 ...
随机推荐
- 关于IE8上传文件的一些问题
问题1: IE8下上传完文件后,对后台返回的JSON格式的数据,浏览器提示了下载该文件. 原因是因为IE8还不支持'application/json"类型的响应. 解决方法将后台返回的JSO ...
- log4net进阶手札(二):基本用法
本节将主要在WebSite中,对保存日志在文本文件的基本用法来进行介绍,并结合WebForm的初始化方式区别进行说明,解决方案如下图所示: 一.WebSite应用第1步:配置Web.Config文件, ...
- 使用PHP-Beast加密你的PHP源代码
PHP-Beast是一个PHP源码加密的模块,其使用DES算法加密,用户可以自定义加密的key来加密源代码. 1. PHP-Beast的安装 $ wget https://github.com/lie ...
- python(re 模块)
1.re.match() 尝试从字符串的起始位置匹配一个模式,如果不是起始位置匹配成功的话,match()就返回none. group() 以str形式返回对象中match的元素 start() 返回 ...
- 15分钟从零开始搭建支持10w+用户的生产环境(四)
上一篇文章,介绍了这个架构中,WebServer的选择,以及整个架构中扩展时的思路. 原文地址:15分钟从零开始搭建支持10w+用户的生产环境(三) 五.架构实践 前边用了三篇文章,详细介绍了这个 ...
- 搜索+简单dp
前言:即使是简单的递归,在复杂度过高时也可以使用简单的dp. 一般有两种情况,一是利用dp思想求最优子结构进行搜索剪枝,二是利用搜索进行dp数组的填充. 例题一.hdu1978 题目大意:这是一个简单 ...
- (二)Redis在Mac下的安装与SpringBoot中的配置
1 下载Redis 官网下载,下载 stable 版本,稳定版本. 2 本地安装 解压:tar zxvf redis-6.0.1.tar.gz 移动到: sudo mv redis-6.0.1 /us ...
- 简单谈谈Spring的IoC
一.前言 这几天正在复习Spring的相关内容,同时想要对Spring的实现原理做一些深入的研究.今天看了看Spring中IoC的实现,找到了一篇非常详细的博客,研究了一个下午,看完之后唯一的感受 ...
- Openwrt:mtd/mtd_write烧写固件
文章目录 1 查看当前系统分区信息 2 备份固件firmware 3 恢复固件firmware 4 备份恢复Openwrt路由器配置 5 恢复Openwrt路由器默认设置 6 刷新路由器固件 比较简单 ...
- nginx源码安装方法
nginx源码安装方法 安装方法如下 1.安装nginx必要的源码依赖软件包. yum -y install gcc gcc-c++ automake pcre pcre-devel zlib zli ...