Preparation Phase
Before we start, if you have not already done so, you may wish to check that all of the following prerequisites are installed on the platform on which you will be developing blockchain applications or running Hyperledger Fabric.
Install Git
If not installed, download the latest version git , or you have a problem running the curl command.
Install cURL
If you don't have cURl installed or if you get an error running the curl command on the server, please download the latest version of cURL tool.
Docker and Docker Compose
You will need the following installed on the platform that will be running or developing on (or developing for) Hyperledger Fabric:
- MacOSX, *nix or Windows 10: Requirements Docker Version 17.06.2-ce and above.
- Older versions of Windows: Docker Toolbox - Requires Docker version 17.06.2-ce and above.
You can check the version of Docker installed by executing the following command:
docker --version
Make sure the docker daemon is running.
sudo systemctl start docker
Optional: If you want the docker daemon to start automatically when the system boots, use the following command:
sudo systemctl enable docker
Add your user to the docker group.
sudo usermod -a -G docker <username>
install fabric
curl -sSL https://bit.ly/2ysbOFE | bash -s -- <fabric_version> <fabric-ca_version>
#For example
curl -sSL https://bit.ly/2ysbOFE | bash -s -- 2.2.0 1.4.7
curl -sSL https://bit.ly/2ysbOFE | bash -s
#or pull the code
git clone https://github.com/hyperledger/fabric-samples.git
Launch test network
#2.enter directory
cd fabric-samples/test-network
# Start the network and create a channel
./network.sh up createChannel
Add these binaries to your CLI path:
export PATH=${PWD}/../bin:$PATH
../bin
├── configtxgen
├── configtxlator
├── cryptogen
├── discover
├── fabric-ca-client
├── fabric-ca-server
├── ledgerutil
├── orderer
├── osnadmin
└── peer
Import environment variables
Set environment variables for org1,org2
# Environment variables for Org1
export FABRIC_CFG_PATH=$PWD/../config/
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/Admin@org1.example.com/msp
export CORE_PEER_ADDRESS=localhost:7051
# Environment variables for Org2
export FABRIC_CFG_PATH=$PWD/../config/
export CORE_PEER_TLS_ENABLED=true
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_MSPCONFIGPATH=${PWD}/organizations/peerOrganizations/org2.example.com/users/Admin@org2.example.com/msp
export CORE_PEER_ADDRESS=localhost:9051
deploy chaincode
If you use it in an offline environment in the future, you can run the following code. If there is no vendor for the chain code, you need to run the following command:
GO111MODULE=on
go mod vendor
Go back to the test-network directory to package the chaincode
peer lifecycle chaincode package basic.tar.gz --path ../asset-transfer-basic/chaincode-go/ --lang golang --label basic_1.0
Install chaincode
peer lifecycle chaincode install basic.tar.gz
View chaincode installation status
peer lifecycle chaincode queryinstalled
## The following message appears to indicate that the installation is successful
Installed chaincodes on peer:
Package ID: basic_1.0:56069c8c46fe01a7837a218a6e2ab49a2b6c4a715c95ab2ab321a863b642d021, Label: basic_1.0
approve
Set chaincode package environment variables (org1,org2)
We'll be using the CC_PACKAGE_ID when approving the chaincode, so let's go ahead and save it as an environment variable. Paste the returned CC_PACKAGE_ID into the command below. NOTE: The CC_PACKAGE_ID is different for all users, so you need to use the CC_PACKAGE_ID returned from the command window in the previous step to complete this step.
export CC_PACKAGE_ID=basic_1.0:56069c8c46fe01a7837a218a6e2ab49a2b6c4a715c95ab2ab321a863b642d021
Since the environment variable is set for the peer to run the CLI as an Org2 admin, we can approve the basic chaincode definition for Org2. Chaincode is approved at the organization level, so the command only needs to be directed at one peer. Use gossip to distribute approvals to other peers within the organization. use peer lifecycle chaincode approveformyorg Command approval chaincode definition:
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
Commit the chaincode definition to the channel commit
After a sufficient number of organizations approve the chaincode definition, an organization can commit the chaincode definition to the channel. If a majority of channel members approve the definition, the commit transaction will succeed and the parameters agreed in the chaincode definition will be implemented on the channel.
You can use peer lifecycle chaincode checkcommitreadiness command to check if channel members have approved the same chaincode definition. The flags used for the checkcommitreadiness command are the same as those used to approve chaincode for your organization.
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
It mainly checks the authorization status of all organizations and displays the following return values:
{
"approvals": {
"Org1MSP": true,
"Org2MSP": true
}
}
Since both organizations that are members of the channel have approved the same parameters, the chaincode definition is ready to be committed to the channel. You can use peer lifecycle chaincode commit command to commit the chaincode definition to the channel. Commit commands also need to be submitted by an organization administrator. (org1 or org2)
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
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]
--output json can be converted into json format
{
"sequence": 1,
"version": "1.0",
"endorsement_plugin": "escc",
"validation_plugin": "vscc",
"validation_parameter": "EiAvQ2hhbm5lbC9BcHBsaWNhdGlvbi9FbmRvcnNlbWVudA==",
"collections": {},
"approvals": {
"Org1MSP": true,
"Org2MSP": true
}
}
The above method is too troublesome
./network.sh deployCC -ccn basic -ccp ../asset-transfer-basic/chaincode-go -ccl go
call chaincode
After a chaincode definition is committed to a channel, the chaincode will be started on peers joining the channel on which the chaincode was installed. basic The chaincode is now ready to be invoked by client applications. Note that the invoke command needs to target a sufficient number of peers to satisfy the chaincode endorsement policy.
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":[]}'
If the command was successful, you should receive a response similar to the following:
2022-11-29 11:33:39.636 CST 0001 INFO [chaincodeCmd] chaincodeInvokeOrQuery -> Chaincode invoke successful. result: status:200
Query all assets
peer chaincode query -C mychannel -n basic -c '{"Args":["getAllAssets"]}'
return value:
[{"AppraisedValue":300,"Color":"blue","ID":"asset1","Owner":"Tomoko","Size":5},{"AppraisedValue":400,"Color":"red","ID":"asset2","Owner":"Brad","Size":5},{"AppraisedValue":500,"Color":"green","ID":"asset3","Owner":"Jin Soo","Size":10},{"AppraisedValue":600,"Color":"yellow","ID":"asset4","Owner":"Max","Size":10},{"AppraisedValue":700,"Color":"black","ID":"asset5","Owner":"Adriana","Size":15},{"AppraisedValue":800,"Color":"white","ID":"asset6","Owner":"Michel","Size":15}]
add assets
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":["asset7", "pink", "80", "Michel", "800"]}'
return value
2022-11-29 11:51:29.706 CST 0001 INFO [chaincodeCmd] chaincodeInvokeOrQuery -> Chaincode invoke successful. result: status:200
Check the content again
You can see the newly added content
[{"AppraisedValue":300,"Color":"blue","ID":"asset1","Owner":"Tomoko","Size":5},{"AppraisedValue":400,"Color":"red","ID":"asset2","Owner":"Brad","Size":5},{"AppraisedValue":500,"Color":"green","ID":"asset3","Owner":"Jin Soo","Size":10},{"AppraisedValue":600,"Color":"yellow","ID":"asset4","Owner":"Max","Size":10},{"AppraisedValue":700,"Color":"black","ID":"asset5","Owner":"Adriana","Size":15},{"AppraisedValue":800,"Color":"white","ID":"asset6","Owner":"Michel","Size":15},{"AppraisedValue":800,"Color":"pink","ID":"asset7","Owner":"Michel","Size":80}]
Upgrade chaincode
repackage chain
peer lifecycle chaincode package basic.2.0.0.tar.gz --path ../asset-transfer-basic/chaincode-go/ --lang golang --label basic_2.0