Hyperledger Fabric SDK 示例fabric-samples-《balance-transfer》之五《初始化chaincode》
来源:互联网 发布:java中反射method 编辑:程序博客网 时间:2024/05/22 10:53
前言
初始化chaincode只需要在一个节点上初始即可。我们需要指定以下参数:
- channel名称
- chaincode名称
- chaincode版本
- 初始化要执行的方法(默认为
Init
) - 方法参数
本例中chaincode初始化的时候会调用合约的Init
的方法,所以我们需要传递该方法内部定义的参数,我们先来看下该Init
的具体实现:
example_cc.go
func (t *SimpleChaincode) Init(stub shim.ChaincodeStubInterface) pb.Response { logger.Info("########### example_cc0 Init ###########") _, args := stub.GetFunctionAndParameters() var A, B string // Entities var Aval, Bval int // Asset holdings var err error // 1 获取四个参数 // Initialize the chaincode A = args[0] Aval, err = strconv.Atoi(args[1]) if err != nil { return shim.Error("Expecting integer value for asset holding") } B = args[2] Bval, err = strconv.Atoi(args[3]) if err != nil { return shim.Error("Expecting integer value for asset holding") } logger.Info("Aval = %d, Bval = %d\n", Aval, Bval) //2 写入到分类账中(类似map一样 k-v存储) // Write the state to the ledger err = stub.PutState(A, []byte(strconv.Itoa(Aval))) if err != nil { return shim.Error(err.Error()) } err = stub.PutState(B, []byte(strconv.Itoa(Bval))) if err != nil { return shim.Error(err.Error()) } return shim.Success(nil)}
路由
app.js
//初始化chaincode Instantiate chaincode on target peersapp.post('/channels/:channelName/chaincodes', function(req, res) { logger.debug('==================== INSTANTIATE CHAINCODE =================='); var chaincodeName = req.body.chaincodeName; var chaincodeVersion = req.body.chaincodeVersion; var channelName = req.params.channelName; var fcn = req.body.fcn; var args = req.body.args; //1 参数校验 // channel名字 logger.debug('channelName : ' + channelName); //chaincode名字 logger.debug('chaincodeName : ' + chaincodeName); //chaincode版本 logger.debug('chaincodeVersion : ' + chaincodeVersion); // //执行的方法 logger.debug('fcn : ' + fcn); //方法参数 logger.debug('args : ' + args); if (!chaincodeName) { res.json(getErrorMessage('\'chaincodeName\'')); return; } if (!chaincodeVersion) { res.json(getErrorMessage('\'chaincodeVersion\'')); return; } if (!channelName) { res.json(getErrorMessage('\'channelName\'')); return; } if (!args) { res.json(getErrorMessage('\'args\'')); return; } //2 具体实现 instantiate.instantiateChaincode(channelName, chaincodeName, chaincodeVersion, fcn, args, req.username, req.orgname) .then(function(message) { res.send(message); });});
具体实现
instantiate-chaincode.js
var path = require('path');var fs = require('fs');var util = require('util');var hfc = require('fabric-client');var Peer = require('fabric-client/lib/Peer.js');var EventHub = require('fabric-client/lib/EventHub.js');var helper = require('./helper.js');var logger = helper.getLogger('instantiate-chaincode');var ORGS = hfc.getConfigSetting('network-config');var tx_id = null;var eh = null;var instantiateChaincode = function(channelName, chaincodeName, chaincodeVersion, functionName, args, username, org) { logger.debug('\n============ Instantiate chaincode on organization ' + org + ' ============\n'); var channel = helper.getChannelForOrg(org); var client = helper.getClientForOrg(org);// 1 获取组织管理员 return helper.getOrgAdmin(org).then((user) => { // read the config block from the orderer for the channel // and initialize the verify MSPs based on the participating // organizations // 2 初始化 channel 的msp 会从order里获取配置 return channel.initialize(); }, (err) => { logger.error('Failed to enroll user \'' + username + '\'. ' + err); throw new Error('Failed to enroll user \'' + username + '\'. ' + err); }).then((success) => { tx_id = client.newTransactionID(); // send proposal to endorser //3.1封装提案请求 var request = { chaincodeId: chaincodeName, chaincodeVersion: chaincodeVersion, args: args, txId: tx_id }; if (functionName) request.fcn = functionName; // 3.2 提交初始化chaincode提案给背书节点 return channel.sendInstantiateProposal(request); }, (err) => { logger.error('Failed to initialize the channel'); throw new Error('Failed to initialize the channel'); }).then((results) => { var proposalResponses = results[0]; var proposal = results[1]; var all_good = true; //4 验证所有的背书响应是否ok 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; } if (all_good) { logger.info(util.format( 'Successfully sent Proposal and received ProposalResponse: Status - %s, message - "%s", metadata - "%s", endorsement signature: %s', proposalResponses[0].response.status, proposalResponses[0].response.message, proposalResponses[0].response.payload, proposalResponses[0].endorsement .signature)); //4.0 封装交易请求 var request = { proposalResponses: proposalResponses, proposal: proposal }; // set the transaction listener and set a timeout of 30sec // if the transaction did not get committed within the timeout period, // fail the test var deployId = tx_id.getTransactionID(); // 4.1 设置监听事件链接 eh = client.newEventHub(); let data = fs.readFileSync(path.join(__dirname, ORGS[org].peers['peer1'][ 'tls_cacerts' ])); eh.setPeerAddr(ORGS[org].peers['peer1']['events'], { pem: Buffer.from(data).toString(), 'ssl-target-name-override': ORGS[org].peers['peer1']['server-hostname'] }); eh.connect(); //4.2 监听事件并设置超时, 生成promise let txPromise = new Promise((resolve, reject) => { let handle = setTimeout(() => { eh.disconnect(); reject(); }, 30000); eh.registerTxEvent(deployId, (tx, code) => { logger.info( 'The chaincode instantiate transaction has been committed on peer ' + eh._ep._endpoint.addr); clearTimeout(handle); eh.unregisterTxEvent(deployId); eh.disconnect(); if (code !== 'VALID') { logger.error('The chaincode instantiate transaction was invalid, code = ' + code); reject(); } else { logger.info('The chaincode instantiate transaction was valid.'); resolve(); } }); }); // 5 背书响应ok 发送交易 var sendPromise = channel.sendTransaction(request); //6 集成promise 并运行 return Promise.all([sendPromise].concat([txPromise])).then((results) => { logger.debug('Event promise all complete and testing complete'); //7 这个是第五步执行的结果 return results[0]; // the first returned value is from the 'sendPromise' which is from the 'sendTransaction()' call }).catch((err) => { logger.error( util.format('Failed to send instantiate transaction and get notifications within the timeout period. %s', err) ); return 'Failed to send instantiate transaction and get notifications within the timeout period.'; }); } else { logger.error( 'Failed to send instantiate Proposal or receive valid response. Response null or status is not 200. exiting...' ); return 'Failed to send instantiate Proposal or receive valid response. Response null or status is not 200. exiting...'; } }, (err) => { logger.error('Failed to send instantiate proposal due to error: ' + err.stack ? err.stack : err); return 'Failed to send instantiate proposal due to error: ' + err.stack ? err.stack : err; }).then((response) => { // 8 处理第六步返回的结果 if (response.status === 'SUCCESS') { logger.info('Successfully sent transaction to the orderer.'); return 'Chaincode Instantiation is SUCCESS'; } else { logger.error('Failed to order the transaction. Error code: ' + response.status); return 'Failed to order the transaction. Error code: ' + response.status; } }, (err) => { logger.error('Failed to send instantiate due to error: ' + err.stack ? err .stack : err); return 'Failed to send instantiate due to error: ' + err.stack ? err.stack : err; });};exports.instantiateChaincode = instantiateChaincode;
基本流程
API访问
echo "POST instantiate chaincode on peer1 of Org1"echocurl -s -X POST \ http://localhost:4000/channels/mychannel/chaincodes \ -H "authorization: Bearer $ORG1_TOKEN" \ -H "content-type: application/json" \ -d '{ "chaincodeName":"mycc", "chaincodeVersion":"v0", "args":["a","100","b","200"]}'echoecho
控制台打印:
POST instantiate chaincode on peer1 of Org1Chaincode Instantiation is SUCCESS
后台打印:
[2017-10-16 11:07:12.477] [DEBUG] SampleWebApp - Decoded from JWT token: username - Jim, orgname - org1[2017-10-16 11:07:12.477] [DEBUG] SampleWebApp - ==================== INSTANTIATE CHAINCODE ==================// 后台获取到的参数[2017-10-16 11:07:12.477] [DEBUG] SampleWebApp - channelName : mychannel[2017-10-16 11:07:12.477] [DEBUG] SampleWebApp - chaincodeName : mycc[2017-10-16 11:07:12.477] [DEBUG] SampleWebApp - chaincodeVersion : v0[2017-10-16 11:07:12.477] [DEBUG] SampleWebApp - fcn : undefined[2017-10-16 11:07:12.478] [DEBUG] SampleWebApp - args : a,100,b,200[2017-10-16 11:07:12.478] [DEBUG] instantiate-chaincode - ============ Instantiate chaincode on organization org1 ============[2017-10-16 11:07:12.478] [DEBUG] Helper - [crypto_ecdsa_aes]: constructor, keySize: 256[2017-10-16 11:07:12.478] [DEBUG] Helper - [crypto_ecdsa_aes]: Hash algorithm: SHA2, hash output size: 256[2017-10-16 11:07:12.479] [DEBUG] Helper - [utils.CryptoKeyStore]: CryptoKeyStore, constructor - start[2017-10-16 11:07:12.479] [DEBUG] Helper - [utils.CryptoKeyStore]: constructor, no super class specified, using config: fabric-client/lib/impl/FileKeyValueStore.js[2017-10-16 11:07:12.479] [DEBUG] Helper - [FileKeyValueStore.js]: FileKeyValueStore.js - constructor[2017-10-16 11:07:12.482] [DEBUG] Helper - Msp ID : Org1MSP[2017-10-16 11:07:12.482] [DEBUG] Helper - [crypto_ecdsa_aes]: importKey - start[2017-10-16 11:07:12.483] [DEBUG] Helper - [crypto_ecdsa_aes]: importKey - have the key [Circular][2017-10-16 11:07:12.484] [DEBUG] Helper - [utils.CryptoKeyStore]: This class requires a CryptoKeyStore to save keys, using the store: {"opts":{"path":"/tmp/fabric-client-kvs_peerOrg1"}}[2017-10-16 11:07:12.484] [DEBUG] Helper - [FileKeyValueStore.js]: FileKeyValueStore.js - constructor[2017-10-16 11:07:12.485] [DEBUG] Helper - [utils.CryptoKeyStore]: _getKeyStore returning ks[2017-10-16 11:07:12.485] [DEBUG] Helper - [ecdsa/key.js]: ECDSA curve param X: 0a66f3503a3322b2ca8e9dce03322d486ee6ec5970efaad3f153bc13aa2d942c[2017-10-16 11:07:12.485] [DEBUG] Helper - [ecdsa/key.js]: ECDSA curve param Y: 312ad05190fa592fb9e8ac2dcdb23c84df7f49e4ee295c2aa1200a50c9146c46[2017-10-16 11:07:12.488] [DEBUG] Helper - [FileKeyValueStore.js]: FileKeyValueStore -- setValue[2017-10-16 11:07:12.488] [DEBUG] Helper - [crypto_ecdsa_aes]: importKey - start[2017-10-16 11:07:12.488] [DEBUG] Helper - [crypto_ecdsa_aes]: importKey - have the key [Circular][2017-10-16 11:07:12.489] [DEBUG] Helper - [utils.CryptoKeyStore]: _getKeyStore resolving store[2017-10-16 11:07:12.489] [DEBUG] Helper - [ecdsa/key.js]: ECDSA curve param X: 0a66f3503a3322b2ca8e9dce03322d486ee6ec5970efaad3f153bc13aa2d942c[2017-10-16 11:07:12.489] [DEBUG] Helper - [ecdsa/key.js]: ECDSA curve param Y: 312ad05190fa592fb9e8ac2dcdb23c84df7f49e4ee295c2aa1200a50c9146c46[2017-10-16 11:07:12.489] [DEBUG] Helper - [FileKeyValueStore.js]: FileKeyValueStore -- setValue[2017-10-16 11:07:12.490] [DEBUG] Helper - [ecdsa/key.js]: ECDSA curve param X: 0a66f3503a3322b2ca8e9dce03322d486ee6ec5970efaad3f153bc13aa2d942c[2017-10-16 11:07:12.490] [DEBUG] Helper - [ecdsa/key.js]: ECDSA curve param Y: 312ad05190fa592fb9e8ac2dcdb23c84df7f49e4ee295c2aa1200a50c9146c46[2017-10-16 11:07:12.490] [DEBUG] Helper - [ecdsa/key.js]: ECDSA curve param X: 0a66f3503a3322b2ca8e9dce03322d486ee6ec5970efaad3f153bc13aa2d942c[2017-10-16 11:07:12.491] [DEBUG] Helper - [ecdsa/key.js]: ECDSA curve param Y: 312ad05190fa592fb9e8ac2dcdb23c84df7f49e4ee295c2aa1200a50c9146c46[2017-10-16 11:07:12.491] [DEBUG] Helper - [ecdsa/key.js]: ECDSA curve param X: 0a66f3503a3322b2ca8e9dce03322d486ee6ec5970efaad3f153bc13aa2d942c[2017-10-16 11:07:12.491] [DEBUG] Helper - [ecdsa/key.js]: ECDSA curve param Y: 312ad05190fa592fb9e8ac2dcdb23c84df7f49e4ee295c2aa1200a50c9146c46[2017-10-16 11:07:12.491] [DEBUG] Helper - [FileKeyValueStore.js]: FileKeyValueStore -- setValue[2017-10-16 11:07:12.498] [DEBUG] Helper - [crypto_ecdsa_aes]: ecdsa signature: Signature { r: <BN: 543af07c0785003b0f406545e1ff7bc72dbdb78b9180719cb164d0230d35bd0b>, s: <BN: 4d14477dcb169248fa51fab7721c4c54d34bdf3e24de19a93b63cc2de74eec27>, recoveryParam: 1 }[2017-10-16 11:07:12.510] [DEBUG] Helper - [crypto_ecdsa_aes]: ecdsa signature: Signature { r: <BN: 5d56b83f757abe7e261a11e2dd737a03397b610c9ec66df6f2f617cb4bd118f7>, s: <BN: 417d31cdb264150f32b8d7781d7c70e2d428064ab2b02057db2d68f653d98cc8>, recoveryParam: 0 }[2017-10-16 11:07:12.520] [DEBUG] Helper - [crypto_ecdsa_aes]: constructor, keySize: 256[2017-10-16 11:07:12.521] [DEBUG] Helper - [crypto_ecdsa_aes]: Hash algorithm: SHA2, hash output size: 256[2017-10-16 11:07:12.521] [DEBUG] Helper - [utils.CryptoKeyStore]: CryptoKeyStore, constructor - start[2017-10-16 11:07:12.521] [DEBUG] Helper - [utils.CryptoKeyStore]: constructor, no super class specified, using config: fabric-client/lib/impl/FileKeyValueStore.js[2017-10-16 11:07:12.522] [DEBUG] Helper - [crypto_ecdsa_aes]: constructor, keySize: 256[2017-10-16 11:07:12.522] [DEBUG] Helper - [crypto_ecdsa_aes]: Hash algorithm: SHA2, hash output size: 256[2017-10-16 11:07:12.522] [DEBUG] Helper - [utils.CryptoKeyStore]: CryptoKeyStore, constructor - start[2017-10-16 11:07:12.522] [DEBUG] Helper - [utils.CryptoKeyStore]: constructor, no super class specified, using config: fabric-client/lib/impl/FileKeyValueStore.js[2017-10-16 11:07:12.530] [DEBUG] Helper - [crypto_ecdsa_aes]: ecdsa signature: Signature { r: <BN: 26309898c764726afae02fc8db2d9a90940ef1e01ee4ef29a5fb499c3b8a7ea>, s: <BN: 3741f21b4bb248ef180260f9f171e3d9ed0e870b1c850032ccee86d127085e32>, recoveryParam: 1 }[2017-10-16 11:07:38.630] [INFO] instantiate-chaincode - instantiate proposal was good[2017-10-16 11:07:38.630] [INFO] instantiate-chaincode - instantiate proposal was good// 发送交易提案成功 并且相应ok[2017-10-16 11:07:38.630] [INFO] instantiate-chaincode - Successfully sent Proposal and received ProposalResponse: Status - 200, message - "OK", metadata - "myccv0escc"vscc*(Org1MSPOrg2MSP2D �����ϧ�i?v��OCjˢ��"���Hq���Gb *PI�w�jL5x6^�E=�)ˡF�� ��C55: ���ԣV��k����ر��� >z!F�P"�+I�B,Org1MSPb�4��SP", endorsement signature: 0D 5�/Ց��%SׂU��r��kWڳd;[c� #�Τ��1@p/�\h1�C�?�'w,��܅info: [EventHub.js]: _connect - options {"grpc.ssl_target_name_override":"peer0.org1.example.com","grpc.default_authority":"peer0.org1.example.com"}[2017-10-16 11:07:38.642] [DEBUG] Helper - [crypto_ecdsa_aes]: ecdsa signature: Signature { r: <BN: e1cdeef11d37de28810bed04d525abf4ed4959899f64e7129483110b07d9ef50>, s: <BN: 65720ba0dfcdb959cce0a3d69b016097c7895aab1891172ded659aece90d467e>, recoveryParam: 1 }[2017-10-16 11:07:38.647] [DEBUG] Helper - [crypto_ecdsa_aes]: ecdsa signature: Signature { r: <BN: cd796d1905d53fc6619f2a8d3d597d8e45de7264b0be0324447846510bf5af37>, s: <BN: 5f8efb833b37d2d7a141a952b482933a9b9ba6653c39020a29e2dff59d6fe46>, recoveryParam: 0 }[2017-10-16 11:07:40.802] [INFO] instantiate-chaincode - The chaincode instantiate transaction has been committed on peer localhost:7053[2017-10-16 11:07:40.808] [DEBUG] Helper - [crypto_ecdsa_aes]: ecdsa signature: Signature { r: <BN: ab6a1ea9d36c8cabc53cad8cfdf545dc0f7e7751bf43979552bb980f7fcb4b7e>, s: <BN: 1839adef53808d6e3ffba1f40495827cc6b4fa047d2c03dfe9ab76933581d35b>, recoveryParam: 1 }// 交易 有效 ok[2017-10-16 11:07:40.809] [INFO] instantiate-chaincode - The chaincode instantiate transaction was valid.[2017-10-16 11:07:40.809] [DEBUG] instantiate-chaincode - Event promise all complete and testing complete[2017-10-16 11:07:40.809] [INFO] instantiate-chaincode - Successfully sent transaction to the orderer.
阅读全文
0 0
- Hyperledger Fabric SDK 示例fabric-samples-《balance-transfer》之五《初始化chaincode》
- Hyperledger Fabric SDK 示例fabric-samples-《balance-transfer》之四《安装chaincode》
- Hyperledger Fabric SDK 示例fabric-samples-《balance-transfer》之六《执行chaincode》
- Hyperledger Fabric SDK 示例fabric-samples-《balance-transfer》之七《查询chaincode》
- Hyperledger Fabric SDK 示例 fabric-samples-《balance-transfer》之简介
- Hyperledger Fabric SDK 示例fabric-samples-《balance-transfer》之十一《查询已经安装/实例化的chaincode》
- Hyperledger Fabric SDK 示例fabric-samples-《balance-transfer》之二《创建Channel》
- Hyperledger Fabric SDK 示例fabric-samples-《balance-transfer》之三《加入到Channel》
- Hyperledger Fabric SDK 示例fabric-samples-《balance-transfer》之八《查询指定的区块信息》
- Hyperledger Fabric SDK 示例fabric-samples-《balance-transfer》之九《查询指定的交易信息》
- Hyperledger Fabric SDK 示例fabric-samples-《balance-transfer》之十《查询链信息》
- Hyperledger Fabric SDK 示例fabric-samples-《balance-transfer》之十二《查询已经加入的channel名称》
- Hyperledger Fabric SDK 示例fabric-samples-《balance-transfer》之一《注册用户》
- hyperledger fabric chaincode开发示例
- Hyperledger Fabric Chaincode 开发
- Hyperledger Fabric SDK
- HyperLedger Fabric的Java Chaincode配置
- 使用 Cloudsoft AMP 部署 Hyperledger fabric App & Validating Peers & Chaincode
- 深度学习基础篇:如何选择正确的激活函数?
- invalidate、postInvalidate的区别
- 函数声明和函数表达式
- Unity2D:Sprite和UI Image的区别
- 原生JS添加类名 删除类名
- Hyperledger Fabric SDK 示例fabric-samples-《balance-transfer》之五《初始化chaincode》
- iOS 11 SDK新特性
- SLAM相关概念及ORB算法步骤总结
- SparseArray浅析
- jsp实现页面分页。
- java.lang.NoClassDefFoundError: org/quartz/JobDetail
- IDEA远程Debug
- 薪水支付案例(1)
- Spring boot中出现JDK dynamic proxy使用@Resource注入实例出现问题