Hyperledger Fabric SDK 示例fabric-samples-《balance-transfer》之五《初始化chaincode》

本文已在我的公众号Fabric技术分享原创首发。
转载请标明出处:
https://blog.csdn.net/qq_27818541/article/details/78390354
本文出自:【BigManing的博客】

前言

初始化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 peers
app.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.2 Start 获取到admin 封装提案请求 发送提案request给背书节点 所有的背书响应是否ok 封装交易请求 发送交易 处理结果 End yes no

API访问

echo "POST instantiate chaincode on peer1 of Org1"
echo
curl -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"]
}'
echo
echo

控制台打印:


POST instantiate chaincode on peer1 of Org1

Chaincode 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*(


Org1MSP

Org2MSP2D
 �����ϧ�i?v��OCjˢ��"���Hq���Gb *PI�w�jL5x6^�E=�)ˡF��    ��C55: ���ԣV��k����ر���
                                                                               >z!F�P"�+΋I�B,


Org1MSP

b�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.

猜你喜欢

转载自blog.csdn.net/qq_27818541/article/details/78390354