fabric_node_sdk的编写与运行

前言

这两周主要学习了一下如何用nodejs搭建hyperledger fabric的sdk。

fabric_node_sdk环境搭建

更新npm镜像源

1
npm config set registry https://registry.npm.taobao.org

查看npm镜像源

1
npm config get registry

成功则返回https://registry.npm.taobao.org

下载fabric_node_sdk的最新版本

1
2
cd ~/go/src/github.com/hyperledger/fabric
git clone -b release-1.4 https://github.com/hyperledger/fabric-sdk-node.git

根据package.json安装依赖

1
2
3
4
5
6
7
8
cd ~/go/src/github.com/hyperledger/fabric/fabric-sdk-node
cd fabric-common && npm install && cd ..
cd fabric-ca-client && npm install && cd ..
cd fabric-client && npm install && cd ..
cd fabric-network && npm install && cd ..

cd ~/go/src/github.com/hyperledger/fabric/fabric-sdk-node
npm install

这个过程有可能出错,一般的警告可以忽略。提示需要且未安装的包可自行安装

1
npm install <pacakge>@[version] --save

–save参数是将该包加入package.json的dependencies中。

nodejs脚本编写及运行

1
cd ~/go/src/github.com/hyperledger/fabric/checkinsystem/node_sdk

结构如下

1
2
3
4
5
6
7
8
node_sdk
   ├── connprofile.json
   ├── enrollAdmin.js
   ├── invoke.js
   ├── package.json
  ├── query.js
   ├── registerUser.js
   └── wallet

package.json主要依赖包如下

1
2
3
4
5
6
7
8
9
10
11
12
"dependencies": {
"fabric-ca-client": "~1.4.0",
"fabric-network": "~1.4.0"
},
"devDependencies": {
"chai": "^4.2.0",
"eslint": "^5.9.0",
"mocha": "^5.2.0",
"nyc": "^13.1.0",
"sinon": "^7.1.1",
"sinon-chai": "^3.3.0"
},

安装好相关依赖

1
npm install

查看org1中有哪些用户

有Admin和User1两个用户,下面来创建这两个用相关的sdk。

enrollAdmin.js编写,创建admin

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
/*
* SPDX-License-Identifier: Apache-2.0
*/

'use strict';

const FabricCAServices = require('fabric-ca-client');
const { FileSystemWallet, X509WalletMixin } = require('fabric-network');
const fs = require('fs');
const path = require('path');

async function main() {
try {

// Create a new CA client for interacting with the CA.
const keyPath = path.join(__dirname, "../../fabric-samples/first-network/crypto-config/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp/keystore/5ff3716b887dd7c97b8276eab73bebc95cd1119625110ea0984cc8d559ed16a2_sk");
const keyPEM = Buffer.from(fs.readFileSync(keyPath)).toString();
const certPath = path.join(__dirname, "../../fabric-samples/first-network/crypto-config/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp/signcerts/Admin@org1.example.com-cert.pem");
const certPEM = Buffer.from(fs.readFileSync(certPath)).toString();

// Create a new file system based wallet for managing identities.
const walletPath = path.join(process.cwd(), 'wallet');
const wallet = new FileSystemWallet(walletPath);
console.log(`Wallet path: ${walletPath}`);

// Check to see if we've already enrolled the admin user.
const adminExists = await wallet.exists('admin');
if (adminExists) {
console.log('An identity for the admin user "admin" already exists in the wallet');
return;
}

// Enroll the admin user, and import the new identity into the wallet.
const identity = X509WalletMixin.createIdentity('Org1MSP', certPEM, keyPEM);
wallet.import('admin', identity);
console.log('Successfully enrolled admin user "admin" and imported it into the wallet');

} catch (error) {
console.error(`Failed to enroll admin user "admin": ${error}`);
process.exit(1);
}
}

main();

其中keyPath中的文件要换成自己环境下的文件,运行

1
node enroll.js

registerUser.js编写,注册user1用户

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
/*
* SPDX-License-Identifier: Apache-2.0
*/

'use strict';

const { FileSystemWallet, Gateway, X509WalletMixin } = require('fabric-network');
const fs = require('fs');
const path = require('path');

async function main() {
try {
const keyPath = path.join(__dirname, "../../fabric-samples/first-network/crypto-config/peerOrganizations/org1.example.com/users/User1@org1.example.com/msp/keystore/cc111873571e461c95bce39dfe59af3bb17d4600643753dca9ff4fd84409c9d1_sk");
const keyPEM = Buffer.from(fs.readFileSync(keyPath)).toString();
const certPath = path.join(__dirname, "../../fabric-samples/first-network/crypto-config/peerOrganizations/org1.example.com/users/User1@org1.example.com/msp/signcerts/User1@org1.example.com-cert.pem");
const certPEM = Buffer.from(fs.readFileSync(certPath)).toString();
// Create a new file system based wallet for managing identities.
const walletPath = path.join(process.cwd(), 'wallet');
const wallet = new FileSystemWallet(walletPath);
console.log(`Wallet path: ${walletPath}`);

// Check to see if we've already enrolled the user.
const userExists = await wallet.exists('user1');
if (userExists) {
console.log('An identity for the user "user1" already exists in the wallet');
return;
}

// Check to see if we've already enrolled the admin user.
const adminExists = await wallet.exists('admin');
if (!adminExists) {
console.log('An identity for the admin user "admin" does not exist in the wallet');
console.log('Run the enrollAdmin.js application before retrying');
return;
}

// Create a new gateway for connecting to our peer node.
const gateway = new Gateway();
await gateway.connect(path.join(__dirname, './connprofile.json'),
{
wallet: wallet,
identity: 'admin'
});


// Register the user, enroll the user, and import the new identity into the wallet.

const userIdentity = X509WalletMixin.createIdentity('Org1MSP', certPEM, keyPEM);
wallet.import('user1', userIdentity);
console.log('Successfully registered and enrolled admin user "user1" and imported it into the wallet');

} catch (error) {
console.error(`Failed to register user "user1": ${error}`);
process.exit(1);
}
}

main();

然后实现invoke和query相关的SDK

invoke.js编写,用来增删改操作

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
/*
* SPDX-License-Identifier: Apache-2.0
*/

'use strict';

const { FileSystemWallet, Gateway } = require('fabric-network');
const fs = require('fs');
const path = require('path');

async function main() {
try {

// Create a new file system based wallet for managing identities.
const walletPath = path.join(process.cwd(), 'wallet');
const wallet = new FileSystemWallet(walletPath);
console.log(`Wallet path: ${walletPath}`);

// Check to see if we've already enrolled the user.
const userExists = await wallet.exists('user1');
if (!userExists) {
console.log('An identity for the user "user1" does not exist in the wallet');
console.log('Run the registerUser.js application before retrying');
return;
}

// Create a new gateway for connecting to our peer node.
const gateway = new Gateway();
await gateway.connect(path.join(__dirname, './connprofile.json'), { wallet, identity: 'user1', discovery: { enabled: false } });

// Get the network (channel) our contract is deployed to.
const network = await gateway.getNetwork('mychannel');

// Get the contract from the network.
const contract = network.getContract('checkinsystem');

// Submit the specified transaction.
// createCar transaction - requires 5 argument, ex: ('createCar', 'CAR12', 'Honda', 'Accord', 'Black', 'Tom')
// changeCarOwner transaction - requires 2 args , ex: ('changeCarOwner', 'CAR10', 'Dave')
await contract.submitTransaction('create', "ACCOUNT2","0001","0002","0003","0004","420222199804295996","123456","kangel","10","11","12","0");
console.log('Transaction has been submitted');

// Disconnect from the gateway.
await gateway.disconnect();

} catch (error) {
console.error(`Failed to submit transaction: ${error}`);
process.exit(1);
}
}

main();

运行结果

查看couchdb

query.js编写,用来进行查询操作

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
/*
* SPDX-License-Identifier: Apache-2.0
*/

'use strict';

const { FileSystemWallet, Gateway } = require('fabric-network');
const fs = require('fs');
const path = require('path');

async function main() {
try {

// Create a new file system based wallet for managing identities.
const walletPath = path.join(process.cwd(), 'wallet');
const wallet = new FileSystemWallet(walletPath);
console.log(`Wallet path: ${walletPath}`);

// Check to see if we've already enrolled the user.
const userExists = await wallet.exists('user1');
if (!userExists) {
console.log('An identity for the user "user1" does not exist in the wallet');
console.log('Run the registerUser.js application before retrying');
return;
}

// Create a new gateway for connecting to our peer node.
const gateway = new Gateway();
await gateway.connect(path.join(__dirname, './connprofile.json'), { wallet, identity: 'user1', discovery: { enabled: false } });

// Get the network (channel) our contract is deployed to.
const network = await gateway.getNetwork('mychannel');

// Get the contract from the network.
const contract = network.getContract('checkinsystem');

// Evaluate the specified transaction.
const result = await contract.evaluateTransaction('query','ACCOUNT0');
console.log(`Transaction has been evaluated, result is: ${result.toString()}`);

} catch (error) {
console.error(`Failed to evaluate transaction: ${error}`);
process.exit(1);
}
}

main();

运行结果

-------------本文结束感谢您的阅读-------------