官网上描述了Commercial Paper这个应用场景,并且提供了nodejs实现。这里补充chaincode的golang实现,保持逻辑一致,以及记录实际操作中的一些步骤和要点。实现的源码已上传github。
按照官网Commercial Paper nodejs实现里的步骤,启动
net_basic
网络,并且启动了peer0.org1.example.com
,couchdb
,ca.example.com
,orderer.example.com
,cliDigiBank
,cliMagnetoCorp
这些容器(按照步骤里执行下来,docker ps能看到这些容器)。install chaincode。执行
docker inspect cliMagnetoCorp
,能看到/Users/ckcclc/github/fabric-samples/commercial-paper/organization/magnetocorp:/opt/gopath/src/github.com
这个路径绑定。在/Users/ckcclc/github/fabric-samples/commercial-paper/organization/magnetocorp
创建目录gocontract
,将golang实现放在这个目录里。这时候登录到cliMagnetoCorp
容器,可以看到容器内/opt/gopath/src/github.com/application
下有gocontract
这个目录,并且go实现在内。1
peer chaincode install -n gopapercontract -v 0 -p github.com/gocontract
同时,
docker inspect cliMagnetoCorp
(或者cliMagnetoCorp
容器执行env
查看),GOPATH=/opt/gopath, CORE_PEER_ADDRESS=peer0.org1.example.com:7051
。install
会到${GOPATH}/src
下寻找source code。然后install chaincode到${CORE_PEER_ADDRESS}
。登录
peer0.org1.example.com
容器。env
出来FABRIC_CFG_PATH=/etc/hyperledger/fabric
,查看改路径下的core.yaml
配置文件,其中peer.fileSystemPath : /var/hyperledger/production
。查看/var/hyperledger/production/chaincodes
目录,存在文件gopapercontract.0
(即${chaincodeName}.${chaincodeVersion}).instantiate chaincode。登录
cliMagnetoCorp
容器,执行1
peer chaincode instantiate -n gopapercontract -v 0 -c '{"Args":[]}' -C mychannel -P "AND ('Org1MSP.member')"
此时,
docker ps
可以看到dev-peer0.org1.example.com-gopapercontract-0这个容器。可以在cliMagnetoCorp
容器执行。1
2peer chaincode invoke -c '{"Args":["issue","MagnetoCorp", "00001", "2020-05-31", "2020-11-30", "5000000"]}' -C mychannel -n gopapercontract
peer chaincode query -c '{"Args":["query","MagnetoCorp", "00001"]}' -C mychannel -n gopapercontract如果后续更新chaincode,假设更新版本为1,则执行
1
peer chaincode upgrade -n gopapercontract -v 1 -c '{"Args":[]}' -C mychannel -P "AND ('Org1MSP.member')"
修改
fabric-samples/commercial-paper/organization/magnetocorp/application/issue.js
这个文件1
2
3
4
5// 63行 const contract = await network.getContract('papercontract', 'org.papernet.commercialpaper');
const contract = await network.getContract('gopapercontract');
// 73行 let paper = CommercialPaper.fromBuffer(issueResponse);
let paper = JSON.parse(issueResponse);然后,就可以正常调用
node issue.js
访问刚启动的golang commercial paper容器了。在整个流程中,可以执行./monitordocker.sh net_basic
查看chaincode的日志。
另外,在peer0.org1.example.com节点上可以使用peer chaincode list
命令查询channel内instantiated的chaincode以及peer上installed的chaincode。
- 查询channel内instantiated的chaincode。
1
2
3
4
5$ peer chaincode list -C mychannel --instantiated
Get instantiated chaincodes on channel mychannel:
Name: gopapercontract, Version: 1, Path: github.com/gocontract, Escc: escc, Vscc: vscc
Name: papercontract, Version: 0, Path: /opt/gopath/src/github.com/contract, Escc: escc, Vscc: vscc - 查询peer上installed的chaincode。 从返回结果可以看出,当前使用的角色并非Admin(这与MSP相关,使用的非Admin的X509证书)。因此可以指定使用Admin。
1
2
3$ peer chaincode list -C mychannel --installed
Error: Bad response: 500 - access denied for [getinstalledchaincodes]: Failed verifying that proposal's creator satisfies local MSP principal during channelless check policy with policy [Admins]: [This identity is not an admin]1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17# 默认使用的MSP config
$ echo $CORE_PEER_MSPCONFIGPATH
/etc/hyperledger/msp/peer/
# 区别在于keystore存放的用来签名请求的私钥。
$ ls $CORE_PEER_MSPCONFIGPATH
admincerts cacerts keystore signcerts tlscacerts
# 设置使用Admin的MSP config
$ CORE_PEER_MSPCONFIGPATH=/etc/hyperledger/msp/users/Admin@org1.example.com/msp
$ peer chaincode list -C mychannel --installed
Get installed chaincodes on peer:
Name: gopapercontract, Version: 0, Path: github.com/gocontract, Id: 44777e9463329c5b03a93abd48975980a795152907d0c6226b0b85589f4a0ca7
Name: gopapercontract, Version: 1, Path: github.com/gocontract, Id: d000a5b0e4ed415ae1739e716c13a481096b947cb31dd5f25ab1d67633d18bb0
Name: papercontract, Version: 0, Path: /opt/gopath/src/github.com/contract, Id: f09e75abcf455f6fb83257080ebd739f1d2397cf50ce2e52cd805d992a64bc03 - 使用openssl查看X.509证书。下面是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$ openssl x509 -noout -text -in Admin\@org1.example.com-cert.pem
Certificate:
Data:
Version: 3 (0x2)
Serial Number:
15:2c:67:2c:01:ac:bb:4e:33:ac:59:00:13:0c:e7:eb
Signature Algorithm: ecdsa-with-SHA256
Issuer: C=US, ST=California, L=San Francisco, O=org1.example.com, CN=ca.org1.example.com
Validity
Not Before: Aug 31 09:14:32 2017 GMT
Not After : Aug 29 09:14:32 2027 GMT
Subject: C=US, ST=California, L=San Francisco, CN=Admin@org1.example.com
Subject Public Key Info:
Public Key Algorithm: id-ecPublicKey
Public-Key: (256 bit)
pub:
04:57:57:5f:98:ac:6c:14:a5:a8:ee:8e:83:34:12:
1a:21:57:9b:08:23:c0:33:d0:bf:b0:b0:6d:e2:92:
51:ad:ef:69:58:4f:7c:ec:38:d7:66:86:77:82:57:
38:f8:3a:0f:32:d4:e6:05:1a:9b:3d:5c:18:71:4b:
e9:6d:86:3c:a7
ASN1 OID: prime256v1
NIST CURVE: P-256
X509v3 extensions:
X509v3 Key Usage: critical
Digital Signature
X509v3 Basic Constraints: critical
CA:FALSE
X509v3 Authority Key Identifier:
keyid:42:39:AA:0D:CD:76:DA:EE:B8:BA:0C:DA:70:18:51:D1:45:04:D3:1A:AD:1B:2D:DD:DB:AC:6A:57:36:5E:49:7C
Signature Algorithm: ecdsa-with-SHA256
30:44:02:20:5c:cc:b6:e8:01:14:fc:65:0c:3d:f0:8c:b3:f9:
d0:8d:03:04:d5:9c:41:1c:06:19:b4:a1:2e:45:1d:fa:d4:9b:
02:20:48:3d:04:e6:5d:22:88:a8:46:2b:c9:0b:e6:54:ce:f2:
54:9e:45:ee:a3:61:e4:5a:2b:b1:2e:c8:9b:1b:1b:44