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;

基本流程

Created with Raphaël 2.1.0Start 获取到admin封装提案请求发送提案request给背书节点所有的背书响应是否ok封装交易请求发送交易处理结果End yesno

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