详细解析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的更多相关文章

  1. Hyperledger Fabric——balance transfer(一)启动示例

    Blacne transfer是Hyperledger fabric Node SDK的一个示例应用,主要使用了SDK中fabric-client 和 fabric-ca-client 模块中的API ...

  2. Hyperledger Fabric——balance transfer(六)查询

    balance transfer 提供了很多查询接口,包括链码查询,根据区块号查询区块数据,根据交易ID查询交易信息,查询链上的区块数,查询已安装或已实例化的链码,查询通道. 源码解析 1.调用链码查 ...

  3. Hyperledger Fabric——balance transfer(五)执行交易

    链码安装和实例化之后就可以调用chaincode执行交易,下面分析简单的账户转账操作是如何完成的. 源码分析 1.首先看app.js的路由函数 app.post('/channels/:channel ...

  4. Hyperledger Fabric——balance transfer(三)创建和加入Channel

    详细解析blance transfer示例的创建通道(Channel)和加入节点到通道的过程. 创建Channel 1.首先看app.js的路由函数 var createChannel = requi ...

  5. Hyperledger Fabric——balance transfer(二)注册用户

    详细分析blance transfer示例的用户注册(register)与登录(enroll)功能. 源码分析 1.首先分析项目根目录的app.js文件中关于用户注册和登录的路由函数.注意这里的tok ...

  6. Hyperledger Fabric v1.1.0安装记录(国内源版)

    1. 安装虚拟机     虚拟机软件采用:VirtualBox     操作系统选择:Ubuntu 14.04     内存:4G     CPU:2核     硬盘:20G     2.(可选)更改 ...

  7. Hyperledger Fabric (1.0)环境部署 chaincode【转】

    三.测试Fabric 其实我们在前面运行./network_setup.sh up的时候系统已经运行了一个Example02的ChainCode测试,部署上去的ChainCodeName是mycc,所 ...

  8. 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 ...

  9. Hyperledger Fabric Chaincode for Operators——实操智能合约

    什么是Chaincode(智能合约)? chaincode是一个程序,它是使用Go语言编写的,最终在Java等其他编程语言中实现了指定的接口.chaincode运行在一个被背书peer进程独立出来的安 ...

随机推荐

  1. Linux系统目录结构:目录层次标准、常用目录和文件

    1. 目录层次标准FHS FHS(Filesystem Hierarchy Standard)目录层次标准,是Linux的目录规范标准.   FHS定义了两层规范: 第一层:是"/" ...

  2. Python3的日期和时间

    2019独角兽企业重金招聘Python工程师标准>>> python 中处理日期时间数据通常使用datetime和time库 因为这两个库中的一些功能有些重复,所以,首先我们来比较一 ...

  3. JAVA连接Excel最好用的开源项目EasyExcel,官方使用文档及.jar包下载

    EasyExcel是一个基于Java的简单.省内存的读写Excel的开源项目.在尽可能节约内存的情况下支持读写百M的Excel. github地址:https://github.com/alibaba ...

  4. 一张图告诉你E-R图怎么画

    E-R图也称实体-联系图(Entity Relationship Diagram),提供了表示实体类型.属性和联系的方法,用来描述现实世界的概念模型. 它是描述现实世界关系概念模型的有效方法.是表示概 ...

  5. codeforce 225B Code Parsing

      Little Vitaly loves different algorithms. Today he has invented a new algorithm just for you. Vita ...

  6. 2019-2020Nowcoder Girl初赛 题解

    题目都不是很难,就是最后一题有点毒瘤 第一题:牛妹爱整除 这个你把一个进制数进行拆分,拆分成若干位,然后在取模,这样会发现如果是x进制的数,那么对x+1这个进制转化即满足条件. 举个例子:一个x进制数 ...

  7. Springboot邮件发送思路分析

    毕业设计里需要邮件发送,所以学习,总的来讲,我考虑以下几点, 代码量少,代码简单.配置少,一看就懂,使用 JavaMail 太麻烦了. 异步执行,添加员工之后会发送入职邮件, 多线程处理,设计里有一个 ...

  8. 【Scala】Actor并发编程实现单机版wordCount

    文章目录 对单个文本文件进行单词计数 对多个文本文件进行单词计数 对单个文本文件进行单词计数 import scala.actors.Actor import scala.io.Source //读取 ...

  9. failed parsing overlays.

    clearn + rebuild + 重新运行: 删掉模拟器进程 + 重新运行:

  10. 透过面试题掌握HashMap【持续更新中】

    本文主要是自己阅读了HashMap和ConcurrentHashMap源码及一些Java容器类相关的博客后,找了一些很多面经中涉及到的Java容器相关的面试题,自己全部手写的解答,也花了一些流程图,之 ...