7.1 Hyperleger Fabric - Deploying a smart contract to a channel
Делаю:
31.08.2020
Все удаляю
$ cd ~/projects/dev/hyperledger/
$ sudo rm -rf *
$ {
docker stop $(docker ps -aq)
docker rm $(docker ps -aq)
docker system prune -a
}
$ curl -sSL https://raw.githubusercontent.com/hyperledger/fabric/master/scripts/bootstrap.sh | bash -s
$ cd fabric-samples/test-network/
// Чего-то как-то не каждый раз срабатывает. Приходится по несколько раз делать down/up
$ ./network.sh down && ./network.sh up createChannel
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
b30252361fcc hyperledger/fabric-orderer:latest "orderer" 31 seconds ago Up 29 seconds 0.0.0.0:7050->7050/tcp orderer.example.com
b6c92736704e hyperledger/fabric-peer:latest "peer node start" 31 seconds ago Up 29 seconds 7051/tcp, 0.0.0.0:9051->9051/tcp peer0.org2.example.com
0c1b84ff5e47 hyperledger/fabric-peer:latest "peer node start" 31 seconds ago Up 30 seconds 0.0.0.0:7051->7051/tcp peer0.org1.example.com
We can now use the Peer CLI to deploy the asset-transfer (basic) chaincode to the channel using the following steps:
• Step one: Package the smart contract • Step two: Install the chaincode package • Step three: Approve a chaincode definition • Step four: Committing the chaincode definition to the channel
Запускаем утилиту для мониторинга контейнеров в отдельном терминале
Терминал 2
$ cp ../commercial-paper/organization/digibank/configuration/cli/monitordocker.sh .
$ ./monitordocker.sh net_test
7.1.3 Package the smart contract
Пример с Go
$ cd ../asset-transfer-basic/chaincode-go/
$ GO111MODULE=on go mod vendor
If the command is successful, the go packages will be installed inside a vendor folder.
$ cd ../../test-network
$ export PATH=${PWD}/../bin:$PATH
$ export FABRIC_CFG_PATH=$PWD/../config/
$ peer version
$ peer lifecycle chaincode package basic.tar.gz \
--path ../asset-transfer-basic/chaincode-go/ \
--lang golang \
--label basic_1.0
Создался basic.tar.gz в текущем каталоге.
JavaScript
$ cd ~/projects/dev/hyperledger/
$ cd fabric-samples/asset-transfer-basic/chaincode-javascript
$ npm install
$ cd ../../test-network
$ export PATH=${PWD}/../bin:$PATH
$ export FABRIC_CFG_PATH=$PWD/../config/
$ peer lifecycle chaincode \
package basic.tar.gz \
--path ../asset-transfer-basic/chaincode-javascript/ \
--lang node \
--label basic_1.0
Создался basic.tar.gz в текущем каталоге.
Typescript
$ cd ~/projects/dev/hyperledger/
$ cd fabric-samples/asset-transfer-basic/chaincode-typescript
$ npm install
// В интрукции этого пункта нет
$ npm run build
$ cd /home/marley/projects/dev/hyperledger/fabric-samples/test-network/
$ {
export PATH=${PWD}/../bin:$PATH
export FABRIC_CFG_PATH=$PWD/../config/
}
$ peer lifecycle chaincode \
package basic.tar.gz \
--path ../asset-transfer-basic/chaincode-typescript/ \
--lang node \
--label basic_1.0
Создался basic.tar.gz в текущем каталоге.
7.1.4 Install the chaincode package
Org1
$ {
export CORE_PEER_TLS_ENABLED=true
export CORE_PEER_LOCALMSPID="Org1MSP"
export CORE_PEER_TLS_ROOTCERT_FILE=${PWD}/organizations/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt
export CORE_PEER_MSPCONFIGPATH=${PWD}/organizations/peerOrganizations/org1.example.com/users/[email protected]/msp
export CORE_PEER_ADDRESS=localhost:7051
}
$ peer lifecycle chaincode install basic.tar.gz
Org2
$ {
export CORE_PEER_LOCALMSPID="Org2MSP"
export CORE_PEER_TLS_ROOTCERT_FILE=${PWD}/organizations/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt
export CORE_PEER_TLS_ROOTCERT_FILE=${PWD}/organizations/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt
export CORE_PEER_MSPCONFIGPATH=${PWD}/organizations/peerOrganizations/org2.example.com/users/[email protected]/msp
export CORE_PEER_ADDRESS=localhost:9051
}
$ peer lifecycle chaincode install basic.tar.gz
7.1.5 Approve a chaincode definition
$ peer lifecycle chaincode queryinstalled
// Будет отличаться от того, что у меня
$ export CC_PACKAGE_ID=basic_1.0:4ec191e793b27e953ff2ede5a8bcc63152cecb1e4c3f301a26e22692c61967ad
$ echo $CC_PACKAGE_ID
$ peer lifecycle chaincode approveformyorg \
-o localhost:7050 \
--ordererTLSHostnameOverride orderer.example.com \
--channelID mychannel \
--name basic \
--version 1.0 \
--package-id $CC_PACKAGE_ID \
--sequence 1 \
--tls \
--cafile ${PWD}/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem
You need to approve a chaincode definition with an identity that has an admin role.
$ {
export CORE_PEER_LOCALMSPID="Org1MSP"
export CORE_PEER_MSPCONFIGPATH=${PWD}/organizations/peerOrganizations/org1.example.com/users/[email protected]/msp
export CORE_PEER_TLS_ROOTCERT_FILE=${PWD}/organizations/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt
export CORE_PEER_ADDRESS=localhost:7051
}
$ peer lifecycle chaincode approveformyorg \
-o localhost:7050 \
--ordererTLSHostnameOverride orderer.example.com \
--channelID mychannel \
--name basic \
--version 1.0 \
--package-id $CC_PACKAGE_ID \
--sequence 1 \
--tls \
--cafile ${PWD}/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem
7.1.6 Committing the chaincode definition to the channel
$ peer lifecycle chaincode checkcommitreadiness \
--channelID mychannel \
--name basic \
--version 1.0 \
--sequence 1 \
--tls \
--cafile ${PWD}/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem \
--output json
{
"approvals": {
"Org1MSP": true,
"Org2MSP": true
}
}
$ peer lifecycle chaincode commit \
-o localhost:7050 \
--ordererTLSHostnameOverride orderer.example.com \
--channelID mychannel \
--name basic \
--version 1.0 \
--sequence 1 \
--tls \
--cafile ${PWD}/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem \
--peerAddresses localhost:7051 \
--tlsRootCertFiles ${PWD}/organizations/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt \
--peerAddresses localhost:9051 \
--tlsRootCertFiles ${PWD}/organizations/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt
You can use the peer lifecycle chaincode querycommitted command to confirm that the chaincode definition has been committed to the channel.
$ peer lifecycle chaincode querycommitted \
--channelID mychannel \
--name basic \
--cafile ${PWD}/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem
Committed chaincode definition for chaincode 'basic' on channel 'mychannel':
Version: 1.0, Sequence: 1, Endorsement Plugin: escc, Validation Plugin: vscc, Approvals: [Org1MSP: true, Org2MSP: true]
7.1.7 Invoking the chaincode
$ peer chaincode invoke \
-o localhost:7050 \
--ordererTLSHostnameOverride orderer.example.com \
--tls \
--cafile ${PWD}/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem \
-C mychannel \
-n basic \
--peerAddresses localhost:7051 --tlsRootCertFiles ${PWD}/organizations/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt \
--peerAddresses localhost:9051 \
--tlsRootCertFiles ${PWD}/organizations/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt \
-c '{"function":"initLedger","Args":[]}'
Для TypeScript и JavaScript
Когда ошибка:
Error: endorsement failure during invoke. response: status:500 message:"error in simulation: transaction returned with failure: Error: You've asked to invoke a function that does not exist: initLedger"
// Нужно вызывать функцию следующим образом! Я на этой @#$%^& часа 3-4 потерял!
-c '{"function":"InitLedger","Args":[]}'
$ peer chaincode query -C mychannel -n basic -c '{"Args":["getAllAssets"]}' | python -m json.tool
Для TypeScript и JavaScript
$ peer chaincode query -C mychannel -n basic -c '{"Args":["GetAllAssets"]}' | python -m json.tool
[
{
"ID": "asset1",
"color": "blue",
"size": 5,
"owner": "Tomoko",
"appraisedValue": 300
},
{
"ID": "asset2",
"color": "red",
"size": 5,
"owner": "Brad",
"appraisedValue": 400
},
{
"ID": "asset3",
"color": "green",
"size": 10,
"owner": "Jin Soo",
"appraisedValue": 500
},
{
"ID": "asset4",
"color": "yellow",
"size": 10,
"owner": "Max",
"appraisedValue": 600
},
{
"ID": "asset5",
"color": "black",
"size": 15,
"owner": "Adriana",
"appraisedValue": 700
},
{
"ID": "asset6",
"color": "white",
"size": 15,
"owner": "Michel",
"appraisedValue": 800
}
]
$ docker ps
Должны быть контейнеры с chaincode.
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
3570e77abece dev-peer0.org1.example.com-basic_1.0-ba2cf24a6d127ece5cf5b287c5dc19e39649c695539e455c10f760ac9e9b90a8-da0dc2176d3e64b66e2110369ab6a453d2d86e8fe828bffa81ef9a36fe7e5c24 "docker-entrypoint.s…" 2 minutes ago Up 2 minutes dev-peer0.org1.example.com-basic_1.0-ba2cf24a6d127ece5cf5b287c5dc19e39649c695539e455c10f760ac9e9b90a8
fe56e624c0f5 dev-peer0.org2.example.com-basic_1.0-ba2cf24a6d127ece5cf5b287c5dc19e39649c695539e455c10f760ac9e9b90a8-ff8b4282f1e26ed874801675b2dddb3b40efefc8ef61b74fe58fc113631378b1 "docker-entrypoint.s…" 2 minutes ago Up 2 minutes dev-peer0.org2.example.com-basic_1.0-ba2cf24a6d127ece5cf5b287c5dc19e39649c695539e455c10f760ac9e9b90a8
b30252361fcc hyperledger/fabric-orderer:latest "orderer" 9 minutes ago Up 9 minutes 0.0.0.0:7050->7050/tcp orderer.example.com
b6c92736704e hyperledger/fabric-peer:latest "peer node start" 9 minutes ago Up 9 minutes 7051/tcp, 0.0.0.0:9051->9051/tcp peer0.org2.example.com
0c1b84ff5e47 hyperledger/fabric-peer:latest "peer node start" 9 minutes ago Up 9 minutes 0.0.0.0:7051->7051/tcp peer0.org1.example.com
7.1.8 Upgrading a smart contract
Предполагается, что бы задеплоили chaincode на go, теперь обновляем его на javascript
$ cd ../asset-transfer-basic/chaincode-javascript
$ npm install
$ cd ../../test-network
$ {
export PATH=${PWD}/../bin:$PATH
export FABRIC_CFG_PATH=$PWD/../config/
export CORE_PEER_MSPCONFIGPATH=${PWD}/organizations/peerOrganizations/org1.example.com/users/[email protected]/msp
}
$ peer lifecycle chaincode package basic_2.tar.gz --path ../asset-transfer-basic/chaincode-javascript/ --lang node --label basic_2.0
Org1
$ {
export CORE_PEER_TLS_ENABLED=true
export CORE_PEER_LOCALMSPID="Org1MSP"
export CORE_PEER_TLS_ROOTCERT_FILE=${PWD}/organizations/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt
export CORE_PEER_MSPCONFIGPATH=${PWD}/organizations/peerOrganizations/org1.example.com/users/[email protected]/msp
export CORE_PEER_ADDRESS=localhost:7051
}
$ peer lifecycle chaincode install basic_2.tar.gz
$ peer lifecycle chaincode queryinstalled
Installed chaincodes on peer:
Package ID: basic_1.0:4ec191e793b27e953ff2ede5a8bcc63152cecb1e4c3f301a26e22692c61967ad, Label: basic_1.0
Package ID: basic_2.0:58b24c58b05c1be32b529d4d64e9ec569bc4d7c7e7acb6810aeef3b3f1200a9c, Label: basic_2.0
$ export NEW_CC_PACKAGE_ID=basic_2.0:58b24c58b05c1be32b529d4d64e9ec569bc4d7c7e7acb6810aeef3b3f1200a9c
$ echo $NEW_CC_PACKAGE_ID
$ peer lifecycle chaincode approveformyorg \
-o localhost:7050 \
--ordererTLSHostnameOverride orderer.example.com \
--channelID mychannel \
--name basic \
--version 2.0 \
--package-id $NEW_CC_PACKAGE_ID \
--sequence 2 \
--tls \
--cafile ${PWD}/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem
Org2
$ {
export CORE_PEER_LOCALMSPID="Org2MSP"
export CORE_PEER_TLS_ROOTCERT_FILE=${PWD}/organizations/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt
export CORE_PEER_TLS_ROOTCERT_FILE=${PWD}/organizations/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt
export CORE_PEER_MSPCONFIGPATH=${PWD}/organizations/peerOrganizations/org2.example.com/users/[email protected]/msp
export CORE_PEER_ADDRESS=localhost:9051
}
$ peer lifecycle chaincode install basic_2.tar.gz
$ peer lifecycle chaincode approveformyorg \
-o localhost:7050 \
--ordererTLSHostnameOverride orderer.example.com \
--channelID mychannel \
--name basic \
--version 2.0 \
--package-id $NEW_CC_PACKAGE_ID \
--sequence 2 \
--tls \
--cafile ${PWD}/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem
$ peer lifecycle chaincode checkcommitreadiness \
--channelID mychannel \
--name basic \
--version 2.0 \
--sequence 2 \
--tls \
--cafile ${PWD}/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem \
--output json
{
"approvals": {
"Org1MSP": true,
"Org2MSP": true
}
}
$ peer lifecycle chaincode commit \
-o localhost:7050 \
--ordererTLSHostnameOverride orderer.example.com \
--channelID mychannel \
--name basic \
--version 2.0 \
--sequence 2 \
--tls \
--cafile ${PWD}/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem \
--peerAddresses localhost:7051 \
--tlsRootCertFiles ${PWD}/organizations/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt \
--peerAddresses localhost:9051 \
--tlsRootCertFiles ${PWD}/organizations/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt
$ docker ps
$ peer chaincode invoke \
-o localhost:7050 \
--ordererTLSHostnameOverride orderer.example.com \
--tls \
--cafile ${PWD}/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem \
-C mychannel \
-n basic \
--peerAddresses localhost:7051 \
--tlsRootCertFiles ${PWD}/organizations/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt --peerAddresses localhost:9051 \
--tlsRootCertFiles ${PWD}/organizations/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt \
-c '{"function":"createAsset","Args":["asset8","blue","16","Kelley","750"]}'
Для TypeScript и JavaScript
-c '{"function":"CreateAsset","Args":["asset8","blue","16","Kelley","750"]}'
$ peer chaincode query \
-C mychannel \
-n basic \
-c '{"Args":["getAllAssets"]}'
Для TypeScript и JavaScript
$ peer chaincode query \
-C mychannel \
-n basic \
-c '{"Args":["GetAllAssets"]}'