安装Fabric2.4.3
预备环境:略
go env -w GOPROXY=https://goproxy.cn,direct
1 一键安装
wget https://raw.githubusercontent.com/hyperledger/fabric/master/scripts/bootstrap.sh
上面这个地址来自Install Samples, Binaries, and Docker Images — hyperledger-fabricdocs master documentation
结果
allan@Hyperledger-Fabric-23:~/go/src/github.com/hyperledger$ ./bootstrap.sh Clone hyperledger/fabric-samples repo ===> Changing directory to fabric-samples fabric-samples v2.4.3 does not exist, defaulting to main. fabric-samples main branch is intended to work with recent versions of fabric. Pull Hyperledger Fabric binaries ===> Downloading version 2.4.3 platform specific fabric binaries ===> Downloading: https://github.com/hyperledger/fabric/releases/download/v2.4.3/hyperledger-fabric-linux-amd64-2.4.3.tar.gz ··· ==> Done. ===> Downloading version 1.5.3 platform specific fabric-ca-client binary ===> Downloading: https://github.com/hyperledger/fabric-ca/releases/download/v1.5.3/hyperledger-fabric-ca-linux-amd64-1.5.3.tar.gz ··· ==> Done. Pull Hyperledger Fabric docker images FABRIC_IMAGES: peer orderer ccenv tools baseos ===> Pulling fabric Images ====> hyperledger/fabric-peer:2.4.3 2.4.3: Pulling from hyperledger/fabric-peer ··· Digest: sha256:6be12ebf5161df1735c024796cb1181cff8b6ce8cb0f7988adfea42b62813f9c Status: Downloaded newer image for hyperledger/fabric-peer:2.4.3 docker.io/hyperledger/fabric-peer:2.4.3 ====> hyperledger/fabric-orderer:2.4.3 2.4.3: Pulling from hyperledger/fabric-orderer ··· Digest: sha256:78fa78126c026c94c8f5a12ac36c39b205cbac13b08379872d849fff5e1df0a6 Status: Downloaded newer image for hyperledger/fabric-orderer:2.4.3 docker.io/hyperledger/fabric-orderer:2.4.3 ====> hyperledger/fabric-ccenv:2.4.3 2.4.3: Pulling from hyperledger/fabric-ccenv ··· Digest: sha256:d5d00426297b9347b6f08541e1e7de6e4244053b93bb442e16260c6df0ef6582 Status: Downloaded newer image for hyperledger/fabric-tools:2.4.3 docker.io/hyperledger/fabric-tools:2.4.3 ====> hyperledger/fabric-baseos:2.4.3 2.4.3: Pulling from hyperledger/fabric-baseos ··· Digest: sha256:14e8994c0faa5ca5fbfe6ebcdb9dc42102ffae55d147fddcbbc2b19e570eab03 Status: Downloaded newer image for hyperledger/fabric-baseos:2.4.3 docker.io/hyperledger/fabric-baseos:2.4.3 ===> Pulling fabric ca Image ====> hyperledger/fabric-ca:1.5.3 1.5.3: Pulling from hyperledger/fabric-ca ··· Digest: sha256:f4878c8fc60e71e509fa5827f04129bbb69e519fd89bca68b1dfabfc0272d5d5 Status: Downloaded newer image for hyperledger/fabric-ca:1.5.3 docker.io/hyperledger/fabric-ca:1.5.3 ===> List out hyperledger docker images hyperledger/fabric-ca 1.5 b2aed5002b3d 3 weeks ago 68.1MB hyperledger/fabric-ca 1.5.3 b2aed5002b3d 3 weeks ago 68.1MB hyperledger/fabric-ca latest b2aed5002b3d 3 weeks ago 68.1MB hyperledger/fabric-tools 2.4 625237d887db 2 months ago 473MB hyperledger/fabric-tools 2.4.3 625237d887db 2 months ago 473MB hyperledger/fabric-tools latest 625237d887db 2 months ago 473MB hyperledger/fabric-peer 2.4 ee643d889779 2 months ago 62.3MB hyperledger/fabric-peer 2.4.3 ee643d889779 2 months ago 62.3MB hyperledger/fabric-peer latest ee643d889779 2 months ago 62.3MB hyperledger/fabric-orderer 2.4 df64446ac2df 2 months ago 37.3MB hyperledger/fabric-orderer 2.4.3 df64446ac2df 2 months ago 37.3MB hyperledger/fabric-orderer latest df64446ac2df 2 months ago 37.3MB hyperledger/fabric-ccenv 2.4 da4f00cb576a 2 months ago 517MB hyperledger/fabric-ccenv 2.4.3 da4f00cb576a 2 months ago 517MB hyperledger/fabric-ccenv latest da4f00cb576a 2 months ago 517MB hyperledger/fabric-baseos 2.4 0287ebf8aaf3 2 months ago 6.94MB hyperledger/fabric-baseos 2.4.3 0287ebf8aaf3 2 months ago 6.94MB hyperledger/fabric-baseos latest 0287ebf8aaf3 2 months ago 6.94MB
2 测试网络
将bin加入环境变量,使bin下的二进制文件可以被全局访问
export PATH=/root/go/src/github.com/hyperledger/fabric-samples/bin:$PATH # export PATH=${PWD}/../bin:$PATH export PATH=/home/allan/go/src/github.com/hyperledger/fabric-samples/bin:$PATH
进入测试网络文件夹
cd fabric-samples/test-network
开启和关闭测试网络
./network.sh up # ./network.sh down
结果ne
Using docker and docker-compose Starting nodes with CLI timeout of '5' tries and CLI delay of '3' seconds and using database 'leveldb' with crypto from 'cryptogen' LOCAL_VERSION=2.4.3 DOCKER_IMAGE_VERSION=2.4.3 /home/allan/go/src/github.com/hyperledger/fabric-samples/test-network/../bin/cryptogen Generating certificates using cryptogen tool Creating Org1 Identities + cryptogen generate --config=./organizations/cryptogen/crypto-config-org1.yaml --output=organizations org1.example.com + res=0 Creating Org2 Identities + cryptogen generate --config=./organizations/cryptogen/crypto-config-org2.yaml --output=organizations org2.example.com + res=0 Creating Orderer Org Identities + cryptogen generate --config=./organizations/cryptogen/crypto-config-orderer.yaml --output=organizations + res=0 Generating CCP files for Org1 and Org2 Creating network "fabric_test" with the default driver Creating volume "compose_orderer.example.com" with default driver Creating volume "compose_peer0.org1.example.com" with default driver Creating volume "compose_peer0.org2.example.com" with default driver Creating peer0.org2.example.com ... done Creating orderer.example.com ... done Creating peer0.org1.example.com ... done Creating cli ... done CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES fcf98db11b4d hyperledger/fabric-tools:latest "/bin/bash" 1 second ago Up Less than a second cli e418e4ba8ace hyperledger/fabric-peer:latest "peer node start" 4 seconds ago Up 2 seconds 0.0.0.0:7051->7051/tcp, :::7051->7051/tcp, 0.0.0.0:9444->9444/tcp, :::9444->9444/tcp peer0.org1.example.com 86da0c657eb7 hyperledger/fabric-orderer:latest "orderer" 4 seconds ago Up Less than a second 0.0.0.0:7050->7050/tcp, :::7050->7050/tcp, 0.0.0.0:7053->7053/tcp, :::7053->7053/tcp, 0.0.0.0:9443->9443/tcp, :::9443->9443/tcp orderer.example.com 77bfa8521c1c hyperledger/fabric-peer:latest "peer node start" 4 seconds ago Up 1 second 0.0.0.0:9051->9051/tcp, :::9051->9051/tcp, 7051/tcp, 0.0.0.0:9445->9445/tcp, :::9445->9445/tcp peer0.org2.example.com
创建通道
./network.sh createChannel # 或者自定义名称/创建另一条通道 # ./network.sh createChannel -c channel1
结果
Using docker and docker-compose Creating channel 'mychannel'. If network is not up, starting nodes with CLI timeout of '5' tries and CLI delay of '3' seconds and using database 'leveldb Network Running Already Using docker and docker-compose Generating channel genesis block 'mychannel.block' /home/allan/go/src/github.com/hyperledger/fabric-samples/test-network/../bin/configtxgen + configtxgen -profile TwoOrgsApplicationGenesis -outputBlock ./channel-artifacts/mychannel.block -channelID mychannel 2022-05-05 21:06:26.019 CST 0001 INFO [common.tools.configtxgen] main -> Loading configuration 2022-05-05 21:06:26.036 CST 0002 INFO [common.tools.configtxgen.localconfig] completeInitialization -> orderer type: etcdraft 2022-05-05 21:06:26.036 CST 0003 INFO [common.tools.configtxgen.localconfig] completeInitialization -> Orderer.EtcdRaft.Options unset, setting to tick_interval:"500ms" election_tick:10 heartbeat_tick:1 max_inflight_blocks:5 snapshot_interval_size:16777216 2022-05-05 21:06:26.037 CST 0004 INFO [common.tools.configtxgen.localconfig] Load -> Loaded configuration: /home/allan/go/src/github.com/hyperledger/fabric-samples/test-network/configtx/configtx.yaml 2022-05-05 21:06:26.040 CST 0005 INFO [common.tools.configtxgen] doOutputBlock -> Generating genesis block 2022-05-05 21:06:26.040 CST 0006 INFO [common.tools.configtxgen] doOutputBlock -> Creating application channel genesis block 2022-05-05 21:06:26.040 CST 0007 INFO [common.tools.configtxgen] doOutputBlock -> Writing genesis block + res=0 Creating channel mychannel Using organization 1 + osnadmin channel join --channelID mychannel --config-block ./channel-artifacts/mychannel.block -o localhost:7053 --ca-file /home/allan/go/src/github.com/hyperledger/fabric-samples/test-network/organizations/ordererOrganizations/example.com/tlsca/tlsca.example.com-cert.pem --client-cert /home/allan/go/src/github.com/hyperledger/fabric-samples/test-network/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/tls/server.crt --client-key /home/allan/go/src/github.com/hyperledger/fabric-samples/test-network/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/tls/server.key + res=0 Status: 201 { "name": "mychannel", "url": "/participation/v1/channels/mychannel", "consensusRelation": "consenter", "status": "active", "height": 1 } Channel 'mychannel' created Joining org1 peer to the channel... Using organization 1 + peer channel join -b ./channel-artifacts/mychannel.block + res=0 2022-05-05 21:06:32.368 CST 0001 INFO [channelCmd] InitCmdFactory -> Endorser and orderer connections initialized 2022-05-05 21:06:32.479 CST 0002 INFO [channelCmd] executeJoin -> Successfully submitted proposal to join channel Joining org2 peer to the channel... Using organization 2 + peer channel join -b ./channel-artifacts/mychannel.block + res=0 2022-05-05 21:06:35.537 CST 0001 INFO [channelCmd] InitCmdFactory -> Endorser and orderer connections initialized 2022-05-05 21:06:35.626 CST 0002 INFO [channelCmd] executeJoin -> Successfully submitted proposal to join channel Setting anchor peer for org1... Using organization 1 Fetching channel config for channel mychannel Using organization 1 Fetching the most recent configuration block for the channel + peer channel fetch config config_block.pb -o orderer.example.com:7050 --ordererTLSHostnameOverride orderer.example.com -c mychannel --tls --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/organizations/ordererOrganizations/example.com/tlsca/tlsca.example.com-cert.pem 2022-05-05 13:06:35.824 UTC 0001 INFO [channelCmd] InitCmdFactory -> Endorser and orderer connections initialized 2022-05-05 13:06:35.829 UTC 0002 INFO [cli.common] readBlock -> Received block: 0 2022-05-05 13:06:35.829 UTC 0003 INFO [channelCmd] fetch -> Retrieving last config block: 0 2022-05-05 13:06:35.832 UTC 0004 INFO [cli.common] readBlock -> Received block: 0 Decoding config block to JSON and isolating config to Org1MSPconfig.json + configtxlator proto_decode --input config_block.pb --type common.Block --output config_block.json + jq '.data.data[0].payload.data.config' config_block.json Generating anchor peer update transaction for Org1 on channel mychannel + jq '.channel_group.groups.Application.groups.Org1MSP.values += {"AnchorPeers":{"mod_policy": "Admins","value":{"anchor_peers": [{"host": "peer0.org1.example.com","port": 7051}]},"version": "0"}}' Org1MSPconfig.json + configtxlator proto_encode --input Org1MSPconfig.json --type common.Config --output original_config.pb + configtxlator proto_encode --input Org1MSPmodified_config.json --type common.Config --output modified_config.pb + configtxlator compute_update --channel_id mychannel --original original_config.pb --updated modified_config.pb --output config_update.pb + configtxlator proto_decode --input config_update.pb --type common.ConfigUpdate --output config_update.json + jq . ++ cat config_update.json + echo '{"payload":{"header":{"channel_header":{"channel_id":"mychannel", "type":2}},"data":{"config_update":{' '"channel_id":' '"mychannel",' '"isolated_data":' '{},' '"read_set":' '{' '"groups":' '{' '"Application":' '{' '"groups":' '{' '"Org1MSP":' '{' '"groups":' '{},' '"mod_policy":' '"",' '"policies":' '{' '"Admins":' '{' '"mod_policy":' '"",' '"policy":' null, '"version":' '"0"' '},' '"Endorsement":' '{' '"mod_policy":' '"",' '"policy":' null, '"version":' '"0"' '},' '"Readers":' '{' '"mod_policy":' '"",' '"policy":' null, '"version":' '"0"' '},' '"Writers":' '{' '"mod_policy":' '"",' '"policy":' null, '"version":' '"0"' '}' '},' '"values":' '{' '"MSP":' '{' '"mod_policy":' '"",' '"value":' null, '"version":' '"0"' '}' '},' '"version":' '"0"' '}' '},' '"mod_policy":' '"",' '"policies":' '{},' '"values":' '{},' '"version":' '"0"' '}' '},' '"mod_policy":' '"",' '"policies":' '{},' '"values":' '{},' '"version":' '"0"' '},' '"write_set":' '{' '"groups":' '{' '"Application":' '{' '"groups":' '{' '"Org1MSP":' '{' '"groups":' '{},' '"mod_policy":' '"Admins",' '"policies":' '{' '"Admins":' '{' '"mod_policy":' '"",' '"policy":' null, '"version":' '"0"' '},' '"Endorsement":' '{' '"mod_policy":' '"",' '"policy":' null, '"version":' '"0"' '},' '"Readers":' '{' '"mod_policy":' '"",' '"policy":' null, '"version":' '"0"' '},' '"Writers":' '{' '"mod_policy":' '"",' '"policy":' null, '"version":' '"0"' '}' '},' '"values":' '{' '"AnchorPeers":' '{' '"mod_policy":' '"Admins",' '"value":' '{' '"anchor_peers":' '[' '{' '"host":' '"peer0.org1.example.com",' '"port":' 7051 '}' ']' '},' '"version":' '"0"' '},' '"MSP":' '{' '"mod_policy":' '"",' '"value":' null, '"version":' '"0"' '}' '},' '"version":' '"1"' '}' '},' '"mod_policy":' '"",' '"policies":' '{},' '"values":' '{},' '"version":' '"0"' '}' '},' '"mod_policy":' '"",' '"policies":' '{},' '"values":' '{},' '"version":' '"0"' '}' '}}}}' + configtxlator proto_encode --input config_update_in_envelope.json --type common.Envelope --output Org1MSPanchors.tx 2022-05-05 13:06:36.077 UTC 0001 INFO [channelCmd] InitCmdFactory -> Endorser and orderer connections initialized 2022-05-05 13:06:36.096 UTC 0002 INFO [channelCmd] update -> Successfully submitted channel update Anchor peer set for org 'Org1MSP' on channel 'mychannel' Setting anchor peer for org2... Using organization 2 Fetching channel config for channel mychannel Using organization 2 Fetching the most recent configuration block for the channel + peer channel fetch config config_block.pb -o orderer.example.com:7050 --ordererTLSHostnameOverride orderer.example.com -c mychannel --tls --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/organizations/ordererOrganizations/example.com/tlsca/tlsca.example.com-cert.pem 2022-05-05 13:06:36.295 UTC 0001 INFO [channelCmd] InitCmdFactory -> Endorser and orderer connections initialized 2022-05-05 13:06:36.297 UTC 0002 INFO [cli.common] readBlock -> Received block: 1 2022-05-05 13:06:36.297 UTC 0003 INFO [channelCmd] fetch -> Retrieving last config block: 1 2022-05-05 13:06:36.298 UTC 0004 INFO [cli.common] readBlock -> Received block: 1 Decoding config block to JSON and isolating config to Org2MSPconfig.json + configtxlator proto_decode --input config_block.pb --type common.Block --output config_block.json + jq '.data.data[0].payload.data.config' config_block.json Generating anchor peer update transaction for Org2 on channel mychannel + jq '.channel_group.groups.Application.groups.Org2MSP.values += {"AnchorPeers":{"mod_policy": "Admins","value":{"anchor_peers": [{"host": "peer0.org2.example.com","port": 9051}]},"version": "0"}}' Org2MSPconfig.json + configtxlator proto_encode --input Org2MSPconfig.json --type common.Config --output original_config.pb + configtxlator proto_encode --input Org2MSPmodified_config.json --type common.Config --output modified_config.pb + configtxlator compute_update --channel_id mychannel --original original_config.pb --updated modified_config.pb --output config_update.pb + configtxlator proto_decode --input config_update.pb --type common.ConfigUpdate --output config_update.json + jq . ++ cat config_update.json + echo '{"payload":{"header":{"channel_header":{"channel_id":"mychannel", "type":2}},"data":{"config_update":{' '"channel_id":' '"mychannel",' '"isolated_data":' '{},' '"read_set":' '{' '"groups":' '{' '"Application":' '{' '"groups":' '{' '"Org2MSP":' '{' '"groups":' '{},' '"mod_policy":' '"",' '"policies":' '{' '"Admins":' '{' '"mod_policy":' '"",' '"policy":' null, '"version":' '"0"' '},' '"Endorsement":' '{' '"mod_policy":' '"",' '"policy":' null, '"version":' '"0"' '},' '"Readers":' '{' '"mod_policy":' '"",' '"policy":' null, '"version":' '"0"' '},' '"Writers":' '{' '"mod_policy":' '"",' '"policy":' null, '"version":' '"0"' '}' '},' '"values":' '{' '"MSP":' '{' '"mod_policy":' '"",' '"value":' null, '"version":' '"0"' '}' '},' '"version":' '"0"' '}' '},' '"mod_policy":' '"",' '"policies":' '{},' '"values":' '{},' '"version":' '"0"' '}' '},' '"mod_policy":' '"",' '"policies":' '{},' '"values":' '{},' '"version":' '"0"' '},' '"write_set":' '{' '"groups":' '{' '"Application":' '{' '"groups":' '{' '"Org2MSP":' '{' '"groups":' '{},' '"mod_policy":' '"Admins",' '"policies":' '{' '"Admins":' '{' '"mod_policy":' '"",' '"policy":' null, '"version":' '"0"' '},' '"Endorsement":' '{' '"mod_policy":' '"",' '"policy":' null, '"version":' '"0"' '},' '"Readers":' '{' '"mod_policy":' '"",' '"policy":' null, '"version":' '"0"' '},' '"Writers":' '{' '"mod_policy":' '"",' '"policy":' null, '"version":' '"0"' '}' '},' '"values":' '{' '"AnchorPeers":' '{' '"mod_policy":' '"Admins",' '"value":' '{' '"anchor_peers":' '[' '{' '"host":' '"peer0.org2.example.com",' '"port":' 9051 '}' ']' '},' '"version":' '"0"' '},' '"MSP":' '{' '"mod_policy":' '"",' '"value":' null, '"version":' '"0"' '}' '},' '"version":' '"1"' '}' '},' '"mod_policy":' '"",' '"policies":' '{},' '"values":' '{},' '"version":' '"0"' '}' '},' '"mod_policy":' '"",' '"policies":' '{},' '"values":' '{},' '"version":' '"0"' '}' '}}}}' + configtxlator proto_encode --input config_update_in_envelope.json --type common.Envelope --output Org2MSPanchors.tx 2022-05-05 13:06:36.529 UTC 0001 INFO [channelCmd] InitCmdFactory -> Endorser and orderer connections initialized 2022-05-05 13:06:36.545 UTC 0002 INFO [channelCmd] update -> Successfully submitted channel update Anchor peer set for org 'Org2MSP' on channel 'mychannel' Channel 'mychannel' joined
在通道中安装链码
./network.sh deployCC -ccn basic -ccp ../asset-transfer-basic/chaincode-go -ccl go #./network.sh deployCC -c channel1 -ccn basic -ccp ../asset-transfer-basic/chaincode-go -ccl go
注意
链码需要先 go mod vendor (https://zhuanlan.zhihu.com/p/428434597)
结果
Using docker and docker-compose deploying chaincode on channel 'mychannel' executing with the following - CHANNEL_NAME: mychannel - CC_NAME: basic - CC_SRC_PATH: ../asset-transfer-basic/chaincode-go - CC_SRC_LANGUAGE: go - CC_VERSION: 1.0 - CC_SEQUENCE: 1 - CC_END_POLICY: NA - CC_COLL_CONFIG: NA - CC_INIT_FCN: NA - DELAY: 3 - MAX_RETRY: 5 - VERBOSE: false Vendoring Go dependencies at ../asset-transfer-basic/chaincode-go ~/go/src/github.com/hyperledger/fabric-samples/asset-transfer-basic/chaincode-go ~/go/src/github.com/hyperledger/fabric-samples/test-network ~/go/src/github.com/hyperledger/fabric-samples/test-network Finished vendoring Go dependencies + peer lifecycle chaincode package basic.tar.gz --path ../asset-transfer-basic/chaincode-go --lang golang --label basic_1.0 + res=0 Chaincode is packaged Installing chaincode on peer0.org1... Using organization 1 + peer lifecycle chaincode install basic.tar.gz + res=0 2022-05-05 21:28:23.448 CST 0001 INFO [cli.lifecycle.chaincode] submitInstallProposal -> Installed remotely: response:<status:200 payload:"\nJbasic_1.0:dee2d612e15f5059478b9048fa4b3c9f792096554841d642b9b59099fa0e04a4\022\tbasic_1.0" > 2022-05-05 21:28:23.448 CST 0002 INFO [cli.lifecycle.chaincode] submitInstallProposal -> Chaincode code package identifier: basic_1.0:dee2d612e15f5059478b9048fa4b3c9f792096554841d642b9b59099fa0e04a4 Chaincode is installed on peer0.org1 Install chaincode on peer0.org2... Using organization 2 + peer lifecycle chaincode install basic.tar.gz + res=0 2022-05-05 21:28:33.092 CST 0001 INFO [cli.lifecycle.chaincode] submitInstallProposal -> Installed remotely: response:<status:200 payload:"\nJbasic_1.0:dee2d612e15f5059478b9048fa4b3c9f792096554841d642b9b59099fa0e04a4\022\tbasic_1.0" > 2022-05-05 21:28:33.093 CST 0002 INFO [cli.lifecycle.chaincode] submitInstallProposal -> Chaincode code package identifier: basic_1.0:dee2d612e15f5059478b9048fa4b3c9f792096554841d642b9b59099fa0e04a4 Chaincode is installed on peer0.org2 Using organization 1 + peer lifecycle chaincode queryinstalled + res=0 Installed chaincodes on peer: Package ID: basic_1.0:dee2d612e15f5059478b9048fa4b3c9f792096554841d642b9b59099fa0e04a4, Label: basic_1.0 Query installed successful on peer0.org1 on channel Using organization 1 + peer lifecycle chaincode approveformyorg -o localhost:7050 --ordererTLSHostnameOverride orderer.example.com --tls --cafile /home/allan/go/src/github.com/hyperledger/fabric-samples/test-network/organizations/ordererOrganizations/example.com/tlsca/tlsca.example.com-cert.pem --channelID mychannel --name basic --version 1.0 --package-id basic_1.0:dee2d612e15f5059478b9048fa4b3c9f792096554841d642b9b59099fa0e04a4 --sequence 1 + res=0 2022-05-05 21:28:35.389 CST 0001 INFO [chaincodeCmd] ClientWait -> txid [bade9480a249f6c71b1ba9f21da1472582079fc5c0f68a3b578ffb688d4160a8] committed with status (VALID) at localhost:7051 Chaincode definition approved on peer0.org1 on channel 'mychannel' Using organization 1 Checking the commit readiness of the chaincode definition on peer0.org1 on channel 'mychannel'... Attempting to check the commit readiness of the chaincode definition on peer0.org1, Retry after 3 seconds. + peer lifecycle chaincode checkcommitreadiness --channelID mychannel --name basic --version 1.0 --sequence 1 --output json + res=0 { "approvals": { "Org1MSP": true, "Org2MSP": false } } Checking the commit readiness of the chaincode definition successful on peer0.org1 on channel 'mychannel' Using organization 2 Checking the commit readiness of the chaincode definition on peer0.org2 on channel 'mychannel'... Attempting to check the commit readiness of the chaincode definition on peer0.org2, Retry after 3 seconds. + peer lifecycle chaincode checkcommitreadiness --channelID mychannel --name basic --version 1.0 --sequence 1 --output json + res=0 { "approvals": { "Org1MSP": true, "Org2MSP": false } } Checking the commit readiness of the chaincode definition successful on peer0.org2 on channel 'mychannel' Using organization 2 + peer lifecycle chaincode approveformyorg -o localhost:7050 --ordererTLSHostnameOverride orderer.example.com --tls --cafile /home/allan/go/src/github.com/hyperledger/fabric-samples/test-network/organizations/ordererOrganizations/example.com/tlsca/tlsca.example.com-cert.pem --channelID mychannel --name basic --version 1.0 --package-id basic_1.0:dee2d612e15f5059478b9048fa4b3c9f792096554841d642b9b59099fa0e04a4 --sequence 1 + res=0 2022-05-05 21:28:43.674 CST 0001 INFO [chaincodeCmd] ClientWait -> txid [a7028eeea9f50167ef0b8be6c2717e8ce2196474c418a2fcbe71571246c13378] committed with status (VALID) at localhost:9051 Chaincode definition approved on peer0.org2 on channel 'mychannel' Using organization 1 Checking the commit readiness of the chaincode definition on peer0.org1 on channel 'mychannel'... Attempting to check the commit readiness of the chaincode definition on peer0.org1, Retry after 3 seconds. + peer lifecycle chaincode checkcommitreadiness --channelID mychannel --name basic --version 1.0 --sequence 1 --output json + res=0 { "approvals": { "Org1MSP": true, "Org2MSP": true } } Checking the commit readiness of the chaincode definition successful on peer0.org1 on channel 'mychannel' Using organization 2 Checking the commit readiness of the chaincode definition on peer0.org2 on channel 'mychannel'... Attempting to check the commit readiness of the chaincode definition on peer0.org2, Retry after 3 seconds. + peer lifecycle chaincode checkcommitreadiness --channelID mychannel --name basic --version 1.0 --sequence 1 --output json + res=0 { "approvals": { "Org1MSP": true, "Org2MSP": true } } Checking the commit readiness of the chaincode definition successful on peer0.org2 on channel 'mychannel' Using organization 1 Using organization 2 + peer lifecycle chaincode commit -o localhost:7050 --ordererTLSHostnameOverride orderer.example.com --tls --cafile /home/allan/go/src/github.com/hyperledger/fabric-samples/test-network/organizations/ordererOrganizations/example.com/tlsca/tlsca.example.com-cert.pem --channelID mychannel --name basic --peerAddresses localhost:7051 --tlsRootCertFiles /home/allan/go/src/github.com/hyperledger/fabric-samples/test-network/organizations/peerOrganizations/org1.example.com/tlsca/tlsca.org1.example.com-cert.pem --peerAddresses localhost:9051 --tlsRootCertFiles /home/allan/go/src/github.com/hyperledger/fabric-samples/test-network/organizations/peerOrganizations/org2.example.com/tlsca/tlsca.org2.example.com-cert.pem --version 1.0 --sequence 1 + res=0 2022-05-05 21:28:52.097 CST 0001 INFO [chaincodeCmd] ClientWait -> txid [11d4bb31f979133f936f10d28213accc05af34049b38c7f2c9add4f35d91f73d] committed with status (VALID) at localhost:7051 2022-05-05 21:28:52.106 CST 0002 INFO [chaincodeCmd] ClientWait -> txid [11d4bb31f979133f936f10d28213accc05af34049b38c7f2c9add4f35d91f73d] committed with status (VALID) at localhost:9051 Chaincode definition committed on channel 'mychannel' Using organization 1 Querying chaincode definition on peer0.org1 on channel 'mychannel'... Attempting to Query committed status on peer0.org1, Retry after 3 seconds. + peer lifecycle chaincode querycommitted --channelID mychannel --name basic + res=0 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] Query chaincode definition successful on peer0.org1 on channel 'mychannel' Using organization 2 Querying chaincode definition on peer0.org2 on channel 'mychannel'... Attempting to Query committed status on peer0.org2, Retry after 3 seconds. + peer lifecycle chaincode querycommitted --channelID mychannel --name basic + res=0 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] Query chaincode definition successful on peer0.org2 on channel 'mychannel' Chaincode initialization is not required
3 和区块链网络进行交互
导出环境变量
export PATH=${PWD}/../bin:$PATH # set the FABRIC_CFG_PATH to point to the core.yaml file in the fabric-samples repository # pwd : /home/allan/go/src/github.com/hyperledger/fabric-samples/test-network export FABRIC_CFG_PATH=$PWD/../config/
切换成org1
为可操作 the peer
CLI as Org1 设置环境变量
# Environment variables for 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/Admin@org1.example.com/msp export CORE_PEER_ADDRESS=localhost:7051
链码初始化
若使用
./network.sh deployCC -ccl go
安装 asset-transfer (basic) chaincode,可以调用GO链码的InitLedger
函数 to put an initial list of assets on the ledger (若使用 TypeScript or JavaScript./network.sh deployCC -ccl javascript
for example, you will invoke theInitLedger
function of the respective chaincodes).Run the following command to initialize the ledger with assets. (注意 the CLI does not access the Fabric Gateway peer, so each endorsing peer must be specified.)
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":[]}'
结果
2022-05-05 21:41:22.729 CST 0001 INFO [chaincodeCmd] chaincodeInvokeOrQuery -> Chaincode invoke successful. result: status:200
查询所有资产
调用链码来 get the list of assets that were added to your channel ledger:
peer chaincode query -C mychannel -n basic -c '{"Args":["GetAllAssets"]}'
结果
[{"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}]
资产转移
Because the endorsement policy for the asset-transfer (basic) chaincode requires the transaction to be signed by Org1 and Org2, the chaincode invoke command needs to target both
peer0.org1.example.com
andpeer0.org2.example.com
using the--peerAddresses
flag. Because TLS is enabled for the network, the command also needs to reference the TLS certificate for each peer using the--tlsRootCertFiles
flag.
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":"TransferAsset","Args":["asset6","Christopher"]}'
结果
2022-05-05 21:46:45.135 CST 0001 INFO [chaincodeCmd] chaincodeInvokeOrQuery -> Chaincode invoke successful. result: status:200 payload:"Michel"
切换成org2
After we invoke the chaincode, we can use another query to see how the invoke changed the assets on the blockchain ledger. Since we already queried the Org1 peer, we can take this opportunity to query the chaincode running on the Org2 peer. Set the following environment variables to operate as Org2:
# Environment variables for Org2 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
查看指定资产
peer chaincode query -C mychannel -n basic -c '{"Args":["ReadAsset","asset6"]}'
结果
{"AppraisedValue":800,"Color":"white","ID":"asset6","Owner":"Christopher","Size":15}
再次查看所有资产
peer chaincode query -C mychannel -n basic -c '{"Args":["GetAllAssets"]}'
可以看到"asset6","Owner":"Christopher"
结果
[{"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":"Christopher","Size":15}]
关闭网络
./network.sh down
4 下一步
- Learn how to deploy your own smart contracts to the test network using the Deploying a smart contract to a channel tutorial.
- Visit the Running a Fabric Application tutorial to learn how to use the APIs provided by the Fabric SDKs to invoke smart contracts from your client applications.
You can find the complete list of Fabric tutorials on the tutorials page.
What’s happening behind the scenes?
If you are interested in learning more about the sample network, you can investigate the files and scripts in the test-network
directory. The steps below provide a guided tour of what happens when you issue the command of ./network.sh up
.
./network.sh
creates the certificates and keys for two peer organizations and the orderer organization. By default, the script uses the cryptogen tool using the configuration files located in theorganizations/cryptogen
folder. If you use the-ca
flag to create Certificate Authorities, the script uses Fabric CA server configuration files andregisterEnroll.sh
script located in theorganizations/fabric-ca
folder. Both cryptogen and the Fabric CAs create the crypto material and MSP folders for all three organizations in theorganizations
folder.- Once the organization crypto material has been generated, the
network.sh
can bring up the nodes of the network. The script uses thedocker-compose-test-net.yaml
file in thedocker
folder to create the peer and orderer nodes. Thedocker
folder also contains thedocker-compose-e2e.yaml
file that brings up the nodes of the network alongside three Fabric CAs. This file is meant to be used to run end-to-end tests by the Fabric SDK. Refer to the Node SDK repo for details on running these tests. - If you use the
createChannel
subcommand,./network.sh
runs thecreateChannel.sh
script in thescripts
folder to create a channel using the supplied channel name. The script uses theconfigtxgen
tool to create the channel genesis block based on theTwoOrgsApplicationGenesis
channel profile in theconfigtx/configtx.yaml
file. After creating the channel, the script uses the peer cli to joinpeer0.org1.example.com
andpeer0.org2.example.com
to the channel, and make both of the peers anchor peers. - If you issue the
deployCC
command,./network.sh
runs thedeployCC.sh
script to install the asset-transfer (basic) chaincode on both peers and then define then chaincode on the channel. Once the chaincode definition is committed to the channel, the peer cli initializes the chaincode using theInit
and invokes the chaincode to put initial data on the ledger.
附 network.sh
#!/bin/bash # # Copyright IBM Corp All Rights Reserved # # SPDX-License-Identifier: Apache-2.0 # # This script brings up a Hyperledger Fabric network for testing smart contracts # and applications. The test network consists of two organizations with one # peer each, and a single node Raft ordering service. Users can also use this # script to create a channel deploy a chaincode on the channel # # prepending $PWD/../bin to PATH to ensure we are picking up the correct binaries # this may be commented out to resolve installed version of tools if desired # # However using PWD in the path has the side effect that location that # this script is run from is critical. To ease this, get the directory # this script is actually in and infer location from there. (putting first) ROOTDIR=$(cd "$(dirname "$0")" && pwd) export PATH=${ROOTDIR}/../bin:${PWD}/../bin:$PATH export FABRIC_CFG_PATH=${PWD}/configtx export VERBOSE=false # push to the required directory & set a trap to go back if needed pushd ${ROOTDIR} > /dev/null trap "popd > /dev/null" EXIT . scripts/utils.sh : ${CONTAINER_CLI:="docker"} : ${CONTAINER_CLI_COMPOSE:="${CONTAINER_CLI}-compose"} infoln "Using ${CONTAINER_CLI} and ${CONTAINER_CLI_COMPOSE}" # Obtain CONTAINER_IDS and remove them # This function is called when you bring a network down function clearContainers() { infoln "Removing remaining containers" ${CONTAINER_CLI} rm -f $(${CONTAINER_CLI} ps -aq --filter label=service=hyperledger-fabric) 2>/dev/null || true ${CONTAINER_CLI} rm -f $(${CONTAINER_CLI} ps -aq --filter name='dev-peer*') 2>/dev/null || true } # Delete any images that were generated as a part of this setup # specifically the following images are often left behind: # This function is called when you bring the network down function removeUnwantedImages() { infoln "Removing generated chaincode docker images" ${CONTAINER_CLI} image rm -f $(${CONTAINER_CLI} images -aq --filter reference='dev-peer*') 2>/dev/null || true } # Versions of fabric known not to work with the test network NONWORKING_VERSIONS="^1\.0\. ^1\.1\. ^1\.2\. ^1\.3\. ^1\.4\." # Do some basic sanity checking to make sure that the appropriate versions of fabric # binaries/images are available. In the future, additional checking for the presence # of go or other items could be added. function checkPrereqs() { ## Check if your have cloned the peer binaries and configuration files. peer version > /dev/null 2>&1 if [[ $? -ne 0 || ! -d "../config" ]]; then errorln "Peer binary and configuration files not found.." errorln errorln "Follow the instructions in the Fabric docs to install the Fabric Binaries:" errorln "https://hyperledger-fabric.readthedocs.io/en/latest/install.html" exit 1 fi # use the fabric tools container to see if the samples and binaries match your # docker images LOCAL_VERSION=$(peer version | sed -ne 's/^ Version: //p') DOCKER_IMAGE_VERSION=$(${CONTAINER_CLI} run --rm hyperledger/fabric-tools:latest peer version | sed -ne 's/^ Version: //p') infoln "LOCAL_VERSION=$LOCAL_VERSION" infoln "DOCKER_IMAGE_VERSION=$DOCKER_IMAGE_VERSION" if [ "$LOCAL_VERSION" != "$DOCKER_IMAGE_VERSION" ]; then warnln "Local fabric binaries and docker images are out of sync. This may cause problems." fi for UNSUPPORTED_VERSION in $NONWORKING_VERSIONS; do infoln "$LOCAL_VERSION" | grep -q $UNSUPPORTED_VERSION if [ $? -eq 0 ]; then fatalln "Local Fabric binary version of $LOCAL_VERSION does not match the versions supported by the test network." fi infoln "$DOCKER_IMAGE_VERSION" | grep -q $UNSUPPORTED_VERSION if [ $? -eq 0 ]; then fatalln "Fabric Docker image version of $DOCKER_IMAGE_VERSION does not match the versions supported by the test network." fi done ## Check for fabric-ca if [ "$CRYPTO" == "Certificate Authorities" ]; then fabric-ca-client version > /dev/null 2>&1 if [[ $? -ne 0 ]]; then errorln "fabric-ca-client binary not found.." errorln errorln "Follow the instructions in the Fabric docs to install the Fabric Binaries:" errorln "https://hyperledger-fabric.readthedocs.io/en/latest/install.html" exit 1 fi CA_LOCAL_VERSION=$(fabric-ca-client version | sed -ne 's/ Version: //p') CA_DOCKER_IMAGE_VERSION=$(docker run --rm hyperledger/fabric-ca:latest fabric-ca-client version | sed -ne 's/ Version: //p' | head -1) infoln "CA_LOCAL_VERSION=$CA_LOCAL_VERSION" infoln "CA_DOCKER_IMAGE_VERSION=$CA_DOCKER_IMAGE_VERSION" if [ "$CA_LOCAL_VERSION" != "$CA_DOCKER_IMAGE_VERSION" ]; then warnln "Local fabric-ca binaries and docker images are out of sync. This may cause problems." fi fi } # Before you can bring up a network, each organization needs to generate the crypto # material that will define that organization on the network. Because Hyperledger # Fabric is a permissioned blockchain, each node and user on the network needs to # use certificates and keys to sign and verify its actions. In addition, each user # needs to belong to an organization that is recognized as a member of the network. # You can use the Cryptogen tool or Fabric CAs to generate the organization crypto # material. # By default, the sample network uses cryptogen. Cryptogen is a tool that is # meant for development and testing that can quickly create the certificates and keys # that can be consumed by a Fabric network. The cryptogen tool consumes a series # of configuration files for each organization in the "organizations/cryptogen" # directory. Cryptogen uses the files to generate the crypto material for each # org in the "organizations" directory. # You can also use Fabric CAs to generate the crypto material. CAs sign the certificates # and keys that they generate to create a valid root of trust for each organization. # The script uses Docker Compose to bring up three CAs, one for each peer organization # and the ordering organization. The configuration file for creating the Fabric CA # servers are in the "organizations/fabric-ca" directory. Within the same directory, # the "registerEnroll.sh" script uses the Fabric CA client to create the identities, # certificates, and MSP folders that are needed to create the test network in the # "organizations/ordererOrganizations" directory. # Create Organization crypto material using cryptogen or CAs function createOrgs() { if [ -d "organizations/peerOrganizations" ]; then rm -Rf organizations/peerOrganizations && rm -Rf organizations/ordererOrganizations fi # Create crypto material using cryptogen if [ "$CRYPTO" == "cryptogen" ]; then which cryptogen if [ "$?" -ne 0 ]; then fatalln "cryptogen tool not found. exiting" fi infoln "Generating certificates using cryptogen tool" infoln "Creating Org1 Identities" set -x cryptogen generate --config=./organizations/cryptogen/crypto-config-org1.yaml --output="organizations" res=$? { set +x; } 2>/dev/null if [ $res -ne 0 ]; then fatalln "Failed to generate certificates..." fi infoln "Creating Org2 Identities" set -x cryptogen generate --config=./organizations/cryptogen/crypto-config-org2.yaml --output="organizations" res=$? { set +x; } 2>/dev/null if [ $res -ne 0 ]; then fatalln "Failed to generate certificates..." fi infoln "Creating Orderer Org Identities" set -x cryptogen generate --config=./organizations/cryptogen/crypto-config-orderer.yaml --output="organizations" res=$? { set +x; } 2>/dev/null if [ $res -ne 0 ]; then fatalln "Failed to generate certificates..." fi fi # Create crypto material using Fabric CA if [ "$CRYPTO" == "Certificate Authorities" ]; then infoln "Generating certificates using Fabric CA" ${CONTAINER_CLI_COMPOSE} -f compose/$COMPOSE_FILE_CA -f compose/$CONTAINER_CLI/${CONTAINER_CLI}-$COMPOSE_FILE_CA up -d 2>&1 . organizations/fabric-ca/registerEnroll.sh while : do if [ ! -f "organizations/fabric-ca/org1/tls-cert.pem" ]; then sleep 1 else break fi done infoln "Creating Org1 Identities" createOrg1 infoln "Creating Org2 Identities" createOrg2 infoln "Creating Orderer Org Identities" createOrderer fi infoln "Generating CCP files for Org1 and Org2" ./organizations/ccp-generate.sh } # Once you create the organization crypto material, you need to create the # genesis block of the application channel. # The configtxgen tool is used to create the genesis block. Configtxgen consumes a # "configtx.yaml" file that contains the definitions for the sample network. The # genesis block is defined using the "TwoOrgsApplicationGenesis" profile at the bottom # of the file. This profile defines an application channel consisting of our two Peer Orgs. # The peer and ordering organizations are defined in the "Profiles" section at the # top of the file. As part of each organization profile, the file points to the # location of the MSP directory for each member. This MSP is used to create the channel # MSP that defines the root of trust for each organization. In essence, the channel # MSP allows the nodes and users to be recognized as network members. # # If you receive the following warning, it can be safely ignored: # # [bccsp] GetDefault -> WARN 001 Before using BCCSP, please call InitFactories(). Falling back to bootBCCSP. # # You can ignore the logs regarding intermediate certs, we are not using them in # this crypto implementation. # After we create the org crypto material and the application channel genesis block, # we can now bring up the peers and ordering service. By default, the base # file for creating the network is "docker-compose-test-net.yaml" in the ``docker`` # folder. This file defines the environment variables and file mounts that # point the crypto material and genesis block that were created in earlier. # Bring up the peer and orderer nodes using docker compose. function networkUp() { checkPrereqs # generate artifacts if they don't exist if [ ! -d "organizations/peerOrganizations" ]; then createOrgs fi COMPOSE_FILES="-f compose/${COMPOSE_FILE_BASE} -f compose/${CONTAINER_CLI}/${CONTAINER_CLI}-${COMPOSE_FILE_BASE}" if [ "${DATABASE}" == "couchdb" ]; then COMPOSE_FILES="${COMPOSE_FILES} -f compose/${COMPOSE_FILE_COUCH} -f compose/${CONTAINER_CLI}/${CONTAINER_CLI}-${COMPOSE_FILE_COUCH}" fi DOCKER_SOCK="${DOCKER_SOCK}" ${CONTAINER_CLI_COMPOSE} ${COMPOSE_FILES} up -d 2>&1 $CONTAINER_CLI ps -a if [ $? -ne 0 ]; then fatalln "Unable to start network" fi } # call the script to create the channel, join the peers of org1 and org2, # and then update the anchor peers for each organization function createChannel() { # Bring up the network if it is not already up. bringUpNetwork="false" if ! $CONTAINER_CLI info > /dev/null 2>&1 ; then fatalln "$CONTAINER_CLI network is required to be running to create a channel" fi # check if all containers are present CONTAINERS=($($CONTAINER_CLI ps | grep hyperledger/ | awk '{print $2}')) len=$(echo ${#CONTAINERS[@]}) if [[ $len -ge 4 ]] && [[ ! -d "organizations/peerOrganizations" ]]; then echo "Bringing network down to sync certs with containers" networkDown fi [[ $len -lt 4 ]] || [[ ! -d "organizations/peerOrganizations" ]] && bringUpNetwork="true" || echo "Network Running Already" if [ $bringUpNetwork == "true" ]; then infoln "Bringing up network" networkUp fi # now run the script that creates a channel. This script uses configtxgen once # to create the channel creation transaction and the anchor peer updates. scripts/createChannel.sh $CHANNEL_NAME $CLI_DELAY $MAX_RETRY $VERBOSE } ## Call the script to deploy a chaincode to the channel function deployCC() { scripts/deployCC.sh $CHANNEL_NAME $CC_NAME $CC_SRC_PATH $CC_SRC_LANGUAGE $CC_VERSION $CC_SEQUENCE $CC_INIT_FCN $CC_END_POLICY $CC_COLL_CONFIG $CLI_DELAY $MAX_RETRY $VERBOSE if [ $? -ne 0 ]; then fatalln "Deploying chaincode failed" fi } ## Call the script to deploy a chaincode to the channel function deployCCAAS() { scripts/deployCCAAS.sh $CHANNEL_NAME $CC_NAME $CC_SRC_PATH $CCAAS_DOCKER_RUN $CC_VERSION $CC_SEQUENCE $CC_INIT_FCN $CC_END_POLICY $CC_COLL_CONFIG $CLI_DELAY $MAX_RETRY $VERBOSE $CCAAS_DOCKER_RUN if [ $? -ne 0 ]; then fatalln "Deploying chaincode-as-a-service failed" fi } # Tear down running network function networkDown() { COMPOSE_BASE_FILES="-f compose/${COMPOSE_FILE_BASE} -f compose/${CONTAINER_CLI}/${CONTAINER_CLI}-${COMPOSE_FILE_BASE}" COMPOSE_COUCH_FILES="-f compose/${COMPOSE_FILE_COUCH} -f compose/${CONTAINER_CLI}/${CONTAINER_CLI}-${COMPOSE_FILE_COUCH}" COMPOSE_CA_FILES="-f compose/${COMPOSE_FILE_CA} -f compose/${CONTAINER_CLI}/${CONTAINER_CLI}-${COMPOSE_FILE_CA}" COMPOSE_FILES="${COMPOSE_BASE_FILES} ${COMPOSE_COUCH_FILES} ${COMPOSE_CA_FILES}" # stop org3 containers also in addition to org1 and org2, in case we were running sample to add org3 COMPOSE_ORG3_BASE_FILES="-f addOrg3/compose/${COMPOSE_FILE_ORG3_BASE} -f addOrg3/compose/${CONTAINER_CLI}/${CONTAINER_CLI}-${COMPOSE_FILE_ORG3_BASE}" COMPOSE_ORG3_COUCH_FILES="-f addOrg3/compose/${COMPOSE_FILE_ORG3_COUCH} -f addOrg3/compose/${CONTAINER_CLI}/${CONTAINER_CLI}-${COMPOSE_FILE_ORG3_COUCH}" COMPOSE_ORG3_CA_FILES="-f addOrg3/compose/${COMPOSE_FILE_ORG3_CA} -f addOrg3/compose/${CONTAINER_CLI}/${CONTAINER_CLI}-${COMPOSE_FILE_ORG3_CA}" COMPOSE_ORG3_FILES="${COMPOSE_ORG3_BASE_FILES} ${COMPOSE_ORG3_COUCH_FILES} ${COMPOSE_ORG3_CA_FILES}" if [ "${CONTAINER_CLI}" == "docker" ]; then DOCKER_SOCK=$DOCKER_SOCK ${CONTAINER_CLI_COMPOSE} ${COMPOSE_FILES} ${COMPOSE_ORG3_FILES} down --volumes --remove-orphans elif [ "${CONTAINER_CLI}" == "podman" ]; then ${CONTAINER_CLI_COMPOSE} ${COMPOSE_FILES} ${COMPOSE_ORG3_FILES} down --volumes else fatalln "Container CLI ${CONTAINER_CLI} not supported" fi # Don't remove the generated artifacts -- note, the ledgers are always removed if [ "$MODE" != "restart" ]; then # Bring down the network, deleting the volumes ${CONTAINER_CLI} volume rm docker_orderer.example.com docker_peer0.org1.example.com docker_peer0.org2.example.com #Cleanup the chaincode containers clearContainers #Cleanup images removeUnwantedImages # ${CONTAINER_CLI} kill $(${CONTAINER_CLI} ps -q --filter name=ccaas) || true # remove orderer block and other channel configuration transactions and certs ${CONTAINER_CLI} run --rm -v "$(pwd):/data" busybox sh -c 'cd /data && rm -rf system-genesis-block/*.block organizations/peerOrganizations organizations/ordererOrganizations' ## remove fabric ca artifacts ${CONTAINER_CLI} run --rm -v "$(pwd):/data" busybox sh -c 'cd /data && rm -rf organizations/fabric-ca/org1/msp organizations/fabric-ca/org1/tls-cert.pem organizations/fabric-ca/org1/ca-cert.pem organizations/fabric-ca/org1/IssuerPublicKey organizations/fabric-ca/org1/IssuerRevocationPublicKey organizations/fabric-ca/org1/fabric-ca-server.db' ${CONTAINER_CLI} run --rm -v "$(pwd):/data" busybox sh -c 'cd /data && rm -rf organizations/fabric-ca/org2/msp organizations/fabric-ca/org2/tls-cert.pem organizations/fabric-ca/org2/ca-cert.pem organizations/fabric-ca/org2/IssuerPublicKey organizations/fabric-ca/org2/IssuerRevocationPublicKey organizations/fabric-ca/org2/fabric-ca-server.db' ${CONTAINER_CLI} run --rm -v "$(pwd):/data" busybox sh -c 'cd /data && rm -rf organizations/fabric-ca/ordererOrg/msp organizations/fabric-ca/ordererOrg/tls-cert.pem organizations/fabric-ca/ordererOrg/ca-cert.pem organizations/fabric-ca/ordererOrg/IssuerPublicKey organizations/fabric-ca/ordererOrg/IssuerRevocationPublicKey organizations/fabric-ca/ordererOrg/fabric-ca-server.db' ${CONTAINER_CLI} run --rm -v "$(pwd):/data" busybox sh -c 'cd /data && rm -rf addOrg3/fabric-ca/org3/msp addOrg3/fabric-ca/org3/tls-cert.pem addOrg3/fabric-ca/org3/ca-cert.pem addOrg3/fabric-ca/org3/IssuerPublicKey addOrg3/fabric-ca/org3/IssuerRevocationPublicKey addOrg3/fabric-ca/org3/fabric-ca-server.db' # remove channel and script artifacts ${CONTAINER_CLI} run --rm -v "$(pwd):/data" busybox sh -c 'cd /data && rm -rf channel-artifacts log.txt *.tar.gz' fi } # Using crpto vs CA. default is cryptogen CRYPTO="cryptogen" # timeout duration - the duration the CLI should wait for a response from # another container before giving up MAX_RETRY=5 # default for delay between commands CLI_DELAY=3 # channel name defaults to "mychannel" CHANNEL_NAME="mychannel" # chaincode name defaults to "NA" CC_NAME="NA" # chaincode path defaults to "NA" CC_SRC_PATH="NA" # endorsement policy defaults to "NA". This would allow chaincodes to use the majority default policy. CC_END_POLICY="NA" # collection configuration defaults to "NA" CC_COLL_CONFIG="NA" # chaincode init function defaults to "NA" CC_INIT_FCN="NA" # use this as the default docker-compose yaml definition COMPOSE_FILE_BASE=compose-test-net.yaml # docker-compose.yaml file if you are using couchdb COMPOSE_FILE_COUCH=compose-couch.yaml # certificate authorities compose file COMPOSE_FILE_CA=compose-ca.yaml # use this as the default docker-compose yaml definition for org3 COMPOSE_FILE_ORG3_BASE=compose-org3.yaml # use this as the docker compose couch file for org3 COMPOSE_FILE_ORG3_COUCH=compose-couch-org3.yaml # certificate authorities compose file COMPOSE_FILE_ORG3_CA=compose-ca-org3.yaml # # chaincode language defaults to "NA" CC_SRC_LANGUAGE="NA" # default to running the docker commands for the CCAAS CCAAS_DOCKER_RUN=true # Chaincode version CC_VERSION="1.0" # Chaincode definition sequence CC_SEQUENCE=1 # default database DATABASE="leveldb" # Get docker sock path from environment variable SOCK="${DOCKER_HOST:-/var/run/docker.sock}" DOCKER_SOCK="${SOCK##unix://}" # Parse commandline args ## Parse mode if [[ $# -lt 1 ]] ; then printHelp exit 0 else MODE=$1 shift fi # parse a createChannel subcommand if used if [[ $# -ge 1 ]] ; then key="$1" if [[ "$key" == "createChannel" ]]; then export MODE="createChannel" shift fi fi # parse flags while [[ $# -ge 1 ]] ; do key="$1" case $key in -h ) printHelp $MODE exit 0 ;; -c ) CHANNEL_NAME="$2" shift ;; -ca ) CRYPTO="Certificate Authorities" ;; -r ) MAX_RETRY="$2" shift ;; -d ) CLI_DELAY="$2" shift ;; -s ) DATABASE="$2" shift ;; -ccl ) CC_SRC_LANGUAGE="$2" shift ;; -ccn ) CC_NAME="$2" shift ;; -ccv ) CC_VERSION="$2" shift ;; -ccs ) CC_SEQUENCE="$2" shift ;; -ccp ) CC_SRC_PATH="$2" shift ;; -ccep ) CC_END_POLICY="$2" shift ;; -cccg ) CC_COLL_CONFIG="$2" shift ;; -cci ) CC_INIT_FCN="$2" shift ;; -ccaasdocker ) CCAAS_DOCKER_RUN="$2" shift ;; -verbose ) VERBOSE=true ;; * ) errorln "Unknown flag: $key" printHelp exit 1 ;; esac shift done # Are we generating crypto material with this command? if [ ! -d "organizations/peerOrganizations" ]; then CRYPTO_MODE="with crypto from '${CRYPTO}'" else CRYPTO_MODE="" fi # Determine mode of operation and printing out what we asked for if [ "$MODE" == "up" ]; then infoln "Starting nodes with CLI timeout of '${MAX_RETRY}' tries and CLI delay of '${CLI_DELAY}' seconds and using database '${DATABASE}' ${CRYPTO_MODE}" networkUp elif [ "$MODE" == "createChannel" ]; then infoln "Creating channel '${CHANNEL_NAME}'." infoln "If network is not up, starting nodes with CLI timeout of '${MAX_RETRY}' tries and CLI delay of '${CLI_DELAY}' seconds and using database '${DATABASE} ${CRYPTO_MODE}" createChannel elif [ "$MODE" == "down" ]; then infoln "Stopping network" networkDown elif [ "$MODE" == "restart" ]; then infoln "Restarting network" networkDown networkUp elif [ "$MODE" == "deployCC" ]; then infoln "deploying chaincode on channel '${CHANNEL_NAME}'" deployCC elif [ "$MODE" == "deployCCAAS" ]; then infoln "deploying chaincode-as-a-service on channel '${CHANNEL_NAME}'" deployCCAAS else printHelp exit 1 fi
若非特意注明,本博客内容整理自互联网/课堂(部分来源已给出),仅供个人学习使用,不用于任何商业用途。如果认为可能请侵犯到您的权益,请联系以删除。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!