├── .gitignore
├── README.en.md
├── README.md
├── bootstrap.sh
├── chaincode
├── VERSION
└── go
│ ├── ac
│ └── ac.go
│ ├── dc
│ └── dc.go
│ ├── m
│ ├── policy.go
│ ├── policy_test.go
│ ├── request.go
│ ├── request_test.go
│ ├── resource.go
│ └── util.go
│ └── pc
│ └── pc.go
├── client
└── nodejs
│ ├── base.js
│ ├── enrollAdmin.js
│ ├── init.sh
│ ├── invoke.js
│ ├── invoke_test.sh
│ ├── package.json
│ ├── registerUser.js
│ └── test.js
├── daemon.json
├── docker.sh
├── network
├── cc-install.sh
├── cc-test.sh
├── cc-upgrade.sh
├── cc.sh
├── ccp-generate.sh
├── channel-artifacts
│ └── readme.md
├── clear-docker.sh
├── compose-files
│ ├── base
│ │ ├── docker-compose-base.yaml
│ │ └── peer-base.yaml
│ ├── docker-compose-ca.yaml
│ ├── docker-compose-cli.yaml
│ ├── docker-compose-couch.yaml
│ ├── docker-compose-e2e-template.yaml
│ └── docker-compose-kafka.yaml
├── configtx.yaml
├── conn-conf
│ ├── ccp-template.json
│ └── ccp-template.yaml
├── crypto-config.yaml
├── down.sh
├── env.sh
├── generate.sh
├── restart.sh
├── scripts
│ ├── script.sh
│ └── utils.sh
└── up.sh
└── test
├── consensus
├── kafka
│ ├── kafak_test.go
│ └── kafka.go
└── pow
│ ├── pow.go
│ └── pow_test.go
└── tps
└── test.go
/.gitignore:
--------------------------------------------------------------------------------
1 | /package-lock.json
2 | /hfc-key-store/
3 | /wallet/
4 | node_modules/
5 | crypto-config/
6 | connection-*
7 | *.tx
8 | *.block
9 | .DS_Store
10 | wallet/
11 | log.*
12 | /fabric-samples
13 | .vagrant/
14 | *.log
15 | id_rsa.pub
16 | id_rsa
--------------------------------------------------------------------------------
/README.en.md:
--------------------------------------------------------------------------------
1 | # fabric-iot is a Blockchain Based Decentralized Access Control System in IoT
2 | [中文版](/README.md)
3 | > **WHAT WE HAVE**:
4 | > 1.Using ABAC as permission control method,and chaincode is writed with golang.
5 | > 2.The Hyperledger Fabric network is easily started with a complete shell script.
6 | > 3.Detailed instructions, easy to understand.
7 |
8 | ## 0.Environment & Preparation
9 | ### 0.1.Operation System
10 | OS|VETSION
11 | -|-
12 | mac os|>=10.13
13 | ubuntu|16.04
14 |
15 | ### 0.2.Software:
16 | SDK|VERSION
17 | -|-
18 | git|>=2.0.0
19 | docker|>=19
20 | docker-compose|>=1.24
21 | node|>=12
22 | golang|>=1.10
23 | Hyperledger Fabric|>=1.4
24 |
25 | ### 0.3.Download src
26 | ```go
27 | go get github.com/newham/fabric-iot
28 | ```
29 |
30 | ## 1.Directory Structure
31 |
32 | |-chaincode....................................chaincode folder
33 | |--go..........................................chaincode in golang
34 | |-client.......................................client of blockchain
35 | |--nodejs......................................code in nodejs of client
36 | |-network......................................fabric-iot network module folder,genesis.block
37 | |--channel-artifacts...........................channel comfig folder
38 | |--compose-files...............................docker-compose folder
39 | |--conn-conf...................................connection config of docker
40 | |--crypto-config...............................certs folder
41 | |--scripts.....................................shell scrpits of cli
42 | |--ccp-generate.sh.............................generate certs and blockchain config shell
43 | |--ccp-template.json...........................json template of connection config
44 | |--ccp-template.yaml...........................template of connection config
45 | |--clear-docker.sh.............................clearn docker images
46 | |--configtx.yaml...............................config of configtxgen
47 | |--crypto-config.yaml..........................config of ccp-generate.sh
48 | |--down.sh.....................................shutdown the network
49 | |--env.sh......................................environment of other shell scripts
50 | |--generate.sh.................................init config
51 | |--install-cc.sh...............................install chaincode
52 | |--rm-cc.sh....................................delete chaincode
53 | |--up.sh.......................................start network
54 | ## 2.Build Network of Fabric
55 | ### 2.1.Generate cers and configs
56 | open folder
57 | ```shell
58 | cd network
59 | ```
60 | run
61 | ```shell
62 | ./generate.sh
63 | ```
64 | cers are saved to `crypto-config`
65 | ### 2.2.Start Network
66 | ```shell
67 | ./up.sh
68 | ```
69 | ### 2.3.Install Chaincode
70 | ```shell
71 | ./cc-install.sh
72 | ```
73 | ### 2.4.Upgrade Chaincode
74 | ```shell
75 | ./cc-upgrade.sh [new_version]
76 | ```
77 | *chaincode is saved to `/chaincode/go`,we only support write code with golang now.
78 | ### 2.5.Close Network
79 | ```shell
80 | ./down.sh
81 | ```
82 | *all the stoped docker containers or images will be delete ,be carefull before you do this
83 |
84 | ## 3.Interacting with the Blockchain
85 | ### 3.1.Init Code
86 | enter the foder
87 | *we have only a client writed by nodejs
88 | ```shell
89 | cd client/nodejs
90 | ```
91 | install modules of this program
92 | ```shell
93 | npm install
94 | ```
95 | ### 3.2.Create Users
96 | create admin
97 | ```shell
98 | node ./enrollAdmin.js
99 | ```
100 | create user by admin
101 | ```shell
102 | node ./registerUser.js
103 | ```
104 | ### 3.3.Run Chaincode
105 | ```shell
106 | node ./invoke.js [chaincode_name] [function_name] [args]
107 | ```
108 |
109 |
110 |
111 | ©2019 liuhan[liuhanshmtu@163.com] all rights reserved.
112 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # fabric-iot 是一个基于Hyperledger Fabric框架实现的物联网访问控制管理的区块链模拟实验平台
2 | [English](/README.en.md)
3 | > **WHAT WE HAVE**:
4 | > 1.采用ABAC作为权限控制方法,用golang实现了chaincode.
5 | > 2.编写了完整的脚本,轻松启动fabric-iot网络.
6 | > 3.详细的步骤说明,浅显易懂.
7 |
8 | ## 0.准备工作
9 | ### 0.0.官网
10 | [ github : hyperledger-fabric](https://github.com/hyperledger/fabric)
11 | [ doc 1.4 ](https://hyperledger-fabric.readthedocs.io/en/release-1.4/)
12 | [ node-sdk 1.4 ](https://hyperledger.github.io/fabric-sdk-node/release-1.4/module-fabric-network.html)
13 |
14 | ### 0.1.操作系统
15 | OS|版本
16 | -|-
17 | mac os|>=10.13
18 | ubuntu|16.04
19 |
20 | ### 0.2.软件:
21 | 软件|版本
22 | -|-
23 | git|>=2.0.0
24 | docker|>=19
25 | docker-compose|>=1.24
26 | node|>=12
27 | golang|>=1.10
28 | Hyperledger Fabric|=1.4.*
29 |
30 | ***请将golang、node的\bin加入PATH**
31 |
32 | ***本次实验基于Fabric 1.4.3,默认下载的Fabric版本是1.4.3**
33 |
34 | ***如果需要修改版本,请更改 `bootstrap.sh`**
35 | ```
36 | VERSION=1.4.3
37 |
38 | CA_VERSION=1.4.3
39 | ```
40 |
41 |
42 | ### 0.3.下载本软件
43 | ```go
44 | go get github.com/newham/fabric-iot
45 | ```
46 |
47 | ### 0.4.下载并配置Hyperledger Fabric
48 | 下载源码和bin
49 | ```bash
50 | ./bootstrap.sh
51 | ```
52 | export PATH
53 | ```bash
54 | export PATH=$PATH:$(pwd)/fabric-samples/bin
55 | ```
56 | ***之后的诸如【启动网络、安装链码等操作需要先export PATH,这是让系统知道Hyperledger Fabric的bin目录】**
57 |
58 | ***也可将其加入path中**
59 |
60 | ## 1.目录结构
61 |
62 | |-chaincode....................................链码目录
63 | |--go....................................................golang编写的chaincode代码
64 | |-client............................................交互客户端
65 | |--nodejs..............................................nodejs编写的客户端代码
66 | |-network........................................fabric-iot网络配置和启动脚本
67 | |--channel-artifacts..............................channel配置文件,创世区块目录
68 | |--compose-files...................................docker-compose文件目录
69 | |--conn-conf.........................................链接docker网络配置目录
70 | |--crypto-config....................................存放证书、秘钥文件目录
71 | |--scripts...............................................cli运行脚本目录
72 | |--ccp-generate.sh...............................生成节点证书目录配置文件脚本
73 | |--ccp-template.json.............................配置文件json模板
74 | |--ccp-template.yaml.............................配置文件yaml模板
75 | |--clear-docker.sh................................清理停用docker镜像脚本
76 | |--configtx.yaml....................................configtxgen的配置文件
77 | |--crypto-config.yaml...........................生成证书、秘钥的配置文件
78 | |--down.sh............................................关闭网络shell脚本
79 | |--env.sh...............................................其他shell脚本import的公共配置
80 | |--generate.sh......................................初始化系统配置shell脚本
81 | |--install-cc.sh......................................安装链码shell脚本
82 | |--rm-cc.sh...........................................删除链码shell脚本
83 | |--up.sh................................................启动网络shell脚本
84 | ## 2.搭建网络 [分布式版本](https://github.com/newham/fabric-iot/tree/distributed)
85 | ### 2.1.生成证书、配置文件等
86 | 进入目录
87 | ```shell
88 | cd network
89 | ```
90 | 运行脚本
91 | ```shell
92 | ./generate.sh
93 | ```
94 | 证书保存在`crypto-config`中
95 | ### 2.2.启动网络
96 | ```shell
97 | ./up.sh
98 | ```
99 | ### 2.3.安装链码
100 | ```shell
101 | ./cc-install.sh
102 | ```
103 | ### *2.4.更新链码(本步骤在修改了chain code代码后再执行,[new version]要大于上一个版本)
104 | ```shell
105 | ./cc-upgrade.sh [new version]
106 | ```
107 | *chaincode被保存在`/chaincode/go`目录中,目前只用`golang`实现
108 | ### *2.5.关闭网络
109 | ```shell
110 | ./down.sh
111 | ```
112 | *每次关闭网络会删除所有docker容器和镜像,请谨慎操作
113 | ## 3.与区块链交互
114 |
115 | ## 3.1.使用shell脚本调用链码
116 | 进入shell脚本目录
117 | ```bash
118 | cd network
119 | ```
120 | 调用链码(示例代码在`cc-test.sh`)
121 | ```bash
122 | # invoke
123 | # shell|action|cc_name|cc_version|cc_src|fname|args
124 | # add policy
125 | ./cc.sh invoke pc 1.0 go/pc AddPolicy '"{\"AS\":{\"userId\":\"13800010001\",\"role\":\"u1\",\"group\":\"g1\"},\"AO\":{\"deviceId\":\"D100010001\",\"MAC\":\"00:11:22:33:44:55\"}}"'
126 | # query policy
127 | ./cc.sh invoke pc 1.0 go/pc QueryPolicy '"40db810e4ccb4cc1f3d5bc5803fb61e863cf05ea7fc2f63165599ef53adf5623"'
128 | ```
129 | ## 3.2.使用 Node JS 客户端调用链码
130 | ### 3.2.1初始化代码
131 | 进入客户端代码目录
132 | *目前只实现了nodejs的客户端
133 |
134 | ```shell
135 | cd client/nodejs
136 | ```
137 | 安装依赖
138 | ```shell
139 | npm install
140 | ```
141 | ### 3.2.2.创建用户
142 | 创建管理员账户
143 | ```shell
144 | node ./enrollAdmin.js
145 | ```
146 | 用管理员账户创建子用户
147 | ```shell
148 | node ./registerUser.js
149 | ```
150 | ### 3.2.3.调用chaincode
151 | ```shell
152 | node ./invoke.js [chaincode_name] [function_name] [args]
153 | ```
154 |
155 |
156 |
157 | ©2019 liuhanshmtu@163.com all rights reserved.
158 |
--------------------------------------------------------------------------------
/bootstrap.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | #
3 | # Copyright IBM Corp. All Rights Reserved.
4 | #
5 | # SPDX-License-Identifier: Apache-2.0
6 | #
7 |
8 | # Delete downloaded files
9 | rm -rf ./fabric-samples
10 |
11 | # if version not passed in, default to latest released version
12 | VERSION=1.4.3
13 | # if ca version not passed in, default to latest released version
14 | CA_VERSION=1.4.3
15 | ARCH=$(echo "$(uname -s|tr '[:upper:]' '[:lower:]'|sed 's/mingw64_nt.*/windows/')-$(uname -m | sed 's/x86_64/amd64/g')")
16 | MARCH=$(uname -m)
17 |
18 | printHelp() {
19 | echo "Usage: bootstrap.sh [version [ca_version]] [options]"
20 | echo
21 | echo "options:"
22 | echo "-h : this help"
23 | echo "-d : bypass docker image download"
24 | echo "-s : bypass fabric-samples repo clone"
25 | echo "-b : bypass download of platform-specific binaries"
26 | echo
27 | echo "e.g. bootstrap.sh 2.2.0 1.4.7 -s"
28 | echo "will download docker images and binaries for Fabric v2.2.0 and Fabric CA v1.4.7"
29 | }
30 |
31 | # dockerPull() pulls docker images from fabric and chaincode repositories
32 | # note, if a docker image doesn't exist for a requested release, it will simply
33 | # be skipped, since this script doesn't terminate upon errors.
34 |
35 | dockerPull() {
36 | #three_digit_image_tag is passed in, e.g. "1.4.7"
37 | three_digit_image_tag=$1
38 | shift
39 | #two_digit_image_tag is derived, e.g. "1.4", especially useful as a local tag for two digit references to most recent baseos, ccenv, javaenv, nodeenv patch releases
40 | two_digit_image_tag=$(echo "$three_digit_image_tag" | cut -d'.' -f1,2)
41 | while [[ $# -gt 0 ]]
42 | do
43 | image_name="$1"
44 | echo "====> hyperledger/fabric-$image_name:$three_digit_image_tag"
45 | docker pull "hyperledger/fabric-$image_name:$three_digit_image_tag"
46 | docker tag "hyperledger/fabric-$image_name:$three_digit_image_tag" "hyperledger/fabric-$image_name"
47 | docker tag "hyperledger/fabric-$image_name:$three_digit_image_tag" "hyperledger/fabric-$image_name:$two_digit_image_tag"
48 | shift
49 | done
50 | }
51 |
52 | cloneSamplesRepo() {
53 | # clone (if needed) hyperledger/fabric-samples and checkout corresponding
54 | # version to the binaries and docker images to be downloaded
55 | if [ -d first-network ]; then
56 | # if we are in the fabric-samples repo, checkout corresponding version
57 | echo "===> Checking out v${VERSION} of hyperledger/fabric-samples"
58 | git checkout v${VERSION}
59 | elif [ -d fabric-samples ]; then
60 | # if fabric-samples repo already cloned and in current directory,
61 | # cd fabric-samples and checkout corresponding version
62 | echo "===> Checking out v${VERSION} of hyperledger/fabric-samples"
63 | cd fabric-samples && git checkout v${VERSION}
64 | else
65 | echo "===> Cloning hyperledger/fabric-samples repo and checkout v${VERSION}"
66 | git clone -b master https://github.com/hyperledger/fabric-samples.git && cd fabric-samples && git checkout v${VERSION}
67 | fi
68 | }
69 |
70 | # This will download the .tar.gz
71 | download() {
72 | local BINARY_FILE=$1
73 | local URL=$2
74 | echo "===> Downloading: " "${URL}"
75 | curl -L --retry 5 --retry-delay 3 "${URL}" | tar xz || rc=$?
76 | if [ -n "$rc" ]; then
77 | echo "==> There was an error downloading the binary file."
78 | return 22
79 | else
80 | echo "==> Done."
81 | fi
82 | }
83 |
84 | pullBinaries() {
85 | echo "===> Downloading version ${FABRIC_TAG} platform specific fabric binaries"
86 | download "${BINARY_FILE}" "https://github.com/hyperledger/fabric/releases/download/v${VERSION}/${BINARY_FILE}"
87 | if [ $? -eq 22 ]; then
88 | echo
89 | echo "------> ${FABRIC_TAG} platform specific fabric binary is not available to download <----"
90 | echo
91 | exit
92 | fi
93 |
94 | echo "===> Downloading version ${CA_TAG} platform specific fabric-ca-client binary"
95 | download "${CA_BINARY_FILE}" "https://github.com/hyperledger/fabric-ca/releases/download/v${CA_VERSION}/${CA_BINARY_FILE}"
96 | if [ $? -eq 22 ]; then
97 | echo
98 | echo "------> ${CA_TAG} fabric-ca-client binary is not available to download (Available from 1.1.0-rc1) <----"
99 | echo
100 | exit
101 | fi
102 | }
103 |
104 | pullDockerImages() {
105 | command -v docker >& /dev/null
106 | NODOCKER=$?
107 | if [ "${NODOCKER}" == 0 ]; then
108 | FABRIC_IMAGES=(peer orderer ccenv tools couchdb) # couchdb added by liuhan
109 | case "$VERSION" in
110 | 2.*)
111 | FABRIC_IMAGES+=(baseos)
112 | shift
113 | ;;
114 | esac
115 | echo "FABRIC_IMAGES:" "${FABRIC_IMAGES[@]}"
116 | echo "===> Pulling fabric Images"
117 | dockerPull "${FABRIC_TAG}" "${FABRIC_IMAGES[@]}"
118 | echo "===> Pulling fabric ca Image"
119 | CA_IMAGE=(ca)
120 | dockerPull "${CA_TAG}" "${CA_IMAGE[@]}"
121 | echo "===> List out hyperledger docker images"
122 | docker images | grep hyperledger
123 | else
124 | echo "========================================================="
125 | echo "Docker not installed, bypassing download of Fabric images"
126 | echo "========================================================="
127 | fi
128 | }
129 |
130 | DOCKER=true
131 | SAMPLES=false
132 | BINARIES=true
133 |
134 | # Parse commandline args pull out
135 | # version and/or ca-version strings first
136 | if [ -n "$1" ] && [ "${1:0:1}" != "-" ]; then
137 | VERSION=$1;shift
138 | if [ -n "$1" ] && [ "${1:0:1}" != "-" ]; then
139 | CA_VERSION=$1;shift
140 | if [ -n "$1" ] && [ "${1:0:1}" != "-" ]; then
141 | THIRDPARTY_IMAGE_VERSION=$1;shift
142 | fi
143 | fi
144 | fi
145 |
146 | # prior to 1.2.0 architecture was determined by uname -m
147 | if [[ $VERSION =~ ^1\.[0-1]\.* ]]; then
148 | export FABRIC_TAG=${MARCH}-${VERSION}
149 | export CA_TAG=${MARCH}-${CA_VERSION}
150 | export THIRDPARTY_TAG=${MARCH}-${THIRDPARTY_IMAGE_VERSION}
151 | else
152 | # starting with 1.2.0, multi-arch images will be default
153 | : "${CA_TAG:="$CA_VERSION"}"
154 | : "${FABRIC_TAG:="$VERSION"}"
155 | : "${THIRDPARTY_TAG:="$THIRDPARTY_IMAGE_VERSION"}"
156 | fi
157 |
158 | BINARY_FILE=hyperledger-fabric-${ARCH}-${VERSION}.tar.gz
159 | CA_BINARY_FILE=hyperledger-fabric-ca-${ARCH}-${CA_VERSION}.tar.gz
160 |
161 | # then parse opts
162 | while getopts "h?dsb" opt; do
163 | case "$opt" in
164 | h|\?)
165 | printHelp
166 | exit 0
167 | ;;
168 | d) DOCKER=false
169 | ;;
170 | s) SAMPLES=false
171 | ;;
172 | b) BINARIES=false
173 | ;;
174 | esac
175 | done
176 |
177 | if [ "$SAMPLES" == "true" ]; then
178 | echo
179 | echo "Clone hyperledger/fabric-samples repo"
180 | echo
181 | cloneSamplesRepo
182 | elif [ "$SAMPLES" == "false" ]; then
183 | mkdir fabric-samples && cd fabric-samples
184 | fi
185 | if [ "$BINARIES" == "true" ]; then
186 | echo
187 | echo "Pull Hyperledger Fabric binaries"
188 | echo
189 | pullBinaries
190 | # by liuhan
191 | cd ../
192 | echo
193 | echo "Set Fabric binaries ($(pwd)/fabric-samples/bin) to PATH"
194 | echo
195 | export PATH=$PATH:$(pwd)/fabric-samples/bin
196 | fi
197 | if [ "$DOCKER" == "true" ]; then
198 | echo
199 | echo "Pull Hyperledger Fabric docker images"
200 | echo
201 | pullDockerImages
202 | fi
203 |
--------------------------------------------------------------------------------
/chaincode/VERSION:
--------------------------------------------------------------------------------
1 | PC=1.0
2 | DC=1.0
3 | AC=1.0
--------------------------------------------------------------------------------
/chaincode/go/ac/ac.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "encoding/json"
5 | "fmt"
6 |
7 | "github.com/hyperledger/fabric/core/chaincode/shim"
8 | sc "github.com/hyperledger/fabric/protos/peer"
9 | "github.com/newham/fabric-iot/chaincode/go/m"
10 | )
11 |
12 | type AccessContract interface {
13 | Init(shim.ChaincodeStubInterface) sc.Response
14 | Invoke(shim.ChaincodeStubInterface) sc.Response
15 | Synchro() sc.Response
16 |
17 | CheckAccess(shim.ChaincodeStubInterface, []string) sc.Response
18 | Auth(string) (m.ABACRequest, error)
19 | }
20 |
21 | type ChainCode struct {
22 | AccessContract
23 | }
24 |
25 | func NewAccessContract() AccessContract {
26 | return new(ChainCode)
27 | }
28 |
29 | func (cc *ChainCode) Auth(str string) (m.ABACRequest, error) {
30 | r := m.ABACRequest{}
31 | b := []byte(str)
32 | err := json.Unmarshal(b, &r)
33 | return r, err
34 | }
35 |
36 | func (cc *ChainCode) CheckAccess(APIstub shim.ChaincodeStubInterface, args []string) sc.Response {
37 | if len(args) != 1 {
38 | return shim.Error("Incorrect number of argumentcc. Expecting 1")
39 | }
40 | r, err := cc.Auth(args[0])
41 | if err != nil {
42 | return shim.Error("403")
43 | }
44 | attrs := r.GetAttrs()
45 | //get policy
46 | resp := APIstub.InvokeChaincode("pc", [][]byte{[]byte("QueryPolicy"), []byte(attrs.GetId())}, "iot-channel")
47 | if resp.GetStatus() != 200 {
48 | return shim.Error("403")
49 | }
50 |
51 | policy := m.Policy{}
52 | err = json.Unmarshal(resp.GetPayload(), &policy)
53 | if err != nil {
54 | return shim.Error("403")
55 | // return shim.Error(attrs.GetId() + ";" + string(resp.GetPayload()) + ";" + err.Error())
56 | }
57 | //check AP
58 | if policy.AP != 1 {
59 | return shim.Error("403")
60 | // return shim.Error(string(policy.ToBytes()) + ": AP is deney")
61 | }
62 | //check AE
63 | if attrs.Timestamp > policy.AE.EndTime {
64 | //disable the contract
65 | // DeletePolicy(APIstub, attrs.GetId())
66 | return shim.Error("AE is timeout")
67 | }
68 | //get URL
69 | resp = APIstub.InvokeChaincode("dc", [][]byte{[]byte("GetURL"), []byte(attrs.DeviceId)}, "iot-channel")
70 | res, err := m.NewResource(resp.GetPayload())
71 | if err != nil {
72 | return shim.Error(err.Error())
73 | }
74 | return shim.Success([]byte(res.URL))
75 | }
76 |
77 | /*
78 | * The Init method is called when the Smart Contract "fabcar" is instantiated by the blockchain network
79 | * Best practice is to have any Ledger initialization in separate function -- see initLedger()
80 | */
81 | func (cc *ChainCode) Init(APIstub shim.ChaincodeStubInterface) sc.Response {
82 | return shim.Success(m.OK)
83 | }
84 |
85 | /*
86 | * The Invoke method is called as a result of an application request to run the Smart Contract "fabcar"
87 | * The calling application program has also specified the particular smart contract function to be called, with arguments
88 | */
89 | func (cc *ChainCode) Invoke(APIstub shim.ChaincodeStubInterface) sc.Response {
90 |
91 | // Retrieve the requested Smart Contract function and arguments
92 | function, args := APIstub.GetFunctionAndParameters()
93 | // Route to the appropriate handler function to interact with the ledger appropriately
94 | if function == "CheckAccess" {
95 | return cc.CheckAccess(APIstub, args)
96 | } else if function == "Synchro" {
97 | return cc.Synchro()
98 | }
99 |
100 | return shim.Error("Invalid Smart Contract function name.")
101 | }
102 |
103 | // base function
104 | func (cc *ChainCode) Synchro() sc.Response {
105 | return shim.Success(m.OK)
106 | }
107 |
108 | func main() {
109 | // Create a new Smart Contract
110 | err := shim.Start(NewAccessContract())
111 | if err != nil {
112 | fmt.Printf("Error creating new Smart Contract: %s", err)
113 | }
114 | }
115 |
--------------------------------------------------------------------------------
/chaincode/go/dc/dc.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "fmt"
5 | "time"
6 |
7 | "github.com/hyperledger/fabric/core/chaincode/shim"
8 | sc "github.com/hyperledger/fabric/protos/peer"
9 | "github.com/newham/fabric-iot/chaincode/go/m"
10 | )
11 |
12 | type DeviceContract interface {
13 | Init(shim.ChaincodeStubInterface) sc.Response
14 | Invoke(shim.ChaincodeStubInterface) sc.Response
15 | AddURL(shim.ChaincodeStubInterface, []string) sc.Response
16 | GetURL(shim.ChaincodeStubInterface, []string) sc.Response
17 | Synchro() sc.Response
18 | }
19 |
20 | // Define the Device Contract structure
21 | type ChainCode struct {
22 | DeviceContract
23 | }
24 |
25 | func NewDeviceContract() DeviceContract {
26 | return new(ChainCode)
27 | }
28 |
29 | /*
30 | * The Init method is called when the Smart Contract "fabcar" is instantiated by the blockchain network
31 | * Best practice is to have any Ledger initialization in separate function -- see initLedger()
32 | */
33 | func (cc *ChainCode) Init(APIstub shim.ChaincodeStubInterface) sc.Response {
34 | return shim.Success(m.OK)
35 | }
36 |
37 | /*
38 | * The Invoke method is called as a result of an application request to run the Smart Contract "fabcar"
39 | * The calling application program has also specified the particular smart contract function to be called, with arguments
40 | */
41 | func (cc *ChainCode) Invoke(APIstub shim.ChaincodeStubInterface) sc.Response {
42 |
43 | // Retrieve the requested Smart Contract function and arguments
44 | function, args := APIstub.GetFunctionAndParameters()
45 | // Route to the appropriate handler function to interact with the ledger appropriately
46 | if function == "AddURL" {
47 | return cc.AddURL(APIstub, args)
48 | } else if function == "GetURL" {
49 | return cc.GetURL(APIstub, args)
50 | } else if function == "Synchro" {
51 | return cc.Synchro()
52 | }
53 |
54 | return shim.Error("Invalid Smart Contract function name.")
55 | }
56 |
57 | //This is the main smart contract of system
58 | func (cc *ChainCode) AddURL(APIstub shim.ChaincodeStubInterface, args []string) sc.Response {
59 | if len(args) != 2 {
60 | return shim.Error("Incorrect number of arguments. Expecting 2")
61 | }
62 |
63 | deviceId := args[0]
64 | url := args[1]
65 | r := m.Resource{Timestamp: time.Now().Unix(), URL: url}
66 |
67 | // put k-v to DB
68 | err := APIstub.PutState(deviceId, r.ToBytes())
69 | if err != nil {
70 | return shim.Error(err.Error())
71 | }
72 |
73 | return shim.Success(m.OK)
74 | }
75 |
76 | func (cc *ChainCode) GetURL(APIstub shim.ChaincodeStubInterface, args []string) sc.Response {
77 | if len(args) != 1 {
78 | return shim.Error("Incorrect number of arguments. Expecting 1")
79 | }
80 | b, _ := APIstub.GetState(args[0])
81 | return shim.Success(b)
82 | }
83 |
84 | func (cc *ChainCode) Synchro() sc.Response {
85 | return shim.Success(m.OK)
86 | }
87 |
88 | // The main function is only relevant in unit test mode. Only included here for completeness.
89 | func main() {
90 | // Create a new Smart Contract
91 | err := shim.Start(NewDeviceContract())
92 | if err != nil {
93 | fmt.Printf("Error creating new Smart Contract: %s", err)
94 | }
95 | }
96 |
--------------------------------------------------------------------------------
/chaincode/go/m/policy.go:
--------------------------------------------------------------------------------
1 | package m
2 |
3 | import (
4 | "crypto/sha256"
5 | "encoding/json"
6 | "fmt"
7 | )
8 |
9 | // Define the Policy structure
10 | type Policy struct {
11 | AS AS
12 | AO AO
13 | AP int //1 is allow , 0 is deney
14 | AE AE
15 | }
16 |
17 | type AS struct {
18 | UserId string `json:"userId"`
19 | Role string `json:"role"`
20 | Group string `json:"group"`
21 | }
22 |
23 | type AO struct {
24 | DeviceId string `json:"deviceId"`
25 | MAC string `json:"MAC"`
26 | }
27 |
28 | type AE struct {
29 | CreatedTime int64 `json:"createdTime"`
30 | EndTime int64 `json:"endTime"`
31 | AllowedIP string `json:"allowedIP"`
32 | }
33 |
34 | func (p *Policy) ToBytes() []byte {
35 | b, err := json.Marshal(*p)
36 | if err != nil {
37 | return nil
38 | }
39 | return b
40 | }
41 |
42 | func (p *Policy) GetID() string {
43 | return fmt.Sprintf("%x", sha256.Sum256([]byte(p.AS.UserId+p.AO.DeviceId)))
44 | }
45 |
--------------------------------------------------------------------------------
/chaincode/go/m/policy_test.go:
--------------------------------------------------------------------------------
1 | package m
2 |
3 | import (
4 | "fmt"
5 | "testing"
6 | )
7 |
8 | var p = Policy{
9 | AS{"13800010002", "u1", "g1"},
10 | AO{"D100010001", "00:11:22:33:44:55"},
11 | 1,
12 | AE{1575468182, 1576468182, "*.*.*.*"},
13 | }
14 |
15 | func Test_ToBytes(t *testing.T) {
16 | fmt.Printf("%s\n", p.ToBytes())
17 | }
18 |
19 | func Test_GetID(t *testing.T) {
20 | println(p.GetID())
21 | }
22 |
--------------------------------------------------------------------------------
/chaincode/go/m/request.go:
--------------------------------------------------------------------------------
1 | package m
2 |
3 | import (
4 | "crypto/sha256"
5 | "encoding/json"
6 | "fmt"
7 | "time"
8 | )
9 |
10 | type ABACRequest struct {
11 | AS AS
12 | AO AO
13 | }
14 |
15 | func (r *ABACRequest) ToBytes() []byte {
16 | b, err := json.Marshal(*r)
17 | if err != nil {
18 | return nil
19 | }
20 | return b
21 | }
22 |
23 | type Attrs struct {
24 | DeviceId string
25 | UserId string
26 | Timestamp int64
27 | }
28 |
29 | func (a Attrs) GetId() string {
30 | return fmt.Sprintf("%x", sha256.Sum256([]byte(a.UserId+a.DeviceId)))
31 | }
32 |
33 | func (r ABACRequest) GetAttrs() Attrs {
34 | return Attrs{DeviceId: r.AO.DeviceId, UserId: r.AS.UserId, Timestamp: time.Now().Unix()}
35 | }
36 |
--------------------------------------------------------------------------------
/chaincode/go/m/request_test.go:
--------------------------------------------------------------------------------
1 | package m
2 |
3 | import (
4 | "fmt"
5 | "testing"
6 | )
7 |
8 | func Test_ABACRequest(t *testing.T) {
9 | r := ABACRequest{
10 | AS{"13800010002", "u1", "g1"},
11 | AO{"D100010001", "00:11:22:33:44:55"},
12 | }
13 | fmt.Printf("%s\n", r.ToBytes())
14 | }
15 |
--------------------------------------------------------------------------------
/chaincode/go/m/resource.go:
--------------------------------------------------------------------------------
1 | package m
2 |
3 | import "encoding/json"
4 |
5 | // Define the resource structure
6 | type Resource struct {
7 | Timestamp int64 `json:"timestamp"`
8 | URL string `json:"url"`
9 | }
10 |
11 | func (r Resource) ToBytes() []byte {
12 | b, err := json.Marshal(r)
13 | if err != nil {
14 | return nil
15 | }
16 | return b
17 | }
18 |
19 | func NewResource(b []byte) (Resource, error) {
20 | r := Resource{}
21 | err := json.Unmarshal(b, &r)
22 | return r, err
23 | }
24 |
--------------------------------------------------------------------------------
/chaincode/go/m/util.go:
--------------------------------------------------------------------------------
1 | package m
2 |
3 | var OK = []byte("OK")
4 |
--------------------------------------------------------------------------------
/chaincode/go/pc/pc.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "encoding/json"
5 | "fmt"
6 |
7 | "github.com/hyperledger/fabric/core/chaincode/shim"
8 | sc "github.com/hyperledger/fabric/protos/peer"
9 | "github.com/newham/fabric-iot/chaincode/go/m"
10 | )
11 |
12 | type PolicyContract interface {
13 | Init(shim.ChaincodeStubInterface) sc.Response
14 | Invoke(shim.ChaincodeStubInterface) sc.Response
15 | Synchro() sc.Response
16 | CheckPolicy(m.Policy) bool
17 | AddPolicy(shim.ChaincodeStubInterface, []string) sc.Response
18 | UpdatePolicy(shim.ChaincodeStubInterface, []string) sc.Response
19 | QueryPolicy(shim.ChaincodeStubInterface, []string) sc.Response
20 | DeletePolicy(shim.ChaincodeStubInterface, []string) sc.Response
21 | }
22 |
23 | // Define the Smart Contract structure
24 | type ChainCode struct {
25 | }
26 |
27 | /*
28 | * The Init method is called when the Smart Contract "fabcar" is instantiated by the blockchain network
29 | * Best practice is to have any Ledger initialization in separate function -- see initLedger()
30 | */
31 | func (cc *ChainCode) Init(APIstub shim.ChaincodeStubInterface) sc.Response {
32 | return shim.Success(m.OK)
33 | }
34 |
35 | /*
36 | * The Invoke method is called as a result of an application request to run the Smart Contract "fabcar"
37 | * The calling application program has also specified the particular smart contract function to be called, with arguments
38 | */
39 | func (cc *ChainCode) Invoke(APIstub shim.ChaincodeStubInterface) sc.Response {
40 |
41 | // Retrieve the requested Smart Contract function and arguments
42 | function, args := APIstub.GetFunctionAndParameters()
43 | // Route to the appropriate handler function to interact with the ledger appropriately
44 | if function == "AddPolicy" {
45 | return cc.AddPolicy(APIstub, args)
46 | } else if function == "Synchro" {
47 | return cc.Synchro()
48 | } else if function == "QueryPolicy" {
49 | return cc.QueryPolicy(APIstub, args)
50 | } else if function == "DeletePolicy" {
51 | return cc.DeletePolicy(APIstub, args)
52 | } else if function == "UpdatePolicy" {
53 | return cc.UpdatePolicy(APIstub, args)
54 | }
55 |
56 | return shim.Error("Invalid Smart Contract function name.")
57 | }
58 |
59 | func NewPolicyContract() PolicyContract {
60 | return new(ChainCode)
61 | }
62 |
63 | func (cc *ChainCode) parsePolicy(arg string) (m.Policy, error) {
64 | policyAsBytes := []byte(arg)
65 | policy := m.Policy{}
66 | err := json.Unmarshal(policyAsBytes, &policy)
67 | return policy, err
68 | }
69 |
70 | func (cc *ChainCode) CheckPolicy(p m.Policy) bool {
71 | return false
72 | }
73 |
74 | //This is the main smart contract of system
75 | func (cc *ChainCode) AddPolicy(APIstub shim.ChaincodeStubInterface, args []string) sc.Response {
76 | if len(args) != 1 {
77 | return shim.Error("Incorrect number of argumentcc. Expecting 1")
78 | }
79 | // parse policy
80 | policy, err := cc.parsePolicy(args[0])
81 | if err != nil {
82 | return shim.Error(err.Error())
83 | }
84 | // check it
85 | if cc.CheckPolicy(policy) {
86 | return shim.Error("bad policy")
87 | }
88 | // put k-v to DB
89 | err = APIstub.PutState(policy.GetID(), policy.ToBytes())
90 | if err != nil {
91 | return shim.Error(err.Error())
92 | }
93 | return shim.Success(m.OK)
94 | }
95 |
96 | func (cc *ChainCode) QueryPolicy(APIstub shim.ChaincodeStubInterface, args []string) sc.Response {
97 | if len(args) != 1 {
98 | return shim.Error("Incorrect number of argumentcc. Expecting 1")
99 | }
100 | policyAsBytes, _ := APIstub.GetState(args[0])
101 | return shim.Success(policyAsBytes)
102 | }
103 |
104 | func (cc *ChainCode) UpdatePolicy(APIstub shim.ChaincodeStubInterface, args []string) sc.Response {
105 | if len(args) != 1 {
106 | return shim.Error("Incorrect number of argumentcc. Expecting 1")
107 | }
108 | // parse policy
109 | policy, err := cc.parsePolicy(args[0])
110 | if err != nil {
111 | return shim.Error(err.Error())
112 | }
113 | // check it
114 | if cc.CheckPolicy(policy) {
115 | return shim.Error("bad policy")
116 | }
117 | r := cc.QueryPolicy(APIstub, []string{policy.GetID()})
118 | if r.GetStatus() != 200 {
119 | return shim.Error("policy not exist")
120 | }
121 | return cc.AddPolicy(APIstub, args)
122 | }
123 |
124 | func (cc *ChainCode) DeletePolicy(APIstub shim.ChaincodeStubInterface, args []string) sc.Response {
125 | if len(args) != 1 {
126 | return shim.Error("Incorrect number of argumentcc. Expecting 1")
127 | }
128 | err := APIstub.DelState(args[0])
129 | if err != nil {
130 | return shim.Error(err.Error())
131 | }
132 | return shim.Success(m.OK)
133 | }
134 |
135 | func (cc *ChainCode) Synchro() sc.Response {
136 | return shim.Success(m.OK)
137 | }
138 |
139 | // The main function is only relevant in unit test mode. Only included here for completenescc.
140 | func main() {
141 |
142 | // Create a new Smart Contract
143 | err := shim.Start(NewPolicyContract())
144 | if err != nil {
145 | fmt.Printf("Error creating new Smart Contract: %s", err)
146 | }
147 | }
148 |
--------------------------------------------------------------------------------
/client/nodejs/base.js:
--------------------------------------------------------------------------------
1 | //common
2 | const fs = require('fs');
3 | const path = require('path');
4 | const ccpPath = path.resolve(__dirname, '..', '..', 'network', 'conn-conf', 'connection-org1.json');
5 | const ccpJSON = fs.readFileSync(ccpPath, 'utf8');
6 | const ccp = JSON.parse(ccpJSON);
7 | //fabric SDK
8 | const FabricCAServices = require('fabric-ca-client');
9 | const { FileSystemWallet, Gateway, X509WalletMixin } = require('fabric-network');
10 | //const value
11 | const CHANNEL_NAME = 'iot-channel';
12 | //exports
13 | exports.ccp = ccp;
14 | exports.ccpPath = ccpPath;
15 | exports.path = path;
16 | exports.FabricCAServices = FabricCAServices;
17 | exports.FileSystemWallet = FileSystemWallet;
18 | exports.X509WalletMixin = X509WalletMixin;
19 | exports.Gateway = Gateway;
20 | exports.CHANNEL_NAME = CHANNEL_NAME;
21 |
--------------------------------------------------------------------------------
/client/nodejs/enrollAdmin.js:
--------------------------------------------------------------------------------
1 | /*
2 | * SPDX-License-Identifier: Apache-2.0
3 | */
4 | 'use strict';
5 |
6 | const { FabricCAServices, X509WalletMixin, FileSystemWallet, path, ccp } = require('./base')
7 |
8 | async function main() {
9 | try {
10 |
11 | // Create a new CA client for interacting with the CA.
12 | const caInfo = ccp.certificateAuthorities['ca.org1.fabric-iot.edu'];
13 | const caTLSCACerts = caInfo.tlsCACerts.pem;
14 | const ca = new FabricCAServices(caInfo.url, { trustedRoots: caTLSCACerts, verify: false }, caInfo.caName);
15 |
16 | // Create a new file system based wallet for managing identities.
17 | const walletPath = path.join(process.cwd(), 'wallet');
18 | const wallet = new FileSystemWallet(walletPath);
19 | console.log(`Wallet path: ${walletPath}`);
20 |
21 | // Check to see if we've already enrolled the admin user.
22 | const adminExists = await wallet.exists('admin');
23 | if (adminExists) {
24 | console.log('An identity for the admin user "admin" already exists in the wallet');
25 | return;
26 | }
27 |
28 | // Enroll the admin user, and import the new identity into the wallet.
29 | const enrollment = await ca.enroll({ enrollmentID: 'admin', enrollmentSecret: 'adminpw' });
30 | const identity = X509WalletMixin.createIdentity('Org1MSP', enrollment.certificate, enrollment.key.toBytes());
31 | await wallet.import('admin', identity);
32 | console.log('Successfully enrolled admin user "admin" and imported it into the wallet');
33 |
34 | } catch (error) {
35 | console.error(`Failed to enroll admin user "admin": ${error}`);
36 | process.exit(1);
37 | }
38 | }
39 |
40 | main();
41 |
--------------------------------------------------------------------------------
/client/nodejs/init.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | rm -rf wallet
4 | node ./enrollAdmin.js
5 | node ./registerUser.js
--------------------------------------------------------------------------------
/client/nodejs/invoke.js:
--------------------------------------------------------------------------------
1 | /*
2 | * SPDX-License-Identifier: Apache-2.0
3 | */
4 |
5 | 'use strict';
6 |
7 | const { ccpPath, path, FileSystemWallet, Gateway, CHANNEL_NAME } = require("./base")
8 |
9 | function resp(status, msg) {
10 | return { status: status, msg: msg }
11 | }
12 |
13 | var isCMD = false
14 |
15 | async function main() {
16 | isCMD = true
17 | try {
18 | const argv = process.argv;
19 | if (argv.length < 5) {
20 | // console.log("[chaincode name] [function name] [arg]");
21 | console.log('need [chaincode name] [function name] [arg]')
22 | return;
23 | }
24 | // from 2 is args begin
25 | const ccName = argv[2]
26 | const fName = argv[3]
27 | const args = argv.slice(4) //[a,b] to "a b"
28 |
29 | invoke(ccName, fName, args)
30 | } catch (error) {
31 | // console.error(`Failed to evaluate transaction: ${error}`);
32 | process.exit(1);
33 | }
34 | }
35 | async function invoke(ccName, fName, args) {
36 | try {
37 | // Create a new file system based wallet for managing identities.
38 | const walletPath = path.join(process.cwd(), 'wallet');
39 | const wallet = new FileSystemWallet(walletPath);
40 | if (isCMD) {
41 | console.log(`Wallet path: ${walletPath}`);
42 | }
43 |
44 | // Check to see if we've already enrolled the user.
45 | const user = 'user1'
46 | const userExists = await wallet.exists(user);
47 | if (!userExists) {
48 | if (isCMD) {
49 | console.log(`An identity for the user "${user}" does not exist in the wallet`);
50 | console.log('Run the registerUser.js application before retrying');
51 | }
52 | return resp(500, 'Run the registerUser.js application before retrying');
53 | }
54 |
55 | // Create a new gateway for connecting to our peer node.
56 | const gateway = new Gateway();
57 | await gateway.connect(ccpPath, { wallet, identity: user, discovery: { enabled: true, asLocalhost: true } });
58 |
59 | // Get the network (channel) our contract is deployed to.
60 | const network = await gateway.getNetwork(CHANNEL_NAME);
61 |
62 | // Get the contract from the network.
63 | const contract = network.getContract(ccName);
64 |
65 | // Evaluate the specified transaction.
66 | // queryCar transaction - requires 1 argument, ex: ('queryCar', 'CAR4')
67 | // queryAllCars transaction - requires no arguments, ex: ('queryAllCars')
68 | if (isCMD) {
69 | console.log(ccName, fName, ...args)
70 | }
71 | switch (fName) {
72 | case "AddURL":
73 | case "GetURL":
74 | case "AddPolicy":
75 | case "DeletePolicy":
76 | case "UpdatePolicy":
77 | case "CheckAccess":
78 | const r1 = await contract.submitTransaction(fName, ...args);
79 | if (isCMD) {
80 | console.log(`Transaction has been submit, result is: ${r1.toString()}`);
81 |
82 | //exit cmd
83 | process.exit(1);
84 |
85 | }
86 | return resp(200, r1.toString())
87 | break;
88 | default:
89 | // const r2 = await contract.evaluateTransaction(fName, ...args);
90 | if (isCMD) {
91 | console.log(`Transaction has been evaluated, result is: bad cc name`);
92 | }
93 | return resp(400, 'bad cc name')
94 | break;
95 | }
96 |
97 |
98 | } catch (error) {
99 | if (isCMD) {
100 | console.error(`Failed to evaluate transaction: ${error}`);
101 | process.exit(1);
102 | }
103 | return resp(500, error)
104 | }
105 | }
106 |
107 | main();
108 |
109 | module.exports = { invoke }
--------------------------------------------------------------------------------
/client/nodejs/invoke_test.sh:
--------------------------------------------------------------------------------
1 | node invoke.js dc AddURL D100010001 https://test.iot.org/voice00001.mp3
2 | # node invoke.js dc GetURL D100010001
3 |
4 | # node invoke.js pc AddPolicy '{"AS":{"userId":"13800010002","role":"u1","group":"g1"},"AO":{"deviceId":"D100010001","MAC":"00:11:22:33:44:55"},"AP":1,"AE":{"createdTime":1575468182,"endTime":1576468182,"allowedIP":"*.*.*.*"}}'
5 | # node invoke.js pc QueryPolicy da1f08aa8ee250a65057c354b6952e2baf6ae3c9505cb9ca3e5ab4138e56b9d1
6 |
7 | # node invoke.js pc AddPolicy '{"AS":{"userId":"13800010001","role":"u1","group":"g1"},"AO":{"deviceId":"D100010001","MAC":"00:11:22:33:44:55"},"AP":1,"AE":{"createdTime":1575468182,"endTime":1576468182,"allowedIP":"*.*.*.*"}}'
8 | # node invoke.js pc QueryPolicy 40db810e4ccb4cc1f3d5bc5803fb61e863cf05ea7fc2f63165599ef53adf5623
9 |
10 | # node invoke.js ac CheckAccess '{"AS":{"userId":"13800010002","role":"u1","group":"g1"},"AO":{"deviceId":"D100010001","MAC":"00:11:22:33:44:55"}}'
11 | # node invoke.js ac CheckAccess '{"AS":{"userId":"13800010001","role":"u1","group":"g1"},"AO":{"deviceId":"D100010001","MAC":"00:11:22:33:44:55"}}'
--------------------------------------------------------------------------------
/client/nodejs/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "fabcar",
3 | "version": "1.0.0",
4 | "description": "FabCar application implemented in JavaScript",
5 | "engines": {
6 | "node": ">=8",
7 | "npm": ">=5"
8 | },
9 | "scripts": {
10 | "lint": "eslint .",
11 | "pretest": "npm run lint",
12 | "test": "nyc mocha --recursive"
13 | },
14 | "engineStrict": true,
15 | "author": "Hyperledger",
16 | "license": "Apache-2.0",
17 | "dependencies": {
18 | "express": "^4.17.1",
19 | "fabric-ca-client": "~1.4.0",
20 | "fabric-network": "~1.4.0"
21 | },
22 | "devDependencies": {
23 | "chai": "^4.2.0",
24 | "eslint": "^5.9.0",
25 | "mocha": "^5.2.0",
26 | "nyc": "^13.1.0",
27 | "sinon": "^7.1.1",
28 | "sinon-chai": "^3.3.0"
29 | },
30 | "nyc": {
31 | "exclude": [
32 | "coverage/**",
33 | "test/**"
34 | ],
35 | "reporter": [
36 | "text-summary",
37 | "html"
38 | ],
39 | "all": true,
40 | "check-coverage": true,
41 | "statements": 100,
42 | "branches": 100,
43 | "functions": 100,
44 | "lines": 100
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/client/nodejs/registerUser.js:
--------------------------------------------------------------------------------
1 | /*
2 | * SPDX-License-Identifier: Apache-2.0
3 | */
4 |
5 | 'use strict';
6 |
7 | const { FileSystemWallet, Gateway, X509WalletMixin, ccpPath, path } = require('./base')
8 |
9 | async function main() {
10 | try {
11 |
12 | const user = 'user1'
13 |
14 | // Create a new file system based wallet for managing identities.
15 | const walletPath = path.join(process.cwd(), 'wallet');
16 | const wallet = new FileSystemWallet(walletPath);
17 | console.log(`Wallet path: ${walletPath}`);
18 |
19 | // Check to see if we've already enrolled the user.
20 | const userExists = await wallet.exists(user);
21 | if (userExists) {
22 | console.log(`An identity for the user "${user}" already exists in the wallet`);
23 | return;
24 | }
25 |
26 | // Check to see if we've already enrolled the admin user.
27 | const adminExists = await wallet.exists('admin');
28 | if (!adminExists) {
29 | console.log('An identity for the admin user "admin" does not exist in the wallet');
30 | console.log('Run the enrollAdmin.js application before retrying');
31 | return;
32 | }
33 |
34 | // Create a new gateway for connecting to our peer node.
35 | const gateway = new Gateway();
36 | await gateway.connect(ccpPath, { wallet, identity: 'admin', discovery: { enabled: true, asLocalhost: true } });
37 |
38 | // Get the CA client object from the gateway for interacting with the CA.
39 | const ca = gateway.getClient().getCertificateAuthority();
40 | const adminIdentity = gateway.getCurrentIdentity();
41 |
42 | // Register the user, enroll the user, and import the new identity into the wallet.
43 | const secret = await ca.register({ affiliation: 'org1.department1', enrollmentID: user, role: 'client' }, adminIdentity);
44 | const enrollment = await ca.enroll({ enrollmentID: user, enrollmentSecret: secret });
45 | const userIdentity = X509WalletMixin.createIdentity('Org1MSP', enrollment.certificate, enrollment.key.toBytes());
46 | await wallet.import(user, userIdentity);
47 | console.log(`Successfully registered and enrolled admin user "${user}" and imported it into the wallet`);
48 |
49 | } catch (error) {
50 | console.error(`Failed to register user "${user}": ${error}`);
51 | process.exit(1);
52 | }
53 | }
54 |
55 | main();
56 |
--------------------------------------------------------------------------------
/client/nodejs/test.js:
--------------------------------------------------------------------------------
1 | // 测试用客户端,测试系统接口性能
2 |
3 | var express = require('express')
4 | var app = express()
5 |
6 | const { invoke } = require("./invoke")
7 |
8 | // respond with "hello world" when a GET request is made to the homepage
9 | app.get('/fabric-iot/test', async function (req, res) {
10 | const cc_name = req.query.cc_name;
11 | const f_name = req.query.f_name;
12 | const args = req.query.args;
13 | // console.log("invoke",cc_name,f_name,args);
14 | if (cc_name == undefined || f_name == undefined || args == undefined) {
15 | res.status(400).send({ status: 400, msg: 'bad params' });
16 | return
17 | }
18 | const r = await invoke(cc_name, f_name, args.split("|"));
19 | res.status(r.status).send(r);
20 | })
21 |
22 | const port = 8001
23 | app.listen(port, () => console.log(`Test invoke on port ${port}!`))
--------------------------------------------------------------------------------
/daemon.json:
--------------------------------------------------------------------------------
1 | {
2 | "registry-mirrors": [
3 | "https://f1z25q5p.mirror.aliyuncs.com",
4 | "https://d8b3zdiw.mirror.aliyuncs.com"
5 | ]
6 | }
--------------------------------------------------------------------------------
/docker.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | # 更新软件
4 | sudo apt-get update
5 | # 安装依赖工具
6 | sudo apt-get install \
7 | apt-transport-https \
8 | ca-certificates \
9 | curl \
10 | gnupg-agent \
11 | software-properties-common
12 |
13 | # SET UP THE REPOSITORY
14 | curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
15 |
16 | sudo add-apt-repository \
17 | "deb [arch=amd64] https://download.docker.com/linux/ubuntu \
18 | $(lsb_release -cs) \
19 | stable"
20 |
21 | # INSTALL DOCKER ENGINE
22 | sudo apt-get update
23 | sudo apt-get install docker-ce docker-ce-cli containerd.io docker-compose
24 |
25 | #将当前用户添加至docker用户组
26 | sudo gpasswd -a $USER docker
27 | #更新docker用户组
28 | newgrp docker
29 |
30 | #添加淘宝源
31 | echo "==> 添加淘宝源"
32 | # sudo echo '{ "registry-mirrors": ["https://f1z25q5p.mirror.aliyuncs.com"] }' > /etc/docker/daemon.json
33 | sudo cp daemon.json /etc/docker/
34 | echo "==> 重启docker以适配"
35 | sudo systemctl daemon-reload
36 | sudo systemctl restart docker
--------------------------------------------------------------------------------
/network/cc-install.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | # Exit on first error
4 | set -e
5 |
6 | echo "=================== start ==================="
7 | echo start at:$(date +%Y-%m-%d\ %H:%M:%S)
8 | echo "============================================="
9 | ./cc.sh install ac 1.0 go/ac Synchro
10 | ./cc.sh install pc 1.0 go/pc Synchro
11 | ./cc.sh install dc 1.0 go/dc Synchro
12 | echo "=================== end ==================="
13 | echo end at: $(date +%Y-%m-%d\ %H:%M:%S)
14 | echo "==========================================="
15 |
--------------------------------------------------------------------------------
/network/cc-test.sh:
--------------------------------------------------------------------------------
1 | # upgrade
2 | # shell|action|cc_name|cc_version|cc_src|fname|args
3 | ./cc.sh upgrade pc 1.1 go/dc Synchro
4 |
5 | # install
6 | # shell|action|cc_name|cc_version|cc_src|fname|args
7 | ./cc.sh install pc 1.0 go/ac Synchro
8 |
9 | # invoke
10 | # shell|action|cc_name|cc_version|cc_src|fname|args
11 | # add policy
12 | ./cc.sh invoke pc 1.0 go/pc AddPolicy '"{\"AS\":{\"userId\":\"13800010001\",\"role\":\"u1\",\"group\":\"g1\"},\"AO\":{\"deviceId\":\"D100010001\",\"MAC\":\"00:11:22:33:44:55\"}}"'
13 | # query policy
14 | ./cc.sh invoke pc 1.0 go/pc QueryPolicy '"40db810e4ccb4cc1f3d5bc5803fb61e863cf05ea7fc2f63165599ef53adf5623"'
15 | # abe
16 | ./cc.sh invoke abe 0.1 go/abe CheckAccess '"My secret code","((0 AND 1) OR (2 AND 3)) AND 4","0 1 3 4"'
--------------------------------------------------------------------------------
/network/cc-upgrade.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | # Exit on first error
4 | set -e
5 |
6 | ./cc.sh upgrade ac 1.2 go/ac Synchro
--------------------------------------------------------------------------------
/network/cc.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | # Exit on first error
4 | set -e
5 |
6 | # don't rewrite paths for Windows Git Bash users
7 | export MSYS_NO_PATHCONV=1
8 | starttime=$(date +%s)
9 | # use golang as programing language
10 | CC_RUNTIME_LANGUAGE=golang
11 | CC_SRC_PATH=github.com/newham/fabric-iot/chaincode/go/pc
12 | CC_NAME=PC
13 | CC_VERSION=1.0
14 | CC_INVOKE_FUNC_NAME="Synchro"
15 | ARGS=''
16 | # client container's name
17 | CLI=cli
18 | # action
19 | ACTION=install
20 |
21 | # set needed values
22 | CONFIG_ROOT=/opt/gopath/src/github.com/hyperledger/fabric/peer
23 | ORG1_MSPCONFIGPATH=${CONFIG_ROOT}/crypto/peerOrganizations/org1.fabric-iot.edu/users/Admin@org1.fabric-iot.edu/msp
24 | ORG1_TLS_ROOTCERT_FILE=${CONFIG_ROOT}/crypto/peerOrganizations/org1.fabric-iot.edu/peers/peer0.org1.fabric-iot.edu/tls/ca.crt
25 | ORG2_MSPCONFIGPATH=${CONFIG_ROOT}/crypto/peerOrganizations/org2.fabric-iot.edu/users/Admin@org2.fabric-iot.edu/msp
26 | ORG2_TLS_ROOTCERT_FILE=${CONFIG_ROOT}/crypto/peerOrganizations/org2.fabric-iot.edu/peers/peer0.org2.fabric-iot.edu/tls/ca.crt
27 | ORDERER_TLS_ROOTCERT_FILE=${CONFIG_ROOT}/crypto/ordererOrganizations/fabric-iot.edu/orderers/orderer.fabric-iot.edu/msp/tlscacerts/tlsca.fabric-iot.edu-cert.pem
28 |
29 |
30 | if [ -n $1 -a -n $2 -a -n $3 -a -n $4 ]; then
31 | ACTION=$1
32 | CC_NAME=$2
33 | CC_VERSION=$3
34 | CC_SRC_PATH="github.com/newham/fabric-iot/chaincode/$4"
35 | if [ ! $5 = '' ]; then
36 | CC_INVOKE_FUNC_NAME=$5
37 | fi
38 | if [ ! $6 = '' ]; then
39 | ARGS=$6
40 | fi
41 | echo $ACTION ${CC_NAME}:${CC_VERSION} $CC_SRC_PATH $CC_INVOKE_FUNC_NAME $ARGS
42 | else
43 | echo './cc.sh ["install"/"upgrade"] [cc name] [cc version] [cc src path] [fname]'
44 | exit 1
45 | fi
46 |
47 |
48 | # 1:org 2:peer 3:port 4:ORG1_MSPCONFIGPATH 5:ORG1_TLS_ROOTCERT_FILE
49 | function installCC() {
50 | if [ ${1} = 1 ]; then
51 | MSPCONFIGPATH=$ORG1_MSPCONFIGPATH
52 | TLS_ROOTCERT_FILE=$ORG1_TLS_ROOTCERT_FILE
53 | elif [ ${1} = 2 ]; then
54 | MSPCONFIGPATH=$ORG2_MSPCONFIGPATH
55 | TLS_ROOTCERT_FILE=$ORG2_TLS_ROOTCERT_FILE
56 | else
57 | echo "Worng Org,check it"
58 | exit 1
59 | fi
60 | echo "Installing smart contract on peer${2}.org${1}.fabric-iot.edu"
61 | docker exec \
62 | -e CORE_PEER_LOCALMSPID=Org${1}MSP \
63 | -e CORE_PEER_ADDRESS=peer${2}.org${1}.fabric-iot.edu:${3} \
64 | -e CORE_PEER_MSPCONFIGPATH=${MSPCONFIGPATH} \
65 | -e CORE_PEER_TLS_ROOTCERT_FILE=${TLS_ROOTCERT_FILE} \
66 | $CLI \
67 | peer chaincode install \
68 | -n "$CC_NAME" \
69 | -v "$CC_VERSION" \
70 | -p "$CC_SRC_PATH" \
71 | -l "$CC_RUNTIME_LANGUAGE"
72 | }
73 |
74 | function initCC() {
75 | echo "Instantiating smart contract on iot-channel"
76 | docker exec \
77 | -e CORE_PEER_LOCALMSPID=Org1MSP \
78 | -e CORE_PEER_MSPCONFIGPATH=${ORG1_MSPCONFIGPATH} \
79 | $CLI \
80 | peer chaincode instantiate \
81 | -o orderer.fabric-iot.edu:7050 \
82 | -C iot-channel \
83 | -n "$CC_NAME" \
84 | -l "$CC_RUNTIME_LANGUAGE" \
85 | -v "$CC_VERSION" \
86 | -c '{"Args":[]}' \
87 | -P "AND('Org1MSP.member','Org2MSP.member')" \
88 | --tls \
89 | --cafile ${ORDERER_TLS_ROOTCERT_FILE} \
90 | --peerAddresses peer0.org1.fabric-iot.edu:7051 \
91 | --tlsRootCertFiles ${ORG1_TLS_ROOTCERT_FILE}
92 |
93 | echo "Waiting for contract instantiating..."
94 | process 15
95 | }
96 |
97 | function process() {
98 | for ((i = 1; i <= ${1}; i++)); do
99 | sleep 1
100 | echo -e ">\c"
101 | done
102 | echo
103 | }
104 |
105 | function invokeCC() {
106 | echo "Submitting transaction:${CC_INVOKE_FUNC_NAME} to smart contract on iot-channel"
107 | echo 'ARGS:{"function":"'$CC_INVOKE_FUNC_NAME'","Args":['$ARGS']}'
108 | echo "The transaction is sent to all of the peers so that chaincode is built before receiving the following requests"
109 | docker exec \
110 | -e CORE_PEER_LOCALMSPID=Org1MSP \
111 | -e CORE_PEER_MSPCONFIGPATH=${ORG1_MSPCONFIGPATH} \
112 | $CLI \
113 | peer chaincode invoke \
114 | -o orderer.fabric-iot.edu:7050 \
115 | -C iot-channel \
116 | -n "$CC_NAME" \
117 | -c '{"function":"'$CC_INVOKE_FUNC_NAME'","Args":['$ARGS']}' \
118 | --waitForEvent \
119 | --tls \
120 | --cafile ${ORDERER_TLS_ROOTCERT_FILE} \
121 | --peerAddresses peer0.org1.fabric-iot.edu:7051 \
122 | --peerAddresses peer1.org1.fabric-iot.edu:8051 \
123 | --peerAddresses peer0.org2.fabric-iot.edu:9051 \
124 | --peerAddresses peer1.org2.fabric-iot.edu:10051 \
125 | --tlsRootCertFiles ${ORG1_TLS_ROOTCERT_FILE} \
126 | --tlsRootCertFiles ${ORG1_TLS_ROOTCERT_FILE} \
127 | --tlsRootCertFiles ${ORG2_TLS_ROOTCERT_FILE} \
128 | --tlsRootCertFiles ${ORG2_TLS_ROOTCERT_FILE}
129 |
130 | }
131 |
132 | function upgradeCC() {
133 | echo "Upgrading smart contract on iot-channel"
134 | docker exec \
135 | -e CORE_PEER_LOCALMSPID=Org1MSP \
136 | -e CORE_PEER_MSPCONFIGPATH=${ORG1_MSPCONFIGPATH} \
137 | $CLI \
138 | peer chaincode upgrade \
139 | -o orderer.fabric-iot.edu:7050 \
140 | -C iot-channel \
141 | -n "$CC_NAME" \
142 | -l "$CC_RUNTIME_LANGUAGE" \
143 | -v "$CC_VERSION" \
144 | -c '{"Args":[]}' \
145 | -P "AND('Org1MSP.member','Org2MSP.member')" \
146 | --tls \
147 | --cafile ${ORDERER_TLS_ROOTCERT_FILE} \
148 | --peerAddresses peer0.org1.fabric-iot.edu:7051 \
149 | --tlsRootCertFiles ${ORG1_TLS_ROOTCERT_FILE}
150 |
151 | echo "Waiting for instantiation request to be committed ..."
152 | sleep 15
153 | }
154 |
155 | # set -x
156 |
157 | function deployCC(){
158 | # install cc
159 | installCC 1 0 7051
160 | installCC 1 1 8051
161 | installCC 2 0 9051
162 | installCC 2 1 10051
163 | }
164 |
165 | # init
166 | if [ $ACTION = 'install' ]; then
167 | deployCC
168 | initCC
169 | invokeCC # 调用 Synchro 方法,为 chaincode 背书
170 | elif [ $ACTION = 'upgrade' ]; then
171 | deployCC
172 | upgradeCC
173 | invokeCC # 调用 Synchro 方法,为 chaincode 背书
174 | elif [ $ACTION = 'invoke' ]; then
175 | invokeCC
176 | fi
177 | # try
178 | # if [ ! $CC_INVOKE_FUNC_NAME = '' ]; then
179 | # invokeCC
180 | # fi
181 |
182 | echo "done"
183 |
184 | # set +x
--------------------------------------------------------------------------------
/network/ccp-generate.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | . env.sh
4 |
5 | function one_line_pem {
6 | echo "`awk 'NF {sub(/\\n/, ""); printf "%s\\\\\\\n",$0;}' $1`"
7 | }
8 |
9 | function json_ccp {
10 | local PP=$(one_line_pem $5)
11 | local CP=$(one_line_pem $6)
12 | sed -e "s/\${ORG}/$1/" \
13 | -e "s/\${P0PORT}/$2/" \
14 | -e "s/\${P1PORT}/$3/" \
15 | -e "s/\${CAPORT}/$4/" \
16 | -e "s#\${PEERPEM}#$PP#" \
17 | -e "s#\${CAPEM}#$CP#" \
18 | $CONN_CONF_PATH/ccp-template.json
19 | }
20 |
21 | function yaml_ccp {
22 | local PP=$(one_line_pem $5)
23 | local CP=$(one_line_pem $6)
24 | sed -e "s/\${ORG}/$1/" \
25 | -e "s/\${P0PORT}/$2/" \
26 | -e "s/\${P1PORT}/$3/" \
27 | -e "s/\${CAPORT}/$4/" \
28 | -e "s#\${PEERPEM}#$PP#" \
29 | -e "s#\${CAPEM}#$CP#" \
30 | $CONN_CONF_PATH/ccp-template.yaml | sed -e $'s/\\\\n/\\\n /g'
31 | }
32 |
33 | ORG=1
34 | P0PORT=7051
35 | P1PORT=8051
36 | CAPORT=7054
37 | PEERPEM=crypto-config/peerOrganizations/org1.fabric-iot.edu/tlsca/tlsca.org1.fabric-iot.edu-cert.pem
38 | CAPEM=crypto-config/peerOrganizations/org1.fabric-iot.edu/ca/ca.org1.fabric-iot.edu-cert.pem
39 |
40 | echo "$(json_ccp $ORG $P0PORT $P1PORT $CAPORT $PEERPEM $CAPEM)" > $CONN_CONF_PATH/connection-org1.json
41 | echo "$(yaml_ccp $ORG $P0PORT $P1PORT $CAPORT $PEERPEM $CAPEM)" > $CONN_CONF_PATH/connection-org1.yaml
42 |
43 | ORG=2
44 | P0PORT=9051
45 | P1PORT=10051
46 | CAPORT=8054
47 | PEERPEM=crypto-config/peerOrganizations/org2.fabric-iot.edu/tlsca/tlsca.org2.fabric-iot.edu-cert.pem
48 | CAPEM=crypto-config/peerOrganizations/org2.fabric-iot.edu/ca/ca.org2.fabric-iot.edu-cert.pem
49 |
50 | echo "$(json_ccp $ORG $P0PORT $P1PORT $CAPORT $PEERPEM $CAPEM)" > $CONN_CONF_PATH/connection-org2.json
51 | echo "$(yaml_ccp $ORG $P0PORT $P1PORT $CAPORT $PEERPEM $CAPEM)" > $CONN_CONF_PATH/connection-org2.yaml
52 |
--------------------------------------------------------------------------------
/network/channel-artifacts/readme.md:
--------------------------------------------------------------------------------
1 | **this folder contains certs**
--------------------------------------------------------------------------------
/network/clear-docker.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | # 默认筛选关键词
4 | key=iot
5 | # 输入关键词
6 | if [ -n "$1" ] ;then
7 | key="$1"
8 | fi
9 |
10 | # 取得所有符合条件的容器名
11 | containers=$(docker ps -a |grep $key |awk '{print $1}')
12 | if [ ! -n "$containers" ] ;then
13 | echo "no containers"
14 | else
15 | # 删除停止的容器
16 | docker rm $containers
17 | fi
18 |
19 | # 取得所有符合条件的镜像名
20 | imgs=$(docker images |grep $key |awk '{print $3}')
21 | if [ ! -n "$imgs" ] ;then
22 | echo "no imgs"
23 | else
24 | # 删除镜像
25 | docker rmi -f $imgs
26 | fi
27 |
--------------------------------------------------------------------------------
/network/compose-files/base/docker-compose-base.yaml:
--------------------------------------------------------------------------------
1 | # Copyright IBM Corp. All Rights Reserved.
2 | #
3 | # SPDX-License-Identifier: Apache-2.0
4 | #
5 |
6 | version: '2'
7 |
8 | services:
9 |
10 | orderer.fabric-iot.edu:
11 | container_name: orderer.fabric-iot.edu
12 | extends:
13 | file: peer-base.yaml
14 | service: orderer-base
15 | volumes:
16 | - ../../channel-artifacts/genesis.block:/var/hyperledger/orderer/orderer.genesis.block
17 | - ../../crypto-config/ordererOrganizations/fabric-iot.edu/orderers/orderer.fabric-iot.edu/msp:/var/hyperledger/orderer/msp
18 | - ../../crypto-config/ordererOrganizations/fabric-iot.edu/orderers/orderer.fabric-iot.edu/tls/:/var/hyperledger/orderer/tls
19 | - orderer.fabric-iot.edu:/var/hyperledger/production/orderer
20 | ports:
21 | - 7050:7050
22 |
23 | peer0.org1.fabric-iot.edu:
24 | container_name: peer0.org1.fabric-iot.edu
25 | extends:
26 | file: peer-base.yaml
27 | service: peer-base
28 | environment:
29 | - CORE_PEER_ID=peer0.org1.fabric-iot.edu
30 | - CORE_PEER_ADDRESS=peer0.org1.fabric-iot.edu:7051
31 | - CORE_PEER_LISTENADDRESS=0.0.0.0:7051
32 | - CORE_PEER_CHAINCODEADDRESS=peer0.org1.fabric-iot.edu:7052
33 | - CORE_PEER_CHAINCODELISTENADDRESS=0.0.0.0:7052
34 | - CORE_PEER_GOSSIP_BOOTSTRAP=peer1.org1.fabric-iot.edu:8051
35 | - CORE_PEER_GOSSIP_EXTERNALENDPOINT=peer0.org1.fabric-iot.edu:7051
36 | - CORE_PEER_LOCALMSPID=Org1MSP
37 | volumes:
38 | - /var/run/:/host/var/run/
39 | - ../../crypto-config/peerOrganizations/org1.fabric-iot.edu/peers/peer0.org1.fabric-iot.edu/msp:/etc/hyperledger/fabric/msp
40 | - ../../crypto-config/peerOrganizations/org1.fabric-iot.edu/peers/peer0.org1.fabric-iot.edu/tls:/etc/hyperledger/fabric/tls
41 | - peer0.org1.fabric-iot.edu:/var/hyperledger/production
42 | ports:
43 | - 7051:7051
44 |
45 | peer1.org1.fabric-iot.edu:
46 | container_name: peer1.org1.fabric-iot.edu
47 | extends:
48 | file: peer-base.yaml
49 | service: peer-base
50 | environment:
51 | - CORE_PEER_ID=peer1.org1.fabric-iot.edu
52 | - CORE_PEER_ADDRESS=peer1.org1.fabric-iot.edu:8051
53 | - CORE_PEER_LISTENADDRESS=0.0.0.0:8051
54 | - CORE_PEER_CHAINCODEADDRESS=peer1.org1.fabric-iot.edu:8052
55 | - CORE_PEER_CHAINCODELISTENADDRESS=0.0.0.0:8052
56 | - CORE_PEER_GOSSIP_EXTERNALENDPOINT=peer1.org1.fabric-iot.edu:8051
57 | - CORE_PEER_GOSSIP_BOOTSTRAP=peer0.org1.fabric-iot.edu:7051
58 | - CORE_PEER_LOCALMSPID=Org1MSP
59 | volumes:
60 | - /var/run/:/host/var/run/
61 | - ../../crypto-config/peerOrganizations/org1.fabric-iot.edu/peers/peer1.org1.fabric-iot.edu/msp:/etc/hyperledger/fabric/msp
62 | - ../../crypto-config/peerOrganizations/org1.fabric-iot.edu/peers/peer1.org1.fabric-iot.edu/tls:/etc/hyperledger/fabric/tls
63 | - peer1.org1.fabric-iot.edu:/var/hyperledger/production
64 |
65 | ports:
66 | - 8051:8051
67 |
68 | peer0.org2.fabric-iot.edu:
69 | container_name: peer0.org2.fabric-iot.edu
70 | extends:
71 | file: peer-base.yaml
72 | service: peer-base
73 | environment:
74 | - CORE_PEER_ID=peer0.org2.fabric-iot.edu
75 | - CORE_PEER_ADDRESS=peer0.org2.fabric-iot.edu:9051
76 | - CORE_PEER_LISTENADDRESS=0.0.0.0:9051
77 | - CORE_PEER_CHAINCODEADDRESS=peer0.org2.fabric-iot.edu:9052
78 | - CORE_PEER_CHAINCODELISTENADDRESS=0.0.0.0:9052
79 | - CORE_PEER_GOSSIP_EXTERNALENDPOINT=peer0.org2.fabric-iot.edu:9051
80 | - CORE_PEER_GOSSIP_BOOTSTRAP=peer1.org2.fabric-iot.edu:10051
81 | - CORE_PEER_LOCALMSPID=Org2MSP
82 | volumes:
83 | - /var/run/:/host/var/run/
84 | - ../../crypto-config/peerOrganizations/org2.fabric-iot.edu/peers/peer0.org2.fabric-iot.edu/msp:/etc/hyperledger/fabric/msp
85 | - ../../crypto-config/peerOrganizations/org2.fabric-iot.edu/peers/peer0.org2.fabric-iot.edu/tls:/etc/hyperledger/fabric/tls
86 | - peer0.org2.fabric-iot.edu:/var/hyperledger/production
87 | ports:
88 | - 9051:9051
89 |
90 | peer1.org2.fabric-iot.edu:
91 | container_name: peer1.org2.fabric-iot.edu
92 | extends:
93 | file: peer-base.yaml
94 | service: peer-base
95 | environment:
96 | - CORE_PEER_ID=peer1.org2.fabric-iot.edu
97 | - CORE_PEER_ADDRESS=peer1.org2.fabric-iot.edu:10051
98 | - CORE_PEER_LISTENADDRESS=0.0.0.0:10051
99 | - CORE_PEER_CHAINCODEADDRESS=peer1.org2.fabric-iot.edu:10052
100 | - CORE_PEER_CHAINCODELISTENADDRESS=0.0.0.0:10052
101 | - CORE_PEER_GOSSIP_EXTERNALENDPOINT=peer1.org2.fabric-iot.edu:10051
102 | - CORE_PEER_GOSSIP_BOOTSTRAP=peer0.org2.fabric-iot.edu:9051
103 | - CORE_PEER_LOCALMSPID=Org2MSP
104 | volumes:
105 | - /var/run/:/host/var/run/
106 | - ../../crypto-config/peerOrganizations/org2.fabric-iot.edu/peers/peer1.org2.fabric-iot.edu/msp:/etc/hyperledger/fabric/msp
107 | - ../../crypto-config/peerOrganizations/org2.fabric-iot.edu/peers/peer1.org2.fabric-iot.edu/tls:/etc/hyperledger/fabric/tls
108 | - peer1.org2.fabric-iot.edu:/var/hyperledger/production
109 | ports:
110 | - 10051:10051
111 |
--------------------------------------------------------------------------------
/network/compose-files/base/peer-base.yaml:
--------------------------------------------------------------------------------
1 | # Copyright IBM Corp. All Rights Reserved.
2 | #
3 | # SPDX-License-Identifier: Apache-2.0
4 | #
5 |
6 | version: '2'
7 |
8 | services:
9 | peer-base:
10 | image: hyperledger/fabric-peer:$IMAGE_TAG
11 | environment:
12 | - CORE_VM_ENDPOINT=unix:///host/var/run/docker.sock
13 | # the following setting starts chaincode containers on the same
14 | # bridge network as the peers
15 | # https://docs.docker.com/compose/networking/
16 | - CORE_VM_DOCKER_HOSTCONFIG_NETWORKMODE=${COMPOSE_PROJECT_NAME}_bc_net
17 | - FABRIC_LOGGING_SPEC=INFO
18 | #- FABRIC_LOGGING_SPEC=DEBUG
19 | - CORE_PEER_TLS_ENABLED=true
20 | - CORE_PEER_GOSSIP_USELEADERELECTION=true
21 | - CORE_PEER_GOSSIP_ORGLEADER=false
22 | - CORE_PEER_PROFILE_ENABLED=true
23 | - CORE_PEER_TLS_CERT_FILE=/etc/hyperledger/fabric/tls/server.crt
24 | - CORE_PEER_TLS_KEY_FILE=/etc/hyperledger/fabric/tls/server.key
25 | - CORE_PEER_TLS_ROOTCERT_FILE=/etc/hyperledger/fabric/tls/ca.crt
26 | working_dir: /opt/gopath/src/github.com/hyperledger/fabric/peer
27 | command: peer node start
28 |
29 | orderer-base:
30 | image: hyperledger/fabric-orderer:$IMAGE_TAG
31 | environment:
32 | - FABRIC_LOGGING_SPEC=INFO
33 | - ORDERER_GENERAL_LISTENADDRESS=0.0.0.0
34 | - ORDERER_GENERAL_GENESISMETHOD=file
35 | - ORDERER_GENERAL_GENESISFILE=/var/hyperledger/orderer/orderer.genesis.block
36 | - ORDERER_GENERAL_LOCALMSPID=OrdererMSP
37 | - ORDERER_GENERAL_LOCALMSPDIR=/var/hyperledger/orderer/msp
38 | # enabled TLS
39 | - ORDERER_GENERAL_TLS_ENABLED=true
40 | - ORDERER_GENERAL_TLS_PRIVATEKEY=/var/hyperledger/orderer/tls/server.key
41 | - ORDERER_GENERAL_TLS_CERTIFICATE=/var/hyperledger/orderer/tls/server.crt
42 | - ORDERER_GENERAL_TLS_ROOTCAS=[/var/hyperledger/orderer/tls/ca.crt]
43 | - ORDERER_KAFKA_TOPIC_REPLICATIONFACTOR=1
44 | - ORDERER_KAFKA_VERBOSE=true
45 | - ORDERER_GENERAL_CLUSTER_CLIENTCERTIFICATE=/var/hyperledger/orderer/tls/server.crt
46 | - ORDERER_GENERAL_CLUSTER_CLIENTPRIVATEKEY=/var/hyperledger/orderer/tls/server.key
47 | - ORDERER_GENERAL_CLUSTER_ROOTCAS=[/var/hyperledger/orderer/tls/ca.crt]
48 | working_dir: /opt/gopath/src/github.com/hyperledger/fabric
49 | command: orderer
50 |
51 |
--------------------------------------------------------------------------------
/network/compose-files/docker-compose-ca.yaml:
--------------------------------------------------------------------------------
1 | # Copyright IBM Corp. All Rights Reserved.
2 | #
3 | # SPDX-License-Identifier: Apache-2.0
4 | #
5 |
6 | version: '2'
7 |
8 | networks:
9 | bc_net:
10 |
11 | services:
12 | ca0:
13 | image: hyperledger/fabric-ca:$IMAGE_TAG
14 | environment:
15 | - FABRIC_CA_HOME=/etc/hyperledger/fabric-ca-server
16 | - FABRIC_CA_SERVER_CA_NAME=ca-org1
17 | - FABRIC_CA_SERVER_TLS_ENABLED=true
18 | - FABRIC_CA_SERVER_TLS_CERTFILE=/etc/hyperledger/fabric-ca-server-config/ca.org1.fabric-iot.edu-cert.pem
19 | - FABRIC_CA_SERVER_TLS_KEYFILE=/etc/hyperledger/fabric-ca-server-config/${CA1_PRIVATE_KEY}
20 | - FABRIC_CA_SERVER_PORT=7054
21 | ports:
22 | - "7054:7054"
23 | command: sh -c 'fabric-ca-server start --ca.certfile /etc/hyperledger/fabric-ca-server-config/ca.org1.fabric-iot.edu-cert.pem --ca.keyfile /etc/hyperledger/fabric-ca-server-config/${CA1_PRIVATE_KEY} -b admin:adminpw -d'
24 | volumes:
25 | - ./../crypto-config/peerOrganizations/org1.fabric-iot.edu/ca/:/etc/hyperledger/fabric-ca-server-config
26 | container_name: ca_peerOrg1
27 | networks:
28 | - bc_net
29 |
30 | ca1:
31 | image: hyperledger/fabric-ca:$IMAGE_TAG
32 | environment:
33 | - FABRIC_CA_HOME=/etc/hyperledger/fabric-ca-server
34 | - FABRIC_CA_SERVER_CA_NAME=ca-org2
35 | - FABRIC_CA_SERVER_TLS_ENABLED=true
36 | - FABRIC_CA_SERVER_TLS_CERTFILE=/etc/hyperledger/fabric-ca-server-config/ca.org2.fabric-iot.edu-cert.pem
37 | - FABRIC_CA_SERVER_TLS_KEYFILE=/etc/hyperledger/fabric-ca-server-config/${CA2_PRIVATE_KEY}
38 | - FABRIC_CA_SERVER_PORT=8054
39 | ports:
40 | - "8054:8054"
41 | command: sh -c 'fabric-ca-server start --ca.certfile /etc/hyperledger/fabric-ca-server-config/ca.org2.fabric-iot.edu-cert.pem --ca.keyfile /etc/hyperledger/fabric-ca-server-config/${CA2_PRIVATE_KEY} -b admin:adminpw -d'
42 | volumes:
43 | - ./../crypto-config/peerOrganizations/org2.fabric-iot.edu/ca/:/etc/hyperledger/fabric-ca-server-config
44 | container_name: ca_peerOrg2
45 | networks:
46 | - bc_net
--------------------------------------------------------------------------------
/network/compose-files/docker-compose-cli.yaml:
--------------------------------------------------------------------------------
1 | # Copyright IBM Corp. All Rights Reserved.
2 | #
3 | # SPDX-License-Identifier: Apache-2.0
4 | #
5 |
6 | version: '2'
7 |
8 | volumes:
9 | orderer.fabric-iot.edu:
10 | peer0.org1.fabric-iot.edu:
11 | peer1.org1.fabric-iot.edu:
12 | peer0.org2.fabric-iot.edu:
13 | peer1.org2.fabric-iot.edu:
14 |
15 | networks:
16 | bc_net:
17 |
18 | services:
19 |
20 | orderer.fabric-iot.edu:
21 | extends:
22 | file: base/docker-compose-base.yaml
23 | service: orderer.fabric-iot.edu
24 | container_name: orderer.fabric-iot.edu
25 | networks:
26 | - bc_net
27 |
28 | peer0.org1.fabric-iot.edu:
29 | container_name: peer0.org1.fabric-iot.edu
30 | extends:
31 | file: base/docker-compose-base.yaml
32 | service: peer0.org1.fabric-iot.edu
33 | networks:
34 | - bc_net
35 |
36 | peer1.org1.fabric-iot.edu:
37 | container_name: peer1.org1.fabric-iot.edu
38 | extends:
39 | file: base/docker-compose-base.yaml
40 | service: peer1.org1.fabric-iot.edu
41 | networks:
42 | - bc_net
43 |
44 | peer0.org2.fabric-iot.edu:
45 | container_name: peer0.org2.fabric-iot.edu
46 | extends:
47 | file: base/docker-compose-base.yaml
48 | service: peer0.org2.fabric-iot.edu
49 | networks:
50 | - bc_net
51 |
52 | peer1.org2.fabric-iot.edu:
53 | container_name: peer1.org2.fabric-iot.edu
54 | extends:
55 | file: base/docker-compose-base.yaml
56 | service: peer1.org2.fabric-iot.edu
57 | networks:
58 | - bc_net
59 |
60 | cli:
61 | container_name: cli
62 | image: hyperledger/fabric-tools:$IMAGE_TAG
63 | tty: true
64 | stdin_open: true
65 | environment:
66 | - SYS_CHANNEL=$SYS_CHANNEL
67 | - GOPATH=/opt/gopath
68 | - CORE_VM_ENDPOINT=unix:///host/var/run/docker.sock
69 | #- FABRIC_LOGGING_SPEC=DEBUG
70 | - FABRIC_LOGGING_SPEC=INFO
71 | - CORE_PEER_ID=cli
72 | - CORE_PEER_ADDRESS=peer0.org1.fabric-iot.edu:7051
73 | - CORE_PEER_LOCALMSPID=Org1MSP
74 | - CORE_PEER_TLS_ENABLED=true
75 | - CORE_PEER_TLS_CERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.fabric-iot.edu/peers/peer0.org1.fabric-iot.edu/tls/server.crt
76 | - CORE_PEER_TLS_KEY_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.fabric-iot.edu/peers/peer0.org1.fabric-iot.edu/tls/server.key
77 | - CORE_PEER_TLS_ROOTCERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.fabric-iot.edu/peers/peer0.org1.fabric-iot.edu/tls/ca.crt
78 | - CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.fabric-iot.edu/users/Admin@org1.fabric-iot.edu/msp
79 | working_dir: /opt/gopath/src/github.com/hyperledger/fabric/peer
80 | command: /bin/bash
81 | volumes:
82 | - /var/run/:/host/var/run/
83 | - ./../../chaincode/:/opt/gopath/src/github.com/newham/fabric-iot/chaincode
84 | - ./../crypto-config:/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/
85 | - ./../scripts:/opt/gopath/src/github.com/hyperledger/fabric/peer/scripts/
86 | - ./../channel-artifacts:/opt/gopath/src/github.com/hyperledger/fabric/peer/channel-artifacts
87 | depends_on:
88 | - orderer.fabric-iot.edu
89 | - peer0.org1.fabric-iot.edu
90 | - peer1.org1.fabric-iot.edu
91 | - peer0.org2.fabric-iot.edu
92 | - peer1.org2.fabric-iot.edu
93 | networks:
94 | - bc_net
95 |
--------------------------------------------------------------------------------
/network/compose-files/docker-compose-couch.yaml:
--------------------------------------------------------------------------------
1 | # Copyright IBM Corp. All Rights Reserved.
2 | #
3 | # SPDX-License-Identifier: Apache-2.0
4 | #
5 |
6 | version: '2'
7 |
8 | networks:
9 | bc_net:
10 |
11 | services:
12 | couchdb0:
13 | container_name: couchdb0
14 | image: hyperledger/fabric-couchdb
15 | # Populate the COUCHDB_USER and COUCHDB_PASSWORD to set an admin user and password
16 | # for CouchDB. This will prevent CouchDB from operating in an "Admin Party" mode.
17 | environment:
18 | - COUCHDB_USER=
19 | - COUCHDB_PASSWORD=
20 | # Comment/Uncomment the port mapping if you want to hide/expose the CouchDB service,
21 | # for example map it to utilize Fauxton User Interface in dev environments.
22 | ports:
23 | - "5984:5984"
24 | networks:
25 | - bc_net
26 |
27 | peer0.org1.fabric-iot.edu:
28 | environment:
29 | - CORE_LEDGER_STATE_STATEDATABASE=CouchDB
30 | - CORE_LEDGER_STATE_COUCHDBCONFIG_COUCHDBADDRESS=couchdb0:5984
31 | # The CORE_LEDGER_STATE_COUCHDBCONFIG_USERNAME and CORE_LEDGER_STATE_COUCHDBCONFIG_PASSWORD
32 | # provide the credentials for ledger to connect to CouchDB. The username and password must
33 | # match the username and password set for the associated CouchDB.
34 | - CORE_LEDGER_STATE_COUCHDBCONFIG_USERNAME=
35 | - CORE_LEDGER_STATE_COUCHDBCONFIG_PASSWORD=
36 | depends_on:
37 | - couchdb0
38 |
39 | couchdb1:
40 | container_name: couchdb1
41 | image: hyperledger/fabric-couchdb
42 | # Populate the COUCHDB_USER and COUCHDB_PASSWORD to set an admin user and password
43 | # for CouchDB. This will prevent CouchDB from operating in an "Admin Party" mode.
44 | environment:
45 | - COUCHDB_USER=
46 | - COUCHDB_PASSWORD=
47 | # Comment/Uncomment the port mapping if you want to hide/expose the CouchDB service,
48 | # for example map it to utilize Fauxton User Interface in dev environments.
49 | ports:
50 | - "6984:5984"
51 | networks:
52 | - bc_net
53 |
54 | peer1.org1.fabric-iot.edu:
55 | environment:
56 | - CORE_LEDGER_STATE_STATEDATABASE=CouchDB
57 | - CORE_LEDGER_STATE_COUCHDBCONFIG_COUCHDBADDRESS=couchdb1:5984
58 | # The CORE_LEDGER_STATE_COUCHDBCONFIG_USERNAME and CORE_LEDGER_STATE_COUCHDBCONFIG_PASSWORD
59 | # provide the credentials for ledger to connect to CouchDB. The username and password must
60 | # match the username and password set for the associated CouchDB.
61 | - CORE_LEDGER_STATE_COUCHDBCONFIG_USERNAME=
62 | - CORE_LEDGER_STATE_COUCHDBCONFIG_PASSWORD=
63 | depends_on:
64 | - couchdb1
65 |
66 | couchdb2:
67 | container_name: couchdb2
68 | image: hyperledger/fabric-couchdb
69 | # Populate the COUCHDB_USER and COUCHDB_PASSWORD to set an admin user and password
70 | # for CouchDB. This will prevent CouchDB from operating in an "Admin Party" mode.
71 | environment:
72 | - COUCHDB_USER=
73 | - COUCHDB_PASSWORD=
74 | # Comment/Uncomment the port mapping if you want to hide/expose the CouchDB service,
75 | # for example map it to utilize Fauxton User Interface in dev environments.
76 | ports:
77 | - "7984:5984"
78 | networks:
79 | - bc_net
80 |
81 | peer0.org2.fabric-iot.edu:
82 | environment:
83 | - CORE_LEDGER_STATE_STATEDATABASE=CouchDB
84 | - CORE_LEDGER_STATE_COUCHDBCONFIG_COUCHDBADDRESS=couchdb2:5984
85 | # The CORE_LEDGER_STATE_COUCHDBCONFIG_USERNAME and CORE_LEDGER_STATE_COUCHDBCONFIG_PASSWORD
86 | # provide the credentials for ledger to connect to CouchDB. The username and password must
87 | # match the username and password set for the associated CouchDB.
88 | - CORE_LEDGER_STATE_COUCHDBCONFIG_USERNAME=
89 | - CORE_LEDGER_STATE_COUCHDBCONFIG_PASSWORD=
90 | depends_on:
91 | - couchdb2
92 |
93 | couchdb3:
94 | container_name: couchdb3
95 | image: hyperledger/fabric-couchdb
96 | # Populate the COUCHDB_USER and COUCHDB_PASSWORD to set an admin user and password
97 | # for CouchDB. This will prevent CouchDB from operating in an "Admin Party" mode.
98 | environment:
99 | - COUCHDB_USER=
100 | - COUCHDB_PASSWORD=
101 | # Comment/Uncomment the port mapping if you want to hide/expose the CouchDB service,
102 | # for example map it to utilize Fauxton User Interface in dev environments.
103 | ports:
104 | - "8984:5984"
105 | networks:
106 | - bc_net
107 |
108 | peer1.org2.fabric-iot.edu:
109 | environment:
110 | - CORE_LEDGER_STATE_STATEDATABASE=CouchDB
111 | - CORE_LEDGER_STATE_COUCHDBCONFIG_COUCHDBADDRESS=couchdb3:5984
112 | # The CORE_LEDGER_STATE_COUCHDBCONFIG_USERNAME and CORE_LEDGER_STATE_COUCHDBCONFIG_PASSWORD
113 | # provide the credentials for ledger to connect to CouchDB. The username and password must
114 | # match the username and password set for the associated CouchDB.
115 | - CORE_LEDGER_STATE_COUCHDBCONFIG_USERNAME=
116 | - CORE_LEDGER_STATE_COUCHDBCONFIG_PASSWORD=
117 | depends_on:
118 | - couchdb3
119 |
--------------------------------------------------------------------------------
/network/compose-files/docker-compose-e2e-template.yaml:
--------------------------------------------------------------------------------
1 | # Copyright IBM Corp. All Rights Reserved.
2 | #
3 | # SPDX-License-Identifier: Apache-2.0
4 | #
5 |
6 | version: '2'
7 |
8 | volumes:
9 | orderer.fabric-iot.edu:
10 | peer0.org1.fabric-iot.edu:
11 | peer1.org1.fabric-iot.edu:
12 | peer0.org2.fabric-iot.edu:
13 | peer1.org2.fabric-iot.edu:
14 |
15 | networks:
16 | bc_net:
17 | services:
18 | ca0:
19 | image: hyperledger/fabric-ca:$IMAGE_TAG
20 | environment:
21 | - FABRIC_CA_HOME=/etc/hyperledger/fabric-ca-server
22 | - FABRIC_CA_SERVER_CA_NAME=ca-org1
23 | - FABRIC_CA_SERVER_TLS_ENABLED=true
24 | - FABRIC_CA_SERVER_TLS_CERTFILE=/etc/hyperledger/fabric-ca-server-config/ca.org1.fabric-iot.edu-cert.pem
25 | - FABRIC_CA_SERVER_TLS_KEYFILE=/etc/hyperledger/fabric-ca-server-config/CA1_PRIVATE_KEY
26 | ports:
27 | - "7054:7054"
28 | command: sh -c 'fabric-ca-server start --ca.certfile /etc/hyperledger/fabric-ca-server-config/ca.org1.fabric-iot.edu-cert.pem --ca.keyfile /etc/hyperledger/fabric-ca-server-config/CA1_PRIVATE_KEY -b admin:adminpw -d'
29 | volumes:
30 | - ./../crypto-config/peerOrganizations/org1.fabric-iot.edu/ca/:/etc/hyperledger/fabric-ca-server-config
31 | container_name: ca_peerOrg1
32 | networks:
33 | - bc_net
34 |
35 | ca1:
36 | image: hyperledger/fabric-ca:$IMAGE_TAG
37 | environment:
38 | - FABRIC_CA_HOME=/etc/hyperledger/fabric-ca-server
39 | - FABRIC_CA_SERVER_CA_NAME=ca-org2
40 | - FABRIC_CA_SERVER_TLS_ENABLED=true
41 | - FABRIC_CA_SERVER_TLS_CERTFILE=/etc/hyperledger/fabric-ca-server-config/ca.org2.fabric-iot.edu-cert.pem
42 | - FABRIC_CA_SERVER_TLS_KEYFILE=/etc/hyperledger/fabric-ca-server-config/CA2_PRIVATE_KEY
43 | ports:
44 | - "8054:7054"
45 | command: sh -c 'fabric-ca-server start --ca.certfile /etc/hyperledger/fabric-ca-server-config/ca.org2.fabric-iot.edu-cert.pem --ca.keyfile /etc/hyperledger/fabric-ca-server-config/CA2_PRIVATE_KEY -b admin:adminpw -d'
46 | volumes:
47 | - ./../crypto-config/peerOrganizations/org2.fabric-iot.edu/ca/:/etc/hyperledger/fabric-ca-server-config
48 | container_name: ca_peerOrg2
49 | networks:
50 | - bc_net
51 |
52 | orderer.fabric-iot.edu:
53 | extends:
54 | file: base/docker-compose-base.yaml
55 | service: orderer.fabric-iot.edu
56 | container_name: orderer.fabric-iot.edu
57 | networks:
58 | - bc_net
59 |
60 | peer0.org1.fabric-iot.edu:
61 | container_name: peer0.org1.fabric-iot.edu
62 | extends:
63 | file: base/docker-compose-base.yaml
64 | service: peer0.org1.fabric-iot.edu
65 | networks:
66 | - bc_net
67 |
68 | peer1.org1.fabric-iot.edu:
69 | container_name: peer1.org1.fabric-iot.edu
70 | extends:
71 | file: base/docker-compose-base.yaml
72 | service: peer1.org1.fabric-iot.edu
73 | networks:
74 | - bc_net
75 |
76 | peer0.org2.fabric-iot.edu:
77 | container_name: peer0.org2.fabric-iot.edu
78 | extends:
79 | file: base/docker-compose-base.yaml
80 | service: peer0.org2.fabric-iot.edu
81 | networks:
82 | - bc_net
83 |
84 | peer1.org2.fabric-iot.edu:
85 | container_name: peer1.org2.fabric-iot.edu
86 | extends:
87 | file: base/docker-compose-base.yaml
88 | service: peer1.org2.fabric-iot.edu
89 | networks:
90 | - bc_net
91 |
--------------------------------------------------------------------------------
/network/compose-files/docker-compose-kafka.yaml:
--------------------------------------------------------------------------------
1 | # Copyright IBM Corp. All Rights Reserved.
2 | #
3 | # SPDX-License-Identifier: Apache-2.0
4 | #
5 |
6 |
7 | # NOTE: This is not the way a Kafka cluster would normally be deployed in production, as it is not secure
8 | # and is not fault tolerant. This example is a toy deployment that is only meant to exercise the Kafka code path
9 | # of the ordering service.
10 |
11 | version: '2'
12 |
13 | networks:
14 | bc_net:
15 |
16 | services:
17 | zookeeper.fabric-iot.edu:
18 | container_name: zookeeper.fabric-iot.edu
19 | image: hyperledger/fabric-zookeeper:$IMAGE_TAG
20 | environment:
21 | ZOOKEEPER_CLIENT_PORT: 32181
22 | ZOOKEEPER_TICK_TIME: 2000
23 | networks:
24 | - bc_net
25 |
26 | kafka.fabric-iot.edu:
27 | container_name: kafka.fabric-iot.edu
28 | image: hyperledger/fabric-kafka:$IMAGE_TAG
29 | depends_on:
30 | - zookeeper.fabric-iot.edu
31 | environment:
32 | - KAFKA_BROKER_ID=1
33 | - KAFKA_ZOOKEEPER_CONNECT=zookeeper.fabric-iot.edu:2181
34 | - KAFKA_ADVERTISED_LISTENERS=PLAINTEXT://kafka.fabric-iot.edu:9092
35 | - KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR=1
36 | - KAFKA_MESSAGE_MAX_BYTES=1048576 # 1 * 1024 * 1024 B
37 | - KAFKA_REPLICA_FETCH_MAX_BYTES=1048576 # 1 * 1024 * 1024 B
38 | - KAFKA_UNCLEAN_LEADER_ELECTION_ENABLE=false
39 | - KAFKA_LOG_RETENTION_MS=-1
40 | - KAFKA_MIN_INSYNC_REPLICAS=1
41 | - KAFKA_DEFAULT_REPLICATION_FACTOR=1
42 | networks:
43 | - bc_net
44 |
--------------------------------------------------------------------------------
/network/configtx.yaml:
--------------------------------------------------------------------------------
1 | # Copyright IBM Corp. All Rights Reserved.
2 | #
3 | # SPDX-License-Identifier: Apache-2.0
4 | #
5 |
6 | ---
7 | ################################################################################
8 | #
9 | # Section: Organizations
10 | #
11 | # - This section defines the different organizational identities which will
12 | # be referenced later in the configuration.
13 | #
14 | ################################################################################
15 | Organizations:
16 |
17 | # SampleOrg defines an MSP using the sampleconfig. It should never be used
18 | # in production but may be used as a template for other definitions
19 | - &OrdererOrg
20 | # DefaultOrg defines the organization which is used in the sampleconfig
21 | # of the fabric.git development environment
22 | Name: OrdererOrg
23 |
24 | # ID to load the MSP definition as
25 | ID: OrdererMSP
26 |
27 | # MSPDir is the filesystem path which contains the MSP configuration
28 | MSPDir: crypto-config/ordererOrganizations/fabric-iot.edu/msp
29 |
30 | # Policies defines the set of policies at this level of the config tree
31 | # For organization policies, their canonical path is usually
32 | # /Channel///
33 | Policies:
34 | Readers:
35 | Type: Signature
36 | Rule: "OR('OrdererMSP.member')"
37 | Writers:
38 | Type: Signature
39 | Rule: "OR('OrdererMSP.member')"
40 | Admins:
41 | Type: Signature
42 | Rule: "OR('OrdererMSP.admin')"
43 |
44 | - &Org1
45 | # DefaultOrg defines the organization which is used in the sampleconfig
46 | # of the fabric.git development environment
47 | Name: Org1MSP
48 |
49 | # ID to load the MSP definition as
50 | ID: Org1MSP
51 |
52 | MSPDir: crypto-config/peerOrganizations/org1.fabric-iot.edu/msp
53 |
54 | # Policies defines the set of policies at this level of the config tree
55 | # For organization policies, their canonical path is usually
56 | # /Channel///
57 | Policies:
58 | Readers:
59 | Type: Signature
60 | Rule: "OR('Org1MSP.admin', 'Org1MSP.peer', 'Org1MSP.client')"
61 | Writers:
62 | Type: Signature
63 | Rule: "OR('Org1MSP.admin', 'Org1MSP.client')"
64 | Admins:
65 | Type: Signature
66 | Rule: "OR('Org1MSP.admin')"
67 |
68 | # leave this flag set to true.
69 | AnchorPeers:
70 | # AnchorPeers defines the location of peers which can be used
71 | # for cross org gossip communication. Note, this value is only
72 | # encoded in the genesis block in the Application section context
73 | - Host: peer0.org1.fabric-iot.edu
74 | Port: 7051
75 |
76 | - &Org2
77 | # DefaultOrg defines the organization which is used in the sampleconfig
78 | # of the fabric.git development environment
79 | Name: Org2MSP
80 |
81 | # ID to load the MSP definition as
82 | ID: Org2MSP
83 |
84 | MSPDir: crypto-config/peerOrganizations/org2.fabric-iot.edu/msp
85 |
86 | # Policies defines the set of policies at this level of the config tree
87 | # For organization policies, their canonical path is usually
88 | # /Channel///
89 | Policies:
90 | Readers:
91 | Type: Signature
92 | Rule: "OR('Org2MSP.admin', 'Org2MSP.peer', 'Org2MSP.client')"
93 | Writers:
94 | Type: Signature
95 | Rule: "OR('Org2MSP.admin', 'Org2MSP.client')"
96 | Admins:
97 | Type: Signature
98 | Rule: "OR('Org2MSP.admin')"
99 |
100 | AnchorPeers:
101 | # AnchorPeers defines the location of peers which can be used
102 | # for cross org gossip communication. Note, this value is only
103 | # encoded in the genesis block in the Application section context
104 | - Host: peer0.org2.fabric-iot.edu
105 | Port: 9051
106 |
107 | ################################################################################
108 | #
109 | # SECTION: Capabilities
110 | #
111 | # - This section defines the capabilities of fabric network. This is a new
112 | # concept as of v1.1.0 and should not be utilized in mixed networks with
113 | # v1.0.x peers and orderers. Capabilities define features which must be
114 | # present in a fabric binary for that binary to safely participate in the
115 | # fabric network. For instance, if a new MSP type is added, newer binaries
116 | # might recognize and validate the signatures from this type, while older
117 | # binaries without this support would be unable to validate those
118 | # transactions. This could lead to different versions of the fabric binaries
119 | # having different world states. Instead, defining a capability for a channel
120 | # informs those binaries without this capability that they must cease
121 | # processing transactions until they have been upgraded. For v1.0.x if any
122 | # capabilities are defined (including a map with all capabilities turned off)
123 | # then the v1.0.x peer will deliberately crash.
124 | #
125 | ################################################################################
126 | Capabilities:
127 | # Channel capabilities apply to both the orderers and the peers and must be
128 | # supported by both.
129 | # Set the value of the capability to true to require it.
130 | Channel: &ChannelCapabilities
131 | # V1.4.3 for Channel is a catchall flag for behavior which has been
132 | # determined to be desired for all orderers and peers running at the v1.4.3
133 | # level, but which would be incompatible with orderers and peers from
134 | # prior releases.
135 | # Prior to enabling V1.4.3 channel capabilities, ensure that all
136 | # orderers and peers on a channel are at v1.4.3 or later.
137 | V1_4_3: true
138 | # V1.3 for Channel enables the new non-backwards compatible
139 | # features and fixes of fabric v1.3
140 | V1_3: false
141 | # V1.1 for Channel enables the new non-backwards compatible
142 | # features and fixes of fabric v1.1
143 | V1_1: false
144 |
145 | # Orderer capabilities apply only to the orderers, and may be safely
146 | # used with prior release peers.
147 | # Set the value of the capability to true to require it.
148 | Orderer: &OrdererCapabilities
149 | # V1.4.2 for Orderer is a catchall flag for behavior which has been
150 | # determined to be desired for all orderers running at the v1.4.2
151 | # level, but which would be incompatible with orderers from prior releases.
152 | # Prior to enabling V1.4.2 orderer capabilities, ensure that all
153 | # orderers on a channel are at v1.4.2 or later.
154 | V1_4_2: true
155 | # V1.1 for Orderer enables the new non-backwards compatible
156 | # features and fixes of fabric v1.1
157 | V1_1: false
158 |
159 | # Application capabilities apply only to the peer network, and may be safely
160 | # used with prior release orderers.
161 | # Set the value of the capability to true to require it.
162 | Application: &ApplicationCapabilities
163 | # V1.4.2 for Application enables the new non-backwards compatible
164 | # features and fixes of fabric v1.4.2.
165 | V1_4_2: true
166 | # V1.3 for Application enables the new non-backwards compatible
167 | # features and fixes of fabric v1.3.
168 | V1_3: false
169 | # V1.2 for Application enables the new non-backwards compatible
170 | # features and fixes of fabric v1.2 (note, this need not be set if
171 | # later version capabilities are set)
172 | V1_2: false
173 | # V1.1 for Application enables the new non-backwards compatible
174 | # features and fixes of fabric v1.1 (note, this need not be set if
175 | # later version capabilities are set).
176 | V1_1: false
177 |
178 | ################################################################################
179 | #
180 | # SECTION: Application
181 | #
182 | # - This section defines the values to encode into a config transaction or
183 | # genesis block for application related parameters
184 | #
185 | ################################################################################
186 | Application: &ApplicationDefaults
187 |
188 | # Organizations is the list of orgs which are defined as participants on
189 | # the application side of the network
190 | Organizations:
191 |
192 | # Policies defines the set of policies at this level of the config tree
193 | # For Application policies, their canonical path is
194 | # /Channel/Application/
195 | Policies:
196 | Readers:
197 | Type: ImplicitMeta
198 | Rule: "ANY Readers"
199 | Writers:
200 | Type: ImplicitMeta
201 | Rule: "ANY Writers"
202 | Admins:
203 | Type: ImplicitMeta
204 | Rule: "MAJORITY Admins"
205 |
206 | Capabilities:
207 | <<: *ApplicationCapabilities
208 | ################################################################################
209 | #
210 | # SECTION: Orderer
211 | #
212 | # - This section defines the values to encode into a config transaction or
213 | # genesis block for orderer related parameters
214 | #
215 | ################################################################################
216 | Orderer: &OrdererDefaults
217 |
218 | # Orderer Type: The orderer implementation to start
219 | # Available types are "solo" and "kafka"
220 | OrdererType: solo
221 |
222 | Addresses:
223 | - orderer.fabric-iot.edu:7050
224 |
225 | # Batch Timeout: The amount of time to wait before creating a batch
226 | BatchTimeout: 2s
227 |
228 | # Batch Size: Controls the number of messages batched into a block
229 | BatchSize:
230 |
231 | # Max Message Count: The maximum number of messages to permit in a batch
232 | MaxMessageCount: 10
233 |
234 | # Absolute Max Bytes: The absolute maximum number of bytes allowed for
235 | # the serialized messages in a batch.
236 | AbsoluteMaxBytes: 99 MB
237 |
238 | # Preferred Max Bytes: The preferred maximum number of bytes allowed for
239 | # the serialized messages in a batch. A message larger than the preferred
240 | # max bytes will result in a batch larger than preferred max bytes.
241 | PreferredMaxBytes: 512 KB
242 |
243 | Kafka:
244 | # Brokers: A list of Kafka brokers to which the orderer connects
245 | # NOTE: Use IP:port notation
246 | Brokers:
247 | - 127.0.0.1:9092
248 |
249 | # Organizations is the list of orgs which are defined as participants on
250 | # the orderer side of the network
251 | Organizations:
252 |
253 | # Policies defines the set of policies at this level of the config tree
254 | # For Orderer policies, their canonical path is
255 | # /Channel/Orderer/
256 | Policies:
257 | Readers:
258 | Type: ImplicitMeta
259 | Rule: "ANY Readers"
260 | Writers:
261 | Type: ImplicitMeta
262 | Rule: "ANY Writers"
263 | Admins:
264 | Type: ImplicitMeta
265 | Rule: "MAJORITY Admins"
266 | # BlockValidation specifies what signatures must be included in the block
267 | # from the orderer for the peer to validate it.
268 | BlockValidation:
269 | Type: ImplicitMeta
270 | Rule: "ANY Writers"
271 |
272 | ################################################################################
273 | #
274 | # CHANNEL
275 | #
276 | # This section defines the values to encode into a config transaction or
277 | # genesis block for channel related parameters.
278 | #
279 | ################################################################################
280 | Channel: &ChannelDefaults
281 | # Policies defines the set of policies at this level of the config tree
282 | # For Channel policies, their canonical path is
283 | # /Channel/
284 | Policies:
285 | # Who may invoke the 'Deliver' API
286 | Readers:
287 | Type: ImplicitMeta
288 | Rule: "ANY Readers"
289 | # Who may invoke the 'Broadcast' API
290 | Writers:
291 | Type: ImplicitMeta
292 | Rule: "ANY Writers"
293 | # By default, who may modify elements at this config level
294 | Admins:
295 | Type: ImplicitMeta
296 | Rule: "MAJORITY Admins"
297 |
298 | # Capabilities describes the channel level capabilities, see the
299 | # dedicated Capabilities section elsewhere in this file for a full
300 | # description
301 | Capabilities:
302 | <<: *ChannelCapabilities
303 |
304 | ################################################################################
305 | #
306 | # Profile
307 | #
308 | # - Different configuration profiles may be encoded here to be specified
309 | # as parameters to the configtxgen tool
310 | #
311 | ################################################################################
312 | Profiles:
313 |
314 | TwoOrgsOrdererGenesis:
315 | <<: *ChannelDefaults
316 | Orderer:
317 | <<: *OrdererDefaults
318 | Organizations:
319 | - *OrdererOrg
320 | Capabilities:
321 | <<: *OrdererCapabilities
322 | Consortiums:
323 | SampleConsortium:
324 | Organizations:
325 | - *Org1
326 | - *Org2
327 | TwoOrgsChannel:
328 | Consortium: SampleConsortium
329 | <<: *ChannelDefaults
330 | Application:
331 | <<: *ApplicationDefaults
332 | Organizations:
333 | - *Org1
334 | - *Org2
335 | Capabilities:
336 | <<: *ApplicationCapabilities
337 |
338 | SampleDevModeKafka:
339 | <<: *ChannelDefaults
340 | Capabilities:
341 | <<: *ChannelCapabilities
342 | Orderer:
343 | <<: *OrdererDefaults
344 | OrdererType: kafka
345 | Kafka:
346 | Brokers:
347 | - kafka.fabric-iot.edu:9092
348 |
349 | Organizations:
350 | - *OrdererOrg
351 | Capabilities:
352 | <<: *OrdererCapabilities
353 | Application:
354 | <<: *ApplicationDefaults
355 | Organizations:
356 | - <<: *OrdererOrg
357 | Consortiums:
358 | SampleConsortium:
359 | Organizations:
360 | - *Org1
361 | - *Org2
362 |
363 | SampleMultiNodeEtcdRaft:
364 | <<: *ChannelDefaults
365 | Capabilities:
366 | <<: *ChannelCapabilities
367 | Orderer:
368 | <<: *OrdererDefaults
369 | OrdererType: etcdraft
370 | EtcdRaft:
371 | Consenters:
372 | - Host: orderer.fabric-iot.edu
373 | Port: 7050
374 | ClientTLSCert: crypto-config/ordererOrganizations/fabric-iot.edu/orderers/orderer.fabric-iot.edu/tls/server.crt
375 | ServerTLSCert: crypto-config/ordererOrganizations/fabric-iot.edu/orderers/orderer.fabric-iot.edu/tls/server.crt
376 | - Host: orderer2.fabric-iot.edu
377 | Port: 7050
378 | ClientTLSCert: crypto-config/ordererOrganizations/fabric-iot.edu/orderers/orderer2.fabric-iot.edu/tls/server.crt
379 | ServerTLSCert: crypto-config/ordererOrganizations/fabric-iot.edu/orderers/orderer2.fabric-iot.edu/tls/server.crt
380 | - Host: orderer3.fabric-iot.edu
381 | Port: 7050
382 | ClientTLSCert: crypto-config/ordererOrganizations/fabric-iot.edu/orderers/orderer3.fabric-iot.edu/tls/server.crt
383 | ServerTLSCert: crypto-config/ordererOrganizations/fabric-iot.edu/orderers/orderer3.fabric-iot.edu/tls/server.crt
384 | - Host: orderer4.fabric-iot.edu
385 | Port: 7050
386 | ClientTLSCert: crypto-config/ordererOrganizations/fabric-iot.edu/orderers/orderer4.fabric-iot.edu/tls/server.crt
387 | ServerTLSCert: crypto-config/ordererOrganizations/fabric-iot.edu/orderers/orderer4.fabric-iot.edu/tls/server.crt
388 | - Host: orderer5.fabric-iot.edu
389 | Port: 7050
390 | ClientTLSCert: crypto-config/ordererOrganizations/fabric-iot.edu/orderers/orderer5.fabric-iot.edu/tls/server.crt
391 | ServerTLSCert: crypto-config/ordererOrganizations/fabric-iot.edu/orderers/orderer5.fabric-iot.edu/tls/server.crt
392 | Addresses:
393 | - orderer.fabric-iot.edu:7050
394 | - orderer2.fabric-iot.edu:7050
395 | - orderer3.fabric-iot.edu:7050
396 | - orderer4.fabric-iot.edu:7050
397 | - orderer5.fabric-iot.edu:7050
398 |
399 | Organizations:
400 | - *OrdererOrg
401 | Capabilities:
402 | <<: *OrdererCapabilities
403 | Application:
404 | <<: *ApplicationDefaults
405 | Organizations:
406 | - <<: *OrdererOrg
407 | Consortiums:
408 | SampleConsortium:
409 | Organizations:
410 | - *Org1
411 | - *Org2
412 |
--------------------------------------------------------------------------------
/network/conn-conf/ccp-template.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "first-network-org${ORG}",
3 | "version": "1.0.0",
4 | "client": {
5 | "organization": "Org${ORG}",
6 | "connection": {
7 | "timeout": {
8 | "peer": {
9 | "endorser": "300"
10 | }
11 | }
12 | }
13 | },
14 | "organizations": {
15 | "Org${ORG}": {
16 | "mspid": "Org${ORG}MSP",
17 | "peers": [
18 | "peer0.org${ORG}.fabric-iot.edu",
19 | "peer1.org${ORG}.fabric-iot.edu"
20 | ],
21 | "certificateAuthorities": [
22 | "ca.org${ORG}.fabric-iot.edu"
23 | ]
24 | }
25 | },
26 | "peers": {
27 | "peer0.org${ORG}.fabric-iot.edu": {
28 | "url": "grpcs://localhost:${P0PORT}",
29 | "tlsCACerts": {
30 | "pem": "${PEERPEM}"
31 | },
32 | "grpcOptions": {
33 | "ssl-target-name-override": "peer0.org${ORG}.fabric-iot.edu",
34 | "hostnameOverride": "peer0.org${ORG}.fabric-iot.edu"
35 | }
36 | },
37 | "peer1.org${ORG}.fabric-iot.edu": {
38 | "url": "grpcs://localhost:${P1PORT}",
39 | "tlsCACerts": {
40 | "pem": "${PEERPEM}"
41 | },
42 | "grpcOptions": {
43 | "ssl-target-name-override": "peer1.org${ORG}.fabric-iot.edu",
44 | "hostnameOverride": "peer1.org${ORG}.fabric-iot.edu"
45 | }
46 | }
47 | },
48 | "certificateAuthorities": {
49 | "ca.org${ORG}.fabric-iot.edu": {
50 | "url": "https://localhost:${CAPORT}",
51 | "caName": "ca-org${ORG}",
52 | "tlsCACerts": {
53 | "pem": "${CAPEM}"
54 | },
55 | "httpOptions": {
56 | "verify": false
57 | }
58 | }
59 | }
60 | }
61 |
--------------------------------------------------------------------------------
/network/conn-conf/ccp-template.yaml:
--------------------------------------------------------------------------------
1 | ---
2 | name: first-network-org${ORG}
3 | version: 1.0.0
4 | client:
5 | organization: Org${ORG}
6 | connection:
7 | timeout:
8 | peer:
9 | endorser: '300'
10 | organizations:
11 | Org${ORG}:
12 | mspid: Org${ORG}MSP
13 | peers:
14 | - peer0.org${ORG}.fabric-iot.edu
15 | - peer1.org${ORG}.fabric-iot.edu
16 | certificateAuthorities:
17 | - ca.org${ORG}.fabric-iot.edu
18 | peers:
19 | peer0.org${ORG}.fabric-iot.edu:
20 | url: grpcs://localhost:${P0PORT}
21 | tlsCACerts:
22 | pem: |
23 | ${PEERPEM}
24 | grpcOptions:
25 | ssl-target-name-override: peer0.org${ORG}.fabric-iot.edu
26 | hostnameOverride: peer0.org${ORG}.fabric-iot.edu
27 | peer1.org${ORG}.fabric-iot.edu:
28 | url: grpcs://localhost:${P1PORT}
29 | tlsCACerts:
30 | pem: |
31 | ${PEERPEM}
32 | grpcOptions:
33 | ssl-target-name-override: peer1.org${ORG}.fabric-iot.edu
34 | hostnameOverride: peer1.org${ORG}.fabric-iot.edu
35 | certificateAuthorities:
36 | ca.org${ORG}.fabric-iot.edu:
37 | url: https://localhost:${CAPORT}
38 | caName: ca-org${ORG}
39 | tlsCACerts:
40 | pem: |
41 | ${CAPEM}
42 | httpOptions:
43 | verify: false
44 |
--------------------------------------------------------------------------------
/network/crypto-config.yaml:
--------------------------------------------------------------------------------
1 | # Copyright IBM Corp. All Rights Reserved.
2 | #
3 | # SPDX-License-Identifier: Apache-2.0
4 | #
5 |
6 | # ---------------------------------------------------------------------------
7 | # "OrdererOrgs" - Definition of organizations managing orderer nodes
8 | # ---------------------------------------------------------------------------
9 | OrdererOrgs:
10 | # ---------------------------------------------------------------------------
11 | # Orderer
12 | # ---------------------------------------------------------------------------
13 | - Name: Orderer
14 | Domain: fabric-iot.edu
15 | EnableNodeOUs: true
16 | # ---------------------------------------------------------------------------
17 | # "Specs" - See PeerOrgs below for complete description
18 | # ---------------------------------------------------------------------------
19 | Specs:
20 | - Hostname: orderer
21 | - Hostname: orderer2
22 | - Hostname: orderer3
23 | - Hostname: orderer4
24 | - Hostname: orderer5
25 |
26 | # ---------------------------------------------------------------------------
27 | # "PeerOrgs" - Definition of organizations managing peer nodes
28 | # ---------------------------------------------------------------------------
29 | PeerOrgs:
30 | # ---------------------------------------------------------------------------
31 | # Org1
32 | # ---------------------------------------------------------------------------
33 | - Name: Org1
34 | Domain: org1.fabric-iot.edu
35 | EnableNodeOUs: true
36 | # ---------------------------------------------------------------------------
37 | # "Specs"
38 | # ---------------------------------------------------------------------------
39 | # Uncomment this section to enable the explicit definition of hosts in your
40 | # configuration. Most users will want to use Template, below
41 | #
42 | # Specs is an array of Spec entries. Each Spec entry consists of two fields:
43 | # - Hostname: (Required) The desired hostname, sans the domain.
44 | # - CommonName: (Optional) Specifies the template or explicit override for
45 | # the CN. By default, this is the template:
46 | #
47 | # "{{.Hostname}}.{{.Domain}}"
48 | #
49 | # which obtains its values from the Spec.Hostname and
50 | # Org.Domain, respectively.
51 | # ---------------------------------------------------------------------------
52 | # Specs:
53 | # - Hostname: foo # implicitly "foo.org1.fabric-iot.edu"
54 | # CommonName: foo27.org5.fabric-iot.edu # overrides Hostname-based FQDN set above
55 | # - Hostname: bar
56 | # - Hostname: baz
57 | # ---------------------------------------------------------------------------
58 | # "Template"
59 | # ---------------------------------------------------------------------------
60 | # Allows for the definition of 1 or more hosts that are created sequentially
61 | # from a template. By default, this looks like "peer%d" from 0 to Count-1.
62 | # You may override the number of nodes (Count), the starting index (Start)
63 | # or the template used to construct the name (Hostname).
64 | #
65 | # Note: Template and Specs are not mutually exclusive. You may define both
66 | # sections and the aggregate nodes will be created for you. Take care with
67 | # name collisions
68 | # ---------------------------------------------------------------------------
69 | Template:
70 | Count: 2
71 | # Start: 5
72 | # Hostname: {{.Prefix}}{{.Index}} # default
73 | # ---------------------------------------------------------------------------
74 | # "Users"
75 | # ---------------------------------------------------------------------------
76 | # Count: The number of user accounts _in addition_ to Admin
77 | # ---------------------------------------------------------------------------
78 | Users:
79 | Count: 1
80 | # ---------------------------------------------------------------------------
81 | # Org2: See "Org1" for full specification
82 | # ---------------------------------------------------------------------------
83 | - Name: Org2
84 | Domain: org2.fabric-iot.edu
85 | EnableNodeOUs: true
86 | Template:
87 | Count: 2
88 | Users:
89 | Count: 1
90 |
--------------------------------------------------------------------------------
/network/down.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | # import env
4 | . env.sh
5 |
6 | # Obtain CONTAINER_IDS and remove them
7 | # TODO Might want to make this optional - could clear other containers
8 | function clearContainers() {
9 | CONTAINER_IDS=$(docker ps -a | awk '($2 ~ /dev-peer*.*.fabric-iot.*/) {print $1}')
10 | if [ -z "$CONTAINER_IDS" -o "$CONTAINER_IDS" == " " ]; then
11 | echo "---- No containers available for deletion ----"
12 | else
13 | docker rm -f $CONTAINER_IDS
14 | fi
15 | }
16 |
17 | # Delete any images that were generated as a part of this setup
18 | # specifically the following images are often left behind:
19 | # TODO list generated image naming patterns
20 | function removeUnwantedImages() {
21 | DOCKER_IMAGE_IDS=$(docker images | awk '($1 ~ /dev-peer*.*.*.*c.*/) {print $3}')
22 | if [ -z "$DOCKER_IMAGE_IDS" -o "$DOCKER_IMAGE_IDS" == " " ]; then
23 | echo "---- No images available for deletion ----"
24 | else
25 | docker rmi -f $DOCKER_IMAGE_IDS
26 | fi
27 | }
28 |
29 | MODE="down"
30 |
31 | # Tear down running network
32 | function networkDown() {
33 | # stop org3 containers also in addition to org1 and org2, in case we were running sample to add org3
34 | # stop kafka and zookeeper containers in case we're running with kafka consensus-type
35 | # docker-compose -f $COMPOSE_FILE -f $COMPOSE_FILE_COUCH -f $COMPOSE_FILE_KAFKA -f $COMPOSE_FILE_RAFT2 -f $COMPOSE_FILE_CA -f $COMPOSE_FILE_ORG3 down --volumes --remove-orphans
36 | # we delete $COMPOSE_FILE_RAFT2 , $COMPOSE_FILE_ORG3
37 | docker-compose -f $COMPOSE_FILE -f $COMPOSE_FILE_COUCH -f $COMPOSE_FILE_KAFKA -f $COMPOSE_FILE_CA down --volumes --remove-orphans
38 |
39 | # Don't remove the generated artifacts -- note, the ledgers are always removed
40 | if [ "$MODE" != "restart" ]; then
41 | # Bring down the network, deleting the volumes
42 | #Delete any ledger backups
43 | docker run -v $PWD:/tmp/first-network --rm hyperledger/fabric-tools:$IMAGETAG rm -Rf /tmp/first-network/ledgers-backup
44 | #Cleanup the chaincode containers
45 | clearContainers
46 | #Cleanup images
47 | removeUnwantedImages
48 | # remove orderer block and other channel configuration transactions and certs
49 | rm -rf channel-artifacts/*.block channel-artifacts/*.tx crypto-config ./org3-artifacts/crypto-config/ channel-artifacts/org3.json
50 | # remove the docker-compose yaml file that was customized to the example
51 | rm -f compose-files/docker-compose-e2e.yaml
52 | fi
53 | }
54 |
55 | networkDown
--------------------------------------------------------------------------------
/network/env.sh:
--------------------------------------------------------------------------------
1 | # Set default value
2 | # Obtain the OS and Architecture string that will be used to select the correct
3 | # native binaries for your platform, e.g., darwin-amd64 or linux-amd64
4 | OS_ARCH=$(echo "$(uname -s | tr '[:upper:]' '[:lower:]' | sed 's/mingw64_nt.*/windows/')-$(uname -m | sed 's/x86_64/amd64/g')" | awk '{print tolower($0)}')
5 | # timeout duration - the duration the CLI should wait for a response from
6 | # another container before giving up
7 | CLI_TIMEOUT=10
8 | # default for delay between commands
9 | CLI_DELAY=3
10 | # compose files path
11 | COMPOSE_FILE_PATH=compose-files
12 | # use this as the default docker-compose yaml definition
13 | COMPOSE_FILE=$COMPOSE_FILE_PATH/docker-compose-cli.yaml
14 | #
15 | COMPOSE_FILE_COUCH=$COMPOSE_FILE_PATH/docker-compose-couch.yaml
16 | # org3 docker compose file
17 | COMPOSE_FILE_ORG3=$COMPOSE_FILE_PATH/docker-compose-org3.yaml
18 | # kafka and zookeeper compose file
19 | COMPOSE_FILE_KAFKA=$COMPOSE_FILE_PATH/docker-compose-kafka.yaml
20 | # two additional etcd/raft orderers
21 | COMPOSE_FILE_RAFT2=$COMPOSE_FILE_PATH/docker-compose-etcdraft2.yaml
22 | # certificate authorities compose file
23 | COMPOSE_FILE_CA=$COMPOSE_FILE_PATH/docker-compose-ca.yaml
24 | #
25 | # use golang as the default language for chaincode
26 | LANGUAGE=golang
27 | # default image tag
28 | IMAGETAG="latest"
29 | # Versions of fabric known not to work with this release of first-network
30 | BLACKLISTED_VERSIONS="^1\.0\. ^1\.1\.0-preview ^1\.1\.0-alpha"
31 | # channel name
32 | CHANNEL_NAME="iot-channel"
33 | # system channem name
34 | SYS_CHANNEL="iot-sys-channel"
35 | # set exports
36 | export COMPOSE_PROJECT_NAME=iot
37 | export IMAGE_TAG=$IMAGE_TAG
38 | export SYS_CHANNEL=$SYS_CHANNEL
39 | # conn conf
40 | CONN_CONF_PATH=conn-conf
41 | # default consensus type,[kafka,solo,etcdraft]
42 | CONSENSUS_TYPE="kafka"
--------------------------------------------------------------------------------
/network/generate.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | . env.sh
3 |
4 | export VERBOSE=false
5 | export FABRIC_CFG_PATH=${PWD}
6 |
7 | # Generates Org certs using cryptogen tool
8 | function generateCerts() {
9 | which cryptogen
10 | if [ "$?" -ne 0 ]; then
11 | echo "cryptogen tool not found. exiting"
12 | exit 1
13 | fi
14 | echo
15 | echo "##########################################################"
16 | echo "##### Generate certificates using cryptogen tool #########"
17 | echo "##########################################################"
18 |
19 | if [ -d "crypto-config" ]; then
20 | rm -Rf crypto-config
21 | fi
22 | set -x
23 | cryptogen generate --config=./crypto-config.yaml
24 | res=$?
25 | set +x
26 | if [ $res -ne 0 ]; then
27 | echo "Failed to generate certificates..."
28 | exit 1
29 | fi
30 | echo
31 | echo "Generate CCP files for Org1 and Org2"
32 | ./ccp-generate.sh
33 | }
34 |
35 | function replacePrivateKey() {
36 | # sed on MacOSX does not support -i flag with a null extension. We will use
37 | # 't' for our back-up's extension and delete it at the end of the function
38 | ARCH=$(uname -s | grep Darwin)
39 | if [ "$ARCH" == "Darwin" ]; then
40 | OPTS="-it"
41 | else
42 | OPTS="-i"
43 | fi
44 |
45 | # Copy the template to the file that will be modified to add the private key
46 | cp $CONN_CONF_PATH/docker-compose-e2e-template.yaml $CONN_CONF_PATH/docker-compose-e2e.yaml
47 |
48 | # The next steps will replace the template's contents with the
49 | # actual values of the private key file names for the two CAs.
50 | CURRENT_DIR=$PWD
51 | cd crypto-config/peerOrganizations/org1.fabric-iot.edu/ca/
52 | PRIV_KEY=$(ls *_sk)
53 | cd "$CURRENT_DIR"
54 | sed $OPTS "s/CA1_PRIVATE_KEY/${PRIV_KEY}/g" $CONN_CONF_PATH/docker-compose-e2e.yaml
55 | cd crypto-config/peerOrganizations/org2.fabric-iot.edu/ca/
56 | PRIV_KEY=$(ls *_sk)
57 | cd "$CURRENT_DIR"
58 | sed $OPTS "s/CA2_PRIVATE_KEY/${PRIV_KEY}/g" $CONN_CONF_PATH/docker-compose-e2e.yaml
59 | # If MacOSX, remove the temporary backup of the docker-compose file
60 | if [ "$ARCH" == "Darwin" ]; then
61 | rm $CONN_CONF_PATH/docker-compose-e2e.yamlt
62 | fi
63 | }
64 |
65 | # Generate orderer genesis block, channel configuration transaction and
66 | # anchor peer update transactions
67 | function generateChannelArtifacts() {
68 | which configtxgen
69 | if [ "$?" -ne 0 ]; then
70 | echo "configtxgen tool not found. exiting"
71 | exit 1
72 | fi
73 |
74 | echo "##########################################################"
75 | echo "######### Generating Orderer Genesis block ##############"
76 | echo "##########################################################"
77 | # Note: For some unknown reason (at least for now) the block file can't be
78 | # named orderer.genesis.block or the orderer will fail to launch!
79 | echo "CONSENSUS_TYPE="$CONSENSUS_TYPE
80 | set -x
81 | if [ "$CONSENSUS_TYPE" == "solo" ]; then
82 | configtxgen -profile TwoOrgsOrdererGenesis -channelID $SYS_CHANNEL -outputBlock ./channel-artifacts/genesis.block
83 | elif [ "$CONSENSUS_TYPE" == "kafka" ]; then
84 | configtxgen -profile SampleDevModeKafka -channelID $SYS_CHANNEL -outputBlock ./channel-artifacts/genesis.block
85 | elif [ "$CONSENSUS_TYPE" == "etcdraft" ]; then
86 | configtxgen -profile SampleMultiNodeEtcdRaft -channelID $SYS_CHANNEL -outputBlock ./channel-artifacts/genesis.block
87 | else
88 | set +x
89 | echo "unrecognized CONSESUS_TYPE='$CONSENSUS_TYPE'. exiting"
90 | exit 1
91 | fi
92 | res=$?
93 | set +x
94 | if [ $res -ne 0 ]; then
95 | echo "Failed to generate orderer genesis block..."
96 | exit 1
97 | fi
98 | echo
99 | echo "#################################################################"
100 | echo "### Generating channel configuration transaction 'channel.tx' ###"
101 | echo "#################################################################"
102 | set -x
103 | configtxgen -profile TwoOrgsChannel -outputCreateChannelTx ./channel-artifacts/channel.tx -channelID $CHANNEL_NAME
104 | res=$?
105 | set +x
106 | if [ $res -ne 0 ]; then
107 | echo "Failed to generate channel configuration transaction..."
108 | exit 1
109 | fi
110 |
111 | echo
112 | echo "#################################################################"
113 | echo "####### Generating anchor peer update for Org1MSP ##########"
114 | echo "#################################################################"
115 | set -x
116 | configtxgen -profile TwoOrgsChannel -outputAnchorPeersUpdate ./channel-artifacts/Org1MSPanchors.tx -channelID $CHANNEL_NAME -asOrg Org1MSP
117 | res=$?
118 | set +x
119 | if [ $res -ne 0 ]; then
120 | echo "Failed to generate anchor peer update for Org1MSP..."
121 | exit 1
122 | fi
123 |
124 | echo
125 | echo "#################################################################"
126 | echo "####### Generating anchor peer update for Org2MSP ##########"
127 | echo "#################################################################"
128 | set -x
129 | configtxgen -profile TwoOrgsChannel -outputAnchorPeersUpdate \
130 | ./channel-artifacts/Org2MSPanchors.tx -channelID $CHANNEL_NAME -asOrg Org2MSP
131 | res=$?
132 | set +x
133 | if [ $res -ne 0 ]; then
134 | echo "Failed to generate anchor peer update for Org2MSP..."
135 | exit 1
136 | fi
137 | echo
138 | }
139 |
140 | ##利用cryptogen生成新的Certs文件
141 | generateCerts
142 | ##根据e2e模版yaml生成新的yaml,并将生成的Cert文件替换到yaml的CA节点的路径中
143 | replacePrivateKey
144 | ##利用configtxgen生成创世区块、创建通道
145 | generateChannelArtifacts
146 |
147 | echo "========= All GOOD, [fabric-iot] execution completed =========== "
148 |
--------------------------------------------------------------------------------
/network/restart.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | # import env
4 | . env.sh
5 |
6 | # settings
7 | CERTIFICATE_AUTHORITIES="true"
8 | # not install chaincode
9 | NO_CHAINCODE="true"
10 | # use couchdb
11 | IF_COUCHDB="couchdb"
12 |
13 | # Do some basic sanity checking to make sure that the appropriate versions of fabric
14 | # binaries/images are available. In the future, additional checking for the presence
15 | # of go or other items could be added.
16 | function checkPrereqs() {
17 | # Note, we check configtxlator externally because it does not require a config file, and peer in the
18 | # docker image because of FAB-8551 that makes configtxlator return 'development version' in docker
19 | LOCAL_VERSION=$(configtxlator version | sed -ne 's/ Version: //p')
20 | DOCKER_IMAGE_VERSION=$(docker run --rm hyperledger/fabric-tools:$IMAGETAG peer version | sed -ne 's/ Version: //p' | head -1)
21 |
22 | echo "LOCAL_VERSION=$LOCAL_VERSION"
23 | echo "DOCKER_IMAGE_VERSION=$DOCKER_IMAGE_VERSION"
24 |
25 | if [ "$LOCAL_VERSION" != "$DOCKER_IMAGE_VERSION" ]; then
26 | echo "=================== WARNING ==================="
27 | echo " Local fabric binaries and docker images are "
28 | echo " out of sync. This may cause problems. "
29 | echo "==============================================="
30 | fi
31 |
32 | for UNSUPPORTED_VERSION in $BLACKLISTED_VERSIONS; do
33 | echo "$LOCAL_VERSION" | grep -q $UNSUPPORTED_VERSION
34 | if [ $? -eq 0 ]; then
35 | echo "ERROR! Local Fabric binary version of $LOCAL_VERSION does not match this newer version of [fabric-iot] and is unsupported. Either move to a later version of Fabric or checkout an earlier version of fabric-samples."
36 | exit 1
37 | fi
38 |
39 | echo "$DOCKER_IMAGE_VERSION" | grep -q $UNSUPPORTED_VERSION
40 | if [ $? -eq 0 ]; then
41 | echo "ERROR! Fabric Docker image version of $DOCKER_IMAGE_VERSION does not match this newer version of [fabric-iot] and is unsupported. Either move to a later version of Fabric or checkout an earlier version of fabric-samples."
42 | exit 1
43 | fi
44 | done
45 | }
46 |
47 | # Generate the needed certificates, the genesis block and start the network.
48 | function networkUp() {
49 | checkPrereqs
50 | # generate artifacts if they don't exist
51 | if [ ! -d "crypto-config" ]; then
52 | ./generate.sh
53 | fi
54 | COMPOSE_FILES="-f ${COMPOSE_FILE}"
55 | if [ "${CERTIFICATE_AUTHORITIES}" == "true" ]; then
56 | COMPOSE_FILES="${COMPOSE_FILES} -f ${COMPOSE_FILE_CA}"
57 | export CA1_PRIVATE_KEY=$(cd crypto-config/peerOrganizations/org1.fabric-iot.edu/ca && ls *_sk)
58 | export CA2_PRIVATE_KEY=$(cd crypto-config/peerOrganizations/org2.fabric-iot.edu/ca && ls *_sk)
59 | fi
60 | if [ "${CONSENSUS_TYPE}" == "kafka" ]; then
61 | COMPOSE_FILES="${COMPOSE_FILES} -f ${COMPOSE_FILE_KAFKA}"
62 | elif [ "${CONSENSUS_TYPE}" == "etcdraft" ]; then
63 | COMPOSE_FILES="${COMPOSE_FILES} -f ${COMPOSE_FILE_RAFT2}"
64 | fi
65 | if [ "${IF_COUCHDB}" == "couchdb" ]; then
66 | COMPOSE_FILES="${COMPOSE_FILES} -f ${COMPOSE_FILE_COUCH}"
67 | fi
68 | IMAGE_TAG=$IMAGETAG docker-compose ${COMPOSE_FILES} up -d 2>&1
69 | docker ps -a
70 | if [ $? -ne 0 ]; then
71 | echo "ERROR !!!! Unable to start network"
72 | exit 1
73 | fi
74 |
75 | if [ "$CONSENSUS_TYPE" == "kafka" ]; then
76 | sleep 1
77 | echo "Sleeping 10s to allow $CONSENSUS_TYPE cluster to complete booting"
78 | sleep 9
79 | fi
80 |
81 | if [ "$CONSENSUS_TYPE" == "etcdraft" ]; then
82 | sleep 1
83 | echo "Sleeping 15s to allow $CONSENSUS_TYPE cluster to complete booting"
84 | sleep 14
85 | fi
86 | }
87 |
88 | function chaincodeUp(){
89 | DOCKER_IMAGE_IDS=$(docker ps -a | awk '($2 ~ /dev-peer*.*.*.*c.*/) {print $1}')
90 | docker restart $DOCKER_IMAGE_IDS
91 | }
92 |
93 | networkUp
94 | chaincodeUp
--------------------------------------------------------------------------------
/network/scripts/script.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | echo
4 | echo " ____ _____ _ ____ _____ "
5 | echo "/ ___| |_ _| / \ | _ \ |_ _|"
6 | echo "\___ \ | | / _ \ | |_) | | | "
7 | echo " ___) | | | / ___ \ | _ < | | "
8 | echo "|____/ |_| /_/ \_\ |_| \_\ |_| "
9 | echo
10 | echo "Build [fabric-iot] end-to-end test"
11 | echo
12 | CHANNEL_NAME="$1"
13 | DELAY="$2"
14 | LANGUAGE="$3"
15 | TIMEOUT="$4"
16 | VERBOSE="$5"
17 | NO_CHAINCODE="$6"
18 | : ${CHANNEL_NAME:="iot-channel"}
19 | : ${DELAY:="3"}
20 | : ${LANGUAGE:="golang"}
21 | : ${TIMEOUT:="10"}
22 | : ${VERBOSE:="false"}
23 | : ${NO_CHAINCODE:="true"}
24 | LANGUAGE=`echo "$LANGUAGE" | tr [:upper:] [:lower:]`
25 | COUNTER=1
26 | MAX_RETRY=10
27 |
28 | echo "Channel name : "$CHANNEL_NAME
29 |
30 | # import utils
31 | . scripts/utils.sh
32 |
33 | createChannel() {
34 | setGlobals 0 1
35 |
36 | if [ -z "$CORE_PEER_TLS_ENABLED" -o "$CORE_PEER_TLS_ENABLED" = "false" ]; then
37 | set -x
38 | peer channel create -o orderer.fabric-iot.edu:7050 -c $CHANNEL_NAME -f ./channel-artifacts/channel.tx >&log.txt
39 | res=$?
40 | set +x
41 | else
42 | set -x
43 | peer channel create -o orderer.fabric-iot.edu:7050 -c $CHANNEL_NAME -f ./channel-artifacts/channel.tx --tls $CORE_PEER_TLS_ENABLED --cafile $ORDERER_CA >&log.txt
44 | res=$?
45 | set +x
46 | fi
47 | cat log.txt
48 | verifyResult $res "Channel creation failed"
49 | echo "===================== Channel '$CHANNEL_NAME' created ===================== "
50 | echo
51 | }
52 |
53 | joinChannel () {
54 | for org in 1 2; do
55 | for peer in 0 1; do
56 | joinChannelWithRetry $peer $org
57 | echo "===================== peer${peer}.org${org} joined channel '$CHANNEL_NAME' ===================== "
58 | sleep $DELAY
59 | echo
60 | done
61 | done
62 | }
63 |
64 | ## Create channel
65 | echo "Creating channel..."
66 | createChannel
67 |
68 | # Waiting for channel created
69 | echo "Waiting for channel created:"
70 | for((i=1;i<=10;i++))
71 | do
72 | sleep 1
73 | echo -e ">\c"
74 | done
75 | echo
76 |
77 | ## Join all the peers to the channel
78 | echo "Having all peers join the channel..."
79 | joinChannel
80 |
81 | ## Set the anchor peers for each org in the channel
82 | echo "Updating anchor peers for org1..."
83 | updateAnchorPeers 0 1
84 | echo "Updating anchor peers for org2..."
85 | updateAnchorPeers 0 2
86 |
87 | echo
88 | echo "========= All GOOD, [fabric-iot] execution completed =========== "
89 | echo
90 |
91 | echo
92 | echo " _____ _ _ ____ "
93 | echo "| ____| | \ | | | _ \ "
94 | echo "| _| | \| | | | | | "
95 | echo "| |___ | |\ | | |_| | "
96 | echo "|_____| |_| \_| |____/ "
97 | echo
98 |
99 | exit 0
100 |
--------------------------------------------------------------------------------
/network/scripts/utils.sh:
--------------------------------------------------------------------------------
1 | #
2 | # Copyright IBM Corp All Rights Reserved
3 | #
4 | # SPDX-License-Identifier: Apache-2.0
5 | #
6 |
7 | # This is a collection of bash functions used by different scripts
8 |
9 | ORDERER_CA=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/fabric-iot.edu/orderers/orderer.fabric-iot.edu/msp/tlscacerts/tlsca.fabric-iot.edu-cert.pem
10 | PEER0_ORG1_CA=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.fabric-iot.edu/peers/peer0.org1.fabric-iot.edu/tls/ca.crt
11 | PEER0_ORG2_CA=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.fabric-iot.edu/peers/peer0.org2.fabric-iot.edu/tls/ca.crt
12 | PEER0_ORG3_CA=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org3.fabric-iot.edu/peers/peer0.org3.fabric-iot.edu/tls/ca.crt
13 |
14 | # verify the result of the end-to-end test
15 | verifyResult() {
16 | if [ $1 -ne 0 ]; then
17 | echo "!!!!!!!!!!!!!!! "$2" !!!!!!!!!!!!!!!!"
18 | echo "========= ERROR !!! FAILED to execute End-2-End Scenario ==========="
19 | echo
20 | exit 1
21 | fi
22 | }
23 |
24 | # Set OrdererOrg.Admin globals
25 | setOrdererGlobals() {
26 | CORE_PEER_LOCALMSPID="OrdererMSP"
27 | CORE_PEER_TLS_ROOTCERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/fabric-iot.edu/orderers/orderer.fabric-iot.edu/msp/tlscacerts/tlsca.fabric-iot.edu-cert.pem
28 | CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/fabric-iot.edu/users/Admin@fabric-iot.edu/msp
29 | }
30 |
31 | setGlobals() {
32 | PEER=$1
33 | ORG=$2
34 | if [ $ORG -eq 1 ]; then
35 | CORE_PEER_LOCALMSPID="Org1MSP"
36 | CORE_PEER_TLS_ROOTCERT_FILE=$PEER0_ORG1_CA
37 | CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.fabric-iot.edu/users/Admin@org1.fabric-iot.edu/msp
38 | if [ $PEER -eq 0 ]; then
39 | CORE_PEER_ADDRESS=peer0.org1.fabric-iot.edu:7051
40 | else
41 | CORE_PEER_ADDRESS=peer1.org1.fabric-iot.edu:8051
42 | fi
43 | elif [ $ORG -eq 2 ]; then
44 | CORE_PEER_LOCALMSPID="Org2MSP"
45 | CORE_PEER_TLS_ROOTCERT_FILE=$PEER0_ORG2_CA
46 | CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.fabric-iot.edu/users/Admin@org2.fabric-iot.edu/msp
47 | if [ $PEER -eq 0 ]; then
48 | CORE_PEER_ADDRESS=peer0.org2.fabric-iot.edu:9051
49 | else
50 | CORE_PEER_ADDRESS=peer1.org2.fabric-iot.edu:10051
51 | fi
52 |
53 | elif [ $ORG -eq 3 ]; then
54 | CORE_PEER_LOCALMSPID="Org3MSP"
55 | CORE_PEER_TLS_ROOTCERT_FILE=$PEER0_ORG3_CA
56 | CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org3.fabric-iot.edu/users/Admin@org3.fabric-iot.edu/msp
57 | if [ $PEER -eq 0 ]; then
58 | CORE_PEER_ADDRESS=peer0.org3.fabric-iot.edu:11051
59 | else
60 | CORE_PEER_ADDRESS=peer1.org3.fabric-iot.edu:12051
61 | fi
62 | else
63 | echo "================== ERROR !!! ORG Unknown =================="
64 | fi
65 |
66 | if [ "$VERBOSE" == "true" ]; then
67 | env | grep CORE
68 | fi
69 | }
70 |
71 | updateAnchorPeers() {
72 | PEER=$1
73 | ORG=$2
74 | setGlobals $PEER $ORG
75 |
76 | if [ -z "$CORE_PEER_TLS_ENABLED" -o "$CORE_PEER_TLS_ENABLED" = "false" ]; then
77 | set -x
78 | peer channel update -o orderer.fabric.com:7050 -c $CHANNEL_NAME -f ./channel-artifacts/${CORE_PEER_LOCALMSPID}anchors.tx >&log.txt
79 | res=$?
80 | set +x
81 | else
82 | set -x
83 | peer channel update -o orderer.fabric-iot.edu:7050 -c $CHANNEL_NAME -f ./channel-artifacts/${CORE_PEER_LOCALMSPID}anchors.tx --tls $CORE_PEER_TLS_ENABLED --cafile $ORDERER_CA >&log.txt
84 | res=$?
85 | set +x
86 | fi
87 | cat log.txt
88 | verifyResult $res "Anchor peer update failed"
89 | echo "===================== Anchor peers updated for org '$CORE_PEER_LOCALMSPID' on channel '$CHANNEL_NAME' ===================== "
90 | sleep $DELAY
91 | echo
92 | }
93 |
94 | ## Sometimes Join takes time hence RETRY at least 5 times
95 | joinChannelWithRetry() {
96 | PEER=$1
97 | ORG=$2
98 | setGlobals $PEER $ORG
99 |
100 | set -x
101 | peer channel join -b $CHANNEL_NAME.block >&log.txt
102 | res=$?
103 | set +x
104 | cat log.txt
105 | if [ $res -ne 0 -a $COUNTER -lt $MAX_RETRY ]; then
106 | COUNTER=$(expr $COUNTER + 1)
107 | echo "peer${PEER}.org${ORG} failed to join the channel, Retry after $DELAY seconds"
108 | sleep $DELAY
109 | joinChannelWithRetry $PEER $ORG
110 | else
111 | COUNTER=1
112 | fi
113 | verifyResult $res "After $MAX_RETRY attempts, peer${PEER}.org${ORG} has failed to join channel '$CHANNEL_NAME' "
114 | }
115 |
116 | installChaincode() {
117 | PEER=$1
118 | ORG=$2
119 | setGlobals $PEER $ORG
120 | VERSION=${3:-1.0}
121 | set -x
122 | peer chaincode install -n mycc -v ${VERSION} -l ${LANGUAGE} -p ${CC_SRC_PATH} >&log.txt
123 | res=$?
124 | set +x
125 | cat log.txt
126 | verifyResult $res "Chaincode installation on peer${PEER}.org${ORG} has failed"
127 | echo "===================== Chaincode is installed on peer${PEER}.org${ORG} ===================== "
128 | echo
129 | }
130 |
131 | instantiateChaincode() {
132 | PEER=$1
133 | ORG=$2
134 | setGlobals $PEER $ORG
135 | VERSION=${3:-1.0}
136 |
137 | # while 'peer chaincode' command can get the orderer endpoint from the peer
138 | # (if join was successful), let's supply it directly as we know it using
139 | # the "-o" option
140 | if [ -z "$CORE_PEER_TLS_ENABLED" -o "$CORE_PEER_TLS_ENABLED" = "false" ]; then
141 | set -x
142 | peer chaincode instantiate -o orderer.fabric-iot.edu:7050 -C $CHANNEL_NAME -n mycc -l ${LANGUAGE} -v ${VERSION} -c '{"Args":["init","a","100","b","200"]}' -P "AND ('Org1MSP.peer','Org2MSP.peer')" >&log.txt
143 | res=$?
144 | set +x
145 | else
146 | set -x
147 | peer chaincode instantiate -o orderer.fabric-iot.edu:7050 --tls $CORE_PEER_TLS_ENABLED --cafile $ORDERER_CA -C $CHANNEL_NAME -n mycc -l ${LANGUAGE} -v 1.0 -c '{"Args":["init","a","100","b","200"]}' -P "AND ('Org1MSP.peer','Org2MSP.peer')" >&log.txt
148 | res=$?
149 | set +x
150 | fi
151 | cat log.txt
152 | verifyResult $res "Chaincode instantiation on peer${PEER}.org${ORG} on channel '$CHANNEL_NAME' failed"
153 | echo "===================== Chaincode is instantiated on peer${PEER}.org${ORG} on channel '$CHANNEL_NAME' ===================== "
154 | echo
155 | }
156 |
157 | upgradeChaincode() {
158 | PEER=$1
159 | ORG=$2
160 | setGlobals $PEER $ORG
161 |
162 | set -x
163 | peer chaincode upgrade -o orderer.fabric-iot.edu:7050 --tls $CORE_PEER_TLS_ENABLED --cafile $ORDERER_CA -C $CHANNEL_NAME -n mycc -v 2.0 -c '{"Args":["init","a","90","b","210"]}' -P "AND ('Org1MSP.peer','Org2MSP.peer','Org3MSP.peer')"
164 | res=$?
165 | set +x
166 | cat log.txt
167 | verifyResult $res "Chaincode upgrade on peer${PEER}.org${ORG} has failed"
168 | echo "===================== Chaincode is upgraded on peer${PEER}.org${ORG} on channel '$CHANNEL_NAME' ===================== "
169 | echo
170 | }
171 |
172 | chaincodeQuery() {
173 | PEER=$1
174 | ORG=$2
175 | setGlobals $PEER $ORG
176 | EXPECTED_RESULT=$3
177 | echo "===================== Querying on peer${PEER}.org${ORG} on channel '$CHANNEL_NAME'... ===================== "
178 | local rc=1
179 | local starttime=$(date +%s)
180 |
181 | # continue to poll
182 | # we either get a successful response, or reach TIMEOUT
183 | while
184 | test "$(($(date +%s) - starttime))" -lt "$TIMEOUT" -a $rc -ne 0
185 | do
186 | sleep $DELAY
187 | echo "Attempting to Query peer${PEER}.org${ORG} ...$(($(date +%s) - starttime)) secs"
188 | set -x
189 | peer chaincode query -C $CHANNEL_NAME -n mycc -c '{"Args":["query","a"]}' >&log.txt
190 | res=$?
191 | set +x
192 | test $res -eq 0 && VALUE=$(cat log.txt | awk '/Query Result/ {print $NF}')
193 | test "$VALUE" = "$EXPECTED_RESULT" && let rc=0
194 | # removed the string "Query Result" from peer chaincode query command
195 | # result. as a result, have to support both options until the change
196 | # is merged.
197 | test $rc -ne 0 && VALUE=$(cat log.txt | egrep '^[0-9]+$')
198 | test "$VALUE" = "$EXPECTED_RESULT" && let rc=0
199 | done
200 | echo
201 | cat log.txt
202 | if test $rc -eq 0; then
203 | echo "===================== Query successful on peer${PEER}.org${ORG} on channel '$CHANNEL_NAME' ===================== "
204 | else
205 | echo "!!!!!!!!!!!!!!! Query result on peer${PEER}.org${ORG} is INVALID !!!!!!!!!!!!!!!!"
206 | echo "================== ERROR !!! FAILED to execute End-2-End Scenario =================="
207 | echo
208 | exit 1
209 | fi
210 | }
211 |
212 | # fetchChannelConfig
213 | # Writes the current channel config for a given channel to a JSON file
214 | fetchChannelConfig() {
215 | CHANNEL=$1
216 | OUTPUT=$2
217 |
218 | setOrdererGlobals
219 |
220 | echo "Fetching the most recent configuration block for the channel"
221 | if [ -z "$CORE_PEER_TLS_ENABLED" -o "$CORE_PEER_TLS_ENABLED" = "false" ]; then
222 | set -x
223 | peer channel fetch config config_block.pb -o orderer.fabric-iot.edu:7050 -c $CHANNEL --cafile $ORDERER_CA
224 | set +x
225 | else
226 | set -x
227 | peer channel fetch config config_block.pb -o orderer.fabric-iot.edu:7050 -c $CHANNEL --tls --cafile $ORDERER_CA
228 | set +x
229 | fi
230 |
231 | echo "Decoding config block to JSON and isolating config to ${OUTPUT}"
232 | set -x
233 | configtxlator proto_decode --input config_block.pb --type common.Block | jq .data.data[0].payload.data.config >"${OUTPUT}"
234 | set +x
235 | }
236 |
237 | # signConfigtxAsPeerOrg
238 | # Set the peerOrg admin of an org and signing the config update
239 | signConfigtxAsPeerOrg() {
240 | PEERORG=$1
241 | TX=$2
242 | setGlobals 0 $PEERORG
243 | set -x
244 | peer channel signconfigtx -f "${TX}"
245 | set +x
246 | }
247 |
248 | # createConfigUpdate
249 | # Takes an original and modified config, and produces the config update tx
250 | # which transitions between the two
251 | createConfigUpdate() {
252 | CHANNEL=$1
253 | ORIGINAL=$2
254 | MODIFIED=$3
255 | OUTPUT=$4
256 |
257 | set -x
258 | configtxlator proto_encode --input "${ORIGINAL}" --type common.Config >original_config.pb
259 | configtxlator proto_encode --input "${MODIFIED}" --type common.Config >modified_config.pb
260 | configtxlator compute_update --channel_id "${CHANNEL}" --original original_config.pb --updated modified_config.pb >config_update.pb
261 | configtxlator proto_decode --input config_update.pb --type common.ConfigUpdate >config_update.json
262 | echo '{"payload":{"header":{"channel_header":{"channel_id":"'$CHANNEL'", "type":2}},"data":{"config_update":'$(cat config_update.json)'}}}' | jq . >config_update_in_envelope.json
263 | configtxlator proto_encode --input config_update_in_envelope.json --type common.Envelope >"${OUTPUT}"
264 | set +x
265 | }
266 |
267 | # parsePeerConnectionParameters $@
268 | # Helper function that takes the parameters from a chaincode operation
269 | # (e.g. invoke, query, instantiate) and checks for an even number of
270 | # peers and associated org, then sets $PEER_CONN_PARMS and $PEERS
271 | parsePeerConnectionParameters() {
272 | # check for uneven number of peer and org parameters
273 | if [ $(($# % 2)) -ne 0 ]; then
274 | exit 1
275 | fi
276 |
277 | PEER_CONN_PARMS=""
278 | PEERS=""
279 | while [ "$#" -gt 0 ]; do
280 | setGlobals $1 $2
281 | PEER="peer$1.org$2"
282 | PEERS="$PEERS $PEER"
283 | PEER_CONN_PARMS="$PEER_CONN_PARMS --peerAddresses $CORE_PEER_ADDRESS"
284 | if [ -z "$CORE_PEER_TLS_ENABLED" -o "$CORE_PEER_TLS_ENABLED" = "true" ]; then
285 | TLSINFO=$(eval echo "--tlsRootCertFiles \$PEER$1_ORG$2_CA")
286 | PEER_CONN_PARMS="$PEER_CONN_PARMS $TLSINFO"
287 | fi
288 | # shift by two to get the next pair of peer/org parameters
289 | shift
290 | shift
291 | done
292 | # remove leading space for output
293 | PEERS="$(echo -e "$PEERS" | sed -e 's/^[[:space:]]*//')"
294 | }
295 |
296 | # chaincodeInvoke ...
297 | # Accepts as many peer/org pairs as desired and requests endorsement from each
298 | chaincodeInvoke() {
299 | parsePeerConnectionParameters $@
300 | res=$?
301 | verifyResult $res "Invoke transaction failed on channel '$CHANNEL_NAME' due to uneven number of peer and org parameters "
302 |
303 | # while 'peer chaincode' command can get the orderer endpoint from the
304 | # peer (if join was successful), let's supply it directly as we know
305 | # it using the "-o" option
306 | if [ -z "$CORE_PEER_TLS_ENABLED" -o "$CORE_PEER_TLS_ENABLED" = "false" ]; then
307 | set -x
308 | peer chaincode invoke -o orderer.fabric-iot.edu:7050 -C $CHANNEL_NAME -n mycc $PEER_CONN_PARMS -c '{"Args":["invoke","a","b","10"]}' >&log.txt
309 | res=$?
310 | set +x
311 | else
312 | set -x
313 | peer chaincode invoke -o orderer.fabric-iot.edu:7050 --tls $CORE_PEER_TLS_ENABLED --cafile $ORDERER_CA -C $CHANNEL_NAME -n mycc $PEER_CONN_PARMS -c '{"Args":["invoke","a","b","10"]}' >&log.txt
314 | res=$?
315 | set +x
316 | fi
317 | cat log.txt
318 | verifyResult $res "Invoke execution on $PEERS failed "
319 | echo "===================== Invoke transaction successful on $PEERS on channel '$CHANNEL_NAME' ===================== "
320 | echo
321 | }
322 |
--------------------------------------------------------------------------------
/network/up.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | # import env
4 | . env.sh
5 |
6 | # settings
7 | CERTIFICATE_AUTHORITIES="true"
8 | # not install chaincode
9 | NO_CHAINCODE="true"
10 | # use couchdb
11 | IF_COUCHDB="couchdb"
12 |
13 | # Do some basic sanity checking to make sure that the appropriate versions of fabric
14 | # binaries/images are available. In the future, additional checking for the presence
15 | # of go or other items could be added.
16 | function checkPrereqs() {
17 | # Note, we check configtxlator externally because it does not require a config file, and peer in the
18 | # docker image because of FAB-8551 that makes configtxlator return 'development version' in docker
19 | LOCAL_VERSION=$(configtxlator version | sed -ne 's/ Version: //p')
20 | DOCKER_IMAGE_VERSION=$(docker run --rm hyperledger/fabric-tools:$IMAGETAG peer version | sed -ne 's/ Version: //p' | head -1)
21 |
22 | echo "LOCAL_VERSION=$LOCAL_VERSION"
23 | echo "DOCKER_IMAGE_VERSION=$DOCKER_IMAGE_VERSION"
24 |
25 | if [ "$LOCAL_VERSION" != "$DOCKER_IMAGE_VERSION" ]; then
26 | echo "=================== WARNING ==================="
27 | echo " Local fabric binaries and docker images are "
28 | echo " out of sync. This may cause problems. "
29 | echo "==============================================="
30 | fi
31 |
32 | for UNSUPPORTED_VERSION in $BLACKLISTED_VERSIONS; do
33 | echo "$LOCAL_VERSION" | grep -q $UNSUPPORTED_VERSION
34 | if [ $? -eq 0 ]; then
35 | echo "ERROR! Local Fabric binary version of $LOCAL_VERSION does not match this newer version of [fabric-iot] and is unsupported. Either move to a later version of Fabric or checkout an earlier version of fabric-samples."
36 | exit 1
37 | fi
38 |
39 | echo "$DOCKER_IMAGE_VERSION" | grep -q $UNSUPPORTED_VERSION
40 | if [ $? -eq 0 ]; then
41 | echo "ERROR! Fabric Docker image version of $DOCKER_IMAGE_VERSION does not match this newer version of [fabric-iot] and is unsupported. Either move to a later version of Fabric or checkout an earlier version of fabric-samples."
42 | exit 1
43 | fi
44 | done
45 | }
46 |
47 | # Generate the needed certificates, the genesis block and start the network.
48 | function networkUp() {
49 | checkPrereqs
50 | # generate artifacts if they don't exist
51 | if [ ! -d "crypto-config" ]; then
52 | ./generate.sh
53 | fi
54 | COMPOSE_FILES="-f ${COMPOSE_FILE}"
55 | if [ "${CERTIFICATE_AUTHORITIES}" == "true" ]; then
56 | COMPOSE_FILES="${COMPOSE_FILES} -f ${COMPOSE_FILE_CA}"
57 | export CA1_PRIVATE_KEY=$(cd crypto-config/peerOrganizations/org1.fabric-iot.edu/ca && ls *_sk)
58 | export CA2_PRIVATE_KEY=$(cd crypto-config/peerOrganizations/org2.fabric-iot.edu/ca && ls *_sk)
59 | fi
60 | if [ "${CONSENSUS_TYPE}" == "kafka" ]; then
61 | COMPOSE_FILES="${COMPOSE_FILES} -f ${COMPOSE_FILE_KAFKA}"
62 | elif [ "${CONSENSUS_TYPE}" == "etcdraft" ]; then
63 | COMPOSE_FILES="${COMPOSE_FILES} -f ${COMPOSE_FILE_RAFT2}"
64 | fi
65 | if [ "${IF_COUCHDB}" == "couchdb" ]; then
66 | COMPOSE_FILES="${COMPOSE_FILES} -f ${COMPOSE_FILE_COUCH}"
67 | fi
68 | IMAGE_TAG=$IMAGETAG docker-compose ${COMPOSE_FILES} up -d 2>&1
69 | docker ps -a
70 | if [ $? -ne 0 ]; then
71 | echo "ERROR !!!! Unable to start network"
72 | exit 1
73 | fi
74 |
75 | if [ "$CONSENSUS_TYPE" == "kafka" ]; then
76 | sleep 1
77 | echo "Sleeping 15s to allow $CONSENSUS_TYPE cluster to complete booting"
78 | for i in {1..15}
79 | do
80 | echo -n '>'
81 | sleep 1
82 | done
83 | echo ' kafka maybe ready'
84 | fi
85 |
86 | if [ "$CONSENSUS_TYPE" == "etcdraft" ]; then
87 | sleep 1
88 | echo "Sleeping 15s to allow $CONSENSUS_TYPE cluster to complete booting"
89 | for i in {1..15}
90 | do
91 | echo -n '>'
92 | sleep 1
93 | done
94 | echo ' etcdraft maybe ready'
95 | fi
96 | }
97 |
98 | function runScript() {
99 | # now run the end to end script
100 | docker exec cli scripts/script.sh $CHANNEL_NAME $CLI_DELAY $LANGUAGE $CLI_TIMEOUT $VERBOSE $NO_CHAINCODE
101 | if [ $? -ne 0 ]; then
102 | echo "ERROR !!!! Test failed"
103 | exit 1
104 | fi
105 | }
106 |
107 | networkUp
108 | runScript
--------------------------------------------------------------------------------
/test/consensus/kafka/kafak_test.go:
--------------------------------------------------------------------------------
1 | package kafka
2 |
3 | import (
4 | "fmt"
5 | "testing"
6 | "time"
7 | )
8 |
9 | func TestKafka(t *testing.T) {
10 | for j := 10; j <= 500; j += 20 {
11 | start := time.Now().UnixNano()
12 | Kafka(j)
13 | end := time.Now().UnixNano()
14 | fmt.Printf("%-4d%.2f\n", j, float32(end-start)/1e6)
15 | }
16 |
17 | }
18 |
--------------------------------------------------------------------------------
/test/consensus/kafka/kafka.go:
--------------------------------------------------------------------------------
1 | package kafka
2 |
3 | import (
4 | "encoding/json"
5 | "fmt"
6 | "strconv"
7 | "time"
8 |
9 | mqtt "github.com/eclipse/paho.mqtt.golang"
10 | )
11 |
12 | const (
13 | TOPIC = "/test/kafka"
14 | HOST = "tcp://localhost:1883"
15 | )
16 |
17 | func Kafka(n int) {
18 |
19 | sn := make(chan bool)
20 | //start order
21 | go NewOrder(TOPIC, HOST, n).Rank(sn)
22 | <-sn
23 | //log.Println("Order started")
24 | //start peer
25 | ss := make(chan bool, n)
26 | sg := make(chan bool)
27 | for i := 0; i < n; i++ {
28 | go NewPeer(TOPIC, HOST).Submit(ss, sg)
29 | }
30 | //now wait all peer started
31 | for i := 0; i < n; i++ {
32 | <-ss
33 | }
34 | //log.Println("All peer started")
35 | //let all peer to submit Transaction
36 | close(sg)
37 | //wait order finish
38 | <-sn
39 | }
40 |
41 | func Wait() {
42 | sn := make(chan int)
43 | <-sn
44 | }
45 |
46 | /************* MQTTCli *************/
47 | type MQTTCli struct {
48 | id string
49 | c mqtt.Client
50 | }
51 |
52 | func NewMQTTCli(host string) *MQTTCli {
53 | mc := &MQTTCli{}
54 | mc.Connect(host)
55 | return mc
56 | }
57 |
58 | func (mc *MQTTCli) ID() string {
59 | return mc.id
60 | }
61 | func (mc *MQTTCli) Pub(topic string, msg interface{}) {
62 | // //log.Println("pub:", topic, msg)
63 | token := mc.c.Publish(topic, 1, false, msg)
64 | if token.Error() != nil {
65 | //log.Println(token.Error().Error())
66 | }
67 | }
68 |
69 | func (mc *MQTTCli) Sub(topic string, f func(client mqtt.Client, message mqtt.Message)) {
70 | if token := mc.c.Subscribe(topic, 0, f); token.Wait() && token.Error() != nil {
71 | fmt.Println(token.Error())
72 | }
73 | }
74 |
75 | func (mc *MQTTCli) Connect(host string) {
76 | mc.id = strconv.FormatInt(time.Now().UnixNano(), 10)
77 | opts := mqtt.NewClientOptions().AddBroker(host).SetClientID(mc.id)
78 | mc.c = mqtt.NewClient(opts)
79 | if token := mc.c.Connect(); token.Wait() && token.Error() != nil {
80 | panic(token.Error())
81 | }
82 | }
83 |
84 | /************* Peer *************/
85 | type Peer struct {
86 | topic string
87 | mc *MQTTCli
88 | }
89 |
90 | func (p *Peer) Submit(ss, sg chan bool) {
91 | p.mc.Sub(p.topic+"/call", func(client mqtt.Client, message mqtt.Message) {
92 | //sleep cost time
93 | CostTime()
94 | if string(message.Payload()) == "confirm" {
95 | p.mc.Pub(p.topic+"/back", "ok")
96 | }
97 | })
98 | ss <- true
99 | //log.Println("Peer", p.mc.id, "started")
100 | // all peer have started, now can pub
101 | if _, ok := <-sg; !ok {
102 | p.mc.Pub(p.topic, NewTransaction(p.mc.id).Bytes())
103 | }
104 |
105 | }
106 |
107 | func NewPeer(topic string, host string) *Peer {
108 | return &Peer{topic, NewMQTTCli(host)}
109 | }
110 |
111 | /************* Order *************/
112 | type Order struct {
113 | topic string
114 | mc *MQTTCli
115 | cNum int
116 | lock bool
117 | }
118 |
119 | func NewOrder(topic string, host string, cNum int) *Order {
120 | return &Order{topic: topic, mc: NewMQTTCli(host), cNum: cNum, lock: false}
121 | }
122 |
123 | func (o *Order) Rank(c chan bool) {
124 | o.mc.Sub(o.topic, func(client mqtt.Client, message mqtt.Message) {
125 | GetTransaction(message.Payload())
126 | if o.lock {
127 | //log.Println("Order rank:", t.PID, "at", t.Timestamp, "->reject")
128 | return
129 | }
130 | //only recesive 1 submit
131 | o.lock = true
132 | //log.Println("Order rank:", t.PID, "at", t.Timestamp, "->receive")
133 | //sent to other clients
134 | o.mc.Pub(o.topic+"/call", "confirm")
135 | })
136 | //log.Println("Order sub:", o.topic)
137 | o.mc.Sub(o.topic+"/back", func(client mqtt.Client, message mqtt.Message) {
138 | if b := message.Payload(); b != nil && string(b) == "ok" {
139 | CostTime()
140 | //log.Println("Order received:", string(b))
141 | o.cNum -= 1
142 | }
143 | if o.cNum == 0 {
144 | c <- true
145 | }
146 | })
147 | //log.Println("Order sub:", o.topic+"/back")
148 | c <- true
149 | }
150 |
151 | /************* Transaction *************/
152 | type Transaction struct {
153 | PID string
154 | Timestamp int64
155 | }
156 |
157 | func GetTransaction(b []byte) *Transaction {
158 | t := &Transaction{}
159 | if err := json.Unmarshal(b, t); err != nil {
160 | return nil
161 | }
162 | return t
163 | }
164 |
165 | func (t *Transaction) Bytes() []byte {
166 | b, err := json.Marshal(t)
167 | if err != nil {
168 | return nil
169 | }
170 | return b
171 | }
172 |
173 | func NewTransaction(pid string) *Transaction {
174 | return &Transaction{pid, time.Now().Unix()}
175 | }
176 |
177 | func CostTime() {
178 | time.Sleep(time.Microsecond * 500)
179 | }
180 |
--------------------------------------------------------------------------------
/test/consensus/pow/pow.go:
--------------------------------------------------------------------------------
1 | package pow
2 |
3 | import (
4 | "encoding/json"
5 |
6 | "github.com/newham/goblockchain/core"
7 |
8 | mqtt "github.com/eclipse/paho.mqtt.golang"
9 | "github.com/newham/fabric-iot/test/consensus/kafka"
10 | )
11 |
12 | const (
13 | TOPIC = "/test/pow"
14 | HOST = "tcp://localhost:1883"
15 | )
16 |
17 | func PoW(n, nBit int) {
18 | ss := make(chan bool, n)
19 | sg := make(chan bool)
20 | done := make(chan string, 1)
21 | for i := 0; i < n; i++ {
22 | go NewNode(TOPIC, HOST, n, nBit).Mine(ss, sg, done)
23 | }
24 | //now wait all node started
25 | for i := 0; i < n; i++ {
26 | <-ss
27 | }
28 | // log.Println("All node started")
29 | //let all node to submit Transaction
30 | close(sg)
31 | //wait finish
32 | // log.Println("Winner is:", <-done)
33 | }
34 |
35 | type Msg struct {
36 | ID string
37 | Block core.Block
38 | }
39 |
40 | func (m Msg) Bytes() []byte {
41 | bts, err := json.Marshal(m)
42 | if err != nil {
43 | println(err.Error())
44 | }
45 | return bts
46 | }
47 |
48 | type Node struct {
49 | topic string
50 | mc *kafka.MQTTCli
51 | cNum int
52 | cfNum int
53 | nBit int
54 | }
55 |
56 | func NewNode(topic string, host string, cNum, nBit int) *Node {
57 | return &Node{topic, kafka.NewMQTTCli(host), cNum, 0, nBit}
58 | }
59 |
60 | func (n *Node) Mine(ss, sg chan bool, done chan string) {
61 | n.mc.Sub(n.topic+"/mine", func(client mqtt.Client, message mqtt.Message) {
62 | //receive other's block
63 | // core.NewProofOfWork(core.NewBlock(nil, nil, nBit))
64 | b := message.Payload()
65 | msg := &Msg{}
66 | err := json.Unmarshal(b, msg)
67 | if err != nil {
68 | // log.Println(err.Error())
69 | }
70 | ok, _ := core.NewProofOfWork(&msg.Block).Validate(msg.Block.Nonce)
71 | if ok {
72 | n.mc.Pub(n.topic+"/to/"+msg.ID, "ok")
73 | }
74 | })
75 | n.mc.Sub(n.topic+"/to/"+n.mc.ID(), func(client mqtt.Client, message mqtt.Message) {
76 | if string(message.Payload()) == "ok" {
77 | n.cfNum++
78 | }
79 | if n.cfNum > n.cNum/2 {
80 | done <- n.mc.ID()
81 | }
82 | })
83 | ss <- true
84 | // log.Println("Node", n.mc.ID(), "started")
85 | if _, ok := <-sg; !ok {
86 | nb := core.NewGenesisBlock(n.mc.ID(), n.nBit)
87 | //start to pow
88 | nonce, _ := core.NewProofOfWork(nb).Work()
89 | nb.Nonce = nonce
90 | // log.Println("Node", n.mc.ID(), "minded:", nonce)
91 | msg := Msg{n.mc.ID(), *nb}
92 | //pub to all
93 | n.mc.Pub(n.topic+"/mine", msg.Bytes())
94 | }
95 | }
96 |
--------------------------------------------------------------------------------
/test/consensus/pow/pow_test.go:
--------------------------------------------------------------------------------
1 | package pow
2 |
3 | import (
4 | "fmt"
5 | "strconv"
6 | "testing"
7 | "time"
8 |
9 | "github.com/newham/goblockchain/core"
10 | )
11 |
12 | func TestPoW(t *testing.T) {
13 | nBit := 16
14 | for j := 5; j <= 100; j += 5 {
15 | start := time.Now().UnixNano()
16 | PoW(j, nBit)
17 | end := time.Now().UnixNano()
18 | fmt.Printf("%.2f\n", float32(end-start)/1e6)
19 | }
20 | }
21 |
22 | func TestNBit(t *testing.T) {
23 | for i := 1; i <= 23; i++ {
24 | start := time.Now().UnixNano()
25 | id := strconv.FormatInt(time.Now().UnixNano(), 10)
26 | nb := core.NewGenesisBlock(id, i)
27 | //start to pow
28 | nonce, hash := core.NewProofOfWork(nb).Work()
29 | end := time.Now().UnixNano()
30 | fmt.Printf("%-4d%s %-10d %x %.6f\n", i, id, nonce, hash, float32(end-start)/1e9)
31 | }
32 |
33 | }
34 |
--------------------------------------------------------------------------------
/test/tps/test.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "crypto/sha256"
5 | "fmt"
6 | "log"
7 | "math/rand"
8 | "net/http"
9 | "os"
10 | "strconv"
11 | "strings"
12 | "time"
13 |
14 | "github.com/newham/hamtask"
15 | )
16 |
17 | var BASE_URL = "http://localhost:8001/fabric-iot/test"
18 |
19 | func main() {
20 | ccName, fName, n := GetArgs()
21 | if n == -1 {
22 | println("please input client count")
23 | return
24 | }
25 | start := time.Now().Unix()
26 | // start := time.Now().UnixNano()
27 | if ccName == "dc" {
28 | if fName == "AddURL" {
29 | Loop(1, n, TestDCAddURL)
30 | } else if fName == "GetURL" {
31 | Loop(1, n, TestDCGetURL)
32 | }
33 | } else if ccName == "pc" {
34 | if fName == "AddPolicy" {
35 | Loop(1, n, TestPCAddPolicy)
36 | } else if fName == "QueryPolicy" {
37 | Loop(1, n, TestPCQueryPolicy)
38 | } else if fName == "DeletePolicy" {
39 | Loop(1, n, TestPCDeletePolicy)
40 | } else if fName == "UpdatePolicy" {
41 | Loop(1, n, TestPCUpdatePolicy)
42 | }
43 | } else if ccName == "ac" {
44 | if fName == "CheckAccess" {
45 | Loop(1, n, TestACCheckAccess)
46 | }
47 | } else {
48 | println("please input [cc_name] [f_name] [n]")
49 | }
50 |
51 | end := time.Now().Unix()
52 | println("cost time:", end-start, "second") //(end-start)/int64(time.Millisecond)
53 | }
54 |
55 | func GetArgs() (string, string, int) {
56 | args := os.Args
57 | if len(args) > 3 {
58 | cc_name := args[1]
59 | f_name := args[2]
60 | n, err := strconv.Atoi(args[3])
61 | if err != nil {
62 | println("bad count")
63 | return "", "", -1
64 | }
65 | return cc_name, f_name, n
66 | }
67 | return "", "", -1
68 | }
69 |
70 | func Loop(loop int, n int, f func(c chan int, n int)) {
71 | c := make(chan int)
72 | for i := 0; i < loop; i++ {
73 | go func() {
74 | f(c, n)
75 | }()
76 | }
77 | //waite
78 | for i := 0; i < loop; i++ {
79 | <-c
80 | }
81 | }
82 |
83 | func TestPCAddPolicy(c chan int, n int) {
84 | TestCC(c, n, func(i int) string {
85 | return GetURL("pc", "AddPolicy", GetPolicyReq(i, 1, 1, 1))
86 | })
87 | }
88 |
89 | func GetPolicyReq(i, r, g, AP int) string {
90 | now := time.Now().Unix()
91 | policyStr := fmt.Sprintf(`{"AS":{"userId":"%s","role":"u%d","group":"g%d"},"AO":{"deviceId":"%s","MAC":"%s"},"AP":%d,"AE":{"createdTime":%d,"endTime":%d,"allowedIP":"*.*.*.*"}}`, GetUserID(i), r, g, GetDeviceID(i), RandomMac(), AP, now, now+100000)
92 | return policyStr
93 | }
94 |
95 | func TestPCQueryPolicy(c chan int, n int) {
96 | TestCC(c, n, func(i int) string {
97 | return GetURL("pc", "QueryPolicy", GetPolicyID(i))
98 | })
99 | }
100 |
101 | func GetPolicyID(i int) string {
102 | return GetSHA256(GetUserID(i), GetDeviceID(i))
103 | }
104 |
105 | func GetSHA256(args ...string) string {
106 | return fmt.Sprintf("%x", sha256.Sum256([]byte(strings.Join(args, ""))))
107 | }
108 |
109 | func TestPCDeletePolicy(c chan int, n int) {
110 | TestCC(c, n, func(i int) string {
111 | return GetURL("pc", "DeletePolicy", GetPolicyID(i))
112 | })
113 | }
114 |
115 | func TestPCUpdatePolicy(c chan int, n int) {
116 | TestCC(c, n, func(i int) string {
117 | return GetURL("pc", "UpdatePolicy", GetPolicyReq(i, 1, 1, 0))
118 | })
119 | }
120 |
121 | func TestACCheckAccess(c chan int, n int) {
122 | i := 0
123 | hamtask.NewSimpleWorker(n, func(i int, d hamtask.Data) {
124 | url := d.String()
125 | _, err := http.Get(url)
126 | if err != nil {
127 | log.Println("Error", err.Error())
128 | return
129 | }
130 | // println(resp.Status)
131 |
132 | }, func() hamtask.Data {
133 | i++
134 | return hamtask.String(GetURL("ac", "CheckAccess", GetACRequest(i)))
135 | }, n).Start()
136 | c <- 1
137 | }
138 |
139 | func TestDCGetURL(c chan int, n int) {
140 |
141 | TestCC(c, n, func(i int) string {
142 | return GetURL("dc", "GetURL", GetDeviceID(i))
143 | })
144 | }
145 |
146 | func TestDCAddURL(c chan int, n int) {
147 | i := 0
148 | hamtask.NewSimpleWorker(n, func(i int, d hamtask.Data) {
149 | url := d.String()
150 | _, err := http.Get(url)
151 | if err != nil {
152 | log.Println("Error", err.Error())
153 | return
154 | }
155 | // println(resp.Status)
156 |
157 | }, func() hamtask.Data {
158 | i++
159 | return hamtask.String(GetURL("dc", "AddURL", GetDeviceID(i), "https://test"+GetDeviceID(i)+".res"))
160 | }, n).Start()
161 | c <- 1
162 | }
163 |
164 | func TestCC(c chan int, n int, f func(int) string) {
165 | i := 0
166 | hamtask.NewSimpleWorker(n, func(i int, d hamtask.Data) {
167 | url := d.String()
168 | _, err := http.Get(url)
169 | if err != nil {
170 | log.Println("Error", err.Error())
171 | return
172 | }
173 | // println(resp.Status)
174 |
175 | }, func() hamtask.Data {
176 | i++
177 | return hamtask.String(f(i))
178 | }, n).Start()
179 | c <- 1
180 | }
181 |
182 | func GetACRequest(i int) string {
183 | return fmt.Sprintf(`{"AS":{"userId":"%s","role":"u1","group":"g1"},"AO":{"deviceId":"%s","MAC":"00:11:22:33:44:55"}}`, GetUserID(i), GetDeviceID(i))
184 | }
185 |
186 | func GetID(i int) int {
187 | return i + 10000
188 | }
189 |
190 | func GetUserID(i int) string {
191 | return strconv.Itoa(GetID(i))
192 | }
193 |
194 | func GetDeviceID(i int) string {
195 | return fmt.Sprintf("D%d", GetID(i))
196 | }
197 |
198 | func GetURL(cc_name, f_name string, args ...string) string {
199 | return fmt.Sprintf("%s?cc_name=%s&f_name=%s&args=%s", BASE_URL, cc_name, f_name, strings.Join(args, "|"))
200 | }
201 |
202 | func RandomX(N, n int) string {
203 | ip := []string{}
204 | for i := 0; i < N; i++ {
205 | r := rand.New(rand.NewSource(time.Now().UnixNano()))
206 | ip = append(ip, strconv.FormatInt(int64(r.Intn(n)), 16))
207 | }
208 | return strings.Join(ip, ":")
209 | }
210 |
211 | func RandomMac() string {
212 | return RandomX(6, 64)
213 | }
214 |
215 | func RandomIPv6() string {
216 | return RandomX(8, 65536)
217 | }
218 |
--------------------------------------------------------------------------------