Update with new multi-channel support
parent
bcf2d4224c
commit
e3f3087f47
|
@ -1,21 +1,25 @@
|
|||
# Hyperledger fabric 1.0
|
||||
|
||||
If you're using Ubuntu, you can use the following script to install Docker and start a fabric 1.0 Minimum Viable Environment (MVE) in one instruction.
|
||||
|
||||
```sh
|
||||
$ bash setup_fabric_1.0.sh
|
||||
```
|
||||
|
||||
tldr :)
|
||||
|
||||
If you want to explore more, then can follow these steps.
|
||||
Here we give steps on how to setup a fabric 1.0 cluster, and then use it to run chaincode tests.
|
||||
|
||||
If you're not familiar with Docker and Blockchain, can have a look at 2 books (in CN):
|
||||
|
||||
* [Docker Practice](https://github.com/yeasy/docker_practice)
|
||||
* [Blockchain Guide](https://github.com/yeasy/blockchain_guide)
|
||||
|
||||
## Preparation
|
||||
## Manual Setup
|
||||
|
||||
tldr :)
|
||||
|
||||
With Ubuntu/Debian, you can simple use the following script to setup the environment in one instruction.
|
||||
|
||||
```sh
|
||||
$ bash setup_fabric_1.0.sh
|
||||
```
|
||||
|
||||
|
||||
If you want to setup the environment manually, then can follow the below steps in this section.
|
||||
|
||||
|
||||
### Download Images
|
||||
|
||||
|
@ -42,28 +46,9 @@ $ docker pull yeasy/hyperledger-fabric-base:$IMG_VERSION \
|
|||
There are also some community [images](https://hub.docker.com/r/hyperledger/) at Dockerhub, use at your own choice.
|
||||
|
||||
|
||||
### Setup network
|
||||
### Bootup Fabric 1.0
|
||||
|
||||
*Just ignore if you are not familiar with Docker networking configurations.*
|
||||
|
||||
The template can support using separate network for the chain.
|
||||
|
||||
By default, the feature is disabled to use the shared Docker network.
|
||||
|
||||
If you want to enable the feature, just un-comment the bottom networks section in the compose file and the `CORE_VM_DOCKER_HOSTCONFIG_NETWORKMODE` line in the `peer-[noops,pbft].yml` file.
|
||||
|
||||
Then, create the following two Docker networks.
|
||||
|
||||
```sh
|
||||
$ docker network create fabric_noops
|
||||
$ docker network create fabric_pbft
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
### Fabric Bootup
|
||||
|
||||
Start a MVE fabric cluster. with the peer joined the default channel `testchainid`.
|
||||
Start a MVE fabric cluster. All the peers joined the default channel `testchainid`.
|
||||
|
||||
```sh
|
||||
$ docker-compose up
|
||||
|
@ -81,8 +66,12 @@ CONTAINER ID IMAGE COMMAND CREATE
|
|||
71c2246e1165 hyperledger/fabric-ca "fabric-ca server ..." 6 minutes ago Up 6 minutes 7054/tcp, 0.0.0.0:8888->8888/tcp
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
### Test chaincode with default channel
|
||||
|
||||
By default, all the peer will join the system chain of `testchainid`.
|
||||
|
||||
After the cluster is synced successfully, you can validate by deploying, invoking or querying chaincode from the container or from the host.
|
||||
|
||||
#### Deploy
|
||||
|
@ -92,8 +81,8 @@ Inside the container, run the following command to deploy a new chaincode of the
|
|||
|
||||
```bash
|
||||
$ docker exec -it fabric-peer0 bash
|
||||
root@peer0:/go/src/github.com/hyperledger/fabric# peer chaincode install -v 1.0 -n test_cc -p github.com/hyperledger/fabric/examples/chaincode/go/chaincode_example02 -c '{"Args":["init","a","100","b","200"]}' -o orderer:7050
|
||||
root@peer0:/go/src/github.com/hyperledger/fabric# peer chaincode instantiate -v 1.0 -n test_cc -p github.com/hyperledger/fabric/examples/chaincode/go/chaincode_example02 -c '{"Args":["init","a","100","b","200"]}' -o orderer:7050
|
||||
root@peer0:/go/src/github.com/hyperledger/fabric# peer chaincode install -v 1.0 -n test_cc -p github.com/hyperledger/fabric/examples/chaincode/go/chaincode_example02 -c '{"Args":["init","a","100","b","200"]}' -o orderer0:7050
|
||||
root@peer0:/go/src/github.com/hyperledger/fabric# peer chaincode instantiate -v 1.0 -n test_cc -p github.com/hyperledger/fabric/examples/chaincode/go/chaincode_example02 -c '{"Args":["init","a","100","b","200"]}' -o orderer0:7050
|
||||
```
|
||||
|
||||
There should be no error in the return log, and in the peer nodes's output.
|
||||
|
@ -123,7 +112,7 @@ Inside the container, query the existing value of `a` and `b`.
|
|||
*Notice that the query method can be called by invoke a transaction.*
|
||||
|
||||
```bash
|
||||
root@peer0:/go/src/github.com/hyperledger/fabric# peer chaincode query -n test_cc -c '{"Args":["query","a"]}' -o orderer:7050
|
||||
root@peer0:/go/src/github.com/hyperledger/fabric# peer chaincode query -n test_cc -c '{"Args":["query","a"]}' -o orderer0:7050
|
||||
```
|
||||
|
||||
The final output may look like the following, with a payload value of `100`.
|
||||
|
@ -136,7 +125,7 @@ Query Result: 100
|
|||
Query the value of `b`
|
||||
|
||||
```bash
|
||||
root@peer0:/go/src/github.com/hyperledger/fabric# peer chaincode invoke -n test_cc -c '{"Args":["query","b"]}' -o orderer:7050
|
||||
root@peer0:/go/src/github.com/hyperledger/fabric# peer chaincode invoke -n test_cc -c '{"Args":["query","b"]}' -o orderer0:7050
|
||||
```
|
||||
|
||||
The final output may look like the following, with a payload value of `200`.
|
||||
|
@ -151,7 +140,7 @@ Query Result: 200
|
|||
Inside the container, invoke a transaction to transfer `10` from `a` to `b`.
|
||||
|
||||
```bash
|
||||
root@peer0:/go/src/github.com/hyperledger/fabric# peer chaincode invoke -n test_cc -c '{"Args":["invoke","a","b","10"]}' -o orderer:7050
|
||||
root@peer0:/go/src/github.com/hyperledger/fabric# peer chaincode invoke -n test_cc -c '{"Args":["invoke","a","b","10"]}' -o orderer0:7050
|
||||
```
|
||||
|
||||
The final result may look like the following, the response should be `OK`.
|
||||
|
@ -165,69 +154,165 @@ The final result may look like the following, the response should be `OK`.
|
|||
Query again the existing value of `a` and `b`.
|
||||
|
||||
```bash
|
||||
root@peer0:/go/src/github.com/hyperledger/fabric# peer chaincode query -n test_cc -c '{"Args":["query","a"]}' -o orderer:7050
|
||||
root@peer0:/go/src/github.com/hyperledger/fabric# peer chaincode query -n test_cc -c '{"Args":["query","a"]}' -o orderer0:7050
|
||||
```
|
||||
The new value of `a` should be 90.
|
||||
|
||||
```bash
|
||||
root@peer0:/go/src/github.com/hyperledger/fabric# peer chaincode query -n test_cc -c '{"Args":["query","b"]}' -o orderer:7050
|
||||
root@peer0:/go/src/github.com/hyperledger/fabric# peer chaincode query -n test_cc -c '{"Args":["query","b"]}' -o orderer0:7050
|
||||
```
|
||||
The new value of `b` should be 210.
|
||||
|
||||
### Test chaincode with new channel (Optional)
|
||||
### Test chaincode with new created channel (Optional)
|
||||
|
||||
Start the Docker Compose project with `docker-compose-new-channel.yml`.
|
||||
|
||||
```bash
|
||||
$ docker-compose -f docker-compose-new-channel.yml up
|
||||
```
|
||||
|
||||
#### Create genesis block and configuration transaction
|
||||
|
||||
**Skip this step**, as we already put the `orderer.block` and `channel.tx` under `e2e_cli/crypto/orderer/`.
|
||||
|
||||
This explains the creation of `orderer.block` (needed by orderer to bootup) and `channel.tx` (needed by cli to create new channel).
|
||||
|
||||
##### Create the genesis block
|
||||
Enter the `fabric-cli` container, and run the following cmd to use the e2e test's configtx.yaml.
|
||||
|
||||
```bash
|
||||
$ docker exec -it fabric-cli bash
|
||||
root@cli:/go/src/github.com/hyperledger/fabric# cp examples/e2e_cli/configtx.yaml /etc/hyperledger/fabric
|
||||
```
|
||||
|
||||
Generate the genesis block.
|
||||
|
||||
```bash
|
||||
root@cli:/go/src/github.com/hyperledger/fabric# configtxgen -profile TwoOrgs -outputBlock orderer.block
|
||||
Loading configuration
|
||||
Looking for configtx.yaml in: /etc/hyperledger/fabric
|
||||
Found configtx.yaml there
|
||||
Checking for MSPDir at: .
|
||||
Checking for MSPDir at: .
|
||||
Checking for MSPDir at: .
|
||||
Generating genesis block
|
||||
Writing genesis block
|
||||
root@cli:/go/src/github.com/hyperledger/fabric# ls orderer.block
|
||||
orderer.block
|
||||
```
|
||||
|
||||
##### Create the configuration tx
|
||||
Create channel configuration transaction for the to-be-created `newchannel`.
|
||||
|
||||
```bash
|
||||
root@cli:/go/src/github.com/hyperledger/fabric# CHANNEL_NAME="newchannel"
|
||||
root@cli:/go/src/github.com/hyperledger/fabric# configtxgen -profile TwoOrgs -outputCreateChannelTx channel.tx -channelID ${CHANNEL_NAME}
|
||||
Loading configuration
|
||||
Looking for configtx.yaml in: /etc/hyperledger/fabric
|
||||
Found configtx.yaml there
|
||||
Checking for MSPDir at: .
|
||||
Checking for MSPDir at: .
|
||||
Checking for MSPDir at: .
|
||||
Generating new channel configtx
|
||||
Creating no-op MSP instance
|
||||
Obtaining default signing identity
|
||||
Creating no-op signing identity instance
|
||||
Serialinzing identity
|
||||
signing message
|
||||
signing message
|
||||
Writing new channel tx
|
||||
root@cli:/go/src/github.com/hyperledger/fabric# ls channel.tx
|
||||
channel.tx
|
||||
```
|
||||
|
||||
#### Create new channel
|
||||
|
||||
Peers join channel `testchainid` by default. But if you want to use new channel, run the following command.
|
||||
Create new channel named testchannel.
|
||||
Create a new channel named `newchannel` with the existing `channel.tx` file.
|
||||
|
||||
```bash
|
||||
root@peer0:/go/src/github.com/hyperledger/fabric# peer channel create -c testchannel -o orderer:7050
|
||||
root@cli:/go/src/github.com/hyperledger/fabric# CHANNEL_NAME="newchannel"
|
||||
root@peer0:/go/src/github.com/hyperledger/fabric# CORE_PEER_MSPCONFIGPATH=$GOPATH/src/github.com/hyperledger/fabric/peer/crypto/orderer/localMspConfig
|
||||
root@peer0:/go/src/github.com/hyperledger/fabric# CORE_PEER_LOCALMSPID="OrdererMSP"
|
||||
root@peer0:/go/src/github.com/hyperledger/fabric# peer channel create -c ${CHANNEL_NAME} -o orderer0:7050 -f peer/crypto/orderer/channel.tx
|
||||
```
|
||||
The cmd will return lots of info, which is the content of the configuration block.
|
||||
|
||||
And a block with the same name of the channel will be created locally.
|
||||
|
||||
```bash
|
||||
root@cli:/go/src/github.com/hyperledger/fabric# ls newchannel.block
|
||||
newchannel.block
|
||||
```
|
||||
|
||||
Check the log output of `fabric-orderer0`, should find something like
|
||||
|
||||
```bash
|
||||
fabric-orderer0 | UTC [orderer/multichain] newChain -> INFO 004 Created and starting new chain newchannel
|
||||
```
|
||||
This will return a genesis block - testchannel.block.
|
||||
|
||||
#### Join the channel
|
||||
|
||||
Join peer0 to testchannel.
|
||||
Use the following command to join `peer0` the channel
|
||||
|
||||
Notice we will use `peer0`'s configuration here.
|
||||
|
||||
```bash
|
||||
root@peer0:/go/src/github.com/hyperledger/fabric# CORE_PEER_ADDRESS=peer0:7051 peer channel join -b testchannel.block -o orderer:7050
|
||||
root@cli:/go/src/github.com/hyperledger/fabric# CORE_PEER_MSPCONFIGPATH=$GOPATH/src/github.com/hyperledger/fabric/peer/crypto/peer/peer0/localMspConfig \
|
||||
CORE_PEER_LOCALMSPID="Org0MSP" \
|
||||
CORE_PEER_ADDRESS=peer0:7051 \
|
||||
peer channel join -b ${CHANNEL_NAME}.block -o orderer0:7050
|
||||
|
||||
Peer joined the channel!
|
||||
```
|
||||
|
||||
The final result may look like following.
|
||||
Will receive the `Peer joined the channel!` response if succeed.
|
||||
|
||||
#### Install&Instantiate
|
||||
|
||||
First install a chaincode named `test_cc` to `peer0`.
|
||||
|
||||
```bash
|
||||
Join Result:
|
||||
[main] main -> INFO 001 Exiting.....
|
||||
```
|
||||
|
||||
#### Deploy
|
||||
|
||||
First install a chaincode named test_cc to peer0 on channel testchannel:
|
||||
|
||||
```bash
|
||||
root@peer0:/go/src/github.com/hyperledger/fabric# CORE_PEER_ADDRESS=peer0:7051 peer chaincode install -C testchannel -n test_cc -p github.com/hyperledger/fabric/examples/chaincode/go/chaincode_example02 -v 1.0 -o orderer:7050
|
||||
root@cli:/go/src/github.com/hyperledger/fabric# CORE_PEER_MSPCONFIGPATH=$GOPATH/src/github.com/hyperledger/fabric/peer/crypto/peer/peer0/localMspConfig \
|
||||
CORE_PEER_LOCALMSPID="Org0MSP" \
|
||||
CORE_PEER_ADDRESS=peer0:7051 \
|
||||
peer chaincode install -n test_cc -p github.com/hyperledger/fabric/examples/chaincode/go/chaincode_example02 -v 1.0 -o orderer0:7050
|
||||
```
|
||||
|
||||
The result may look like following.
|
||||
|
||||
```bash
|
||||
[golang-platform] writeGopathSrc -> INFO 001 rootDirectory = /go/src
|
||||
[container] WriteFolderToTarPackage -> INFO 002 rootDirectory = /go/src
|
||||
[main] main -> INFO 003 Exiting.....
|
||||
UTC [golang-platform] writeGopathSrc -> INFO 001 rootDirectory = /go/src
|
||||
UTC [container] WriteFolderToTarPackage -> INFO 002 rootDirectory = /go/src
|
||||
UTC [main] main -> INFO 003 Exiting.....
|
||||
```
|
||||
|
||||
Second instantiate chaincode test_cc:
|
||||
Then instantiate the chaincode test_cc on channel `newchannel`:
|
||||
|
||||
```bash
|
||||
root@peer0:/go/src/github.com/hyperledger/fabric# CORE_PEER_ADDRESS=peer0:7051 peer chaincode instantiate -C testchannel -n test_cc -p github.com/hyperledger/fabric/examples/chaincode/go/chaincode_example02 -v 1.0 -c '{"Args":["init","a","100","b","200"]}' -o orderer:7050
|
||||
root@cli:/go/src/github.com/hyperledger/fabric# CORE_PEER_MSPCONFIGPATH=$GOPATH/src/github.com/hyperledger/fabric/peer/crypto/peer/peer0/localMspConfig \
|
||||
CORE_PEER_LOCALMSPID="Org0MSP" \
|
||||
CORE_PEER_ADDRESS=peer0:7051 \
|
||||
peer chaincode instantiate -C ${CHANNEL_NAME} -n test_cc -p github.com/hyperledger/fabric/examples/chaincode/go/chaincode_example02 -v 1.0 -c '{"Args":["init","a","100","b","200"]}' -o orderer0:7050
|
||||
```
|
||||
|
||||
The result may look like following:
|
||||
|
||||
```bash
|
||||
[chaincodeCmd] checkChaincodeCmdParams -> INFO 001 Using default escc
|
||||
[chaincodeCmd] checkChaincodeCmdParams -> INFO 002 Using default vscc
|
||||
[main] main -> INFO 003 Exiting.....
|
||||
UTC [chaincodeCmd] checkChaincodeCmdParams -> INFO 001 Using default escc
|
||||
UTC [chaincodeCmd] checkChaincodeCmdParams -> INFO 002 Using default vscc
|
||||
UTC [main] main -> INFO 003 Exiting.....
|
||||
```
|
||||
|
||||
Now in the system, there will be a new `dev-peer0-test_cc-1.0` container.
|
||||
|
||||
```bash
|
||||
$ docker ps
|
||||
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
|
||||
c0abb4b9206b dev-peer0-test_cc-1.0 "chaincode -peer.a..." 25 seconds ago Up 25 seconds dev-peer0-test_cc-1.0
|
||||
c1cf099e1f76 hyperledger/fabric-peer "bash -c 'while tr..." 40 minutes ago Up 40 minutes 7050-7059/tcp fabric-cli
|
||||
0b67c42fd5cc hyperledger/fabric-peer "peer node start -..." 40 minutes ago Up 40 minutes 7050/tcp, 0.0.0.0:7051->7051/tcp, 7052/tcp, 7054-7059/tcp, 0.0.0.0:7053->7053/tcp fabric-peer0
|
||||
80b5fb85636e hyperledger/fabric-orderer "orderer" 40 minutes ago Up 40 minutes 0.0.0.0:7050->7050/tcp fabric-orderer0
|
||||
f3680e5889b0 hyperledger/fabric-ca "fabric-ca-server ..." 40 minutes ago Up 40 minutes 7054/tcp, 0.0.0.0:8888->8888/tcp fabric-ca
|
||||
```
|
||||
|
||||
#### Query
|
||||
|
@ -235,7 +320,10 @@ The result may look like following:
|
|||
Query the existing value of `a` and `b`.
|
||||
|
||||
```bash
|
||||
root@peer0:/go/src/github.com/hyperledger/fabric# CORE_PEER_ADDRESS=peer0:7051 peer chaincode query -C testchannel -n test_cc -v 1.0 -c '{"Args":["query","a"]}' -o orderer:7050
|
||||
root@cli:/go/src/github.com/hyperledger/fabric# CORE_PEER_MSPCONFIGPATH=$GOPATH/src/github.com/hyperledger/fabric/peer/crypto/peer/peer0/localMspConfig \
|
||||
CORE_PEER_LOCALMSPID="Org0MSP" \
|
||||
CORE_PEER_ADDRESS=peer0:7051 \
|
||||
peer chaincode query -C ${CHANNEL_NAME} -n test_cc -c '{"Args":["query","a"]}'
|
||||
```
|
||||
|
||||
The result may look like following, with a payload value of `100`.
|
||||
|
@ -245,9 +333,14 @@ Query Result: 100
|
|||
```
|
||||
|
||||
```bash
|
||||
root@peer0:/go/src/github.com/hyperledger/fabric# CORE_PEER_ADDRESS=peer0:7051 peer chaincode query -C testchannel -n test_cc -v 1.0 -c '{"Args":["query","b"]}' -o orderer:7050
|
||||
root@cli:/go/src/github.com/hyperledger/fabric# CORE_PEER_MSPCONFIGPATH=$GOPATH/src/github.com/hyperledger/fabric/peer/crypto/peer/peer0/localMspConfig \
|
||||
CORE_PEER_LOCALMSPID="Org0MSP" \
|
||||
CORE_PEER_ADDRESS=peer0:7051 \
|
||||
peer chaincode query -C ${CHANNEL_NAME} -n test_cc -c '{"Args":["query","b"]}'
|
||||
```
|
||||
|
||||
The result may look like following, with a payload value of `200`.
|
||||
|
||||
```bash
|
||||
Query Result: 200
|
||||
[main] main -> INFO 001 Exiting.....
|
||||
|
@ -259,22 +352,29 @@ Query Result: 200
|
|||
Inside the container, invoke a transaction to transfer `10` from `a` to `b`.
|
||||
|
||||
```bash
|
||||
root@peer0:/go/src/github.com/hyperledger/fabric# CORE_PEER_ADDRESS=peer0:7051 peer chaincode invoke -C testchannel -n test_cc -v 1.0 -c '{"Args":["invoke","a","b","10"]}' -o orderer:7050
|
||||
root@cli:/go/src/github.com/hyperledger/fabric# CORE_PEER_MSPCONFIGPATH=$GOPATH/src/github.com/hyperledger/fabric/peer/crypto/peer/peer0/localMspConfig \
|
||||
CORE_PEER_LOCALMSPID="Org0MSP" \
|
||||
CORE_PEER_ADDRESS=peer0:7051 \
|
||||
peer chaincode invoke -o orderer0:7050 -C ${CHANNEL_NAME} -n test_cc -c '{"Args":["invoke","a","b","10"]}'
|
||||
```
|
||||
|
||||
The result may look like following:
|
||||
|
||||
```bash
|
||||
[chaincodeCmd] chaincodeInvokeOrQuery -> INFO 001 Invoke result: version:1 response:<status:200 message:"OK" > payload:"\n L1sx\330\026\226\273\246\014\300\315\303\25501ED!\177\005!\003\312!\033\312\334\240\203y\024\022C\n<\002\004lccc\001\007test_cc\004\001\001\001\001\000\000\007test_cc\002\001a\004\001\001\001\001\001b\004\001\001\001\001\002\001a\000\00290\001b\000\003210\000\032\003\010\310\001" endorsement:<endorser:"\n\007DEFAULT\022\232\007-----BEGIN -----\nMIICjDCCAjKgAwIBAgIUBEVwsSx0TmqdbzNwleNBBzoIT0wwCgYIKoZIzj0EAwIw\nfzELMAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcTDVNh\nbiBGcmFuY2lzY28xHzAdBgNVBAoTFkludGVybmV0IFdpZGdldHMsIEluYy4xDDAK\nBgNVBAsTA1dXVzEUMBIGA1UEAxMLZXhhbXBsZS5jb20wHhcNMTYxMTExMTcwNzAw\nWhcNMTcxMTExMTcwNzAwWjBjMQswCQYDVQQGEwJVUzEXMBUGA1UECBMOTm9ydGgg\nQ2Fyb2xpbmExEDAOBgNVBAcTB1JhbGVpZ2gxGzAZBgNVBAoTEkh5cGVybGVkZ2Vy\nIEZhYnJpYzEMMAoGA1UECxMDQ09QMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE\nHBuKsAO43hs4JGpFfiGMkB/xsILTsOvmN2WmwpsPHZNL6w8HWe3xCPQtdG/XJJvZ\n+C756KEsUBM3yw5PTfku8qOBpzCBpDAOBgNVHQ8BAf8EBAMCBaAwHQYDVR0lBBYw\nFAYIKwYBBQUHAwEGCCsGAQUFBwMCMAwGA1UdEwEB/wQCMAAwHQYDVR0OBBYEFOFC\ndcUZ4es3ltiCgAVDoyLfVpPIMB8GA1UdIwQYMBaAFBdnQj2qnoI/xMUdn1vDmdG1\nnEgQMCUGA1UdEQQeMByCCm15aG9zdC5jb22CDnd3dy5teWhvc3QuY29tMAoGCCqG\nSM49BAMCA0gAMEUCIDf9Hbl4xn3z4EwNKmilM9lX2Fq4jWpAaRVB97OmVEeyAiEA\n25aDPQHGGq2AvhKT0wvt08cX1GTGCIbfmuLpMwKQj38=\n-----END -----\n" signature:"0E\002!\000\306/\2643h\203\326\020x*g\246:E\270F\240<OCA\260\371\346\021\233\204\321Wv\tL\002 cu\241\034\341\316\374O`\332\224^j\354\233y\215\262|\306\303\353,'\332\230\214]R\327\343\024" >
|
||||
[main] main -> INFO 002 Exiting.....
|
||||
UTC [chaincodeCmd] chaincodeInvokeOrQuery -> INFO 001 Invoke result: version:1 response:<status:200 message:"OK" > payload:"\n qm\251\207\312\277\256\261b\317:\300\000\014\203`\005\304\254\304,$a\360\327\010\342\342/y]\323\022X\nQ\022\031\n\004lccc\022\021\n\017\n\007test_cc\022\004\010\001\020\001\0224\n\007test_cc\022)\n\t\n\001a\022\004\010\001\020\001\n\t\n\001b\022\004\010\001\020\001\032\007\n\001a\032\00290\032\010\n\001b\032\003210\032\003\010\310\001" endorsement:<endorser:"\n\007Org0MSP\022\210\004-----BEGIN -----\nMIIBYzCCAQmgAwIBAwICA+gwCgYIKoZIzj0EAwIwEzERMA8GA1UEAwwIcGVlck9y\nZzAwHhcNMTcwMjIwMTkwNjExWhcNMTgwMjIwMTkwNjExWjAQMQ4wDAYDVQQDDAVw\nZWVyMDBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABEF6dfqjqfbIgZuOR+dgoJMl\n/FaUlGI70A/ixmVUY83Yp4YtV3FDBSOPiO5O+s8pHnpbwB1LqhrxAx1Plr0M/UWj\nUDBOMAwGA1UdEwEB/wQCMAAwHQYDVR0OBBYEFBY2bc84vLEwkX1fSAER2p48jJXw\nMB8GA1UdIwQYMBaAFFQzuQR1RZP/Qn/BNDtGSa8n4eN/MAoGCCqGSM49BAMCA0gA\nMEUCIQDeDZ71L+OTYcbbqiDNRf0L8OExO59mH1O3xpdwMAM0MgIgXySG4sv9yV31\nWcWRFfRFyu7o3T72kqiLZ1nkDuJ8jWI=\n-----END -----\n" signature:"0E\002!\000\220M'\245\230do\310>\277\251j\021$\250\237H\353\377\331:\230\362n\216\224~\033\240\006\367%\002 \014\240|h\346\250\356\372\353\301;#\372\027\276!\252F\334/\221\210\254\215\363\235\341v\217\236\274<" >
|
||||
2017-04-06 09:47:15.993 UTC [main] main -> INFO 002 Exiting.....
|
||||
```
|
||||
|
||||
#### Query
|
||||
|
||||
And then query the value of `a` and `b`.
|
||||
|
||||
|
||||
```bash
|
||||
root@peer0:/go/src/github.com/hyperledger/fabric# CORE_PEER_ADDRESS=peer0:7051 peer chaincode query -C testchannel -n test_cc -v 1.0 -c '{"Args":["query","a"]}' -o orderer:7050
|
||||
root@cli:/go/src/github.com/hyperledger/fabric# CORE_PEER_MSPCONFIGPATH=$GOPATH/src/github.com/hyperledger/fabric/peer/crypto/peer/peer0/localMspConfig \
|
||||
CORE_PEER_LOCALMSPID="Org0MSP" \
|
||||
CORE_PEER_ADDRESS=peer0:7051 \
|
||||
peer chaincode query -C ${CHANNEL_NAME} -n test_cc -c '{"Args":["query","a"]}'
|
||||
```
|
||||
|
||||
```bash
|
||||
|
@ -283,8 +383,12 @@ Query Result: 90
|
|||
```
|
||||
The value of `a` should be `90`.
|
||||
|
||||
|
||||
```bash
|
||||
root@peer0:/go/src/github.com/hyperledger/fabric# CORE_PEER_ADDRESS=peer0:7051 peer chaincode query -C testchannel -n test_cc -v 1.0 -c '{"Args":["query","b"]}' -o orderer:7050
|
||||
root@cli:/go/src/github.com/hyperledger/fabric# CORE_PEER_MSPCONFIGPATH=$GOPATH/src/github.com/hyperledger/fabric/peer/crypto/peer/peer0/localMspConfig \
|
||||
CORE_PEER_LOCALMSPID="Org0MSP" \
|
||||
CORE_PEER_ADDRESS=peer0:7051 \
|
||||
peer chaincode query -C ${CHANNEL_NAME} -n test_cc -c '{"Args":["query","b"]}'
|
||||
```
|
||||
|
||||
The value of `b` should be `210`
|
||||
|
@ -294,7 +398,7 @@ Query Result: 210
|
|||
[main] main -> INFO 001 Exiting.....
|
||||
```
|
||||
|
||||
About this part of detailed context, [referenve linking](http://hyperledger-fabric.readthedocs.io/en/latest/asset_setup.html#asset-transfer-with-cli)
|
||||
|
||||
## Acknowledgement
|
||||
* [Hyperledger Fabric](https://github.com/hyperledger/fabric/) project.
|
||||
* [Hyperledger Fabric Getting Started](http://hyperledger-fabric.readthedocs.io/en/latest/getting_started.html).
|
||||
|
|
|
@ -0,0 +1,106 @@
|
|||
# https://github.com/yeasy/docker-compose-files/tree/master/hyperledger
|
||||
# This compose file will start a Hyperledger Fabric 1.0 MVE, including
|
||||
# * ca
|
||||
# * orderer
|
||||
# * peer
|
||||
# * sdk for testing
|
||||
|
||||
version: '2.0'
|
||||
|
||||
services:
|
||||
ca:
|
||||
image: hyperledger/fabric-ca
|
||||
container_name: fabric-ca
|
||||
hostname: ca
|
||||
# command: /go/src/github.com/hyperledger/fabric-ca/bin/ca server start -ca testdata/ec.pem -ca-key testdata/ec-key.pem -config testdata/testconfig.json
|
||||
ports:
|
||||
- "8888:8888"
|
||||
command: fabric-ca-server start -c testdata/testconfig.json
|
||||
|
||||
orderer0: # There can be multiple orderers
|
||||
image: hyperledger/fabric-orderer
|
||||
container_name: fabric-orderer0
|
||||
hostname: orderer0
|
||||
environment:
|
||||
- ORDERER_GENERAL_LEDGERTYPE=ram
|
||||
- ORDERER_GENERAL_BATCHTIMEOUT=10s
|
||||
- ORDERER_GENERAL_MAXMESSAGECOUNT=10
|
||||
- ORDERER_GENERAL_MAXWINDOWSIZE=1000
|
||||
- ORDERER_GENERAL_LISTENADDRESS=0.0.0.0
|
||||
- ORDERER_GENERAL_LISTENPORT=7050
|
||||
- ORDERER_RAMLEDGER_HISTORY_SIZE=100
|
||||
- ORDERER_GENERAL_GENESISMETHOD=file
|
||||
- ORDERER_GENERAL_GENESISFILE=/var/hyperledger/orderer/orderer.block
|
||||
- ORDERER_GENERAL_LOCALMSPID=OrdererMSP
|
||||
- ORDERER_GENERAL_LOCALMSPDIR=/var/hyperledger/orderer/localMspConfig
|
||||
- ORDERER_GENERAL_TLS_ENABLED=false # to enable TLS, make this true
|
||||
- ORDERER_GENERAL_TLS_PRIVATEKEY=/var/hyperledger/orderer/localMspConfig/keystore/ordererSigner.pem
|
||||
- ORDERER_GENERAL_TLS_CERTIFICATE=/var/hyperledger/orderer/localMspConfig/signcerts/orderer0Signer.pem
|
||||
- ORDERER_GENERAL_TLS_ROOTCAS=[/var/hyperledger/orderer/localMspConfig/cacerts/ordererOrg0.pem]
|
||||
ports:
|
||||
- "7050:7050"
|
||||
volumes:
|
||||
- ./e2e_cli/crypto/orderer:/var/hyperledger/orderer
|
||||
command: orderer
|
||||
|
||||
peer0:
|
||||
extends:
|
||||
file: peer.yml
|
||||
service: peer
|
||||
container_name: fabric-peer0
|
||||
hostname: peer0
|
||||
environment:
|
||||
- CORE_PEER_ID=peer0
|
||||
- CORE_PEER_ADDRESS=peer0:7051
|
||||
- CORE_PEER_GOSSIP_EXTERNALENDPOINT=peer0:7051
|
||||
- CORE_PEER_GOSSIP_ORGLEADER=true
|
||||
- CORE_PEER_COMMITTER_LEDGER_ORDERER=orderer0:7050
|
||||
- CORE_PEER_LOCALMSPID=Org0MSP
|
||||
- CORE_PEER_TLS_CERT_FILE=/etc/hyperledger/fabric/msp/sampleconfig/signcerts/peer0Signer.pem
|
||||
- CORE_PEER_TLS_KEY_FILE=/etc/hyperledger/fabric/msp/sampleconfig/keystore/peer0Signer.pem
|
||||
- CORE_PEER_TLS_ROOTCERT_FILE=/etc/hyperledger/fabric/msp/sampleconfig/cacerts/peerOrg0.pem
|
||||
links:
|
||||
- orderer0
|
||||
ports:
|
||||
- 7051:7051
|
||||
- 7053:7053
|
||||
volumes:
|
||||
- ./e2e_cli/crypto/peer/peer0/localMspConfig:/etc/hyperledger/fabric/msp/sampleconfig
|
||||
depends_on:
|
||||
- orderer0
|
||||
command: peer node start --peer-defaultchain=false
|
||||
|
||||
cli:
|
||||
extends:
|
||||
file: peer.yml
|
||||
service: peer
|
||||
container_name: fabric-cli
|
||||
hostname: cli
|
||||
environment:
|
||||
- CORE_PEER_ID=cli
|
||||
- CORE_PEER_ADDRESS=peer0:7051
|
||||
- CORE_PEER_LOCALMSPID=Org0MSP
|
||||
#- CORE_PEER_COMMITTER_LEDGER_ORDERER=orderer:7050
|
||||
- CORE_PEER_TLS_ENABLED=false # to enable TLS, change to true
|
||||
- CORE_PEER_TLS_CERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peer/peer0/localMspConfig/signcerts/peer0Signer.pem
|
||||
- CORE_PEER_TLS_KEY_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peer/peer0/localMspConfig/keystore/peer0Signer.pem
|
||||
- CORE_PEER_TLS_ROOTCERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peer/peer0/localMspConfig/cacerts/peerOrg0.pem
|
||||
# - CORE_PEER_TLS_SERVERHOSTOVERRIDE=peer0
|
||||
- CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peer/peer0/localMspConfig
|
||||
links:
|
||||
- peer0
|
||||
- orderer0
|
||||
volumes:
|
||||
#- ./e2e_cli/examples/:/opt/gopath/src/github.com/hyperledger/fabric/examples/
|
||||
#- ../chaincode/go/:/opt/gopath/src/github.com/hyperledger/fabric/examples/chaincode/go
|
||||
- ./e2e_cli/crypto:/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/
|
||||
#- ./e2e_cli/scripts:/opt/gopath/src/github.com/hyperledger/fabric/peer/scripts/
|
||||
depends_on:
|
||||
- peer0
|
||||
- orderer0
|
||||
command: bash -c 'while true; do sleep 2017; done'
|
||||
|
||||
#networks:
|
||||
# default:
|
||||
# external:
|
||||
# name: hyperledger_fabric
|
|
@ -5,6 +5,8 @@
|
|||
# * peer
|
||||
# * sdk for testing
|
||||
|
||||
# all peers will join the default testchainid channel after bootup
|
||||
|
||||
version: '2.0'
|
||||
|
||||
services:
|
||||
|
@ -17,10 +19,10 @@ services:
|
|||
- "8888:8888"
|
||||
command: fabric-ca-server start -c testdata/testconfig.json
|
||||
|
||||
orderer:
|
||||
orderer0: # There can be multiple orderers
|
||||
image: hyperledger/fabric-orderer
|
||||
container_name: fabric-orderer
|
||||
hostname: orderer
|
||||
container_name: fabric-orderer0
|
||||
hostname: orderer0
|
||||
environment:
|
||||
- ORDERER_GENERAL_LEDGERTYPE=ram
|
||||
- ORDERER_GENERAL_BATCHTIMEOUT=10s
|
||||
|
@ -42,15 +44,32 @@ services:
|
|||
hostname: peer0
|
||||
environment:
|
||||
- CORE_PEER_ID=peer0
|
||||
- CORE_PEER_GOSSIP_ORGLEADER=true
|
||||
- CORE_PEER_COMMITTER_LEDGER_ORDERER=orderer:7050
|
||||
links:
|
||||
- ca
|
||||
- orderer
|
||||
- orderer0
|
||||
ports:
|
||||
- 7051:7051
|
||||
depends_on:
|
||||
- ca
|
||||
- orderer
|
||||
- orderer0
|
||||
|
||||
cli:
|
||||
extends:
|
||||
file: peer.yml
|
||||
service: peer
|
||||
container_name: fabric-cli
|
||||
hostname: cli
|
||||
environment:
|
||||
- CORE_PEER_ID=cli
|
||||
- CORE_PEER_ADDRESS=peer0:7051
|
||||
#- CORE_PEER_LOCALMSPID=Org0MSP
|
||||
#- CORE_PEER_COMMITTER_LEDGER_ORDERER=orderer:7050
|
||||
links:
|
||||
- peer0
|
||||
- orderer0
|
||||
depends_on:
|
||||
- peer0
|
||||
- orderer0
|
||||
|
||||
#networks:
|
||||
# default:
|
||||
|
|
|
@ -0,0 +1,173 @@
|
|||
---
|
||||
################################################################################
|
||||
#
|
||||
# Profile
|
||||
#
|
||||
# - Different configuration profiles may be encoded here to be specified
|
||||
# as parameters to the configtxgen tool
|
||||
#
|
||||
################################################################################
|
||||
Profiles:
|
||||
|
||||
TwoOrgs:
|
||||
Orderer:
|
||||
<<: *OrdererDefaults
|
||||
Organizations:
|
||||
- *OrdererOrg
|
||||
Application:
|
||||
<<: *ApplicationDefaults
|
||||
Organizations:
|
||||
- *Org0
|
||||
- *Org1
|
||||
|
||||
################################################################################
|
||||
#
|
||||
# Section: Organizations
|
||||
#
|
||||
# - This section defines the different organizational identities which will
|
||||
# be referenced later in the configuration.
|
||||
#
|
||||
################################################################################
|
||||
Organizations:
|
||||
|
||||
# SampleOrg defines an MSP using the sampleconfig. It should never be used
|
||||
# in production but may be used as a template for other definitions
|
||||
- &OrdererOrg
|
||||
# DefaultOrg defines the organization which is used in the sampleconfig
|
||||
# of the fabric.git development environment
|
||||
Name: OrdererOrg
|
||||
|
||||
# ID to load the MSP definition as
|
||||
ID: OrdererMSP
|
||||
|
||||
# MSPDir is the filesystem path which contains the MSP configuration
|
||||
MSPDir: examples/e2e_cli/crypto/orderer/localMspConfig
|
||||
|
||||
# BCCSP (Blockchain crypto provider): Select which crypto implementation or
|
||||
# library to use
|
||||
BCCSP:
|
||||
Default: SW
|
||||
SW:
|
||||
Hash: SHA2
|
||||
Security: 256
|
||||
# Location of Key Store. If this is unset, a location will
|
||||
# be chosen using 'MSPDir'/keystore
|
||||
FileKeyStore:
|
||||
KeyStore:
|
||||
|
||||
- &Org0
|
||||
# DefaultOrg defines the organization which is used in the sampleconfig
|
||||
# of the fabric.git development environment
|
||||
Name: Org0MSP
|
||||
|
||||
# ID to load the MSP definition as
|
||||
ID: Org0MSP
|
||||
|
||||
MSPDir: examples/e2e_cli/crypto/peer/peer0/localMspConfig
|
||||
|
||||
# BCCSP (Blockchain crypto provider): Select which crypto implementation or
|
||||
# library to use
|
||||
BCCSP:
|
||||
Default: SW
|
||||
SW:
|
||||
Hash: SHA2
|
||||
Security: 256
|
||||
# Location of Key Store. If this is unset, a location will
|
||||
# be chosen using 'MSPDir'/keystore
|
||||
FileKeyStore:
|
||||
KeyStore:
|
||||
|
||||
AnchorPeers:
|
||||
# AnchorPeers defines the location of peers which can be used
|
||||
# for cross org gossip communication. Note, this value is only
|
||||
# encoded in the genesis block in the Application section context
|
||||
- Host: peer0
|
||||
Port: 7051
|
||||
|
||||
- &Org1
|
||||
# DefaultOrg defines the organization which is used in the sampleconfig
|
||||
# of the fabric.git development environment
|
||||
Name: Org1MSP
|
||||
|
||||
# ID to load the MSP definition as
|
||||
ID: Org1MSP
|
||||
|
||||
MSPDir: examples/e2e_cli/crypto/peer/peer2/localMspConfig
|
||||
|
||||
# BCCSP (Blockchain crypto provider): Select which crypto implementation or
|
||||
# library to use
|
||||
BCCSP:
|
||||
Default: SW
|
||||
SW:
|
||||
Hash: SHA2
|
||||
Security: 256
|
||||
# Location of Key Store. If this is unset, a location will
|
||||
# be chosen using 'MSPDir'/keystore
|
||||
FileKeyStore:
|
||||
KeyStore:
|
||||
|
||||
AnchorPeers:
|
||||
# AnchorPeers defines the location of peers which can be used
|
||||
# for cross org gossip communication. Note, this value is only
|
||||
# encoded in the genesis block in the Application section context
|
||||
- Host: peer2
|
||||
Port: 7051
|
||||
|
||||
################################################################################
|
||||
#
|
||||
# SECTION: Orderer
|
||||
#
|
||||
# - This section defines the values to encode into a config transaction or
|
||||
# genesis block for orderer related parameters
|
||||
#
|
||||
################################################################################
|
||||
Orderer: &OrdererDefaults
|
||||
|
||||
# Orderer Type: The orderer implementation to start
|
||||
# Available types are "solo" and "kafka"
|
||||
OrdererType: solo
|
||||
|
||||
Addresses:
|
||||
- orderer0:7050
|
||||
|
||||
# Batch Timeout: The amount of time to wait before creating a batch
|
||||
BatchTimeout: 2s
|
||||
|
||||
# Batch Size: Controls the number of messages batched into a block
|
||||
BatchSize:
|
||||
|
||||
# Max Message Count: The maximum number of messages to permit in a batch
|
||||
MaxMessageCount: 10
|
||||
|
||||
# Absolute Max Bytes: The absolute maximum number of bytes allowed for
|
||||
# the serialized messages in a batch.
|
||||
AbsoluteMaxBytes: 99 MB
|
||||
|
||||
# Preferred Max Bytes: The preferred maximum number of bytes allowed for
|
||||
# the serialized messages in a batch. A message larger than the preferred
|
||||
# max bytes will result in a batch larger than preferred max bytes.
|
||||
PreferredMaxBytes: 512 KB
|
||||
|
||||
Kafka:
|
||||
# Brokers: A list of Kafka brokers to which the orderer connects
|
||||
# NOTE: Use IP:port notation
|
||||
Brokers:
|
||||
- 127.0.0.1:9092
|
||||
|
||||
# Organizations is the list of orgs which are defined as participants on
|
||||
# the orderer side of the network
|
||||
Organizations:
|
||||
|
||||
################################################################################
|
||||
#
|
||||
# SECTION: Application
|
||||
#
|
||||
# - This section defines the values to encode into a config transaction or
|
||||
# genesis block for application related parameters
|
||||
#
|
||||
################################################################################
|
||||
Application: &ApplicationDefaults
|
||||
|
||||
# Organizations is the list of orgs which are defined as participants on
|
||||
# the application side of the network
|
||||
Organizations:
|
Binary file not shown.
|
@ -0,0 +1,10 @@
|
|||
-----BEGIN CERTIFICATE-----
|
||||
MIIBcjCCARigAwIBAwICA+gwCgYIKoZIzj0EAwIwFjEUMBIGA1UEAwwLb3JkZXJl
|
||||
ck9yZzAwHhcNMTcwMjIwMTkwNjEwWhcNMTgwMjIwMTkwNjEwWjAWMRQwEgYDVQQD
|
||||
DAtvcmRlcmVyT3JnMDBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABK8Sv0EA9h06
|
||||
fmBkUCO+D/b/2INZ2huy+W/HCxSF22c7WGoJbRzQcWtQmW1KqZowUk86RcxVfFqv
|
||||
jEMFVXzV38SjVjBUMBIGA1UdEwEB/wQIMAYBAf8CAQAwHQYDVR0OBBYEFCVakuvq
|
||||
xEcK8pYMf/Hw8hsexRMTMB8GA1UdIwQYMBaAFCVakuvqxEcK8pYMf/Hw8hsexRMT
|
||||
MAoGCCqGSM49BAMCA0gAMEUCIQCmXgDSRTyxpSk+PXg0FNlYZ4ijTVwKgLkYVhod
|
||||
zZPfngIgO4y0p3Fs/gNsJYrroKaaVDe955KrPp/O55jYDKAD/oY=
|
||||
-----END CERTIFICATE-----
|
|
@ -0,0 +1,10 @@
|
|||
-----BEGIN CERTIFICATE-----
|
||||
MIIBcjCCARigAwIBAwICA+gwCgYIKoZIzj0EAwIwFjEUMBIGA1UEAwwLb3JkZXJl
|
||||
ck9yZzAwHhcNMTcwMjIwMTkwNjEwWhcNMTgwMjIwMTkwNjEwWjAWMRQwEgYDVQQD
|
||||
DAtvcmRlcmVyT3JnMDBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABK8Sv0EA9h06
|
||||
fmBkUCO+D/b/2INZ2huy+W/HCxSF22c7WGoJbRzQcWtQmW1KqZowUk86RcxVfFqv
|
||||
jEMFVXzV38SjVjBUMBIGA1UdEwEB/wQIMAYBAf8CAQAwHQYDVR0OBBYEFCVakuvq
|
||||
xEcK8pYMf/Hw8hsexRMTMB8GA1UdIwQYMBaAFCVakuvqxEcK8pYMf/Hw8hsexRMT
|
||||
MAoGCCqGSM49BAMCA0gAMEUCIQCmXgDSRTyxpSk+PXg0FNlYZ4ijTVwKgLkYVhod
|
||||
zZPfngIgO4y0p3Fs/gNsJYrroKaaVDe955KrPp/O55jYDKAD/oY=
|
||||
-----END CERTIFICATE-----
|
|
@ -0,0 +1,5 @@
|
|||
-----BEGIN EC PRIVATE KEY-----
|
||||
MHcCAQEEIJPtBtNKlilpgVZ5FGUBWB2KH3zBtzkBnkrFMmi6W/80oAoGCCqGSM49
|
||||
AwEHoUQDQgAEfWHpZ4VacEOA83luJdvLOpKEasBn3O067iPTfFyupQh6cFABIn+u
|
||||
YASuariSKU3JFWfB1nANwZOsDA9B8BeRUA==
|
||||
-----END EC PRIVATE KEY-----
|
|
@ -0,0 +1,10 @@
|
|||
-----BEGIN CERTIFICATE-----
|
||||
MIIBajCCAQ+gAwIBAwICA+gwCgYIKoZIzj0EAwIwFjEUMBIGA1UEAwwLb3JkZXJl
|
||||
ck9yZzAwHhcNMTcwMjIwMTkwNjEwWhcNMTgwMjIwMTkwNjEwWjATMREwDwYDVQQD
|
||||
DAhvcmRlcmVyMDBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABH1h6WeFWnBDgPN5
|
||||
biXbyzqShGrAZ9ztOu4j03xcrqUIenBQASJ/rmAErmq4kilNyRVnwdZwDcGTrAwP
|
||||
QfAXkVCjUDBOMAwGA1UdEwEB/wQCMAAwHQYDVR0OBBYEFK01/Qm7YoTpXLXjq18D
|
||||
+X2pExanMB8GA1UdIwQYMBaAFCVakuvqxEcK8pYMf/Hw8hsexRMTMAoGCCqGSM49
|
||||
BAMCA0kAMEYCIQDXdRYqrZdTAM6F2JBl/eN3nIHoBa7N3gIQDqdUAris8wIhAP6i
|
||||
f0CgyBN4nWmw2mT+XtxaB0xxWrhYj/j4agiuQzrd
|
||||
-----END CERTIFICATE-----
|
Binary file not shown.
|
@ -0,0 +1,10 @@
|
|||
-----BEGIN CERTIFICATE-----
|
||||
MIIBbDCCARKgAwIBAwICA+gwCgYIKoZIzj0EAwIwEzERMA8GA1UEAwwIcGVlck9y
|
||||
ZzAwHhcNMTcwMjIwMTkwNjEwWhcNMTgwMjIwMTkwNjEwWjATMREwDwYDVQQDDAhw
|
||||
ZWVyT3JnMDBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABKJfDc/CcaiHRipTG2AB
|
||||
K5fA0LO9SOlbtC9bZcjLo/xsL157p+3QB3UVF3gt7nkwgMs/ul3FhSEFTk2EVNlF
|
||||
1QCjVjBUMBIGA1UdEwEB/wQIMAYBAf8CAQAwHQYDVR0OBBYEFFQzuQR1RZP/Qn/B
|
||||
NDtGSa8n4eN/MB8GA1UdIwQYMBaAFFQzuQR1RZP/Qn/BNDtGSa8n4eN/MAoGCCqG
|
||||
SM49BAMCA0gAMEUCIAuG+/Fy3x9JXAD1/rFsu3ZpCKbXiXZLGF7P6Gma8is5AiEA
|
||||
pSQpRcdukxe4zvcfRmNBjMbNLWCoWlHSQA2jD678QGE=
|
||||
-----END CERTIFICATE-----
|
|
@ -0,0 +1,10 @@
|
|||
-----BEGIN CERTIFICATE-----
|
||||
MIIBbDCCARKgAwIBAwICA+gwCgYIKoZIzj0EAwIwEzERMA8GA1UEAwwIcGVlck9y
|
||||
ZzEwHhcNMTcwMjIwMTkwNjEwWhcNMTgwMjIwMTkwNjEwWjATMREwDwYDVQQDDAhw
|
||||
ZWVyT3JnMTBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABJ2S+UvyFgFZYL6qcrKo
|
||||
zy72Nkc/RQVzg1VfwC3X7QcnHEVBuCzba1nxdDVE8XPnhmKBWLKh0adn6GKUZpyf
|
||||
mbKjVjBUMBIGA1UdEwEB/wQIMAYBAf8CAQAwHQYDVR0OBBYEFAQlMVsXlKGMEWPf
|
||||
KMMM6QVASnlPMB8GA1UdIwQYMBaAFAQlMVsXlKGMEWPfKMMM6QVASnlPMAoGCCqG
|
||||
SM49BAMCA0gAMEUCIHr4AD6Xx3R6zFCsveIMnWao9Us88/0uGHoT4ELmMhA1AiEA
|
||||
yzfXU5qHp3xBJ1BrKOGi71UmQZVwWfO26INhxcfpCAg=
|
||||
-----END CERTIFICATE-----
|
|
@ -0,0 +1,10 @@
|
|||
-----BEGIN CERTIFICATE-----
|
||||
MIIBbDCCARKgAwIBAwICA+gwCgYIKoZIzj0EAwIwEzERMA8GA1UEAwwIcGVlck9y
|
||||
ZzIwHhcNMTcwMjIwMTkwNjExWhcNMTgwMjIwMTkwNjExWjATMREwDwYDVQQDDAhw
|
||||
ZWVyT3JnMjBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABH3IweQK1AJdcV3FF27a
|
||||
gNKhy13Nz2OguzsmUbW85/7pReenAWzs89rEApHXoJqUtNzdZfaLkcq32E1Ilk3N
|
||||
oN2jVjBUMBIGA1UdEwEB/wQIMAYBAf8CAQAwHQYDVR0OBBYEFEhOilIyGA53r9Zo
|
||||
O5GQP0RSZcQ1MB8GA1UdIwQYMBaAFEhOilIyGA53r9ZoO5GQP0RSZcQ1MAoGCCqG
|
||||
SM49BAMCA0gAMEUCIQD+/5z68ewJarixMgYrg/MwyTMwX7ikCaCgU5TN2MU1PQIg
|
||||
Qe+klrq6COxsmrctClV64Wj4zhGTOhaZG1yN24OXukQ=
|
||||
-----END CERTIFICATE-----
|
|
@ -0,0 +1,10 @@
|
|||
-----BEGIN CERTIFICATE-----
|
||||
MIIBbDCCARKgAwIBAwICA+gwCgYIKoZIzj0EAwIwEzERMA8GA1UEAwwIcGVlck9y
|
||||
ZzAwHhcNMTcwMjIwMTkwNjEwWhcNMTgwMjIwMTkwNjEwWjATMREwDwYDVQQDDAhw
|
||||
ZWVyT3JnMDBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABKJfDc/CcaiHRipTG2AB
|
||||
K5fA0LO9SOlbtC9bZcjLo/xsL157p+3QB3UVF3gt7nkwgMs/ul3FhSEFTk2EVNlF
|
||||
1QCjVjBUMBIGA1UdEwEB/wQIMAYBAf8CAQAwHQYDVR0OBBYEFFQzuQR1RZP/Qn/B
|
||||
NDtGSa8n4eN/MB8GA1UdIwQYMBaAFFQzuQR1RZP/Qn/BNDtGSa8n4eN/MAoGCCqG
|
||||
SM49BAMCA0gAMEUCIAuG+/Fy3x9JXAD1/rFsu3ZpCKbXiXZLGF7P6Gma8is5AiEA
|
||||
pSQpRcdukxe4zvcfRmNBjMbNLWCoWlHSQA2jD678QGE=
|
||||
-----END CERTIFICATE-----
|
|
@ -0,0 +1,10 @@
|
|||
-----BEGIN CERTIFICATE-----
|
||||
MIIBbDCCARKgAwIBAwICA+gwCgYIKoZIzj0EAwIwEzERMA8GA1UEAwwIcGVlck9y
|
||||
ZzEwHhcNMTcwMjIwMTkwNjEwWhcNMTgwMjIwMTkwNjEwWjATMREwDwYDVQQDDAhw
|
||||
ZWVyT3JnMTBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABJ2S+UvyFgFZYL6qcrKo
|
||||
zy72Nkc/RQVzg1VfwC3X7QcnHEVBuCzba1nxdDVE8XPnhmKBWLKh0adn6GKUZpyf
|
||||
mbKjVjBUMBIGA1UdEwEB/wQIMAYBAf8CAQAwHQYDVR0OBBYEFAQlMVsXlKGMEWPf
|
||||
KMMM6QVASnlPMB8GA1UdIwQYMBaAFAQlMVsXlKGMEWPfKMMM6QVASnlPMAoGCCqG
|
||||
SM49BAMCA0gAMEUCIHr4AD6Xx3R6zFCsveIMnWao9Us88/0uGHoT4ELmMhA1AiEA
|
||||
yzfXU5qHp3xBJ1BrKOGi71UmQZVwWfO26INhxcfpCAg=
|
||||
-----END CERTIFICATE-----
|
|
@ -0,0 +1,10 @@
|
|||
-----BEGIN CERTIFICATE-----
|
||||
MIIBbDCCARKgAwIBAwICA+gwCgYIKoZIzj0EAwIwEzERMA8GA1UEAwwIcGVlck9y
|
||||
ZzIwHhcNMTcwMjIwMTkwNjExWhcNMTgwMjIwMTkwNjExWjATMREwDwYDVQQDDAhw
|
||||
ZWVyT3JnMjBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABH3IweQK1AJdcV3FF27a
|
||||
gNKhy13Nz2OguzsmUbW85/7pReenAWzs89rEApHXoJqUtNzdZfaLkcq32E1Ilk3N
|
||||
oN2jVjBUMBIGA1UdEwEB/wQIMAYBAf8CAQAwHQYDVR0OBBYEFEhOilIyGA53r9Zo
|
||||
O5GQP0RSZcQ1MB8GA1UdIwQYMBaAFEhOilIyGA53r9ZoO5GQP0RSZcQ1MAoGCCqG
|
||||
SM49BAMCA0gAMEUCIQD+/5z68ewJarixMgYrg/MwyTMwX7ikCaCgU5TN2MU1PQIg
|
||||
Qe+klrq6COxsmrctClV64Wj4zhGTOhaZG1yN24OXukQ=
|
||||
-----END CERTIFICATE-----
|
|
@ -0,0 +1,5 @@
|
|||
-----BEGIN EC PRIVATE KEY-----
|
||||
MHcCAQEEIKyhczWGQa7NbV1tq9LkZkvqslzoQ1HaEVwA6FCLOfvioAoGCCqGSM49
|
||||
AwEHoUQDQgAEQXp1+qOp9siBm45H52CgkyX8VpSUYjvQD+LGZVRjzdinhi1XcUMF
|
||||
I4+I7k76zykeelvAHUuqGvEDHU+WvQz9RQ==
|
||||
-----END EC PRIVATE KEY-----
|
|
@ -0,0 +1,10 @@
|
|||
-----BEGIN CERTIFICATE-----
|
||||
MIIBYzCCAQmgAwIBAwICA+gwCgYIKoZIzj0EAwIwEzERMA8GA1UEAwwIcGVlck9y
|
||||
ZzAwHhcNMTcwMjIwMTkwNjExWhcNMTgwMjIwMTkwNjExWjAQMQ4wDAYDVQQDDAVw
|
||||
ZWVyMDBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABEF6dfqjqfbIgZuOR+dgoJMl
|
||||
/FaUlGI70A/ixmVUY83Yp4YtV3FDBSOPiO5O+s8pHnpbwB1LqhrxAx1Plr0M/UWj
|
||||
UDBOMAwGA1UdEwEB/wQCMAAwHQYDVR0OBBYEFBY2bc84vLEwkX1fSAER2p48jJXw
|
||||
MB8GA1UdIwQYMBaAFFQzuQR1RZP/Qn/BNDtGSa8n4eN/MAoGCCqGSM49BAMCA0gA
|
||||
MEUCIQDeDZ71L+OTYcbbqiDNRf0L8OExO59mH1O3xpdwMAM0MgIgXySG4sv9yV31
|
||||
WcWRFfRFyu7o3T72kqiLZ1nkDuJ8jWI=
|
||||
-----END CERTIFICATE-----
|
|
@ -0,0 +1,10 @@
|
|||
-----BEGIN CERTIFICATE-----
|
||||
MIIBbDCCARKgAwIBAwICA+gwCgYIKoZIzj0EAwIwEzERMA8GA1UEAwwIcGVlck9y
|
||||
ZzAwHhcNMTcwMjIwMTkwNjEwWhcNMTgwMjIwMTkwNjEwWjATMREwDwYDVQQDDAhw
|
||||
ZWVyT3JnMDBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABKJfDc/CcaiHRipTG2AB
|
||||
K5fA0LO9SOlbtC9bZcjLo/xsL157p+3QB3UVF3gt7nkwgMs/ul3FhSEFTk2EVNlF
|
||||
1QCjVjBUMBIGA1UdEwEB/wQIMAYBAf8CAQAwHQYDVR0OBBYEFFQzuQR1RZP/Qn/B
|
||||
NDtGSa8n4eN/MB8GA1UdIwQYMBaAFFQzuQR1RZP/Qn/BNDtGSa8n4eN/MAoGCCqG
|
||||
SM49BAMCA0gAMEUCIAuG+/Fy3x9JXAD1/rFsu3ZpCKbXiXZLGF7P6Gma8is5AiEA
|
||||
pSQpRcdukxe4zvcfRmNBjMbNLWCoWlHSQA2jD678QGE=
|
||||
-----END CERTIFICATE-----
|
|
@ -0,0 +1,10 @@
|
|||
-----BEGIN CERTIFICATE-----
|
||||
MIIBbDCCARKgAwIBAwICA+gwCgYIKoZIzj0EAwIwEzERMA8GA1UEAwwIcGVlck9y
|
||||
ZzEwHhcNMTcwMjIwMTkwNjEwWhcNMTgwMjIwMTkwNjEwWjATMREwDwYDVQQDDAhw
|
||||
ZWVyT3JnMTBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABJ2S+UvyFgFZYL6qcrKo
|
||||
zy72Nkc/RQVzg1VfwC3X7QcnHEVBuCzba1nxdDVE8XPnhmKBWLKh0adn6GKUZpyf
|
||||
mbKjVjBUMBIGA1UdEwEB/wQIMAYBAf8CAQAwHQYDVR0OBBYEFAQlMVsXlKGMEWPf
|
||||
KMMM6QVASnlPMB8GA1UdIwQYMBaAFAQlMVsXlKGMEWPfKMMM6QVASnlPMAoGCCqG
|
||||
SM49BAMCA0gAMEUCIHr4AD6Xx3R6zFCsveIMnWao9Us88/0uGHoT4ELmMhA1AiEA
|
||||
yzfXU5qHp3xBJ1BrKOGi71UmQZVwWfO26INhxcfpCAg=
|
||||
-----END CERTIFICATE-----
|
|
@ -0,0 +1,10 @@
|
|||
-----BEGIN CERTIFICATE-----
|
||||
MIIBbDCCARKgAwIBAwICA+gwCgYIKoZIzj0EAwIwEzERMA8GA1UEAwwIcGVlck9y
|
||||
ZzIwHhcNMTcwMjIwMTkwNjExWhcNMTgwMjIwMTkwNjExWjATMREwDwYDVQQDDAhw
|
||||
ZWVyT3JnMjBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABH3IweQK1AJdcV3FF27a
|
||||
gNKhy13Nz2OguzsmUbW85/7pReenAWzs89rEApHXoJqUtNzdZfaLkcq32E1Ilk3N
|
||||
oN2jVjBUMBIGA1UdEwEB/wQIMAYBAf8CAQAwHQYDVR0OBBYEFEhOilIyGA53r9Zo
|
||||
O5GQP0RSZcQ1MB8GA1UdIwQYMBaAFEhOilIyGA53r9ZoO5GQP0RSZcQ1MAoGCCqG
|
||||
SM49BAMCA0gAMEUCIQD+/5z68ewJarixMgYrg/MwyTMwX7ikCaCgU5TN2MU1PQIg
|
||||
Qe+klrq6COxsmrctClV64Wj4zhGTOhaZG1yN24OXukQ=
|
||||
-----END CERTIFICATE-----
|
|
@ -0,0 +1,10 @@
|
|||
-----BEGIN CERTIFICATE-----
|
||||
MIIBbDCCARKgAwIBAwICA+gwCgYIKoZIzj0EAwIwEzERMA8GA1UEAwwIcGVlck9y
|
||||
ZzAwHhcNMTcwMjIwMTkwNjEwWhcNMTgwMjIwMTkwNjEwWjATMREwDwYDVQQDDAhw
|
||||
ZWVyT3JnMDBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABKJfDc/CcaiHRipTG2AB
|
||||
K5fA0LO9SOlbtC9bZcjLo/xsL157p+3QB3UVF3gt7nkwgMs/ul3FhSEFTk2EVNlF
|
||||
1QCjVjBUMBIGA1UdEwEB/wQIMAYBAf8CAQAwHQYDVR0OBBYEFFQzuQR1RZP/Qn/B
|
||||
NDtGSa8n4eN/MB8GA1UdIwQYMBaAFFQzuQR1RZP/Qn/BNDtGSa8n4eN/MAoGCCqG
|
||||
SM49BAMCA0gAMEUCIAuG+/Fy3x9JXAD1/rFsu3ZpCKbXiXZLGF7P6Gma8is5AiEA
|
||||
pSQpRcdukxe4zvcfRmNBjMbNLWCoWlHSQA2jD678QGE=
|
||||
-----END CERTIFICATE-----
|
|
@ -0,0 +1,10 @@
|
|||
-----BEGIN CERTIFICATE-----
|
||||
MIIBbDCCARKgAwIBAwICA+gwCgYIKoZIzj0EAwIwEzERMA8GA1UEAwwIcGVlck9y
|
||||
ZzEwHhcNMTcwMjIwMTkwNjEwWhcNMTgwMjIwMTkwNjEwWjATMREwDwYDVQQDDAhw
|
||||
ZWVyT3JnMTBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABJ2S+UvyFgFZYL6qcrKo
|
||||
zy72Nkc/RQVzg1VfwC3X7QcnHEVBuCzba1nxdDVE8XPnhmKBWLKh0adn6GKUZpyf
|
||||
mbKjVjBUMBIGA1UdEwEB/wQIMAYBAf8CAQAwHQYDVR0OBBYEFAQlMVsXlKGMEWPf
|
||||
KMMM6QVASnlPMB8GA1UdIwQYMBaAFAQlMVsXlKGMEWPfKMMM6QVASnlPMAoGCCqG
|
||||
SM49BAMCA0gAMEUCIHr4AD6Xx3R6zFCsveIMnWao9Us88/0uGHoT4ELmMhA1AiEA
|
||||
yzfXU5qHp3xBJ1BrKOGi71UmQZVwWfO26INhxcfpCAg=
|
||||
-----END CERTIFICATE-----
|
|
@ -0,0 +1,10 @@
|
|||
-----BEGIN CERTIFICATE-----
|
||||
MIIBbDCCARKgAwIBAwICA+gwCgYIKoZIzj0EAwIwEzERMA8GA1UEAwwIcGVlck9y
|
||||
ZzIwHhcNMTcwMjIwMTkwNjExWhcNMTgwMjIwMTkwNjExWjATMREwDwYDVQQDDAhw
|
||||
ZWVyT3JnMjBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABH3IweQK1AJdcV3FF27a
|
||||
gNKhy13Nz2OguzsmUbW85/7pReenAWzs89rEApHXoJqUtNzdZfaLkcq32E1Ilk3N
|
||||
oN2jVjBUMBIGA1UdEwEB/wQIMAYBAf8CAQAwHQYDVR0OBBYEFEhOilIyGA53r9Zo
|
||||
O5GQP0RSZcQ1MB8GA1UdIwQYMBaAFEhOilIyGA53r9ZoO5GQP0RSZcQ1MAoGCCqG
|
||||
SM49BAMCA0gAMEUCIQD+/5z68ewJarixMgYrg/MwyTMwX7ikCaCgU5TN2MU1PQIg
|
||||
Qe+klrq6COxsmrctClV64Wj4zhGTOhaZG1yN24OXukQ=
|
||||
-----END CERTIFICATE-----
|
|
@ -0,0 +1,5 @@
|
|||
-----BEGIN EC PRIVATE KEY-----
|
||||
MHcCAQEEIGke7eS6obPUxqqTr3k4svyI+7H2K8vtauJslox/rNjooAoGCCqGSM49
|
||||
AwEHoUQDQgAEj3/vPecw5FR5Letn4X3fKYNHaOIHpab5BKhLP+5C5Fq+eiSyBTql
|
||||
4XmsEx95uT8982hWN1Hh6AKoAcEcimnsiw==
|
||||
-----END EC PRIVATE KEY-----
|
|
@ -0,0 +1,10 @@
|
|||
-----BEGIN CERTIFICATE-----
|
||||
MIIBYzCCAQmgAwIBAwICA+gwCgYIKoZIzj0EAwIwEzERMA8GA1UEAwwIcGVlck9y
|
||||
ZzAwHhcNMTcwMjIwMTkwNjExWhcNMTgwMjIwMTkwNjExWjAQMQ4wDAYDVQQDDAVw
|
||||
ZWVyMTBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABI9/7z3nMORUeS3rZ+F93ymD
|
||||
R2jiB6Wm+QSoSz/uQuRavnoksgU6peF5rBMfebk/PfNoVjdR4egCqAHBHIpp7Iuj
|
||||
UDBOMAwGA1UdEwEB/wQCMAAwHQYDVR0OBBYEFJpxVAXpMAEOHtbNCwvL1m/ku9gt
|
||||
MB8GA1UdIwQYMBaAFFQzuQR1RZP/Qn/BNDtGSa8n4eN/MAoGCCqGSM49BAMCA0gA
|
||||
MEUCIQDsQ6lmuLdKmMgnN5+9YjlpCRQEJCoaG3uxRHhrAecZngIgQZlwnvwka+TM
|
||||
gF/yC3r2MeELK9ocw8c22DAe6x71RT4=
|
||||
-----END CERTIFICATE-----
|
|
@ -0,0 +1,10 @@
|
|||
-----BEGIN CERTIFICATE-----
|
||||
MIIBbDCCARKgAwIBAwICA+gwCgYIKoZIzj0EAwIwEzERMA8GA1UEAwwIcGVlck9y
|
||||
ZzAwHhcNMTcwMjIwMTkwNjEwWhcNMTgwMjIwMTkwNjEwWjATMREwDwYDVQQDDAhw
|
||||
ZWVyT3JnMDBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABKJfDc/CcaiHRipTG2AB
|
||||
K5fA0LO9SOlbtC9bZcjLo/xsL157p+3QB3UVF3gt7nkwgMs/ul3FhSEFTk2EVNlF
|
||||
1QCjVjBUMBIGA1UdEwEB/wQIMAYBAf8CAQAwHQYDVR0OBBYEFFQzuQR1RZP/Qn/B
|
||||
NDtGSa8n4eN/MB8GA1UdIwQYMBaAFFQzuQR1RZP/Qn/BNDtGSa8n4eN/MAoGCCqG
|
||||
SM49BAMCA0gAMEUCIAuG+/Fy3x9JXAD1/rFsu3ZpCKbXiXZLGF7P6Gma8is5AiEA
|
||||
pSQpRcdukxe4zvcfRmNBjMbNLWCoWlHSQA2jD678QGE=
|
||||
-----END CERTIFICATE-----
|
|
@ -0,0 +1,10 @@
|
|||
-----BEGIN CERTIFICATE-----
|
||||
MIIBbDCCARKgAwIBAwICA+gwCgYIKoZIzj0EAwIwEzERMA8GA1UEAwwIcGVlck9y
|
||||
ZzEwHhcNMTcwMjIwMTkwNjEwWhcNMTgwMjIwMTkwNjEwWjATMREwDwYDVQQDDAhw
|
||||
ZWVyT3JnMTBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABJ2S+UvyFgFZYL6qcrKo
|
||||
zy72Nkc/RQVzg1VfwC3X7QcnHEVBuCzba1nxdDVE8XPnhmKBWLKh0adn6GKUZpyf
|
||||
mbKjVjBUMBIGA1UdEwEB/wQIMAYBAf8CAQAwHQYDVR0OBBYEFAQlMVsXlKGMEWPf
|
||||
KMMM6QVASnlPMB8GA1UdIwQYMBaAFAQlMVsXlKGMEWPfKMMM6QVASnlPMAoGCCqG
|
||||
SM49BAMCA0gAMEUCIHr4AD6Xx3R6zFCsveIMnWao9Us88/0uGHoT4ELmMhA1AiEA
|
||||
yzfXU5qHp3xBJ1BrKOGi71UmQZVwWfO26INhxcfpCAg=
|
||||
-----END CERTIFICATE-----
|
|
@ -0,0 +1,10 @@
|
|||
-----BEGIN CERTIFICATE-----
|
||||
MIIBbDCCARKgAwIBAwICA+gwCgYIKoZIzj0EAwIwEzERMA8GA1UEAwwIcGVlck9y
|
||||
ZzIwHhcNMTcwMjIwMTkwNjExWhcNMTgwMjIwMTkwNjExWjATMREwDwYDVQQDDAhw
|
||||
ZWVyT3JnMjBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABH3IweQK1AJdcV3FF27a
|
||||
gNKhy13Nz2OguzsmUbW85/7pReenAWzs89rEApHXoJqUtNzdZfaLkcq32E1Ilk3N
|
||||
oN2jVjBUMBIGA1UdEwEB/wQIMAYBAf8CAQAwHQYDVR0OBBYEFEhOilIyGA53r9Zo
|
||||
O5GQP0RSZcQ1MB8GA1UdIwQYMBaAFEhOilIyGA53r9ZoO5GQP0RSZcQ1MAoGCCqG
|
||||
SM49BAMCA0gAMEUCIQD+/5z68ewJarixMgYrg/MwyTMwX7ikCaCgU5TN2MU1PQIg
|
||||
Qe+klrq6COxsmrctClV64Wj4zhGTOhaZG1yN24OXukQ=
|
||||
-----END CERTIFICATE-----
|
|
@ -0,0 +1,10 @@
|
|||
-----BEGIN CERTIFICATE-----
|
||||
MIIBbDCCARKgAwIBAwICA+gwCgYIKoZIzj0EAwIwEzERMA8GA1UEAwwIcGVlck9y
|
||||
ZzAwHhcNMTcwMjIwMTkwNjEwWhcNMTgwMjIwMTkwNjEwWjATMREwDwYDVQQDDAhw
|
||||
ZWVyT3JnMDBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABKJfDc/CcaiHRipTG2AB
|
||||
K5fA0LO9SOlbtC9bZcjLo/xsL157p+3QB3UVF3gt7nkwgMs/ul3FhSEFTk2EVNlF
|
||||
1QCjVjBUMBIGA1UdEwEB/wQIMAYBAf8CAQAwHQYDVR0OBBYEFFQzuQR1RZP/Qn/B
|
||||
NDtGSa8n4eN/MB8GA1UdIwQYMBaAFFQzuQR1RZP/Qn/BNDtGSa8n4eN/MAoGCCqG
|
||||
SM49BAMCA0gAMEUCIAuG+/Fy3x9JXAD1/rFsu3ZpCKbXiXZLGF7P6Gma8is5AiEA
|
||||
pSQpRcdukxe4zvcfRmNBjMbNLWCoWlHSQA2jD678QGE=
|
||||
-----END CERTIFICATE-----
|
|
@ -0,0 +1,10 @@
|
|||
-----BEGIN CERTIFICATE-----
|
||||
MIIBbDCCARKgAwIBAwICA+gwCgYIKoZIzj0EAwIwEzERMA8GA1UEAwwIcGVlck9y
|
||||
ZzEwHhcNMTcwMjIwMTkwNjEwWhcNMTgwMjIwMTkwNjEwWjATMREwDwYDVQQDDAhw
|
||||
ZWVyT3JnMTBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABJ2S+UvyFgFZYL6qcrKo
|
||||
zy72Nkc/RQVzg1VfwC3X7QcnHEVBuCzba1nxdDVE8XPnhmKBWLKh0adn6GKUZpyf
|
||||
mbKjVjBUMBIGA1UdEwEB/wQIMAYBAf8CAQAwHQYDVR0OBBYEFAQlMVsXlKGMEWPf
|
||||
KMMM6QVASnlPMB8GA1UdIwQYMBaAFAQlMVsXlKGMEWPfKMMM6QVASnlPMAoGCCqG
|
||||
SM49BAMCA0gAMEUCIHr4AD6Xx3R6zFCsveIMnWao9Us88/0uGHoT4ELmMhA1AiEA
|
||||
yzfXU5qHp3xBJ1BrKOGi71UmQZVwWfO26INhxcfpCAg=
|
||||
-----END CERTIFICATE-----
|
|
@ -0,0 +1,10 @@
|
|||
-----BEGIN CERTIFICATE-----
|
||||
MIIBbDCCARKgAwIBAwICA+gwCgYIKoZIzj0EAwIwEzERMA8GA1UEAwwIcGVlck9y
|
||||
ZzIwHhcNMTcwMjIwMTkwNjExWhcNMTgwMjIwMTkwNjExWjATMREwDwYDVQQDDAhw
|
||||
ZWVyT3JnMjBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABH3IweQK1AJdcV3FF27a
|
||||
gNKhy13Nz2OguzsmUbW85/7pReenAWzs89rEApHXoJqUtNzdZfaLkcq32E1Ilk3N
|
||||
oN2jVjBUMBIGA1UdEwEB/wQIMAYBAf8CAQAwHQYDVR0OBBYEFEhOilIyGA53r9Zo
|
||||
O5GQP0RSZcQ1MB8GA1UdIwQYMBaAFEhOilIyGA53r9ZoO5GQP0RSZcQ1MAoGCCqG
|
||||
SM49BAMCA0gAMEUCIQD+/5z68ewJarixMgYrg/MwyTMwX7ikCaCgU5TN2MU1PQIg
|
||||
Qe+klrq6COxsmrctClV64Wj4zhGTOhaZG1yN24OXukQ=
|
||||
-----END CERTIFICATE-----
|
|
@ -0,0 +1,5 @@
|
|||
-----BEGIN EC PRIVATE KEY-----
|
||||
MHcCAQEEICO7+w9YD/MdNiZHXusiWGhHTOOAXks10aJGuITmZ0wkoAoGCCqGSM49
|
||||
AwEHoUQDQgAEtnKiIRz/RpNy2TxMcoe1DxYXYEAbW+AHqTFP5xRoucQfYSX01O9F
|
||||
iMeaOryjMz379HYlW5wQZl6UAhDEoPmlew==
|
||||
-----END EC PRIVATE KEY-----
|
|
@ -0,0 +1,10 @@
|
|||
-----BEGIN CERTIFICATE-----
|
||||
MIIBYzCCAQmgAwIBAwICA+gwCgYIKoZIzj0EAwIwEzERMA8GA1UEAwwIcGVlck9y
|
||||
ZzEwHhcNMTcwMjIwMTkwNjExWhcNMTgwMjIwMTkwNjExWjAQMQ4wDAYDVQQDDAVw
|
||||
ZWVyMjBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABLZyoiEc/0aTctk8THKHtQ8W
|
||||
F2BAG1vgB6kxT+cUaLnEH2El9NTvRYjHmjq8ozM9+/R2JVucEGZelAIQxKD5pXuj
|
||||
UDBOMAwGA1UdEwEB/wQCMAAwHQYDVR0OBBYEFDdoFJ6jiClMPOVsNx5akist91so
|
||||
MB8GA1UdIwQYMBaAFAQlMVsXlKGMEWPfKMMM6QVASnlPMAoGCCqGSM49BAMCA0gA
|
||||
MEUCIQC7wATZy+O/7UIPzSiMSXNgBKCaT2U55+Y/e0FcHQFSoQIgCyKExrm3gtW0
|
||||
SAN1VofiAZkr3gYndu9goHZe4wVh9eQ=
|
||||
-----END CERTIFICATE-----
|
|
@ -0,0 +1,10 @@
|
|||
-----BEGIN CERTIFICATE-----
|
||||
MIIBbDCCARKgAwIBAwICA+gwCgYIKoZIzj0EAwIwEzERMA8GA1UEAwwIcGVlck9y
|
||||
ZzAwHhcNMTcwMjIwMTkwNjEwWhcNMTgwMjIwMTkwNjEwWjATMREwDwYDVQQDDAhw
|
||||
ZWVyT3JnMDBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABKJfDc/CcaiHRipTG2AB
|
||||
K5fA0LO9SOlbtC9bZcjLo/xsL157p+3QB3UVF3gt7nkwgMs/ul3FhSEFTk2EVNlF
|
||||
1QCjVjBUMBIGA1UdEwEB/wQIMAYBAf8CAQAwHQYDVR0OBBYEFFQzuQR1RZP/Qn/B
|
||||
NDtGSa8n4eN/MB8GA1UdIwQYMBaAFFQzuQR1RZP/Qn/BNDtGSa8n4eN/MAoGCCqG
|
||||
SM49BAMCA0gAMEUCIAuG+/Fy3x9JXAD1/rFsu3ZpCKbXiXZLGF7P6Gma8is5AiEA
|
||||
pSQpRcdukxe4zvcfRmNBjMbNLWCoWlHSQA2jD678QGE=
|
||||
-----END CERTIFICATE-----
|
|
@ -0,0 +1,10 @@
|
|||
-----BEGIN CERTIFICATE-----
|
||||
MIIBbDCCARKgAwIBAwICA+gwCgYIKoZIzj0EAwIwEzERMA8GA1UEAwwIcGVlck9y
|
||||
ZzEwHhcNMTcwMjIwMTkwNjEwWhcNMTgwMjIwMTkwNjEwWjATMREwDwYDVQQDDAhw
|
||||
ZWVyT3JnMTBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABJ2S+UvyFgFZYL6qcrKo
|
||||
zy72Nkc/RQVzg1VfwC3X7QcnHEVBuCzba1nxdDVE8XPnhmKBWLKh0adn6GKUZpyf
|
||||
mbKjVjBUMBIGA1UdEwEB/wQIMAYBAf8CAQAwHQYDVR0OBBYEFAQlMVsXlKGMEWPf
|
||||
KMMM6QVASnlPMB8GA1UdIwQYMBaAFAQlMVsXlKGMEWPfKMMM6QVASnlPMAoGCCqG
|
||||
SM49BAMCA0gAMEUCIHr4AD6Xx3R6zFCsveIMnWao9Us88/0uGHoT4ELmMhA1AiEA
|
||||
yzfXU5qHp3xBJ1BrKOGi71UmQZVwWfO26INhxcfpCAg=
|
||||
-----END CERTIFICATE-----
|
|
@ -0,0 +1,10 @@
|
|||
-----BEGIN CERTIFICATE-----
|
||||
MIIBbDCCARKgAwIBAwICA+gwCgYIKoZIzj0EAwIwEzERMA8GA1UEAwwIcGVlck9y
|
||||
ZzIwHhcNMTcwMjIwMTkwNjExWhcNMTgwMjIwMTkwNjExWjATMREwDwYDVQQDDAhw
|
||||
ZWVyT3JnMjBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABH3IweQK1AJdcV3FF27a
|
||||
gNKhy13Nz2OguzsmUbW85/7pReenAWzs89rEApHXoJqUtNzdZfaLkcq32E1Ilk3N
|
||||
oN2jVjBUMBIGA1UdEwEB/wQIMAYBAf8CAQAwHQYDVR0OBBYEFEhOilIyGA53r9Zo
|
||||
O5GQP0RSZcQ1MB8GA1UdIwQYMBaAFEhOilIyGA53r9ZoO5GQP0RSZcQ1MAoGCCqG
|
||||
SM49BAMCA0gAMEUCIQD+/5z68ewJarixMgYrg/MwyTMwX7ikCaCgU5TN2MU1PQIg
|
||||
Qe+klrq6COxsmrctClV64Wj4zhGTOhaZG1yN24OXukQ=
|
||||
-----END CERTIFICATE-----
|
|
@ -0,0 +1,10 @@
|
|||
-----BEGIN CERTIFICATE-----
|
||||
MIIBbDCCARKgAwIBAwICA+gwCgYIKoZIzj0EAwIwEzERMA8GA1UEAwwIcGVlck9y
|
||||
ZzAwHhcNMTcwMjIwMTkwNjEwWhcNMTgwMjIwMTkwNjEwWjATMREwDwYDVQQDDAhw
|
||||
ZWVyT3JnMDBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABKJfDc/CcaiHRipTG2AB
|
||||
K5fA0LO9SOlbtC9bZcjLo/xsL157p+3QB3UVF3gt7nkwgMs/ul3FhSEFTk2EVNlF
|
||||
1QCjVjBUMBIGA1UdEwEB/wQIMAYBAf8CAQAwHQYDVR0OBBYEFFQzuQR1RZP/Qn/B
|
||||
NDtGSa8n4eN/MB8GA1UdIwQYMBaAFFQzuQR1RZP/Qn/BNDtGSa8n4eN/MAoGCCqG
|
||||
SM49BAMCA0gAMEUCIAuG+/Fy3x9JXAD1/rFsu3ZpCKbXiXZLGF7P6Gma8is5AiEA
|
||||
pSQpRcdukxe4zvcfRmNBjMbNLWCoWlHSQA2jD678QGE=
|
||||
-----END CERTIFICATE-----
|
|
@ -0,0 +1,10 @@
|
|||
-----BEGIN CERTIFICATE-----
|
||||
MIIBbDCCARKgAwIBAwICA+gwCgYIKoZIzj0EAwIwEzERMA8GA1UEAwwIcGVlck9y
|
||||
ZzEwHhcNMTcwMjIwMTkwNjEwWhcNMTgwMjIwMTkwNjEwWjATMREwDwYDVQQDDAhw
|
||||
ZWVyT3JnMTBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABJ2S+UvyFgFZYL6qcrKo
|
||||
zy72Nkc/RQVzg1VfwC3X7QcnHEVBuCzba1nxdDVE8XPnhmKBWLKh0adn6GKUZpyf
|
||||
mbKjVjBUMBIGA1UdEwEB/wQIMAYBAf8CAQAwHQYDVR0OBBYEFAQlMVsXlKGMEWPf
|
||||
KMMM6QVASnlPMB8GA1UdIwQYMBaAFAQlMVsXlKGMEWPfKMMM6QVASnlPMAoGCCqG
|
||||
SM49BAMCA0gAMEUCIHr4AD6Xx3R6zFCsveIMnWao9Us88/0uGHoT4ELmMhA1AiEA
|
||||
yzfXU5qHp3xBJ1BrKOGi71UmQZVwWfO26INhxcfpCAg=
|
||||
-----END CERTIFICATE-----
|
|
@ -0,0 +1,10 @@
|
|||
-----BEGIN CERTIFICATE-----
|
||||
MIIBbDCCARKgAwIBAwICA+gwCgYIKoZIzj0EAwIwEzERMA8GA1UEAwwIcGVlck9y
|
||||
ZzIwHhcNMTcwMjIwMTkwNjExWhcNMTgwMjIwMTkwNjExWjATMREwDwYDVQQDDAhw
|
||||
ZWVyT3JnMjBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABH3IweQK1AJdcV3FF27a
|
||||
gNKhy13Nz2OguzsmUbW85/7pReenAWzs89rEApHXoJqUtNzdZfaLkcq32E1Ilk3N
|
||||
oN2jVjBUMBIGA1UdEwEB/wQIMAYBAf8CAQAwHQYDVR0OBBYEFEhOilIyGA53r9Zo
|
||||
O5GQP0RSZcQ1MB8GA1UdIwQYMBaAFEhOilIyGA53r9ZoO5GQP0RSZcQ1MAoGCCqG
|
||||
SM49BAMCA0gAMEUCIQD+/5z68ewJarixMgYrg/MwyTMwX7ikCaCgU5TN2MU1PQIg
|
||||
Qe+klrq6COxsmrctClV64Wj4zhGTOhaZG1yN24OXukQ=
|
||||
-----END CERTIFICATE-----
|
|
@ -0,0 +1,5 @@
|
|||
-----BEGIN EC PRIVATE KEY-----
|
||||
MHcCAQEEIPK7O2ZBw9tXDiVd2OM+riCIHT+uQPynGd0z9fjLSUltoAoGCCqGSM49
|
||||
AwEHoUQDQgAEy+ACkoJdggRjhiA9OBAqsswYx0r/WPxYSXaGKMQP6idVQX/D+iV6
|
||||
JKWM04LF11re7dfTJepfP+jNA8kv93hgvw==
|
||||
-----END EC PRIVATE KEY-----
|
|
@ -0,0 +1,10 @@
|
|||
-----BEGIN CERTIFICATE-----
|
||||
MIIBYzCCAQmgAwIBAwICA+gwCgYIKoZIzj0EAwIwEzERMA8GA1UEAwwIcGVlck9y
|
||||
ZzEwHhcNMTcwMjIwMTkwNjExWhcNMTgwMjIwMTkwNjExWjAQMQ4wDAYDVQQDDAVw
|
||||
ZWVyMzBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABMvgApKCXYIEY4YgPTgQKrLM
|
||||
GMdK/1j8WEl2hijED+onVUF/w/oleiSljNOCxdda3u3X0yXqXz/ozQPJL/d4YL+j
|
||||
UDBOMAwGA1UdEwEB/wQCMAAwHQYDVR0OBBYEFOzMeVZK5xYzjaeO2uGvz8B7CQS7
|
||||
MB8GA1UdIwQYMBaAFAQlMVsXlKGMEWPfKMMM6QVASnlPMAoGCCqGSM49BAMCA0gA
|
||||
MEUCIQCgKtFodSdXcz2yf9MZB90t1nXYytpGUPMAl0/Gy2/yfQIgAcC1KRtaiclr
|
||||
9C9tshhXdYdbpvDruVZrwqjJ4drPHik=
|
||||
-----END CERTIFICATE-----
|
|
@ -0,0 +1,131 @@
|
|||
version: '2'
|
||||
|
||||
services:
|
||||
|
||||
orderer0:
|
||||
container_name: orderer0
|
||||
image: hyperledger/fabric-orderer
|
||||
environment:
|
||||
- ORDERER_GENERAL_LOGLEVEL=debug
|
||||
- ORDERER_GENERAL_LISTENADDRESS=0.0.0.0
|
||||
- ORDERER_GENERAL_GENESISMETHOD=file
|
||||
- ORDERER_GENERAL_GENESISFILE=/var/hyperledger/orderer/orderer.block
|
||||
- ORDERER_GENERAL_LOCALMSPID=OrdererMSP
|
||||
- ORDERER_GENERAL_LOCALMSPDIR=/var/hyperledger/orderer/localMspConfig
|
||||
working_dir: /opt/gopath/src/github.com/hyperledger/fabric
|
||||
command: orderer
|
||||
volumes:
|
||||
- ./crypto/orderer:/var/hyperledger/orderer
|
||||
ports:
|
||||
- 7050:7050
|
||||
|
||||
peer0:
|
||||
container_name: peer0
|
||||
extends:
|
||||
file: peer-base/peer-base-no-tls.yaml
|
||||
service: peer-base
|
||||
environment:
|
||||
- CORE_PEER_ID=peer0
|
||||
#- CORE_PEER_COMMITTER_LEDGER_ORDERER=orderer:7050
|
||||
- CORE_PEER_LOCALMSPID=Org0MSP
|
||||
volumes:
|
||||
- /var/run/:/host/var/run/
|
||||
- ./crypto/peer/peer0/localMspConfig:/etc/hyperledger/fabric/msp/sampleconfig
|
||||
ports:
|
||||
- 7051:7051
|
||||
- 7053:7053
|
||||
depends_on:
|
||||
- orderer0
|
||||
|
||||
peer1:
|
||||
container_name: peer1
|
||||
extends:
|
||||
file: peer-base/peer-base-no-tls.yaml
|
||||
service: peer-base
|
||||
environment:
|
||||
- CORE_PEER_ID=peer1
|
||||
- CORE_PEER_GOSSIP_BOOTSTRAP=peer0:7051
|
||||
#- CORE_PEER_COMMITTER_LEDGER_ORDERER=orderer:7050
|
||||
- CORE_PEER_LOCALMSPID=Org0MSP
|
||||
volumes:
|
||||
- /var/run/:/host/var/run/
|
||||
- ./crypto/peer/peer1/localMspConfig:/etc/hyperledger/fabric/msp/sampleconfig
|
||||
ports:
|
||||
- 8051:7051
|
||||
- 8053:7053
|
||||
depends_on:
|
||||
- orderer0
|
||||
- peer0
|
||||
|
||||
peer2:
|
||||
container_name: peer2
|
||||
extends:
|
||||
file: peer-base/peer-base-no-tls.yaml
|
||||
service: peer-base
|
||||
environment:
|
||||
- CORE_PEER_ID=peer2
|
||||
- CORE_PEER_GOSSIP_BOOTSTRAP=peer0:7051
|
||||
#- CORE_PEER_COMMITTER_LEDGER_ORDERER=orderer:7050
|
||||
- CORE_PEER_LOCALMSPID=Org1MSP
|
||||
volumes:
|
||||
- /var/run/:/host/var/run/
|
||||
- ./crypto/peer/peer2/localMspConfig:/etc/hyperledger/fabric/msp/sampleconfig
|
||||
ports:
|
||||
- 9051:7051
|
||||
- 9053:7053
|
||||
depends_on:
|
||||
- orderer0
|
||||
- peer0
|
||||
- peer1
|
||||
|
||||
peer3:
|
||||
container_name: peer3
|
||||
extends:
|
||||
file: peer-base/peer-base-no-tls.yaml
|
||||
service: peer-base
|
||||
environment:
|
||||
- CORE_PEER_ID=peer3
|
||||
- CORE_PEER_GOSSIP_BOOTSTRAP=peer0:7051
|
||||
#- CORE_PEER_COMMITTER_LEDGER_ORDERER=orderer:7050
|
||||
- CORE_PEER_LOCALMSPID=Org1MSP
|
||||
volumes:
|
||||
- /var/run/:/host/var/run/
|
||||
- ./crypto/peer/peer3/localMspConfig:/etc/hyperledger/fabric/msp/sampleconfig
|
||||
ports:
|
||||
- 10051:7051
|
||||
- 10053:7053
|
||||
depends_on:
|
||||
- orderer0
|
||||
- peer0
|
||||
- peer1
|
||||
- peer2
|
||||
|
||||
cli:
|
||||
container_name: cli
|
||||
image: hyperledger/fabric-peer
|
||||
tty: true
|
||||
environment:
|
||||
- GOPATH=/opt/gopath
|
||||
- CORE_PEER_ADDRESSAUTODETECT=true
|
||||
- CORE_VM_ENDPOINT=unix:///host/var/run/docker.sock
|
||||
- CORE_LOGGING_LEVEL=DEBUG
|
||||
- CORE_NEXT=true
|
||||
- CORE_PEER_ID=cli
|
||||
- CORE_PEER_ENDORSER_ENABLED=true
|
||||
#- CORE_PEER_COMMITTER_LEDGER_ORDERER=orderer:7050
|
||||
- CORE_PEER_ADDRESS=peer0:7051
|
||||
- CORE_PEER_GOSSIP_IGNORESECURITY=true
|
||||
- CORE_PEER_LOCALMSPID=Org0MSP
|
||||
working_dir: /opt/gopath/src/github.com/hyperledger/fabric/peer
|
||||
command: /bin/bash -c './scripts/script.sh ${CHANNEL_NAME}; '
|
||||
volumes:
|
||||
- /var/run/:/host/var/run/
|
||||
- ./examples/:/opt/gopath/src/github.com/hyperledger/fabric/examples/
|
||||
- ./crypto:/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/
|
||||
- ./scripts:/opt/gopath/src/github.com/hyperledger/fabric/peer/scripts/
|
||||
depends_on:
|
||||
- orderer0
|
||||
- peer0
|
||||
- peer1
|
||||
- peer2
|
||||
- peer3
|
|
@ -0,0 +1,218 @@
|
|||
version: '2'
|
||||
|
||||
services:
|
||||
|
||||
orderer0:
|
||||
container_name: orderer0
|
||||
image: hyperledger/fabric-orderer
|
||||
environment:
|
||||
- ORDERER_GENERAL_LOGLEVEL=debug
|
||||
- ORDERER_GENERAL_LISTENADDRESS=0.0.0.0
|
||||
- ORDERER_GENERAL_GENESISMETHOD=file
|
||||
- ORDERER_GENERAL_GENESISFILE=/var/hyperledger/orderer/orderer.block
|
||||
- ORDERER_GENERAL_LOCALMSPID=OrdererMSP
|
||||
- ORDERER_GENERAL_LOCALMSPDIR=/var/hyperledger/orderer/localMspConfig
|
||||
# enabled TLS
|
||||
- ORDERER_GENERAL_TLS_ENABLED=true
|
||||
- ORDERER_GENERAL_TLS_PRIVATEKEY=/var/hyperledger/orderer/localMspConfig/keystore/ordererSigner.pem
|
||||
- ORDERER_GENERAL_TLS_CERTIFICATE=/var/hyperledger/orderer/localMspConfig/signcerts/orderer0Signer.pem
|
||||
- ORDERER_GENERAL_TLS_ROOTCAS=[/var/hyperledger/orderer/localMspConfig/cacerts/ordererOrg0.pem]
|
||||
working_dir: /opt/gopath/src/github.com/hyperledger/fabric
|
||||
command: orderer
|
||||
volumes:
|
||||
- ./crypto/orderer:/var/hyperledger/orderer
|
||||
ports:
|
||||
- 7050:7050
|
||||
|
||||
## To enable CouchDB as state database, uncomment the following sections of this file:
|
||||
## 1) couchdb containers
|
||||
## 2) peer environment variables CORE_LEDGER_STATE_STATEDATABASE and
|
||||
## CORE_LEDGER_STATE_COUCHDBCONFIG_COUCHDBADDRESS
|
||||
## 3) couch container names in "depends_on" section
|
||||
|
||||
# couchdb0:
|
||||
# container_name: couchdb0
|
||||
# image: hyperledger/fabric-couchdb
|
||||
## Uncomment the port mapping if you want to expose the CouchDB service,
|
||||
## for example to utilize Fauxton User Interface in dev environments.
|
||||
# ports:
|
||||
# - "5984:5984"
|
||||
|
||||
peer0:
|
||||
container_name: peer0
|
||||
extends:
|
||||
file: peer-base/peer-base.yaml
|
||||
service: peer-base
|
||||
environment:
|
||||
- CORE_PEER_ID=peer0
|
||||
- CORE_PEER_ADDRESS=peer0:7051
|
||||
- CORE_PEER_GOSSIP_EXTERNALENDPOINT=peer0:7051
|
||||
# - CORE_PEER_COMMITTER_LEDGER_ORDERER=orderer0:7050
|
||||
- CORE_PEER_LOCALMSPID=Org0MSP
|
||||
- CORE_PEER_TLS_CERT_FILE=/etc/hyperledger/fabric/msp/sampleconfig/signcerts/peer0Signer.pem
|
||||
- CORE_PEER_TLS_KEY_FILE=/etc/hyperledger/fabric/msp/sampleconfig/keystore/peer0Signer.pem
|
||||
- CORE_PEER_TLS_ROOTCERT_FILE=/etc/hyperledger/fabric/msp/sampleconfig/cacerts/peerOrg0.pem
|
||||
# - CORE_PEER_TLS_SERVERHOSTOVERRIDE=peer0
|
||||
# - CORE_LEDGER_STATE_STATEDATABASE=CouchDB
|
||||
# - CORE_LEDGER_STATE_COUCHDBCONFIG_COUCHDBADDRESS=couchdb0:5984
|
||||
volumes:
|
||||
- /var/run/:/host/var/run/
|
||||
- ./crypto/peer/peer0/localMspConfig:/etc/hyperledger/fabric/msp/sampleconfig
|
||||
ports:
|
||||
- 7051:7051
|
||||
- 7053:7053
|
||||
depends_on:
|
||||
- orderer0
|
||||
# - couchdb0
|
||||
|
||||
# couchdb1:
|
||||
# container_name: couchdb1
|
||||
# image: hyperledger/fabric-couchdb
|
||||
## Uncomment the port mapping if you want to expose the CouchDB service,
|
||||
## for example to utilize Fauxton User Interface in dev environments.
|
||||
# ports:
|
||||
# - "6984:5984"
|
||||
|
||||
peer1:
|
||||
container_name: peer1
|
||||
extends:
|
||||
file: peer-base/peer-base.yaml
|
||||
service: peer-base
|
||||
environment:
|
||||
- CORE_PEER_ID=peer1
|
||||
- CORE_PEER_ADDRESS=peer1:7051
|
||||
- CORE_PEER_GOSSIP_EXTERNALENDPOINT=peer1:7051
|
||||
- CORE_PEER_GOSSIP_BOOTSTRAP=peer0:7051
|
||||
# - CORE_PEER_COMMITTER_LEDGER_ORDERER=orderer0:7050
|
||||
- CORE_PEER_LOCALMSPID=Org0MSP
|
||||
- CORE_PEER_TLS_CERT_FILE=/etc/hyperledger/fabric/msp/sampleconfig/signcerts/peer1Signer.pem
|
||||
- CORE_PEER_TLS_KEY_FILE=/etc/hyperledger/fabric/msp/sampleconfig/keystore/peer1Signer.pem
|
||||
- CORE_PEER_TLS_ROOTCERT_FILE=/etc/hyperledger/fabric/msp/sampleconfig/cacerts/peerOrg0.pem
|
||||
# - CORE_PEER_TLS_SERVERHOSTOVERRIDE=peer1
|
||||
# - CORE_LEDGER_STATE_STATEDATABASE=CouchDB
|
||||
# - CORE_LEDGER_STATE_COUCHDBCONFIG_COUCHDBADDRESS=couchdb1:5984
|
||||
volumes:
|
||||
- /var/run/:/host/var/run/
|
||||
- ./crypto/peer/peer1/localMspConfig:/etc/hyperledger/fabric/msp/sampleconfig
|
||||
ports:
|
||||
- 8051:7051
|
||||
- 8053:7053
|
||||
depends_on:
|
||||
- orderer0
|
||||
- peer0
|
||||
# - couchdb1
|
||||
|
||||
# couchdb2:
|
||||
# container_name: couchdb2
|
||||
# image: hyperledger/fabric-couchdb
|
||||
## Uncomment the port mapping if you want to expose the CouchDB service,
|
||||
## for example to utilize Fauxton User Interface in dev environments.
|
||||
# ports:
|
||||
# - "7984:5984"
|
||||
|
||||
peer2:
|
||||
container_name: peer2
|
||||
extends:
|
||||
file: peer-base/peer-base.yaml
|
||||
service: peer-base
|
||||
environment:
|
||||
- CORE_PEER_ID=peer2
|
||||
- CORE_PEER_ADDRESS=peer2:7051
|
||||
- CORE_PEER_GOSSIP_EXTERNALENDPOINT=peer2:7051
|
||||
- CORE_PEER_GOSSIP_BOOTSTRAP=peer2:7051
|
||||
#- CORE_PEER_COMMITTER_LEDGER_ORDERER=orderer0:7050
|
||||
- CORE_PEER_LOCALMSPID=Org1MSP
|
||||
- CORE_PEER_TLS_CERT_FILE=/etc/hyperledger/fabric/msp/sampleconfig/signcerts/peer2Signer.pem
|
||||
- CORE_PEER_TLS_KEY_FILE=/etc/hyperledger/fabric/msp/sampleconfig/keystore/peer2Signer.pem
|
||||
- CORE_PEER_TLS_ROOTCERT_FILE=/etc/hyperledger/fabric/msp/sampleconfig/admincerts/peerOrg1.pem
|
||||
#- CORE_PEER_TLS_SERVERHOSTOVERRIDE=peer2
|
||||
# - CORE_LEDGER_STATE_STATEDATABASE=CouchDB
|
||||
# - CORE_LEDGER_STATE_COUCHDBCONFIG_COUCHDBADDRESS=couchdb2:5984
|
||||
volumes:
|
||||
- /var/run/:/host/var/run/
|
||||
- ./crypto/peer/peer2/localMspConfig:/etc/hyperledger/fabric/msp/sampleconfig
|
||||
ports:
|
||||
- 9051:7051
|
||||
- 9053:7053
|
||||
depends_on:
|
||||
- orderer0
|
||||
- peer0
|
||||
- peer1
|
||||
# - couchdb2
|
||||
|
||||
# couchdb3:
|
||||
# container_name: couchdb3
|
||||
# image: hyperledger/fabric-couchdb
|
||||
## Uncomment the port mapping if you want to expose the CouchDB service,
|
||||
## for example to utilize Fauxton User Interface in dev environments.
|
||||
# ports:
|
||||
# - "8984:5984"
|
||||
|
||||
peer3:
|
||||
container_name: peer3
|
||||
extends:
|
||||
file: peer-base/peer-base.yaml
|
||||
service: peer-base
|
||||
environment:
|
||||
- CORE_PEER_ID=peer3
|
||||
- CORE_PEER_ADDRESS=peer3:7051
|
||||
- CORE_PEER_GOSSIP_EXTERNALENDPOINT=peer3:7051
|
||||
- CORE_PEER_GOSSIP_BOOTSTRAP=peer0:7051
|
||||
# - CORE_PEER_COMMITTER_LEDGER_ORDERER=orderer0:7050
|
||||
- CORE_PEER_LOCALMSPID=Org1MSP
|
||||
- CORE_PEER_TLS_CERT_FILE=/etc/hyperledger/fabric/msp/sampleconfig/signcerts/peer3Signer.pem
|
||||
- CORE_PEER_TLS_KEY_FILE=/etc/hyperledger/fabric/msp/sampleconfig/keystore/peer3Signer.pem
|
||||
- CORE_PEER_TLS_ROOTCERT_FILE=/etc/hyperledger/fabric/msp/sampleconfig/cacerts/peerOrg1.pem
|
||||
# - CORE_PEER_TLS_SERVERHOSTOVERRIDE=peer3
|
||||
# - CORE_LEDGER_STATE_STATEDATABASE=CouchDB
|
||||
# - CORE_LEDGER_STATE_COUCHDBCONFIG_COUCHDBADDRESS=couchdb3:5984
|
||||
volumes:
|
||||
- /var/run/:/host/var/run/
|
||||
- ./crypto/peer/peer3/localMspConfig:/etc/hyperledger/fabric/msp/sampleconfig
|
||||
ports:
|
||||
- 10051:7051
|
||||
- 10053:7053
|
||||
depends_on:
|
||||
- orderer0
|
||||
- peer0
|
||||
- peer1
|
||||
- peer2
|
||||
# - couchdb3
|
||||
|
||||
cli:
|
||||
container_name: cli
|
||||
image: hyperledger/fabric-peer
|
||||
tty: true
|
||||
environment:
|
||||
- GOPATH=/opt/gopath
|
||||
- CORE_PEER_ADDRESSAUTODETECT=true
|
||||
- CORE_VM_ENDPOINT=unix:///host/var/run/docker.sock
|
||||
- CORE_LOGGING_LEVEL=DEBUG
|
||||
- CORE_NEXT=true
|
||||
- CORE_PEER_ID=cli
|
||||
- CORE_PEER_ENDORSER_ENABLED=true
|
||||
# - CORE_PEER_COMMITTER_LEDGER_ORDERER=orderer0:7050
|
||||
- CORE_PEER_ADDRESS=peer0:7051
|
||||
- CORE_PEER_LOCALMSPID=Org0MSP
|
||||
- CORE_PEER_TLS_ENABLED=true
|
||||
- CORE_PEER_TLS_CERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peer/peer0/localMspConfig/signcerts/peer0Signer.pem
|
||||
- CORE_PEER_TLS_KEY_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peer/peer0/localMspConfig/keystore/peer0Signer.pem
|
||||
- CORE_PEER_TLS_ROOTCERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peer/peer0/localMspConfig/cacerts/peerOrg0.pem
|
||||
# - CORE_PEER_TLS_SERVERHOSTOVERRIDE=peer0
|
||||
- CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peer/peer0/localMspConfig
|
||||
|
||||
working_dir: /opt/gopath/src/github.com/hyperledger/fabric/peer
|
||||
command: /bin/bash -c './scripts/script.sh ${CHANNEL_NAME}; '
|
||||
#command: /bin/bash
|
||||
volumes:
|
||||
- /var/run/:/host/var/run/
|
||||
- ./examples/:/opt/gopath/src/github.com/hyperledger/fabric/examples/
|
||||
- ../chaincode/go/:/opt/gopath/src/github.com/hyperledger/fabric/examples/chaincode/go
|
||||
- ./crypto:/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/
|
||||
- ./scripts:/opt/gopath/src/github.com/hyperledger/fabric/peer/scripts/
|
||||
depends_on:
|
||||
- orderer0
|
||||
- peer0
|
||||
- peer1
|
||||
- peer2
|
||||
- peer3
|
|
@ -0,0 +1,72 @@
|
|||
#!/bin/bash -eu
|
||||
|
||||
##################################################
|
||||
# This script pulls docker images from hyperledger
|
||||
# docker hub repository and Tag it as
|
||||
# hyperledger/fabric-<image> latest tag
|
||||
##################################################
|
||||
|
||||
dockerFabricPull() {
|
||||
local FABRIC_TAG=$1
|
||||
for IMAGES in peer orderer couchdb ccenv javaenv kafka zookeeper; do
|
||||
echo "==> FABRIC IMAGE: $IMAGES"
|
||||
echo
|
||||
docker pull hyperledger/fabric-$IMAGES:$FABRIC_TAG
|
||||
docker tag hyperledger/fabric-$IMAGES:$FABRIC_TAG hyperledger/fabric-$IMAGES
|
||||
done
|
||||
}
|
||||
|
||||
dockerCaPull() {
|
||||
local CA_TAG=$1
|
||||
echo "==> FABRIC CA IMAGE"
|
||||
echo
|
||||
docker pull hyperledger/fabric-ca:$CA_TAG
|
||||
docker tag hyperledger/fabric-ca:$CA_TAG hyperledger/fabric-ca
|
||||
}
|
||||
usage() {
|
||||
echo "Description "
|
||||
echo
|
||||
echo "Pulls docker images from hyperledger dockerhub repository"
|
||||
echo "tag as hyperledger/fabric-<image>:latest"
|
||||
echo
|
||||
echo "USAGE: "
|
||||
echo
|
||||
echo "./download-dockerimages.sh [-c <fabric-ca tag>] [-f <fabric tag>]"
|
||||
echo " -c fabric-ca docker image tag"
|
||||
echo " -f fabric docker image tag"
|
||||
echo
|
||||
echo
|
||||
echo "EXAMPLE:"
|
||||
echo "./download-dockerimages.sh -c x86_64-1.0.0-alpha -f x86_64-1.0.0-alpha"
|
||||
echo
|
||||
echo "By default, pulls fabric-ca and fabric 1.0.0-alpha docker images"
|
||||
echo "from hyperledger dockerhub"
|
||||
exit 0
|
||||
}
|
||||
|
||||
while getopts "\?hc:f:" opt; do
|
||||
case "$opt" in
|
||||
c) CA_TAG="$OPTARG"
|
||||
echo "Pull CA IMAGES"
|
||||
;;
|
||||
|
||||
f) FABRIC_TAG="$OPTARG"
|
||||
echo "Pull FABRIC TAG"
|
||||
;;
|
||||
\?|h) usage
|
||||
echo "Print Usage"
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
: ${CA_TAG:="x86_64-1.0.0-alpha"}
|
||||
: ${FABRIC_TAG:="x86_64-1.0.0-alpha"}
|
||||
|
||||
echo "===> Pulling fabric Images"
|
||||
dockerFabricPull ${FABRIC_TAG}
|
||||
|
||||
echo "===> Pulling fabric ca Image"
|
||||
dockerCaPull ${CA_TAG}
|
||||
echo
|
||||
echo "===> List out hyperledger docker images"
|
||||
docker images | grep hyperledger*
|
|
@ -0,0 +1,841 @@
|
|||
End-to-End Flow
|
||||
===============
|
||||
|
||||
The end-to-end verification demonstrates usage of the configuration
|
||||
transaction tool for orderer bootstrap and channel creation. The tool
|
||||
consumes a configuration transaction yaml file, which defines the
|
||||
cryptographic material (certs) used for member identity and network
|
||||
authentication. In other words, the MSP information for each member and
|
||||
its corresponding network entities.
|
||||
|
||||
*Currently the crypto material is baked into the directory. However,
|
||||
there will be a tool in the near future to organically generate the
|
||||
certificates*
|
||||
|
||||
Prerequisites
|
||||
-------------
|
||||
|
||||
- Follow the steps for setting up a `development
|
||||
environment <http://hyperledger-fabric.readthedocs.io/en/latest/dev-setup/devenv.html>`__
|
||||
|
||||
- Clone the Fabric code base.
|
||||
|
||||
.. code:: bash
|
||||
|
||||
git clone http://gerrit.hyperledger.org/r/fabric
|
||||
|
||||
or though a mirrored repository in github:
|
||||
|
||||
::
|
||||
|
||||
git clone https://github.com/hyperledger/fabric.git
|
||||
|
||||
- Make the ``configtxgen`` tool.
|
||||
|
||||
.. code:: bash
|
||||
|
||||
cd $GOPATH/src/github.com/hyperledger/fabric/devenv
|
||||
vagrant up
|
||||
vagrant ssh
|
||||
# ensure sure you are in the /fabric directory where the Makefile resides
|
||||
make configtxgen
|
||||
|
||||
- Make the peer and orderer images.
|
||||
|
||||
.. code:: bash
|
||||
|
||||
# make sure you are in vagrant and in the /fabric directory
|
||||
make peer-docker orderer-docker
|
||||
|
||||
Execute a ``docker images`` command in your terminal. If the images
|
||||
compiled successfully, you should see an output similar to the
|
||||
following:
|
||||
|
||||
.. code:: bash
|
||||
|
||||
vagrant@hyperledger-devenv:v0.3.0-4eec836:/opt/gopath/src/github.com/hyperledger/fabric$ docker images
|
||||
REPOSITORY TAG IMAGE ID CREATED SIZE
|
||||
hyperledger/fabric-orderer latest 264e45897bfb 10 minutes ago 180 MB
|
||||
hyperledger/fabric-orderer x86_64-0.7.0-snapshot-a0d032b 264e45897bfb 10 minutes ago 180 MB
|
||||
hyperledger/fabric-peer latest b3d44cff07c6 10 minutes ago 184 MB
|
||||
hyperledger/fabric-peer x86_64-0.7.0-snapshot-a0d032b b3d44cff07c6 10 minutes ago 184 MB
|
||||
hyperledger/fabric-javaenv latest 6e2a2adb998a 10 minutes ago 1.42 GB
|
||||
hyperledger/fabric-javaenv x86_64-0.7.0-snapshot-a0d032b 6e2a2adb998a 10 minutes ago 1.42 GB
|
||||
hyperledger/fabric-ccenv latest 0ce0e7dc043f 12 minutes ago 1.29 GB
|
||||
hyperledger/fabric-ccenv x86_64-0.7.0-snapshot-a0d032b 0ce0e7dc043f 12 minutes ago 1.29 GB
|
||||
hyperledger/fabric-baseimage x86_64-0.3.0 f4751a503f02 4 weeks ago 1.27 GB
|
||||
hyperledger/fabric-baseos x86_64-0.3.0 c3a4cf3b3350 4 weeks ago 161 MB
|
||||
|
||||
Configuration Transaction Generator
|
||||
-----------------------------------
|
||||
|
||||
The `configtxgen
|
||||
tool <https://github.com/hyperledger/fabric/blob/master/docs/source/configtxgen.rst>`__
|
||||
is used to create two artifacts: - orderer **bootstrap block** - fabric
|
||||
**channel configuration transaction**
|
||||
|
||||
The orderer block is the genesis block for the ordering service, and the
|
||||
channel transaction file is broadcast to the orderer at channel creation
|
||||
time.
|
||||
|
||||
The ``configtx.yaml`` contains the definitions for the sample network.
|
||||
There are two members, each managing and maintaining two peer nodes.
|
||||
Inspect this file to better understand the corresponding cryptographic
|
||||
material tied to the member components. The ``/crypto`` directory
|
||||
contains the admin certs, ca certs, private keys for each entity, and
|
||||
the signing certs for each entity.
|
||||
|
||||
For ease of use, a script - ``generateCfgTrx.sh`` - is provided. The
|
||||
script will generate the two configuration artifacts.
|
||||
|
||||
Run the shell script
|
||||
^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
Make sure you are in the ``examples/e2e_cli`` directory and in your
|
||||
vagrant environment. You can elect to pass in a unique name for your
|
||||
channel or simply execute the script without the ``channel-ID``
|
||||
parameter. If you choose not to pass in a unique name, then a channel
|
||||
with the default name of ``mychannel`` will be generated.
|
||||
|
||||
.. code:: bash
|
||||
|
||||
cd examples/e2e_cli
|
||||
# note the <channel-ID> parm is optional
|
||||
./generateCfgTrx.sh <channel-ID>
|
||||
|
||||
After you run the shell script, you should see an output in your
|
||||
terminal similar to the following:
|
||||
|
||||
.. code:: bash
|
||||
|
||||
2017/02/28 17:01:52 Generating new channel configtx
|
||||
2017/02/28 17:01:52 Creating no-op MSP instance
|
||||
2017/02/28 17:01:52 Obtaining default signing identity
|
||||
2017/02/28 17:01:52 Creating no-op signing identity instance
|
||||
2017/02/28 17:01:52 Serializing identity
|
||||
2017/02/28 17:01:52 signing message
|
||||
2017/02/28 17:01:52 signing message
|
||||
2017/02/28 17:01:52 Writing new channel tx
|
||||
|
||||
These configuration transactions will bundle the crypto material for the
|
||||
participating members and their network components and output an orderer
|
||||
genesis block and channel transaction artifact. These two artifacts are
|
||||
required for a functioning transactional network with
|
||||
sign/verify/authenticate capabilities.
|
||||
|
||||
Manually generate the artifacts (optional)
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
In your vagrant environment, navigate to the ``/common/configtx/tool``
|
||||
directory and replace the ``configtx.yaml`` file with the supplied yaml
|
||||
file in the ``/e2e_cli`` directory. Then return to the ``/e2e_cli``
|
||||
directory.
|
||||
|
||||
.. code:: bash
|
||||
|
||||
# Generate orderer bootstrap block
|
||||
configtxgen -profile TwoOrgs -outputBlock <block-name>
|
||||
# example: configtxgen -profile TwoOrgs -outputBlock orderer.block
|
||||
|
||||
# Generate channel configuration transaction
|
||||
configtxgen -profile TwoOrgs -outputCreateChannelTx <cfg txn name> -channelID <channel-id>
|
||||
# example: configtxgen -profile TwoOrgs -outputCreateChannelTx channel.tx -channelID mychannel
|
||||
|
||||
Run the end-to-end test with Docker
|
||||
-----------------------------------
|
||||
|
||||
Make sure you are in the ``/e2e_cli`` directory. Then use docker-compose
|
||||
to spawn the network entities and drive the tests.
|
||||
|
||||
.. code:: bash
|
||||
|
||||
[CHANNEL_NAME=<channel-id>] docker-compose up -d
|
||||
|
||||
If you created a unique channel name, be sure to pass in that parameter.
|
||||
For example,
|
||||
|
||||
.. code:: bash
|
||||
|
||||
CHANNEL_NAME=abc docker-compose up -d
|
||||
|
||||
Wait, 30 seconds. Behind the scenes, there are transactions being sent
|
||||
to the peers. Execute a ``docker ps`` to view your active containers.
|
||||
You should see an output identical to the following:
|
||||
|
||||
.. code:: bash
|
||||
|
||||
vagrant@hyperledger-devenv:v0.3.0-4eec836:/opt/gopath/src/github.com/hyperledger/fabric/examples/e2e_cli$ docker ps
|
||||
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
|
||||
45e3e114f7a2 dev-peer3-mycc-1.0 "chaincode -peer.a..." 4 seconds ago Up 4 seconds dev-peer3-mycc-1.0
|
||||
5970f740ad2b dev-peer0-mycc-1.0 "chaincode -peer.a..." 24 seconds ago Up 23 seconds dev-peer0-mycc-1.0
|
||||
b84808d66e99 dev-peer2-mycc-1.0 "chaincode -peer.a..." 48 seconds ago Up 47 seconds dev-peer2-mycc-1.0
|
||||
16d7d94c8773 hyperledger/fabric-peer "peer node start -..." About a minute ago Up About a minute 0.0.0.0:10051->7051/tcp, 0.0.0.0:10053->7053/tcp peer3
|
||||
3561a99e35e6 hyperledger/fabric-peer "peer node start -..." About a minute ago Up About a minute 0.0.0.0:9051->7051/tcp, 0.0.0.0:9053->7053/tcp peer2
|
||||
0baad3047d92 hyperledger/fabric-peer "peer node start -..." About a minute ago Up About a minute 0.0.0.0:8051->7051/tcp, 0.0.0.0:8053->7053/tcp peer1
|
||||
1216896b7b4f hyperledger/fabric-peer "peer node start -..." About a minute ago Up About a minute 0.0.0.0:7051->7051/tcp, 0.0.0.0:7053->7053/tcp peer0
|
||||
155ff8747b4d hyperledger/fabric-orderer "orderer" About a minute ago Up About a minute 0.0.0.0:7050->7050/tcp orderer
|
||||
|
||||
All in one
|
||||
^^^^^^^^^^
|
||||
|
||||
You can also generate the artifacts and drive the tests using a single
|
||||
shell script. The ``configtxgen`` and ``docker-compose`` commands are
|
||||
embedded in the script.
|
||||
|
||||
.. code:: bash
|
||||
|
||||
./network_setup.sh up <channel-ID>
|
||||
|
||||
Once again, if you choose not to pass the ``channel-ID`` parameter, then
|
||||
your channel will default to ``mychannel``.
|
||||
|
||||
What's happening behind the scenes?
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
- A script - ``script.sh`` - is baked inside the CLI container. The
|
||||
script drives the ``createChannel`` command against the default
|
||||
``mychannel`` name.
|
||||
|
||||
- The output of ``createChannel`` is a genesis block -
|
||||
``mychannel.block`` - which is stored on the file system.
|
||||
|
||||
- the ``joinChannel`` command is exercised for all four peers who will
|
||||
pass in the genesis block.
|
||||
|
||||
- Now we have a channel consisting of four peers, and two
|
||||
organizations.
|
||||
|
||||
- ``PEER0`` and ``PEER1`` belong to Org0; ``PEER2`` and ``PEER3``
|
||||
belong to Org1
|
||||
|
||||
- Recall that these relationships are defined in the ``configtx.yaml``
|
||||
|
||||
- A chaincode - *chaincode\_example02* is installed on ``PEER0`` and
|
||||
``PEER2``
|
||||
|
||||
- The chaincode is then "instantiated" on ``PEER2``. Instantiate simply
|
||||
refers to starting the container and initializing the key value pairs
|
||||
associated with the chaincode. The initial values for this example
|
||||
are "a","100" "b","200". This "instantiation" results in a container
|
||||
by the name of ``dev-peer2-mycc-1.0`` starting.
|
||||
|
||||
- The instantiation also passes in an argument for the endorsement
|
||||
policy. The policy is defined as
|
||||
``-P "OR ('Org0MSP.member','Org1MSP.member')"``, meaning that any
|
||||
transaction must be endorsed by a peer tied to Org0 or Org1.
|
||||
|
||||
- A query against the value of "a" is issued to ``PEER0``. The
|
||||
chaincode was previously installed on ``PEER0``, so this will start
|
||||
another container by the name of ``dev-peer0-mycc-1.0``. The result
|
||||
of the query is also returned. No write operations have occurred, so
|
||||
a query against "a" will still return a value of "100"
|
||||
|
||||
- An invoke is sent to ``PEER0`` to move "10" from "a" to "b"
|
||||
|
||||
- The chaincode is installed on ``PEER3``
|
||||
|
||||
- A query is sent to ``PEER3`` for the value of "a". This starts a
|
||||
third chaincode container by the name of ``dev-peer3-mycc-1.0``. A
|
||||
value of 90 is returned, correctly reflecting the previous
|
||||
transaction during which the value for key "a" was modified by 10.
|
||||
|
||||
What does this demonstrate?
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
Chaincode **MUST** be installed on a peer in order for it to
|
||||
successfully perform read/write operations against the ledger.
|
||||
Furthermore, a chaincode container is not started for a peer until a
|
||||
read/write operation is performed against that chaincode (e.g. query for
|
||||
the value of "a"). The transaction causes the container to start. Also,
|
||||
all peers in a channel maintain an exact copy of the ledger which
|
||||
comprises the blockchain to store the immutable, sequenced record in
|
||||
blocks, as well as a state database to maintain current fabric state.
|
||||
This includes those peers that do not have chaincode installed on them
|
||||
(like ``Peer3`` in the above example) . Finally, the chaincode is accessible
|
||||
after it is installed (like ``Peer3`` in the above example) because it
|
||||
already has been instantiated.
|
||||
|
||||
How do I see these transactions?
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
Check the logs for the CLI docker container.
|
||||
|
||||
::
|
||||
|
||||
docker logs -f cli
|
||||
|
||||
You should see the following output:
|
||||
|
||||
.. code:: bash
|
||||
|
||||
2017-02-28 04:31:20.841 UTC [logging] InitFromViper -> DEBU 001 Setting default logging level to DEBUG for command 'chaincode'
|
||||
2017-02-28 04:31:20.842 UTC [msp] GetLocalMSP -> DEBU 002 Returning existing local MSP
|
||||
2017-02-28 04:31:20.842 UTC [msp] GetDefaultSigningIdentity -> DEBU 003 Obtaining default signing identity
|
||||
2017-02-28 04:31:20.843 UTC [msp] Sign -> DEBU 004 Sign: plaintext: 0A8F050A59080322096D796368616E6E...6D7963631A0A0A0571756572790A0161
|
||||
2017-02-28 04:31:20.843 UTC [msp] Sign -> DEBU 005 Sign: digest: 52F1A41B7B0B08CF3FC94D9D7E916AC4C01C54399E71BC81D551B97F5619AB54
|
||||
Query Result: 90
|
||||
2017-02-28 04:31:30.425 UTC [main] main -> INFO 006 Exiting.....
|
||||
===================== Query on chaincode on PEER3 on channel 'mychannel' is successful =====================
|
||||
|
||||
===================== All GOOD, End-2-End execution completed =====================
|
||||
|
||||
How can I see the chaincode logs?
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
Inspect the individual chaincode containers to see the separate
|
||||
transactions executed against each container. Here is the combined
|
||||
output from each container:
|
||||
|
||||
.. code:: bash
|
||||
|
||||
$ docker logs dev-peer2-mycc-1.0
|
||||
04:30:45.947 [BCCSP_FACTORY] DEBU : Initialize BCCSP [SW]
|
||||
ex02 Init
|
||||
Aval = 100, Bval = 200
|
||||
|
||||
$ docker logs dev-peer0-mycc-1.0
|
||||
04:31:10.569 [BCCSP_FACTORY] DEBU : Initialize BCCSP [SW]
|
||||
ex02 Invoke
|
||||
Query Response:{"Name":"a","Amount":"100"}
|
||||
ex02 Invoke
|
||||
Aval = 90, Bval = 210
|
||||
|
||||
$ docker logs dev-peer3-mycc-1.0
|
||||
04:31:30.420 [BCCSP_FACTORY] DEBU : Initialize BCCSP [SW]
|
||||
ex02 Invoke
|
||||
Query Response:{"Name":"a","Amount":"90"}
|
||||
|
||||
Run the end-to-end test manually with Docker
|
||||
--------------------------------------------
|
||||
|
||||
From your vagrant environment exit the currently running containers:
|
||||
|
||||
.. code:: bash
|
||||
|
||||
docker rm -f $(docker ps -aq)
|
||||
|
||||
Execute a ``docker images`` command in your terminal to view the
|
||||
chaincode images. They will look similar to the following:
|
||||
|
||||
.. code:: bash
|
||||
|
||||
REPOSITORY TAG IMAGE ID CREATED SIZE
|
||||
dev-peer3-mycc-1.0 latest 3415bc2e146c 5 hours ago 176 MB
|
||||
dev-peer0-mycc-1.0 latest 140d7ee3e911 5 hours ago 176 MB
|
||||
dev-peer2-mycc-1.0 latest 6e4fc412969e 5 hours ago 176 MB
|
||||
|
||||
Remove these images:
|
||||
|
||||
.. code:: bash
|
||||
|
||||
docker rmi <IMAGE ID> <IMAGE ID> <IMAGE ID>
|
||||
|
||||
For example:
|
||||
|
||||
.. code:: bash
|
||||
|
||||
docker rmi -f 341 140 6e4
|
||||
|
||||
Ensure you have the configuration artifacts. If you deleted them, run
|
||||
the shell script again:
|
||||
|
||||
.. code:: bash
|
||||
|
||||
./generateCfgTrx.sh <channel-ID>
|
||||
|
||||
Modify the docker-compose file
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
Open the docker-compose file and comment out the command to run
|
||||
``script.sh``. Navigate down to the cli image and place a ``#`` to the
|
||||
left of the command. For example:
|
||||
|
||||
.. code:: bash
|
||||
|
||||
working_dir: /opt/gopath/src/github.com/hyperledger/fabric/peer
|
||||
# command: /bin/bash -c './scripts/script.sh ${CHANNEL_NAME}'
|
||||
|
||||
Save the file and return to the ``/e2e_cli`` directory.
|
||||
|
||||
Now restart your network:
|
||||
|
||||
.. code:: bash
|
||||
|
||||
# make sure you are in the /e2e_cli directory where you docker-compose script resides
|
||||
docker-compose up -d
|
||||
|
||||
Command syntax
|
||||
^^^^^^^^^^^^^^
|
||||
|
||||
Refer to the create and join commands in the ``script.sh``.
|
||||
|
||||
For the following CLI commands against `peer0` to work, you need to set the
|
||||
values for four environment variables, given below. Please make sure to override
|
||||
the values accordingly when calling commands against other peers and the
|
||||
orderer.
|
||||
|
||||
.. code:: bash
|
||||
|
||||
# Environment variables for PEER0
|
||||
CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peer/peer0/localMspConfig
|
||||
CORE_PEER_ADDRESS=peer0:7051
|
||||
CORE_PEER_LOCALMSPID="Org0MSP"
|
||||
CORE_PEER_TLS_ROOTCERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peer/peer0/localMspConfig/cacerts/peerOrg0.pem
|
||||
|
||||
These environment variables for each peer are defined in the supplied
|
||||
docker-compose file.
|
||||
|
||||
Create channel
|
||||
^^^^^^^^^^^^^^
|
||||
|
||||
Exec into the cli container:
|
||||
|
||||
.. code:: bash
|
||||
|
||||
docker exec -it cli bash
|
||||
|
||||
If successful you should see the following:
|
||||
|
||||
.. code:: bash
|
||||
|
||||
root@0d78bb69300d:/opt/gopath/src/github.com/hyperledger/fabric/peer#
|
||||
|
||||
Specify your channel name with the ``-c`` flag. Specify your channel
|
||||
configuration transaction with the ``-f`` flag. In this case it is
|
||||
``channeltx``, however you can mount your own configuration transaction
|
||||
with a different name.
|
||||
|
||||
.. code:: bash
|
||||
|
||||
# the channel.tx and orderer.block are mounted in the crypto/orderer folder within your cli container
|
||||
# as a result, we pass the full path for the file
|
||||
peer channel create -o orderer0:7050 -c mychannel -f crypto/orderer/channel.tx --tls $CORE_PEER_TLS_ENABLED --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/orderer/localMspConfig/cacerts/ordererOrg0.pem
|
||||
|
||||
Since the `channel create` runs against the orderer, we need to override the
|
||||
four environment variables set before. So the above command in its entirety would be:
|
||||
|
||||
.. code:: bash
|
||||
|
||||
CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/orderer/localMspConfig CORE_PEER_LOCALMSPID="OrdererMSP" peer channel create -o orderer0:7050 -c mychannel -f crypto/orderer/channel.tx --tls $CORE_PEER_TLS_ENABLED --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/orderer/localMspConfig/cacerts/ordererOrg0.pem
|
||||
|
||||
|
||||
**Note**: You will remain in the CLI container for the remainder of
|
||||
these manual commands. You must also remember to preface all commands
|
||||
with the corresponding environment variables for targetting a peer other than
|
||||
`peer0`.
|
||||
|
||||
Join channel
|
||||
^^^^^^^^^^^^
|
||||
|
||||
Join specific peers to the channel
|
||||
|
||||
.. code:: bash
|
||||
|
||||
# By default, this joins PEER0 only
|
||||
# the mychannel.block is also mounted in the crypto/orderer directory
|
||||
peer channel join -b mychannel.block
|
||||
|
||||
You can make other peers join the channel as necessary by making appropriate
|
||||
changes in the four environment variables.
|
||||
|
||||
Install chaincode onto a remote peer
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
Install the sample go code onto one of the four peer nodes
|
||||
|
||||
.. code:: bash
|
||||
|
||||
peer chaincode install -n mycc -v 1.0 -p github.com/hyperledger/fabric/examples/chaincode/go/chaincode_example02
|
||||
|
||||
Instantiate chaincode and define the endorsement policy
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
Instantiate the chaincode on a peer. This will launch a chaincode
|
||||
container for the targeted peer and set the endorsement policy for the
|
||||
chaincode. In this snippet, we define the policy as requiring an
|
||||
endorsement from one peer node that is a part of either `Org0` or `Org1`.
|
||||
The command is:
|
||||
|
||||
.. code:: bash
|
||||
|
||||
peer chaincode instantiate -o orderer0:7050 --tls $CORE_PEER_TLS_ENABLED --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/orderer/localMspConfig/cacerts/ordererOrg0.pem -C mychannel -n mycc -v 1.0 -p github.com/hyperledger/fabric/examples/chaincode/go/chaincode_example02 -c '{"Args":["init","a", "100", "b","200"]}' -P "OR ('Org0MSP.member','Org1MSP.member')"
|
||||
|
||||
See the `endorsement
|
||||
policies <http://hyperledger-fabric.readthedocs.io/en/latest/endorsement-policies/>`__
|
||||
documentation for more details on policy implementation.
|
||||
|
||||
Invoke chaincode
|
||||
^^^^^^^^^^^^^^^^
|
||||
|
||||
.. code:: bash
|
||||
|
||||
peer chaincode invoke -o orderer0:7050 --tls $CORE_PEER_TLS_ENABLED --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/orderer/localMspConfig/cacerts/ordererOrg0.pem -C mychannel -n mycc -c '{"Args":["invoke","a","b","10"]}'
|
||||
|
||||
**NOTE**: Make sure to wait a few seconds for the operation to complete.
|
||||
|
||||
Query chaincode
|
||||
^^^^^^^^^^^^^^^
|
||||
|
||||
.. code:: bash
|
||||
|
||||
peer chaincode query -C mychannel -n mycc -c '{"Args":["query","a"]}'
|
||||
|
||||
The result of the above command should be as below:
|
||||
|
||||
.. code:: bash
|
||||
|
||||
Query Result: 90
|
||||
|
||||
Run the end-to-end test using the native binaries
|
||||
-------------------------------------------------
|
||||
|
||||
Open your vagrant environment:
|
||||
|
||||
.. code:: bash
|
||||
|
||||
cd $GOPATH/src/github.com/hyperledger/fabric/devenv
|
||||
|
||||
.. code:: bash
|
||||
|
||||
# you may have to first start your VM with vagrant up
|
||||
vagrant ssh
|
||||
|
||||
From the ``fabric`` directory build the issue the following commands to
|
||||
build the peer and orderer executables:
|
||||
|
||||
.. code:: bash
|
||||
|
||||
make clean
|
||||
make native
|
||||
|
||||
You will also need the ``ccenv`` image. From the ``fabric`` directory:
|
||||
|
||||
.. code:: bash
|
||||
|
||||
make peer-docker
|
||||
|
||||
Next, open two more terminals and start your vagrant environment in
|
||||
each. You should now have a total of three terminals, all within
|
||||
vagrant.
|
||||
|
||||
Before starting, make sure to clear your ledger folder
|
||||
``/var/hyperledger/``. You will want to do this after each run to avoid
|
||||
errors and duplication.
|
||||
|
||||
::
|
||||
|
||||
rm -rf /var/hyperledger/*
|
||||
|
||||
**Vagrant window 1**
|
||||
|
||||
Use the ``configtxgen`` tool to create the orderer genesis block:
|
||||
|
||||
.. code:: bash
|
||||
|
||||
configtxgen -profile SampleSingleMSPSolo -outputBlock orderer.block
|
||||
|
||||
**Vagrant window 2**
|
||||
|
||||
Start the orderer with the genesis block you just generated:
|
||||
|
||||
.. code:: bash
|
||||
|
||||
ORDERER_GENERAL_GENESISMETHOD=file ORDERER_GENERAL_GENESISFILE=./orderer.block orderer
|
||||
|
||||
**Vagrant window 1**
|
||||
|
||||
Create the channel configuration transaction:
|
||||
|
||||
.. code:: bash
|
||||
|
||||
configtxgen -profile SampleSingleMSPSolo -outputCreateChannelTx channel.tx -channelID <channel-ID>
|
||||
|
||||
This will generate a ``channel.tx`` file in your current directory
|
||||
|
||||
**Vagrant window 3**
|
||||
|
||||
Start the peer in *"chainless"* mode
|
||||
|
||||
.. code:: bash
|
||||
|
||||
peer node start --peer-defaultchain=false
|
||||
|
||||
**Note**: Use Vagrant window 1 for the remainder of commands
|
||||
|
||||
Create channel
|
||||
^^^^^^^^^^^^^^
|
||||
|
||||
Ask peer to create a channel with the configuration parameters in
|
||||
``channel.tx``
|
||||
|
||||
.. code:: bash
|
||||
|
||||
peer channel create -o 127.0.0.1:7050 -c mychannel -f channel.tx
|
||||
|
||||
This will return a channel genesis block - ``mychannel.block`` - in your
|
||||
current directory.
|
||||
|
||||
Join channel
|
||||
^^^^^^^^^^^^
|
||||
|
||||
Ask peer to join the channel by passing in the channel genesis block:
|
||||
|
||||
.. code:: bash
|
||||
|
||||
peer channel join -b mychannel.block
|
||||
|
||||
Install
|
||||
^^^^^^^
|
||||
|
||||
Install chaincode on the peer:
|
||||
|
||||
.. code:: bash
|
||||
|
||||
peer chaincode install -o 127.0.0.1:7050 -n mycc -v 1.0 -p github.com/hyperledger/fabric/examples/chaincode/go/chaincode_example02
|
||||
|
||||
Make sure the chaincode is in the filesystem:
|
||||
|
||||
.. code:: bash
|
||||
|
||||
ls /var/hyperledger/production/chaincodes
|
||||
|
||||
You should see ``mycc.1.0``
|
||||
|
||||
Instantiate
|
||||
^^^^^^^^^^^
|
||||
|
||||
Instantiate the chaincode:
|
||||
|
||||
.. code:: bash
|
||||
|
||||
peer chaincode instantiate -o 127.0.0.1:7050 -C mychannel -n mycc -v 1.0 -p github.com/hyperledger/fabric/examples/chaincode/go/chaincode_example02 -c '{"Args":["init","a", "100", "b","200"]}'
|
||||
|
||||
Check your active containers:
|
||||
|
||||
.. code:: bash
|
||||
|
||||
docker ps
|
||||
|
||||
If the chaincode container started successfully, you should see:
|
||||
|
||||
.. code:: bash
|
||||
|
||||
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
|
||||
bd9c6bda7560 dev-jdoe-mycc-1.0 "chaincode -peer.a..." 5 seconds ago Up 5 seconds dev-jdoe-mycc-1.0
|
||||
|
||||
Invoke
|
||||
^^^^^^
|
||||
|
||||
Issue an invoke to move "10" from "a" to "b":
|
||||
|
||||
.. code:: bash
|
||||
|
||||
peer chaincode invoke -o 127.0.0.1:7050 -C mychannel -n mycc -c '{"Args":["invoke","a","b","10"]}'
|
||||
|
||||
Wait a few seconds for the operation to complete
|
||||
|
||||
Query
|
||||
^^^^^
|
||||
|
||||
Query for the value of "a":
|
||||
|
||||
.. code:: bash
|
||||
|
||||
# this should return 90
|
||||
peer chaincode query -o 127.0.0.1:7050 -C mychannel -n mycc -c '{"Args":["query","a"]}'
|
||||
|
||||
Don't forget to clear ledger folder ``/var/hyperledger/`` after each
|
||||
run!
|
||||
|
||||
::
|
||||
|
||||
rm -rf /var/hyperledger/*
|
||||
|
||||
Using CouchDB
|
||||
-------------
|
||||
|
||||
The state database can be switched from the default (goleveldb) to CouchDB.
|
||||
The same chaincode functions are available with CouchDB, however, there is the
|
||||
added ability to perform rich and complex queries against the state database
|
||||
data content contingent upon the chaincode data being modeled as JSON.
|
||||
|
||||
To use CouchDB instead of the default database (goleveldb), follow the same
|
||||
procedure in the **Prerequisites** section, and additionally perform the
|
||||
following two steps to enable the CouchDB containers and associate each peer
|
||||
container with a CouchDB container:
|
||||
|
||||
- Make the CouchDB image.
|
||||
|
||||
.. code:: bash
|
||||
|
||||
# make sure you are in the /fabric directory
|
||||
make couchdb
|
||||
|
||||
- Open the ``fabric/examples/e2e_cli/docker-compose.yaml`` and un-comment
|
||||
all commented statements relating to CouchDB containers and peer container
|
||||
use of CouchDB. These instructions are are also outlined in the
|
||||
same ``docker-compose.yaml`` file. Search the file for 'couchdb' (case insensitive) references.
|
||||
|
||||
*chaincode_example02* should now work using CouchDB underneath.
|
||||
|
||||
***Note***: If you choose to implement mapping of the fabric-couchdb container
|
||||
port to a host port, please make sure you are aware of the security
|
||||
implications. Mapping of the port in a development environment allows the
|
||||
visualization of the database via the CouchDB web interface (Fauxton).
|
||||
Production environments would likely refrain from implementing port mapping in
|
||||
order to restrict outside access to the CouchDB containers.
|
||||
|
||||
You can use *chaincode_example02* chaincode against the CouchDB state database
|
||||
using the steps outlined above, however in order to exercise the query
|
||||
capabilities you will need to use a chaincode that has data modeled as JSON,
|
||||
(e.g. *marbles02*). You can locate the *marbles02* chaincode in the
|
||||
``fabric/examples/chaincode/go`` directory.
|
||||
|
||||
Install, instantiate, invoke, and query *marbles02* chaincode by following the
|
||||
same general steps outlined above for *chaincode_example02* in the **Manually
|
||||
create the channel and join peers through CLI** section. After the **Join
|
||||
channel** step, use the following steps to interact with the *marbles02*
|
||||
chaincode:
|
||||
|
||||
- Install and instantiate the chaincode in ``peer0``:
|
||||
|
||||
.. code:: bash
|
||||
|
||||
peer chaincode install -o orderer0:7050 -n marbles -v 1.0 -p github.com/hyperledger/fabric/examples/chaincode/go/marbles02
|
||||
peer chaincode instantiate -o orderer0:7050 --tls $CORE_PEER_TLS_ENABLED --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/orderer/localMspConfig/cacerts/ordererOrg0.pem -C mychannel -n marbles -v 1.0 -p github.com/hyperledger/fabric/examples/chaincode/go/marbles02 -c '{"Args":["init"]}' -P "OR ('Org0MSP.member','Org1MSP.member')"
|
||||
|
||||
- Create some marbles and move them around:
|
||||
|
||||
.. code:: bash
|
||||
|
||||
peer chaincode invoke -o orderer0:7050 --tls $CORE_PEER_TLS_ENABLED --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/orderer/localMspConfig/cacerts/ordererOrg0.pem -C mychannel -n marbles -c '{"Args":["initMarble","marble1","blue","35","tom"]}'
|
||||
peer chaincode invoke -o orderer0:7050 --tls $CORE_PEER_TLS_ENABLED --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/orderer/localMspConfig/cacerts/ordererOrg0.pem -C mychannel -n marbles -c '{"Args":["initMarble","marble2","red","50","tom"]}'
|
||||
peer chaincode invoke -o orderer0:7050 --tls $CORE_PEER_TLS_ENABLED --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/orderer/localMspConfig/cacerts/ordererOrg0.pem -C mychannel -n marbles -c '{"Args":["initMarble","marble3","blue","70","tom"]}'
|
||||
peer chaincode invoke -o orderer0:7050 --tls $CORE_PEER_TLS_ENABLED --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/orderer/localMspConfig/cacerts/ordererOrg0.pem -C mychannel -n marbles -c '{"Args":["transferMarble","marble2","jerry"]}'
|
||||
peer chaincode invoke -o orderer0:7050 --tls $CORE_PEER_TLS_ENABLED --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/orderer/localMspConfig/cacerts/ordererOrg0.pem -C mychannel -n marbles -c '{"Args":["transferMarblesBasedOnColor","blue","jerry"]}'
|
||||
peer chaincode invoke -o orderer0:7050 --tls $CORE_PEER_TLS_ENABLED --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/orderer/localMspConfig/cacerts/ordererOrg0.pem -C mychannel -n marbles -c '{"Args":["delete","marble1"]}'
|
||||
|
||||
|
||||
|
||||
- If you chose to activate port mapping, you can now view the state database
|
||||
through the CouchDB web interface (Fauxton) by opening a browser and
|
||||
navigating to one of the two URLs below.
|
||||
|
||||
For containers running in a vagrant environment:
|
||||
|
||||
``http://localhost:15984/_utils``
|
||||
|
||||
For non-vagrant environment, use the port address that was mapped in CouchDB
|
||||
container specification:
|
||||
|
||||
``http://localhost:5984/_utils``
|
||||
|
||||
You should see a database named ``mychannel`` and the documents
|
||||
inside it.
|
||||
|
||||
- You can run regular queries from the `cli` (e.g. reading ``marble2``):
|
||||
|
||||
.. code:: bash
|
||||
|
||||
peer chaincode query -C mychannel -n marbles -c '{"Args":["readMarble","marble2"]}'
|
||||
|
||||
|
||||
You should see the details of ``marble2``:
|
||||
|
||||
.. code:: bash
|
||||
|
||||
Query Result: {"color":"red","docType":"marble","name":"marble2","owner":"jerry","size":50}
|
||||
|
||||
|
||||
Retrieve the history of ``marble1``:
|
||||
|
||||
.. code:: bash
|
||||
|
||||
peer chaincode query -C mychannel -n marbles -c '{"Args":["getHistoryForMarble","marble1"]}'
|
||||
|
||||
You should see the transactions on ``marble1``:
|
||||
|
||||
.. code:: bash
|
||||
|
||||
Query Result: [{"TxId":"1c3d3caf124c89f91a4c0f353723ac736c58155325f02890adebaa15e16e6464", "Value":{"docType":"marble","name":"marble1","color":"blue","size":35,"owner":"tom"}},{"TxId":"755d55c281889eaeebf405586f9e25d71d36eb3d35420af833a20a2f53a3eefd", "Value":{"docType":"marble","name":"marble1","color":"blue","size":35,"owner":"jerry"}},{"TxId":"819451032d813dde6247f85e56a89262555e04f14788ee33e28b232eef36d98f", "Value":}]
|
||||
|
||||
|
||||
|
||||
- You can also perform rich queries on the data content, such as querying marble fields by owner ``jerry``:
|
||||
|
||||
.. code:: bash
|
||||
|
||||
peer chaincode query -C mychannel -n marbles -c '{"Args":["queryMarblesByOwner","jerry"]}'
|
||||
|
||||
The output should display the two marbles owned by ``jerry``:
|
||||
|
||||
.. code:: bash
|
||||
|
||||
Query Result: [{"Key":"marble2", "Record":{"color":"red","docType":"marble","name":"marble2","owner":"jerry","size":50}},{"Key":"marble3", "Record":{"color":"blue","docType":"marble","name":"marble3","owner":"jerry","size":70}}]
|
||||
|
||||
Query by field ``owner`` where the value is ``jerry``:
|
||||
|
||||
.. code:: bash
|
||||
|
||||
peer chaincode query -C mychannel -n marbles -c '{"Args":["queryMarbles","{\"selector\":{\"owner\":\"jerry\"}}"]}'
|
||||
|
||||
The output should display:
|
||||
|
||||
.. code:: bash
|
||||
|
||||
Query Result: [{"Key":"marble2", "Record":{"color":"red","docType":"marble","name":"marble2","owner":"jerry","size":50}},{"Key":"marble3", "Record":{"color":"blue","docType":"marble","name":"marble3","owner":"jerry","size":70}}]
|
||||
|
||||
A Note on Data Persistence
|
||||
--------------------------
|
||||
|
||||
If data persistence is desired on the peer container or the CouchDB container,
|
||||
one option is to mount a directory in the docker-host into a relevant directory
|
||||
in the container. For example, you may add the following two lines in
|
||||
the peer container specification in the ``docker-compose.yaml`` file:
|
||||
|
||||
.. code:: bash
|
||||
|
||||
volumes:
|
||||
- /var/hyperledger/peer0:/var/hyperledger/production
|
||||
|
||||
|
||||
For the CouchDB container, you may add the following two lines in the CouchDB
|
||||
container specification:
|
||||
|
||||
.. code:: bash
|
||||
|
||||
volumes:
|
||||
- /var/hyperledger/couchdb0:/opt/couchdb/data
|
||||
|
||||
|
||||
Troubleshooting
|
||||
---------------
|
||||
|
||||
- Ensure you clear the file system after each run
|
||||
|
||||
- If you see docker errors, remove your images and start from scratch.
|
||||
|
||||
.. code:: bash
|
||||
|
||||
make clean
|
||||
make peer-docker orderer-docker
|
||||
|
||||
- If you see the below error:
|
||||
|
||||
.. code:: bash
|
||||
|
||||
Error: Error endorsing chaincode: rpc error: code = 2 desc = Error installing chaincode code mycc:1.0(chaincode /var/hyperledger/production/chaincodes/mycc.1.0 exits)
|
||||
|
||||
You likely have chaincode images (e.g. ``peer0-peer0-mycc-1.0`` or
|
||||
``peer1-peer0-mycc1-1.0``) from prior runs. Remove them and try
|
||||
again.
|
||||
|
||||
.. code:: bash
|
||||
|
||||
docker rmi -f $(docker images | grep peer[0-9]-peer[0-9] | awk '{print $3}')
|
||||
|
||||
- To cleanup the network, use the ``down`` option:
|
||||
|
||||
.. code:: bash
|
||||
|
||||
./network_setup.sh down
|
|
@ -0,0 +1,199 @@
|
|||
/*
|
||||
Copyright IBM Corp. 2016 All Rights Reserved.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package main
|
||||
|
||||
//WARNING - this chaincode's ID is hard-coded in chaincode_example04 to illustrate one way of
|
||||
//calling chaincode from a chaincode. If this example is modified, chaincode_example04.go has
|
||||
//to be modified as well with the new ID of chaincode_example02.
|
||||
//chaincode_example05 show's how chaincode ID can be passed in as a parameter instead of
|
||||
//hard-coding.
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strconv"
|
||||
|
||||
"github.com/hyperledger/fabric/core/chaincode/shim"
|
||||
pb "github.com/hyperledger/fabric/protos/peer"
|
||||
)
|
||||
|
||||
// SimpleChaincode example simple Chaincode implementation
|
||||
type SimpleChaincode struct {
|
||||
}
|
||||
|
||||
func (t *SimpleChaincode) Init(stub shim.ChaincodeStubInterface) pb.Response {
|
||||
fmt.Println("ex02 Init")
|
||||
_, args := stub.GetFunctionAndParameters()
|
||||
var A, B string // Entities
|
||||
var Aval, Bval int // Asset holdings
|
||||
var err error
|
||||
|
||||
if len(args) != 4 {
|
||||
return shim.Error("Incorrect number of arguments. Expecting 4")
|
||||
}
|
||||
|
||||
// Initialize the chaincode
|
||||
A = args[0]
|
||||
Aval, err = strconv.Atoi(args[1])
|
||||
if err != nil {
|
||||
return shim.Error("Expecting integer value for asset holding")
|
||||
}
|
||||
B = args[2]
|
||||
Bval, err = strconv.Atoi(args[3])
|
||||
if err != nil {
|
||||
return shim.Error("Expecting integer value for asset holding")
|
||||
}
|
||||
fmt.Printf("Aval = %d, Bval = %d\n", Aval, Bval)
|
||||
|
||||
// Write the state to the ledger
|
||||
err = stub.PutState(A, []byte(strconv.Itoa(Aval)))
|
||||
if err != nil {
|
||||
return shim.Error(err.Error())
|
||||
}
|
||||
|
||||
err = stub.PutState(B, []byte(strconv.Itoa(Bval)))
|
||||
if err != nil {
|
||||
return shim.Error(err.Error())
|
||||
}
|
||||
|
||||
return shim.Success(nil)
|
||||
}
|
||||
|
||||
func (t *SimpleChaincode) Invoke(stub shim.ChaincodeStubInterface) pb.Response {
|
||||
fmt.Println("ex02 Invoke")
|
||||
function, args := stub.GetFunctionAndParameters()
|
||||
if function == "invoke" {
|
||||
// Make payment of X units from A to B
|
||||
return t.invoke(stub, args)
|
||||
} else if function == "delete" {
|
||||
// Deletes an entity from its state
|
||||
return t.delete(stub, args)
|
||||
} else if function == "query" {
|
||||
// the old "Query" is now implemtned in invoke
|
||||
return t.query(stub, args)
|
||||
}
|
||||
|
||||
return shim.Error("Invalid invoke function name. Expecting \"invoke\" \"delete\" \"query\"")
|
||||
}
|
||||
|
||||
// Transaction makes payment of X units from A to B
|
||||
func (t *SimpleChaincode) invoke(stub shim.ChaincodeStubInterface, args []string) pb.Response {
|
||||
var A, B string // Entities
|
||||
var Aval, Bval int // Asset holdings
|
||||
var X int // Transaction value
|
||||
var err error
|
||||
|
||||
if len(args) != 3 {
|
||||
return shim.Error("Incorrect number of arguments. Expecting 3")
|
||||
}
|
||||
|
||||
A = args[0]
|
||||
B = args[1]
|
||||
|
||||
// Get the state from the ledger
|
||||
// TODO: will be nice to have a GetAllState call to ledger
|
||||
Avalbytes, err := stub.GetState(A)
|
||||
if err != nil {
|
||||
return shim.Error("Failed to get state")
|
||||
}
|
||||
if Avalbytes == nil {
|
||||
return shim.Error("Entity not found")
|
||||
}
|
||||
Aval, _ = strconv.Atoi(string(Avalbytes))
|
||||
|
||||
Bvalbytes, err := stub.GetState(B)
|
||||
if err != nil {
|
||||
return shim.Error("Failed to get state")
|
||||
}
|
||||
if Bvalbytes == nil {
|
||||
return shim.Error("Entity not found")
|
||||
}
|
||||
Bval, _ = strconv.Atoi(string(Bvalbytes))
|
||||
|
||||
// Perform the execution
|
||||
X, err = strconv.Atoi(args[2])
|
||||
if err != nil {
|
||||
return shim.Error("Invalid transaction amount, expecting a integer value")
|
||||
}
|
||||
Aval = Aval - X
|
||||
Bval = Bval + X
|
||||
fmt.Printf("Aval = %d, Bval = %d\n", Aval, Bval)
|
||||
|
||||
// Write the state back to the ledger
|
||||
err = stub.PutState(A, []byte(strconv.Itoa(Aval)))
|
||||
if err != nil {
|
||||
return shim.Error(err.Error())
|
||||
}
|
||||
|
||||
err = stub.PutState(B, []byte(strconv.Itoa(Bval)))
|
||||
if err != nil {
|
||||
return shim.Error(err.Error())
|
||||
}
|
||||
|
||||
return shim.Success(nil)
|
||||
}
|
||||
|
||||
// Deletes an entity from state
|
||||
func (t *SimpleChaincode) delete(stub shim.ChaincodeStubInterface, args []string) pb.Response {
|
||||
if len(args) != 1 {
|
||||
return shim.Error("Incorrect number of arguments. Expecting 1")
|
||||
}
|
||||
|
||||
A := args[0]
|
||||
|
||||
// Delete the key from the state in ledger
|
||||
err := stub.DelState(A)
|
||||
if err != nil {
|
||||
return shim.Error("Failed to delete state")
|
||||
}
|
||||
|
||||
return shim.Success(nil)
|
||||
}
|
||||
|
||||
// query callback representing the query of a chaincode
|
||||
func (t *SimpleChaincode) query(stub shim.ChaincodeStubInterface, args []string) pb.Response {
|
||||
var A string // Entities
|
||||
var err error
|
||||
|
||||
if len(args) != 1 {
|
||||
return shim.Error("Incorrect number of arguments. Expecting name of the person to query")
|
||||
}
|
||||
|
||||
A = args[0]
|
||||
|
||||
// Get the state from the ledger
|
||||
Avalbytes, err := stub.GetState(A)
|
||||
if err != nil {
|
||||
jsonResp := "{\"Error\":\"Failed to get state for " + A + "\"}"
|
||||
return shim.Error(jsonResp)
|
||||
}
|
||||
|
||||
if Avalbytes == nil {
|
||||
jsonResp := "{\"Error\":\"Nil amount for " + A + "\"}"
|
||||
return shim.Error(jsonResp)
|
||||
}
|
||||
|
||||
jsonResp := "{\"Name\":\"" + A + "\",\"Amount\":\"" + string(Avalbytes) + "\"}"
|
||||
fmt.Printf("Query Response:%s\n", jsonResp)
|
||||
return shim.Success(Avalbytes)
|
||||
}
|
||||
|
||||
func main() {
|
||||
err := shim.Start(new(SimpleChaincode))
|
||||
if err != nil {
|
||||
fmt.Printf("Error starting Simple chaincode: %s", err)
|
||||
}
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
#!/bin/bash
|
||||
|
||||
CHANNEL_NAME=$1
|
||||
if [ -z "$1" ]; then
|
||||
echo "Setting channel to default name 'mychannel'"
|
||||
CHANNEL_NAME="mychannel"
|
||||
fi
|
||||
|
||||
echo "Channel name - "$CHANNEL_NAME
|
||||
echo
|
||||
|
||||
#Backup the original configtx.yaml
|
||||
cp ../../common/configtx/tool/configtx.yaml ../../common/configtx/tool/configtx.yaml.orig
|
||||
cp configtx.yaml ../../common/configtx/tool/configtx.yaml
|
||||
|
||||
cd $PWD/../../
|
||||
echo "Building configtxgen"
|
||||
make configtxgen
|
||||
|
||||
echo "Generating genesis block"
|
||||
./build/bin/configtxgen -profile TwoOrgs -outputBlock orderer.block
|
||||
mv orderer.block examples/e2e_cli/crypto/orderer/orderer.block
|
||||
|
||||
echo "Generating channel configuration transaction"
|
||||
./build/bin/configtxgen -profile TwoOrgs -outputCreateChannelTx channel.tx -channelID $CHANNEL_NAME
|
||||
mv channel.tx examples/e2e_cli/crypto/orderer/channel.tx
|
||||
|
||||
#reset configtx.yaml file to its original
|
||||
cp common/configtx/tool/configtx.yaml.orig common/configtx/tool/configtx.yaml
|
||||
rm common/configtx/tool/configtx.yaml.orig
|
|
@ -0,0 +1,76 @@
|
|||
#!/bin/bash
|
||||
|
||||
UP_DOWN=$1
|
||||
CH_NAME=$2
|
||||
|
||||
COMPOSE_FILE=docker-compose.yaml
|
||||
|
||||
function printHelp () {
|
||||
echo "Usage: ./network_setup <up|down> <channel-name>"
|
||||
}
|
||||
|
||||
function validateArgs () {
|
||||
if [ -z "${UP_DOWN}" ]; then
|
||||
echo "Option up / down / restart not mentioned"
|
||||
printHelp
|
||||
exit 1
|
||||
fi
|
||||
if [ -z "${CH_NAME}" ]; then
|
||||
echo "setting to default channel 'mychannel'"
|
||||
CH_NAME=mychannel
|
||||
fi
|
||||
}
|
||||
|
||||
function clearContainers () {
|
||||
CONTAINER_IDS=$(docker ps -aq)
|
||||
if [ -z "$CONTAINER_IDS" -o "$CONTAINER_IDS" = " " ]; then
|
||||
echo "---- No containers available for deletion ----"
|
||||
else
|
||||
docker rm -f $CONTAINER_IDS
|
||||
fi
|
||||
}
|
||||
|
||||
function removeUnwantedImages() {
|
||||
DOCKER_IMAGE_IDS=$(docker images | grep "dev\|none\|test-vp\|peer[0-9]-" | awk '{print $3}')
|
||||
if [ -z "$DOCKER_IMAGE_IDS" -o "$DOCKER_IMAGE_IDS" = " " ]; then
|
||||
echo "---- No images available for deletion ----"
|
||||
else
|
||||
docker rmi -f $DOCKER_IMAGE_IDS
|
||||
fi
|
||||
}
|
||||
|
||||
function networkUp () {
|
||||
CURRENT_DIR=$PWD
|
||||
source generateCfgTrx.sh $CH_NAME
|
||||
cd $CURRENT_DIR
|
||||
|
||||
CHANNEL_NAME=$CH_NAME docker-compose -f $COMPOSE_FILE up -d 2>&1
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "ERROR !!!! Unable to pull the images "
|
||||
exit 1
|
||||
fi
|
||||
docker logs -f cli
|
||||
}
|
||||
|
||||
function networkDown () {
|
||||
docker-compose -f $COMPOSE_FILE down
|
||||
#Cleanup the chaincode containers
|
||||
clearContainers
|
||||
#Cleanup images
|
||||
removeUnwantedImages
|
||||
}
|
||||
|
||||
validateArgs
|
||||
|
||||
#Create the network using docker compose
|
||||
if [ "${UP_DOWN}" == "up" ]; then
|
||||
networkUp
|
||||
elif [ "${UP_DOWN}" == "down" ]; then ## Clear the network
|
||||
networkDown
|
||||
elif [ "${UP_DOWN}" == "restart" ]; then ## Restart the network
|
||||
networkDown
|
||||
networkUp
|
||||
else
|
||||
printHelp
|
||||
exit 1
|
||||
fi
|
|
@ -0,0 +1,18 @@
|
|||
version: '2'
|
||||
services:
|
||||
peer-base:
|
||||
image: hyperledger/fabric-peer
|
||||
environment:
|
||||
- CORE_PEER_ADDRESSAUTODETECT=true
|
||||
- CORE_VM_ENDPOINT=unix:///host/var/run/docker.sock
|
||||
- CORE_VM_DOCKER_HOSTCONFIG_NETWORKMODE=e2ecli_default
|
||||
- CORE_LOGGING_LEVEL=ERROR
|
||||
#- CORE_LOGGING_LEVEL=DEBUG
|
||||
- CORE_NEXT=true
|
||||
- CORE_PEER_TLS_ENABLED=false
|
||||
- CORE_PEER_ENDORSER_ENABLED=true
|
||||
- CORE_PEER_GOSSIP_ORGLEADER=false
|
||||
- CORE_PEER_GOSSIP_USELEADERELECTION=true
|
||||
- CORE_PEER_PROFILE_ENABLED=true
|
||||
working_dir: /opt/gopath/src/github.com/hyperledger/fabric/peer
|
||||
command: peer node start --peer-defaultchain=false
|
|
@ -0,0 +1,24 @@
|
|||
version: '2'
|
||||
services:
|
||||
peer-base:
|
||||
image: hyperledger/fabric-peer
|
||||
environment:
|
||||
#- CORE_PEER_ADDRESSAUTODETECT=true
|
||||
- CORE_VM_ENDPOINT=unix:///host/var/run/docker.sock
|
||||
# the following setting starts chaincode containers on the same
|
||||
# bridge network as the peers
|
||||
# https://docs.docker.com/compose/networking/
|
||||
- CORE_VM_DOCKER_HOSTCONFIG_NETWORKMODE=e2ecli_default
|
||||
#- CORE_LOGGING_LEVEL=ERROR
|
||||
- CORE_LOGGING_LEVEL=DEBUG
|
||||
- CORE_PEER_TLS_ENABLED=true
|
||||
- CORE_NEXT=true
|
||||
- CORE_PEER_ENDORSER_ENABLED=true
|
||||
- CORE_PEER_GOSSIP_USELEADERELECTION=true
|
||||
- CORE_PEER_GOSSIP_ORGLEADER=false
|
||||
# The following setting skips the gossip handshake since we are
|
||||
# are not doing mutual TLS
|
||||
- CORE_PEER_GOSSIP_SKIPHANDSHAKE=true
|
||||
- CORE_PEER_PROFILE_ENABLED=true
|
||||
working_dir: /opt/gopath/src/github.com/hyperledger/fabric/peer
|
||||
command: peer node start --peer-defaultchain=false
|
|
@ -0,0 +1,177 @@
|
|||
#!/bin/bash
|
||||
|
||||
CHANNEL_NAME="$1"
|
||||
: ${CHANNEL_NAME:="mychannel"}
|
||||
: ${TIMEOUT:="60"}
|
||||
COUNTER=0
|
||||
MAX_RETRY=5
|
||||
ORDERER_CA=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/orderer/localMspConfig/cacerts/ordererOrg0.pem
|
||||
|
||||
echo "Channel name : "$CHANNEL_NAME
|
||||
|
||||
verifyResult () {
|
||||
if [ $1 -ne 0 ] ; then
|
||||
echo "!!!!!!!!!!!!!!! "$2" !!!!!!!!!!!!!!!!"
|
||||
echo "================== ERROR !!! FAILED to execute End-2-End Scenario =================="
|
||||
echo
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
setGlobals () {
|
||||
|
||||
CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peer/peer$1/localMspConfig
|
||||
CORE_PEER_ADDRESS=peer$1:7051
|
||||
|
||||
if [ $1 -eq 0 -o $1 -eq 1 ] ; then
|
||||
CORE_PEER_LOCALMSPID="Org0MSP"
|
||||
CORE_PEER_TLS_ROOTCERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peer/peer$1/localMspConfig/cacerts/peerOrg0.pem
|
||||
else
|
||||
CORE_PEER_LOCALMSPID="Org1MSP"
|
||||
CORE_PEER_TLS_ROOTCERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peer/peer$1/localMspConfig/cacerts/peerOrg1.pem
|
||||
fi
|
||||
env |grep CORE
|
||||
}
|
||||
|
||||
createChannel() {
|
||||
CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/orderer/localMspConfig
|
||||
CORE_PEER_LOCALMSPID="OrdererMSP"
|
||||
|
||||
if [ -z "$CORE_PEER_TLS_ENABLED" -o "$CORE_PEER_TLS_ENABLED" = "false" ]; then
|
||||
peer channel create -o orderer0:7050 -c $CHANNEL_NAME -f crypto/orderer/channel.tx >&log.txt
|
||||
else
|
||||
peer channel create -o orderer0:7050 -c $CHANNEL_NAME -f crypto/orderer/channel.tx --tls $CORE_PEER_TLS_ENABLED --cafile $ORDERER_CA >&log.txt
|
||||
fi
|
||||
res=$?
|
||||
cat log.txt
|
||||
verifyResult $res "Channel creation failed"
|
||||
echo "===================== Channel \"$CHANNEL_NAME\" is created successfully ===================== "
|
||||
echo
|
||||
}
|
||||
|
||||
## Sometimes Join takes time hence RETRY atleast for 5 times
|
||||
joinWithRetry () {
|
||||
peer channel join -b $CHANNEL_NAME.block >&log.txt
|
||||
res=$?
|
||||
cat log.txt
|
||||
if [ $res -ne 0 -a $COUNTER -lt $MAX_RETRY ]; then
|
||||
COUNTER=` expr $COUNTER + 1`
|
||||
echo "PEER$1 failed to join the channel, Retry after 2 seconds"
|
||||
sleep 2
|
||||
joinWithRetry $1
|
||||
else
|
||||
COUNTER=0
|
||||
fi
|
||||
verifyResult $res "After $MAX_RETRY attempts, PEER$ch has failed to Join the Channel"
|
||||
}
|
||||
|
||||
joinChannel () {
|
||||
for ch in 0 1 2 3; do
|
||||
setGlobals $ch
|
||||
joinWithRetry $ch
|
||||
echo "===================== PEER$ch joined on the channel \"$CHANNEL_NAME\" ===================== "
|
||||
sleep 2
|
||||
echo
|
||||
done
|
||||
}
|
||||
|
||||
installChaincode () {
|
||||
PEER=$1
|
||||
setGlobals $PEER
|
||||
peer chaincode install -n mycc -v 1.0 -p github.com/hyperledger/fabric/examples/chaincode/go/chaincode_example02 >&log.txt
|
||||
res=$?
|
||||
cat log.txt
|
||||
verifyResult $res "Chaincode installation on remote peer PEER$PEER has Failed"
|
||||
echo "===================== Chaincode is installed on remote peer PEER$PEER ===================== "
|
||||
echo
|
||||
}
|
||||
|
||||
instantiateChaincode () {
|
||||
PEER=$1
|
||||
setGlobals $PEER
|
||||
if [ -z "$CORE_PEER_TLS_ENABLED" -o "$CORE_PEER_TLS_ENABLED" = "false" ]; then
|
||||
peer chaincode instantiate -o orderer0:7050 -C $CHANNEL_NAME -n mycc -v 1.0 -c '{"Args":["init","a","100","b","200"]}' -P "OR ('Org0MSP.member','Org1MSP.member')" >&log.txt
|
||||
else
|
||||
peer chaincode instantiate -o orderer0:7050 --tls $CORE_PEER_TLS_ENABLED --cafile $ORDERER_CA -C $CHANNEL_NAME -n mycc -v 1.0 -c '{"Args":["init","a","100","b","200"]}' -P "OR ('Org0MSP.member','Org1MSP.member')" >&log.txt
|
||||
fi
|
||||
res=$?
|
||||
cat log.txt
|
||||
verifyResult $res "Chaincode instantiation on PEER$PEER on channel '$CHANNEL_NAME' failed"
|
||||
echo "===================== Chaincode Instantiation on PEER$PEER on channel '$CHANNEL_NAME' is successful ===================== "
|
||||
echo
|
||||
}
|
||||
|
||||
chaincodeQuery () {
|
||||
PEER=$1
|
||||
echo "===================== Querying on PEER$PEER on channel '$CHANNEL_NAME'... ===================== "
|
||||
setGlobals $PEER
|
||||
local rc=1
|
||||
local starttime=$(date +%s)
|
||||
|
||||
# continue to poll
|
||||
# we either get a successful response, or reach TIMEOUT
|
||||
while test "$(($(date +%s)-starttime))" -lt "$TIMEOUT" -a $rc -ne 0
|
||||
do
|
||||
sleep 3
|
||||
echo "Attempting to Query PEER$PEER ...$(($(date +%s)-starttime)) secs"
|
||||
peer chaincode query -C $CHANNEL_NAME -n mycc -c '{"Args":["query","a"]}' >&log.txt
|
||||
test $? -eq 0 && VALUE=$(cat log.txt | awk '/Query Result/ {print $NF}')
|
||||
test "$VALUE" = "$2" && let rc=0
|
||||
done
|
||||
echo
|
||||
cat log.txt
|
||||
if test $rc -eq 0 ; then
|
||||
echo "===================== Query on PEER$PEER on channel '$CHANNEL_NAME' is successful ===================== "
|
||||
else
|
||||
echo "!!!!!!!!!!!!!!! Query result on PEER$PEER is INVALID !!!!!!!!!!!!!!!!"
|
||||
echo "================== ERROR !!! FAILED to execute End-2-End Scenario =================="
|
||||
echo
|
||||
fi
|
||||
}
|
||||
|
||||
chaincodeInvoke () {
|
||||
PEER=$1
|
||||
if [ -z "$CORE_PEER_TLS_ENABLED" -o "$CORE_PEER_TLS_ENABLED" = "false" ]; then
|
||||
peer chaincode invoke -o orderer0:7050 -C $CHANNEL_NAME -n mycc -c '{"Args":["invoke","a","b","10"]}' >&log.txt
|
||||
else
|
||||
peer chaincode invoke -o orderer0:7050 --tls $CORE_PEER_TLS_ENABLED --cafile $ORDERER_CA -C $CHANNEL_NAME -n mycc -c '{"Args":["invoke","a","b","10"]}' >&log.txt
|
||||
fi
|
||||
res=$?
|
||||
cat log.txt
|
||||
verifyResult $res "Invoke execution on PEER$PEER failed "
|
||||
echo "===================== Invoke transaction on PEER$PEER on channel '$CHANNEL_NAME' is successful ===================== "
|
||||
echo
|
||||
}
|
||||
|
||||
## Create channel
|
||||
createChannel
|
||||
|
||||
## Join all the peers to the channel
|
||||
joinChannel
|
||||
|
||||
|
||||
## Install chaincode on Peer0/Org0 and Peer2/Org1
|
||||
installChaincode 0
|
||||
installChaincode 2
|
||||
|
||||
#Instantiate chaincode on Peer2/Org1
|
||||
echo "Instantiating chaincode on Peer2/Org1 ..."
|
||||
instantiateChaincode 2
|
||||
|
||||
#Query on chaincode on Peer0/Org0
|
||||
chaincodeQuery 0 100
|
||||
|
||||
#Invoke on chaincode on Peer0/Org0
|
||||
echo "send Invoke transaction on Peer0/Org0 ..."
|
||||
chaincodeInvoke 0
|
||||
|
||||
## Install chaincode on Peer3/Org1
|
||||
installChaincode 3
|
||||
|
||||
#Query on chaincode on Peer3/Org1, check if the result is 90
|
||||
chaincodeQuery 3 90
|
||||
|
||||
echo
|
||||
echo "===================== All GOOD, End-2-End execution completed ===================== "
|
||||
echo
|
||||
exit 0
|
|
@ -19,8 +19,12 @@ services:
|
|||
- CORE_PEER_ENDORSER_ENABLED=true
|
||||
- CORE_PEER_COMMITTER_ENABLED=true
|
||||
- CORE_PEER_PROFILE_ENABLED=false
|
||||
- CORE_PEER_GOSSIP_ORGLEADER=true
|
||||
- CORE_PEER_GOSSIP_ORGLEADER=false # this node is the group leader, default to true
|
||||
- CORE_PEER_GOSSIP_USELEADERELECTION=false # automatically run leader election, default to false
|
||||
- CORE_PEER_GOSSIP_IGNORESECURITY=true
|
||||
# The following setting skips the gossip handshake since we are
|
||||
# are not doing mutual TLS
|
||||
- CORE_PEER_GOSSIP_SKIPHANDSHAKE=true
|
||||
#- CORE_PEER_COMMITTER_LEDGER_ORDERER=orderer:7050
|
||||
expose:
|
||||
- "7050" # Rest
|
||||
|
|
|
@ -22,7 +22,7 @@ docker-compose --version
|
|||
ARCH=x86_64
|
||||
BASE_VERSION=1.0.0-preview
|
||||
PROJECT_VERSION=1.0.0-preview
|
||||
IMG_VERSION=0.8.6
|
||||
IMG_VERSION=0.8.7
|
||||
docker pull yeasy/hyperledger-fabric-base:$IMG_VERSION \
|
||||
&& docker pull yeasy/hyperledger-fabric-peer:$IMG_VERSION \
|
||||
&& docker pull yeasy/hyperledger-fabric-orderer:$IMG_VERSION \
|
||||
|
|
Loading…
Reference in New Issue