美文网首页
使用fabric-sdk-node的示例1

使用fabric-sdk-node的示例1

作者: 链播学院 | 来源:发表于2019-03-22 16:09 被阅读0次

    0 导言

    fabric-sdk-node也是分两种写法,一种是底层写法,一种是比较高层的写法。下面先演示比较底层的写法。

    本文档演示了一个汽车资产管理的例子,官方提供相应的链码和客户端示例代码。

    1 创建项目目录

    注:如果已经有该目录则不需 创建了

    $ cd $GOPATH/src/github.com
    $ mkdir -p fabric-study/sdk-node-study1
    

    注:如果上述mkdir 不能执行,可能是没有权限,加上sudo就可以了

    $ sudo mkdir -p fabric-study/sdk-node-study1
    

    2 搭建运行网络

    我们不另行去搭建节点网络了,直接拷贝官网提供的basic-network过来用,执行cp命令进行拷贝.

    $ cd fabric-study/sdk-node-study1/
    $ cp -r ../../hyperledger/fabric-samples/basic-network ./
    

    basic-network会创建如下节点

    序号 组织 IP 域名 端口映射 节点
    docker 容器1 172.18.0.6 orderer.example.com 0.0.0.0:9051->7051/tcp, 0.0.0.0:9053->7053/tcp orderer节点
    docker 容器2 组织1 - org1 172.18.0.7 peer0.org1.example.com 0.0.0.0:10051->7051/tcp, 0.0.0.0:10053->7053/tcp peer1节点
    docker 容器3 172.18.0.6 cli客户端
    docker 容器4 172.18.0.6 couchDB服务器
    docker 容器5 172.18.0.6 ca服务器

    3 创建链码放置目录

    在这里我们不打算自己编写链码了,直接使用官方提供的fabcar示例的链码,如若对该链码不了解,可通过阅读该链码的源码来熟悉它

    $ mkdir chaincode
    $ cp -r ../../hyperledger/fabric-samples/chaincode/fabcar ./chaincode
    

    4 创建app1目录

    $ mkdir app1
    

    5 用vscode打开sdk-node-study1

    Snipaste_2019-03-22_16-10-02.png

    6 在app1下创建package.json

    内容如下

    {
        "name": "fabcar",
        "version": "1.0.0",
        "description": "Hyperledger Fabric Car Sample Application",
        "main": "fabcar.js",
        "scripts": {
            "test": "echo \"Error: no test specified\" && exit 1"
        },
        "dependencies": {
            "fabric-ca-client": "~1.4.0",
            "fabric-client": "~1.4.0",
            "grpc": "^1.6.0"
        },
        "author": "Anthony O'Dowd",
        "license": "Apache-2.0",
        "keywords": [
            "Hyperledger",
            "Fabric",
            "Car",
            "Sample",
            "Application"
        ]
    }
    

    7 创建enrollAdmin.js

    该js脚本用来向ca-服务器注册管理员

    'use strict';
    
    
     // 注册管理员用户
    
    
    var Fabric_Client = require('fabric-client');
    var Fabric_CA_Client = require('fabric-ca-client');
    
    var path = require('path');
    var util = require('util');
    var os = require('os');
    
    
    var fabric_client = new Fabric_Client();
    var fabric_ca_client = null;
    var admin_user = null;
    var member_user = null;
    var store_path = path.join(__dirname, 'hfc-key-store');
    console.log(' Store path:'+store_path);
    
    
    Fabric_Client.newDefaultKeyValueStore({ path: store_path
    }).then((state_store) => {
    
        fabric_client.setStateStore(state_store);
        var crypto_suite = Fabric_Client.newCryptoSuite();
    
    
        var crypto_store = Fabric_Client.newCryptoKeyStore({path: store_path});
        crypto_suite.setCryptoKeyStore(crypto_store);
        fabric_client.setCryptoSuite(crypto_suite);
        var tlsOptions = {
            trustedRoots: [],
            verify: false
        };
    
        fabric_ca_client = new Fabric_CA_Client('http://localhost:7054', tlsOptions , 'ca.example.com', crypto_suite);
    
    
        return fabric_client.getUserContext('admin', true);
    }).then((user_from_store) => {
        if (user_from_store && user_from_store.isEnrolled()) {
            console.log('Successfully loaded admin from persistence');
            admin_user = user_from_store;
            return null;
        } else {
    
            return fabric_ca_client.enroll({
              enrollmentID: 'admin',
              enrollmentSecret: 'adminpw'
            }).then((enrollment) => {
              console.log('Successfully enrolled admin user "admin"');
              return fabric_client.createUser(
                  {username: 'admin',
                      mspid: 'Org1MSP',
                      cryptoContent: { privateKeyPEM: enrollment.key.toBytes(), signedCertPEM: enrollment.certificate }
                  });
            }).then((user) => {
              admin_user = user;
              return fabric_client.setUserContext(admin_user);
            }).catch((err) => {
              console.error('Failed to enroll and persist admin. Error: ' + err.stack ? err.stack : err);
              throw new Error('Failed to enroll admin');
            });
        }
    }).then(() => {
        console.log('Assigned the admin user to the fabric client ::' + admin_user.toString());
    }).catch((err) => {
        console.error('Failed to enroll admin: ' + err);
    });
    

    8 创建registerUser.js

    该js脚本用来向fabric-ca服务器注册普通用户

    
     //注册普通用户
    
    var Fabric_Client = require('fabric-client');
    var Fabric_CA_Client = require('fabric-ca-client');
    
    var path = require('path');
    var util = require('util');
    var os = require('os');
    
    
    var fabric_client = new Fabric_Client();
    var fabric_ca_client = null;
    var admin_user = null;
    var member_user = null;
    var store_path = path.join(__dirname, 'hfc-key-store');
    console.log(' Store path:'+store_path);
    
    
    Fabric_Client.newDefaultKeyValueStore({ path: store_path
    }).then((state_store) => {
    
        fabric_client.setStateStore(state_store);
        var crypto_suite = Fabric_Client.newCryptoSuite();
    
    
        var crypto_store = Fabric_Client.newCryptoKeyStore({path: store_path});
        crypto_suite.setCryptoKeyStore(crypto_store);
        fabric_client.setCryptoSuite(crypto_suite);
        var tlsOptions = {
            trustedRoots: [],
            verify: false
        };
    
        fabric_ca_client = new Fabric_CA_Client('http://localhost:7054', null , '', crypto_suite);
    
    
        return fabric_client.getUserContext('admin', true);
    }).then((user_from_store) => {
        if (user_from_store && user_from_store.isEnrolled()) {
            console.log('Successfully loaded admin from persistence');
            admin_user = user_from_store;
        } else {
            throw new Error('Failed to get admin.... run enrollAdmin.js');
        }
    
    
    
        return fabric_ca_client.register({enrollmentID: 'user1', affiliation: 'org1.department1',role: 'client'}, admin_user);
    }).then((secret) => {
    
        console.log('Successfully registered user1 - secret:'+ secret);
    
        return fabric_ca_client.enroll({enrollmentID: 'user1', enrollmentSecret: secret});
    }).then((enrollment) => {
      console.log('Successfully enrolled member user "user1" ');
      return fabric_client.createUser(
         {username: 'user1',
         mspid: 'Org1MSP',
         cryptoContent: { privateKeyPEM: enrollment.key.toBytes(), signedCertPEM: enrollment.certificate }
         });
    }).then((user) => {
         member_user = user;
    
         return fabric_client.setUserContext(member_user);
    }).then(()=>{
         console.log('User1 was successfully registered and enrolled and is ready to interact with the fabric network');
    
    }).catch((err) => {
        console.error('Failed to register: ' + err);
        if(err.toString().indexOf('Authorization') > -1) {
            console.error('Authorization failures may be caused by having admin credentials from a previous CA instance.\n' +
            'Try again after deleting the contents of the store directory '+store_path);
        }
    });
    

    9 创建query.js

    该js脚本用来查询汽车信息

    'use strict';
    
    
     //通过链码查询
    
    var Fabric_Client = require('fabric-client');
    var path = require('path');
    var util = require('util');
    var os = require('os');
    
    
    var fabric_client = new Fabric_Client();
    
    
    var channel = fabric_client.newChannel('mychannel');
    var peer = fabric_client.newPeer('grpc://localhost:7051');
    channel.addPeer(peer);
    
    
    var member_user = null;
    var store_path = path.join(__dirname, 'hfc-key-store');
    console.log('Store path:'+store_path);
    var tx_id = null;
    
    
    Fabric_Client.newDefaultKeyValueStore({ path: store_path
    }).then((state_store) => {
    
        fabric_client.setStateStore(state_store);
        var crypto_suite = Fabric_Client.newCryptoSuite();
    
    
        var crypto_store = Fabric_Client.newCryptoKeyStore({path: store_path});
        crypto_suite.setCryptoKeyStore(crypto_store);
        fabric_client.setCryptoSuite(crypto_suite);
    
    
        return fabric_client.getUserContext('user1', true);
    }).then((user_from_store) => {
        if (user_from_store && user_from_store.isEnrolled()) {
            console.log('Successfully loaded user1 from persistence');
            member_user = user_from_store;
        } else {
            throw new Error('Failed to get user1.... run registerUser.js');
        }
    
    
    
        const request = {
    
            chaincodeId: 'fabcar',
            fcn: 'queryAllCars',
            args: ['']
        };
    
    
        return channel.queryByChaincode(request);
    }).then((query_responses) => {
        console.log("Query has completed, checking results");
    
        if (query_responses && query_responses.length == 1) {
            if (query_responses[0] instanceof Error) {
                console.error("error from query = ", query_responses[0]);
            } else {
                console.log("Response is ", query_responses[0].toString());
            }
        } else {
            console.log("No payloads were returned from query");
        }
    }).catch((err) => {
        console.error('Failed to query successfully :: ' + err);
    });
    

    10 创建invoke.js

    该js脚本做invoke调用

    'use strict';
    //调用链码
    var Fabric_Client = require('fabric-client');
    var path = require('path');
    var util = require('util');
    var os = require('os');
    var fabric_client = new Fabric_Client();
    var channel = fabric_client.newChannel('mychannel');
    var peer = fabric_client.newPeer('grpc://localhost:7051');
    channel.addPeer(peer);
    var order = fabric_client.newOrderer('grpc://localhost:7050')
    channel.addOrderer(order);
    var member_user = null;
    var store_path = path.join(__dirname, 'hfc-key-store');
    console.log('Store path:' + store_path);
    var tx_id = null;
    Fabric_Client.newDefaultKeyValueStore({
        path: store_path
    }).then((state_store) => {
        fabric_client.setStateStore(state_store);
        var crypto_suite = Fabric_Client.newCryptoSuite();
        var crypto_store = Fabric_Client.newCryptoKeyStore({ path: store_path });
        crypto_suite.setCryptoKeyStore(crypto_store);
        fabric_client.setCryptoSuite(crypto_suite);
        return fabric_client.getUserContext('user1', true);
    }).then((user_from_store) => {
        if (user_from_store && user_from_store.isEnrolled()) {
            console.log('Successfully loaded user1 from persistence');
            member_user = user_from_store;
        } else {
            throw new Error('Failed to get user1.... run registerUser.js');
        }
        tx_id = fabric_client.newTransactionID();
        console.log("Assigning transaction_id: ", tx_id._transaction_id);
        var request = {
            chaincodeId: 'fabcar',
            fcn: 'createCar',
            args: ['CAR12', 'Honda', 'Accord', 'Black', 'Tom'],
            chainId: 'mychannel',
            txId: tx_id
        };
        return channel.sendTransactionProposal(request);
    }).then((results) => {
        var proposalResponses = results[0];
        var proposal = results[1];
        let isProposalGood = false;
        if (proposalResponses && proposalResponses[0].response &&
            proposalResponses[0].response.status === 200) {
            isProposalGood = true;
            console.log('Transaction proposal was good');
        } else {
            console.error('Transaction proposal was bad');
        }
        if (isProposalGood) {
            console.log(util.format(
                'Successfully sent Proposal and received ProposalResponse: Status - %s, message - "%s"',
                proposalResponses[0].response.status, proposalResponses[0].response.message));
            var request = {
                proposalResponses: proposalResponses,
                proposal: proposal
            };
            var transaction_id_string = tx_id.getTransactionID();
            var promises = []; var sendPromise = channel.sendTransaction(request);
            promises.push(sendPromise);
            let txPromise = new Promise((resolve, reject) => {
                let handle = setTimeout(() => {
                    event_hub.unregisterTxEvent(transaction_id_string);
                    event_hub.disconnect();
                    resolve({ event_status: 'TIMEOUT' });
                }, 3000);
                event_hub.registerTxEvent(transaction_id_string, (tx, code) => {
                    clearTimeout(handle);
                    var return_status = { event_status: code, tx_id: transaction_id_string };
                    if (code !== 'VALID') {
                        console.error('The transaction was invalid, code = ' + code);
                        resolve(return_status);
                    } else {
                        console.log('The transaction has been committed on peer ' + event_hub.getPeerAddr());
                        resolve(return_status);
                    }
                }, (err) => {
                    reject(new Error('There was a problem with the eventhub ::' + err));
                },
                    { disconnect: true }
                );
                event_hub.connect();
            });
            promises.push(txPromise); return Promise.all(promises);
        } else {
            console.error('Failed to send Proposal or receive valid response. Response null or status is not 200. exiting...');
            throw new Error('Failed to send Proposal or receive valid response. Response null or status is not 200. exiting...');
        }
    }).then((results) => {
        console.log('Send transaction promise and event listener promise have completed'); if (results && results[0] && results[0].status === 'SUCCESS') {
            console.log('Successfully sent transaction to the orderer.');
        } else {
            console.error('Failed to order the transaction. Error code: ' + results[0].status);
        } if (results && results[1] && results[1].event_status === 'VALID') {
            console.log('Successfully committed the change to the ledger by the peer');
        } else {
            console.log('Transaction failed to be committed to the ledger due to ::' + results[1].event_status);
        }
    }).catch((err) => {
        console.error('Failed to invoke successfully :: ' + err);
    });
    

    11 启动网络

    生成证书(注,只需要执行一次就ok了,以后都不用执行这一步了

    $ ./generate.sh
    

    先停止到旧的网络

    
    $ docker stop -f $(docker ps -aq)
    $ docker rm -f $(docker ps -aq)
    $ docker rmi -f $(docker images | grep fabcar | awk '{print $3}')
    

    然后启动网络,该脚本只启动了ca、orderer、peer、couchDb这几个容器,没有启动cli容器。并且创建名字为mychannel的通道,随后还让peer0.Org1加入了该通道

    $ rm -rf ./hfc-key-store
    $ cd basic-network
    $ ./start.sh
    

    12 启动cli容器

    $ docker-compose -f ./docker-compose.yml up -d cli
    

    13 安装和实例化链码

    打开一个新的终端,不用进入cli容器,可以在外边执行,用-exec表示在外边执行

    安装链码

    $ docker exec -e "CORE_PEER_LOCALMSPID=Org1MSP" -e "CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp" cli peer chaincode install -n fabcar -v 1.0 -p github.com/fabcar/go -l golang
    

    实例化链码

    $ docker exec -e "CORE_PEER_LOCALMSPID=Org1MSP" -e "CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp" cli peer chaincode instantiate -o orderer.example.com:7050 -C mychannel -n fabcar -l golang -v 1.0 -c '{"Args":[]}' -P "OR ('Org1MSP.member','Org2MSP.member')"
    
    

    调用initLedger函数初始化账本

    $ docker exec -e "CORE_PEER_LOCALMSPID=Org1MSP" -e "CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp" cli peer chaincode invoke -o orderer.example.com:7050 -C mychannel -n fabcar -c '{"function":"initLedger","Args":[]}'
    

    14 进入app1目录安装依赖

    到了这一步,证书已经生成,节点网络已经启动,链码也安装和实例化好了,接下来就来测试一下sdk的调用是否成功了。

    进入app1目录,并执行npm install安装依赖模块

    $ cd app1
    $ npm install
    

    15 注册管理员

    $ node enrollAdmin.js
    

    输出如下信息

    Store path:/home/bob/go/src/github.com/fabric-study/sdk-node-study1/app1/hfc-key-store
    Successfully enrolled admin user "admin"
    Assigned the admin user to the fabric client ::{"name":"admin","mspid":"Org1MSP","roles":null,"affiliation":"","enrollmentSecret":"","enrollment":{"signingIdentity":"607d571669d90da409ebdaec5855e3a395bbf7af5aab200cd5a902a4054c9cb0","identity":{"certificate":"-----BEGIN CERTIFICATE-----\nMIICAjCCAaigAwIBAgIUGuRlUgmDVeRPKDsf67/6fom2bvMwCgYIKoZIzj0EAwIw\nczELMAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcTDVNh\nbiBGcmFuY2lzY28xGTAXBgNVBAoTEG9yZzEuZXhhbXBsZS5jb20xHDAaBgNVBAMT\nE2NhLm9yZzEuZXhhbXBsZS5jb20wHhcNMTkwMzIyMDY0NjAwWhcNMjAwMzIxMDY1\nMTAwWjAhMQ8wDQYDVQQLEwZjbGllbnQxDjAMBgNVBAMTBWFkbWluMFkwEwYHKoZI\nzj0CAQYIKoZIzj0DAQcDQgAE4UAK/Z9BFZE7Fji6S4KTTY/2DGK6Vz0FtuhOQStE\n0rQ5PfwcbUEYFP/Z1m3Lhtvkly09eFWM+vibivprOQAbzaNsMGowDgYDVR0PAQH/\nBAQDAgeAMAwGA1UdEwEB/wQCMAAwHQYDVR0OBBYEFFja6ma5kc1yk5ax5h0Fc0zl\niI3XMCsGA1UdIwQkMCKAIEI5qg3NdtruuLoM2nAYUdFFBNMarRst3dusalc2Xkl8\nMAoGCCqGSM49BAMCA0gAMEUCIQDr6unOLXftqasK83fkthyfykHNI4Mt7y7DA+lX\ns2PyHQIgS54OqyzJ0kulh/xyHd9IkDRAM2iJPVsxCzMUP+t/C1s=\n-----END CERTIFICATE-----\n"}}}
    

    16 注册普通用户

    $ node register.js
    

    输出如下信息

     Store path:/home/bob/go/src/github.com/fabric-study/sdk-node-study1/app1/hfc-key-store
    Successfully loaded admin from persistence
    Successfully registered user1 - secret:OhvdSyIJrqqM
    Successfully enrolled member user "user1" 
    User1 was successfully registered and enrolled and is ready to interact with the fabric network
    

    17 执行查询

    $ node query.js
    

    可以看到,所有的汽车被查出来

    Query has completed, checking results
    Response is  [{"Key":"CAR0", "Record":{"colour":"blue","make":"Toyota","model":"Prius","owner":"Tomoko"}},{"Key":"CAR1", "Record":{"colour":"red","make":"Ford","model":"Mustang","owner":"Brad"}},{"Key":"CAR2", "Record":{"colour":"green","make":"Hyundai","model":"Tucson","owner":"Jin Soo"}},{"Key":"CAR3", "Record":{"colour":"yellow","make":"Volkswagen","model":"Passat","owner":"Max"}},{"Key":"CAR4", "Record":{"colour":"black","make":"Tesla","model":"S","owner":"Adriana"}},{"Key":"CAR5", "Record":{"colour":"purple","make":"Peugeot","model":"205","owner":"Michel"}},{"Key":"CAR6", "Record":{"colour":"white","make":"Chery","model":"S22L","owner":"Aarav"}},{"Key":"CAR7", "Record":{"colour":"violet","make":"Fiat","model":"Punto","owner":"Pari"}},{"Key":"CAR8", "Record":{"colour":"indigo","make":"Tata","model":"Nano","owner":"Valeria"}},{"Key":"CAR9", "Record":{"colour":"brown","make":"Holden","model":"Barina","owner":"Shotaro"}}]
    

    18 执行调用

    $ node invoke.js
    

    相关文章

      网友评论

          本文标题:使用fabric-sdk-node的示例1

          本文链接:https://www.haomeiwen.com/subject/bcdrvqtx.html