├── .gitignore ├── Dockerfile ├── README.md ├── app.js ├── basedocker └── nodeNnpm │ ├── Dockerfile │ ├── package.json │ └── run.sh ├── chaincode ├── .DS_Store ├── channel │ ├── configtx.yaml │ ├── crypto-config │ │ ├── ordererOrganizations │ │ │ └── ordererOrg1 │ │ │ │ ├── ca │ │ │ │ ├── 4d4a772215168b6594c87e82650e438f1f37c303e14b5f9e6f3ee06cc2bb823a_sk │ │ │ │ └── ordererOrg1-cert.pem │ │ │ │ ├── msp │ │ │ │ ├── admincerts │ │ │ │ │ └── ordererOrg1-cert.pem │ │ │ │ ├── cacerts │ │ │ │ │ ├── ordererOrg0.pem │ │ │ │ │ ├── ordererOrg1-cert.pem │ │ │ │ │ ├── peerOrg0.pem │ │ │ │ │ ├── peerOrg1.pem │ │ │ │ │ └── peerOrg2.pem │ │ │ │ └── signcerts │ │ │ │ │ └── ordererOrg1-cert.pem │ │ │ │ └── orderers │ │ │ │ └── ordererOrg1orderer1 │ │ │ │ ├── admincerts │ │ │ │ └── ordererOrg1-cert.pem │ │ │ │ ├── cacerts │ │ │ │ └── ordererOrg1-cert.pem │ │ │ │ ├── keystore │ │ │ │ └── 9707908924f92bbaa5c8a6961c260dc4992ad2fd7043cccf3f3948ffbea989e1_sk │ │ │ │ └── signcerts │ │ │ │ └── ordererOrg1orderer1-cert.pem │ │ └── peerOrganizations │ │ │ ├── peerOrg1 │ │ │ ├── ca │ │ │ │ ├── d8a5b3cac1b821f6e4b487ceaf1fd239cdcfc310894150908b90f05e9179556a_sk │ │ │ │ └── peerOrg1-cert.pem │ │ │ ├── msp │ │ │ │ ├── admincerts │ │ │ │ │ └── peerOrg1-cert.pem │ │ │ │ ├── cacerts │ │ │ │ │ ├── peerOrg0.pem │ │ │ │ │ └── peerOrg1-cert.pem │ │ │ │ └── signcerts │ │ │ │ │ └── peerOrg1-cert.pem │ │ │ └── peers │ │ │ │ ├── peerOrg1Peer1 │ │ │ │ ├── admincerts │ │ │ │ │ └── peerOrg1-cert.pem │ │ │ │ ├── cacerts │ │ │ │ │ └── peerOrg1-cert.pem │ │ │ │ ├── keystore │ │ │ │ │ └── 5e67f35124df6a9124bf3659365b8476af4090f73c82c9b626efc15f12739d5d_sk │ │ │ │ └── signcerts │ │ │ │ │ └── peerOrg1Peer1-cert.pem │ │ │ │ └── peerOrg1Peer2 │ │ │ │ ├── admincerts │ │ │ │ └── peerOrg1-cert.pem │ │ │ │ ├── cacerts │ │ │ │ └── peerOrg1-cert.pem │ │ │ │ ├── keystore │ │ │ │ └── 707c2b3c02ddd36a6c4a17771769b54a3dc9066e05be1e76582cabd65c110e4e_sk │ │ │ │ └── signcerts │ │ │ │ └── peerOrg1Peer2-cert.pem │ │ │ └── peerOrg2 │ │ │ ├── ca │ │ │ ├── 96bdb57f4efbdcf201a269899eb47e2a73fbb728ae14d47d0d5afb75ddea71de_sk │ │ │ └── peerOrg2-cert.pem │ │ │ ├── msp │ │ │ ├── admincerts │ │ │ │ └── peerOrg2-cert.pem │ │ │ ├── cacerts │ │ │ │ ├── peerOrg1.pem │ │ │ │ └── peerOrg2-cert.pem │ │ │ └── signcerts │ │ │ │ └── peerOrg2-cert.pem │ │ │ └── peers │ │ │ ├── peerOrg2Peer1 │ │ │ ├── admincerts │ │ │ │ └── peerOrg2-cert.pem │ │ │ ├── cacerts │ │ │ │ └── peerOrg2-cert.pem │ │ │ ├── keystore │ │ │ │ └── 26d8ff264dd3956922ff23e2fa2bca59817df114630f95adce343388f9fffe7a_sk │ │ │ └── signcerts │ │ │ │ └── peerOrg2Peer1-cert.pem │ │ │ └── peerOrg2Peer2 │ │ │ ├── admincerts │ │ │ └── peerOrg2-cert.pem │ │ │ ├── cacerts │ │ │ └── peerOrg2-cert.pem │ │ │ ├── keystore │ │ │ └── cc80356f4275390b2090bf0a62b26d3c5e9420c022d196267990eed7014bfcec_sk │ │ │ └── signcerts │ │ │ └── peerOrg2Peer2-cert.pem │ ├── generateCfgTrx.sh │ ├── jutian │ ├── jutianA │ ├── jutianaaa │ ├── jutianchannel │ ├── mychannel.tx │ ├── orderer.block │ └── twoorgs.orderer.block ├── channelchannel.tx ├── cloudant.json ├── couchdb.json ├── docker-compose-marbles.yml ├── docker-compose.yaml ├── fabricca │ ├── tlsOrg1 │ │ └── fabric-ca-server.db │ └── tlsOrg2 │ │ └── fabric-ca-server.db ├── fabriccop │ ├── ecert.pem │ └── enroll-csr.pem ├── local.json ├── msp │ ├── local │ │ ├── keystore │ │ │ └── admin.pem │ │ └── signcerts │ │ │ └── admin.pem │ ├── org0 │ │ ├── admincerts │ │ │ └── admin.pem │ │ └── cacerts │ │ │ └── org_ca.pem │ └── org1 │ │ ├── admincerts │ │ └── admin.pem │ │ └── cacerts │ │ └── org_ca.pem ├── src │ └── jutian_cc │ │ ├── Dockerfile │ │ ├── account_db.go │ │ ├── account_money_db.go │ │ ├── farmer_asset_db.go │ │ ├── financial_db.go │ │ ├── jutian_cc.go │ │ ├── logistic_db.go │ │ ├── merchant_db.go │ │ ├── order_db.go │ │ ├── package_db.go │ │ ├── pb_response.go │ │ ├── tool.go │ │ └── warehouse_db.go └── tls │ ├── orderer │ ├── ca-cert.pem │ ├── cert.pem │ └── key.pem │ └── peers │ ├── peer0 │ ├── ca-cert.pem │ ├── cert.pem │ └── key.pem │ ├── peer1 │ ├── ca-cert.pem │ ├── cert.pem │ └── key.pem │ ├── peer2 │ ├── ca-cert.pem │ ├── cert.pem │ └── key.pem │ └── peer3 │ ├── ca-cert.pem │ ├── cert.pem │ └── key.pem ├── config ├── config.json ├── credentials.json ├── local-credentials.json └── server_config.js ├── docker.sh ├── package.json ├── pm2.sh ├── server ├── chaincode │ ├── chaincode.js │ ├── create-channel.js │ ├── install-chaincode.js │ ├── instantiate-chaincode.js │ ├── join-channel.js │ └── util.js ├── constant.js ├── middleware │ └── tokenvalidation.js ├── model │ └── user.model.js ├── server.js ├── service │ ├── asset.service.js │ ├── blockchain.service.js │ ├── logistic.service.js │ ├── merchandise.service.js │ ├── order.service.js │ ├── package.service.js │ ├── user.service.js │ └── warehouse.service.js └── tool.js └── test ├── response.js ├── test-chaincode-init.js ├── test-chaincode-upgrade.js ├── test-service-asset.js ├── test-service-blockchain.js ├── test-service-logistic.js ├── test-service-merchandise.js ├── test-service-order.js ├── test-service-package.js ├── test-service-user.js ├── test-service-warehouse.js └── util.js /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | 8 | # Runtime data 9 | pids 10 | *.pid 11 | *.seed 12 | *.pid.lock 13 | 14 | # Directory for instrumented libs generated by jscoverage/JSCover 15 | lib-cov 16 | 17 | # Coverage directory used by tools like istanbul 18 | coverage 19 | 20 | # nyc test coverage 21 | .nyc_output 22 | 23 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 24 | .grunt 25 | 26 | # Bower dependency directory (https://bower.io/) 27 | bower_components 28 | 29 | # node-waf configuration 30 | .lock-wscript 31 | 32 | # Compiled binary addons (http://nodejs.org/api/addons.html) 33 | build/Release 34 | 35 | # Dependency directories 36 | node_modules/ 37 | jspm_packages/ 38 | 39 | # Typescript v1 declaration files 40 | typings/ 41 | 42 | # Optional npm cache directory 43 | .npm 44 | 45 | # Optional eslint cache 46 | .eslintcache 47 | 48 | # Optional REPL history 49 | .node_repl_history 50 | 51 | # Output of 'npm pack' 52 | *.tgz 53 | 54 | # Yarn Integrity file 55 | .yarn-integrity 56 | 57 | # dotenv environment variables file 58 | .env 59 | 60 | tmp 61 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM nodenpm 2 | 3 | # Bundle app source 4 | COPY . /usr/src/app 5 | 6 | RUN npm install 7 | 8 | RUN npm start 9 | 10 | # Expose the port. 11 | EXPOSE 8080 12 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 这里不再更新。 2 | fork到我的项目里了:https://github.com/jasoncodingnow/N0041-argiculture-supplychain 3 | 4 | ### 基于区块链的农业供应链解决方案demo 5 | 6 | #### 说明 7 | * 该demo作为演示,展示了如何在农业场景下使用区块链: 8 | * 农产品流转溯源 9 | * 资金流 10 | * 信息流 11 | * 金融风控 12 | 13 | * 各个角色: 14 | * 商户: 管理订单、结算支付 15 | * 农户: 管理资产、管理订单 16 | * 中间环节: 包装商、仓库、物流 17 | * 金融: 管理贷款还款、风险 18 | 19 | 20 | #### 结构说明 21 | 22 | * basedocker: node以及npm dependencies 打包成Docker container,避免每次Docker运行都需要download dependencies 23 | * chaincode: chaincode代码以及配套工具: 24 | * org define 25 | * channel data tool 26 | * chaincode source code 27 | * certificate files 28 | * docker config files 29 | * config: 配置文档 30 | * public: 前端web页面 31 | * server: 后端服务代码 32 | * chaincode: chaincode tool for service 33 | * middleware: service middleware 34 | * model 35 | * service 36 | * server.js: 后端服务初始化入口 37 | * test: 后端service单元测试代码 38 | * pm2.sh: 如果不采用Docker部署,pm2部署也是可以 39 | * app.js: 初始化backend service,连接chaincode 40 | 41 | 42 | -------------------------------------------------------------------------------- /app.js: -------------------------------------------------------------------------------- 1 | 2 | 3 | 'use strict'; 4 | 5 | let express = require('express'); 6 | let session = require('express-session'); 7 | let cookieParser = require('cookie-parser'); 8 | let bodyParser = require('body-parser'); 9 | let url = require('url'); 10 | let cors = require('cors'); 11 | let fs = require('fs'); 12 | let path = require('path'); 13 | let hfc = require('hfc'); 14 | let http = require('http'); 15 | let Redis = require('ioredis'); 16 | let server = require('./server/server.js'); 17 | 18 | var serve_static = require('serve-static'); 19 | 20 | let config = fs.readFileSync(__dirname + '/config/config.json'); 21 | config = JSON.parse(config)["config"]; 22 | 23 | let app = express(); 24 | 25 | app.use(bodyParser.json()); 26 | app.use(bodyParser.urlencoded()); 27 | app.options('*', cors()); 28 | app.use(cors()); 29 | 30 | var compression = require('compression'); 31 | app.use(compression()); //use compression 32 | app.use(serve_static(path.join(__dirname, 'public'))); 33 | 34 | process.env.APP_NAME = 'ASSET_TRADING'; 35 | 36 | let redis = new Redis(config.redis); 37 | redis.on('error', function(err) { 38 | console.log(err); 39 | }) 40 | redis.set('foo', 'bar'); 41 | redis.get('foo', function (err, result) { 42 | if (result == 'bar') 43 | console.log('redis connect success'); 44 | }); 45 | 46 | let Constant = require("./server/constant.js"); 47 | Constant.redis = redis; 48 | 49 | require('cf-deployment-tracker-client').track(); 50 | process.env.NODE_TLS_REJECT_UNAUTHORIZED = '0'; 51 | process.env.NODE_ENV = 'production'; 52 | process.env.GOPATH = path.resolve(__dirname, 'chaincode'); 53 | 54 | 55 | require(__dirname + "/server/chaincode/chaincode.js").enroll() 56 | .then((admin) => { 57 | Constant.setAdmin(admin); 58 | console.log("SUCCESS"); 59 | server.start(app, redis, config.port); 60 | }).catch((err) => { 61 | console.log(err) 62 | }); 63 | 64 | // require(__dirname + "/server/chaincode/create-channel.js").createChannel() 65 | // .then(() => { 66 | // return require(__dirname + "/server/chaincode/join-channel.js").joinChannel(); 67 | // }).then(() => { 68 | // return require(__dirname + "/server/chaincode/install-chaincode.js").installChaincode(); 69 | // }).then(() => { 70 | // return require(__dirname + "/server/chaincode/instantiate-chaincode.js").instantiateChaincode(); 71 | // }).then(() => { 72 | // return require(__dirname + "/server/chaincode/chaincode.js").enroll(); 73 | // }).then((admin) => { 74 | // console.log("SUCCESS"); 75 | // server.start(app, redis, config.port); 76 | // }).catch((err) => { 77 | // console.log(err) 78 | // }); 79 | 80 | -------------------------------------------------------------------------------- /basedocker/nodeNnpm/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM node:6.9.1 2 | 3 | # Install required prereqs. 4 | # RUN apt-get -y update && apt-get -y install netcat 5 | 6 | # Create app directory 7 | RUN mkdir -p /usr/src/app 8 | WORKDIR /usr/src/app 9 | 10 | RUN npm install -------------------------------------------------------------------------------- /basedocker/nodeNnpm/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "datachain_asset_trading_demo2", 3 | "version": "1.0.0", 4 | "description": "demo for asset trading", 5 | "main": "app.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1", 8 | "start": "node app.js" 9 | }, 10 | "keywords": [ 11 | "asset", 12 | "trading", 13 | "datachain", 14 | "blockchain" 15 | ], 16 | "dependencies": { 17 | "async": "0.9.*", 18 | "body-parser": "^1.17.1", 19 | "cf-deployment-tracker-client": "*", 20 | "compression": "1.6.*", 21 | "cookie-parser": "1.4.*", 22 | "cors": "2.8.*", 23 | "express": "^4.14.1", 24 | "express-session": "1.14.*", 25 | "fabric-ca-client": "^1.0.0-alpha.0", 26 | "fabric-client": "^1.0.0-alpha", 27 | "grpc": "^1.2.0", 28 | "hfc": "^0.6.5", 29 | "ioredis": "^2.5.0", 30 | "jade": "1.11.*", 31 | "jsrsasign": "^7.1.2", 32 | "serve-static": "1.11.*", 33 | "winston": "2.2.*", 34 | "ws": "1.1.*", 35 | "x509": "" 36 | }, 37 | "engines": { 38 | "node": "^6.9.1", 39 | "npm": "^3.10.8" 40 | }, 41 | "author": "Jason", 42 | "license": "ISC" 43 | } 44 | -------------------------------------------------------------------------------- /basedocker/nodeNnpm/run.sh: -------------------------------------------------------------------------------- 1 | # /bin/bash 2 | 3 | # 制作自己的基础镜像,构建好node环境和npm 以及 dependencies 4 | # 因为每次build都得下载一次 dependencies,很累 5 | cp ../../package.json package.json 6 | docker build -t nodenpm . -------------------------------------------------------------------------------- /chaincode/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CBD-Forum/N0041-argiculture-supplychain/1076f95ebb67df8f3246f99a49a0f3c247d39647/chaincode/.DS_Store -------------------------------------------------------------------------------- /chaincode/channel/configtx.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | ################################################################################ 3 | # 4 | # Profile - meant to be used with docker-2orgs-2peerseach-e2e.yml 5 | # 6 | # - Different configuration profiles may be encoded here to be specified 7 | # as parameters to the configtxgen tool 8 | # 9 | ################################################################################ 10 | Profiles: 11 | 12 | TwoOrgs: 13 | Orderer: 14 | <<: *OrdererDefaults 15 | Organizations: 16 | - *OrdererOrg 17 | Application: 18 | <<: *ApplicationDefaults 19 | Organizations: 20 | - *Org0 21 | - *Org1 22 | 23 | ################################################################################ 24 | # 25 | # Section: Organizations 26 | # 27 | # - This section defines the different organizational identities which will 28 | # be referenced later in the configuration. 29 | # 30 | ################################################################################ 31 | Organizations: 32 | 33 | # SampleOrg defines an MSP using the sampleconfig. It should never be used 34 | # in production but may be used as a template for other definitions 35 | - &OrdererOrg 36 | # DefaultOrg defines the organization which is used in the sampleconfig 37 | # of the fabric.git development environment 38 | Name: OrdererMSP 39 | 40 | # ID to load the MSP definition as 41 | ID: OrdererMSP 42 | 43 | # MSPDir is the filesystem path which contains the MSP configuration 44 | ######################################################################### 45 | # FIXME: this path needs to be fixed to point to the actual location of # 46 | # the project 'fabric-sdk-node' in the file system # 47 | ######################################################################### 48 | MSPDir: /Users/david/Desktop/work/code/gopath/src/datachain/jutian-backend/chaincode/channel/crypto-config/ordererOrganizations/ordererOrg1/msp 49 | 50 | # BCCSP (Blockchain crypto provider): Select which crypto implementation or 51 | # library to use 52 | BCCSP: 53 | Default: SW 54 | SW: 55 | Hash: SHA2 56 | Security: 256 57 | # Location of Key Store. If this is unset, a location will 58 | # be chosen using 'MSPDir'/keystore 59 | FileKeyStore: 60 | KeyStore: 61 | 62 | - &Org0 63 | # DefaultOrg defines the organization which is used in the sampleconfig 64 | # of the fabric.git development environment 65 | Name: Org1MSP 66 | 67 | # ID to load the MSP definition as 68 | ID: Org1MSP 69 | 70 | # MSPDir is the filesystem path which contains the MSP configuration 71 | ######################################################################### 72 | # FIXME: this path needs to be fixed to point to the actual location of # 73 | # the project 'fabric-sdk-node' in the file system # 74 | ######################################################################### 75 | MSPDir: /Users/david/Desktop/work/code/gopath/src/datachain/jutian-backend/chaincode/channel/crypto-config/peerOrganizations/peerOrg1/msp/ 76 | 77 | # BCCSP (Blockchain crypto provider): Select which crypto implementation or 78 | # library to use 79 | BCCSP: 80 | Default: SW 81 | SW: 82 | Hash: SHA2 83 | Security: 256 84 | # Location of Key Store. If this is unset, a location will 85 | # be chosen using 'MSPDir'/keystore 86 | FileKeyStore: 87 | KeyStore: 88 | 89 | AnchorPeers: 90 | # AnchorPeers defines the location of peers which can be used 91 | # for cross org gossip communication. Note, this value is only 92 | # encoded in the genesis block in the Application section context 93 | - Host: peer0 94 | Port: 7051 95 | - Host: peer1 96 | Port: 7056 97 | 98 | - &Org1 99 | # DefaultOrg defines the organization which is used in the sampleconfig 100 | # of the fabric.git development environment 101 | Name: Org2MSP 102 | 103 | # ID to load the MSP definition as 104 | ID: Org2MSP 105 | 106 | # MSPDir is the filesystem path which contains the MSP configuration 107 | ######################################################################### 108 | # FIXME: this path needs to be fixed to point to the actual location of # 109 | # the project 'fabric-sdk-node' in the file system # 110 | ######################################################################### 111 | MSPDir: /Users/david/Desktop/work/code/gopath/src/datachain/jutian-backend/chaincode/channel/crypto-config/peerOrganizations/peerOrg2/msp/ 112 | 113 | # BCCSP (Blockchain crypto provider): Select which crypto implementation or 114 | # library to use 115 | BCCSP: 116 | Default: SW 117 | SW: 118 | Hash: SHA2 119 | Security: 256 120 | # Location of Key Store. If this is unset, a location will 121 | # be chosen using 'MSPDir'/keystore 122 | FileKeyStore: 123 | KeyStore: 124 | 125 | AnchorPeers: 126 | # AnchorPeers defines the location of peers which can be used 127 | # for cross org gossip communication. Note, this value is only 128 | # encoded in the genesis block in the Application section context 129 | - Host: peer2 130 | Port: 8051 131 | - Host: peer3 132 | Port: 8056 133 | 134 | ################################################################################ 135 | # 136 | # SECTION: Orderer 137 | # 138 | # - This section defines the values to encode into a config transaction or 139 | # genesis block for orderer related parameters 140 | # 141 | ################################################################################ 142 | Orderer: &OrdererDefaults 143 | 144 | # Orderer Type: The orderer implementation to start 145 | # Available types are "solo" and "kafka" 146 | OrdererType: solo 147 | 148 | Addresses: 149 | - orderer0:7050 150 | 151 | # Batch Timeout: The amount of time to wait before creating a batch 152 | BatchTimeout: 10s 153 | 154 | # Batch Size: Controls the number of messages batched into a block 155 | BatchSize: 156 | 157 | # Max Message Count: The maximum number of messages to permit in a batch 158 | MaxMessageCount: 10 159 | 160 | # Absolute Max Bytes: The absolute maximum number of bytes allowed for 161 | # the serialized messages in a batch. 162 | AbsoluteMaxBytes: 99 MB 163 | 164 | # Preferred Max Bytes: The preferred maximum number of bytes allowed for 165 | # the serialized messages in a batch. A message larger than the preferred 166 | # max bytes will result in a batch larger than preferred max bytes. 167 | PreferredMaxBytes: 512 KB 168 | 169 | Kafka: 170 | # Brokers: A list of Kafka brokers to which the orderer connects 171 | # NOTE: Use IP:port notation 172 | Brokers: 173 | - orderer0:9092 174 | 175 | # Organizations is the list of orgs which are defined as participants on 176 | # the orderer side of the network 177 | Organizations: 178 | 179 | ################################################################################ 180 | # 181 | # SECTION: Application 182 | # 183 | # - This section defines the values to encode into a config transaction or 184 | # genesis block for application related parameters 185 | # 186 | ################################################################################ 187 | Application: &ApplicationDefaults 188 | 189 | # Organizations is the list of orgs which are defined as participants on 190 | # the application side of the network 191 | Organizations: 192 | -------------------------------------------------------------------------------- /chaincode/channel/crypto-config/ordererOrganizations/ordererOrg1/ca/4d4a772215168b6594c87e82650e438f1f37c303e14b5f9e6f3ee06cc2bb823a_sk: -------------------------------------------------------------------------------- 1 | -----BEGIN ECDSA PRIVATE KEY----- 2 | MHcCAQEEIAMJVFaIpzyJViVo/VLSD84gVidcKAvJsllwGwmQlJ6hoAoGCCqGSM49 3 | AwEHoUQDQgAETUmk7oKMKf2OF3GOx67Ppt6BP4/Af4yKdx/LYTYWFHZB1+vcDbEQ 4 | er/7xJR5+gj41B6TQIr218PXSM+192iP1w== 5 | -----END ECDSA PRIVATE KEY----- 6 | -------------------------------------------------------------------------------- /chaincode/channel/crypto-config/ordererOrganizations/ordererOrg1/ca/ordererOrg1-cert.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIICKTCCAdCgAwIBAgIRALz4qIofOY8ff94YDATVyGIwCgYIKoZIzj0EAwIwZjEL 3 | MAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcTDVNhbiBG 4 | cmFuY2lzY28xFDASBgNVBAoTC29yZGVyZXJPcmcxMRQwEgYDVQQDEwtvcmRlcmVy 5 | T3JnMTAeFw0xNzAzMDExNzM2NDFaFw0yNzAyMjcxNzM2NDFaMGYxCzAJBgNVBAYT 6 | AlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlhMRYwFAYDVQQHEw1TYW4gRnJhbmNpc2Nv 7 | MRQwEgYDVQQKEwtvcmRlcmVyT3JnMTEUMBIGA1UEAxMLb3JkZXJlck9yZzEwWTAT 8 | BgcqhkjOPQIBBggqhkjOPQMBBwNCAARNSaTugowp/Y4XcY7Hrs+m3oE/j8B/jIp3 9 | H8thNhYUdkHX69wNsRB6v/vElHn6CPjUHpNAivbXw9dIz7X3aI/Xo18wXTAOBgNV 10 | HQ8BAf8EBAMCAaYwDwYDVR0lBAgwBgYEVR0lADAPBgNVHRMBAf8EBTADAQH/MCkG 11 | A1UdDgQiBCBNSnciFRaLZZTIfoJlDkOPHzfDA+FLX55vPuBswruCOjAKBggqhkjO 12 | PQQDAgNHADBEAiBa6k7Cax+McCHy61Jma1vLuFZswBbnsC6DqbveiKdUoAIgeyAf 13 | HzWxMoVrLfPFwF75PqCjae7xnYq+RWlsHZlMGFU= 14 | -----END CERTIFICATE----- 15 | -------------------------------------------------------------------------------- /chaincode/channel/crypto-config/ordererOrganizations/ordererOrg1/msp/admincerts/ordererOrg1-cert.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIICKTCCAdCgAwIBAgIRALz4qIofOY8ff94YDATVyGIwCgYIKoZIzj0EAwIwZjEL 3 | MAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcTDVNhbiBG 4 | cmFuY2lzY28xFDASBgNVBAoTC29yZGVyZXJPcmcxMRQwEgYDVQQDEwtvcmRlcmVy 5 | T3JnMTAeFw0xNzAzMDExNzM2NDFaFw0yNzAyMjcxNzM2NDFaMGYxCzAJBgNVBAYT 6 | AlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlhMRYwFAYDVQQHEw1TYW4gRnJhbmNpc2Nv 7 | MRQwEgYDVQQKEwtvcmRlcmVyT3JnMTEUMBIGA1UEAxMLb3JkZXJlck9yZzEwWTAT 8 | BgcqhkjOPQIBBggqhkjOPQMBBwNCAARNSaTugowp/Y4XcY7Hrs+m3oE/j8B/jIp3 9 | H8thNhYUdkHX69wNsRB6v/vElHn6CPjUHpNAivbXw9dIz7X3aI/Xo18wXTAOBgNV 10 | HQ8BAf8EBAMCAaYwDwYDVR0lBAgwBgYEVR0lADAPBgNVHRMBAf8EBTADAQH/MCkG 11 | A1UdDgQiBCBNSnciFRaLZZTIfoJlDkOPHzfDA+FLX55vPuBswruCOjAKBggqhkjO 12 | PQQDAgNHADBEAiBa6k7Cax+McCHy61Jma1vLuFZswBbnsC6DqbveiKdUoAIgeyAf 13 | HzWxMoVrLfPFwF75PqCjae7xnYq+RWlsHZlMGFU= 14 | -----END CERTIFICATE----- 15 | -------------------------------------------------------------------------------- /chaincode/channel/crypto-config/ordererOrganizations/ordererOrg1/msp/cacerts/ordererOrg0.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIIBcjCCARigAwIBAwICA+gwCgYIKoZIzj0EAwIwFjEUMBIGA1UEAwwLb3JkZXJl 3 | ck9yZzAwHhcNMTcwMjIwMTkwNjEwWhcNMTgwMjIwMTkwNjEwWjAWMRQwEgYDVQQD 4 | DAtvcmRlcmVyT3JnMDBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABK8Sv0EA9h06 5 | fmBkUCO+D/b/2INZ2huy+W/HCxSF22c7WGoJbRzQcWtQmW1KqZowUk86RcxVfFqv 6 | jEMFVXzV38SjVjBUMBIGA1UdEwEB/wQIMAYBAf8CAQAwHQYDVR0OBBYEFCVakuvq 7 | xEcK8pYMf/Hw8hsexRMTMB8GA1UdIwQYMBaAFCVakuvqxEcK8pYMf/Hw8hsexRMT 8 | MAoGCCqGSM49BAMCA0gAMEUCIQCmXgDSRTyxpSk+PXg0FNlYZ4ijTVwKgLkYVhod 9 | zZPfngIgO4y0p3Fs/gNsJYrroKaaVDe955KrPp/O55jYDKAD/oY= 10 | -----END CERTIFICATE----- 11 | -------------------------------------------------------------------------------- /chaincode/channel/crypto-config/ordererOrganizations/ordererOrg1/msp/cacerts/ordererOrg1-cert.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIICKTCCAdCgAwIBAgIRALz4qIofOY8ff94YDATVyGIwCgYIKoZIzj0EAwIwZjEL 3 | MAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcTDVNhbiBG 4 | cmFuY2lzY28xFDASBgNVBAoTC29yZGVyZXJPcmcxMRQwEgYDVQQDEwtvcmRlcmVy 5 | T3JnMTAeFw0xNzAzMDExNzM2NDFaFw0yNzAyMjcxNzM2NDFaMGYxCzAJBgNVBAYT 6 | AlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlhMRYwFAYDVQQHEw1TYW4gRnJhbmNpc2Nv 7 | MRQwEgYDVQQKEwtvcmRlcmVyT3JnMTEUMBIGA1UEAxMLb3JkZXJlck9yZzEwWTAT 8 | BgcqhkjOPQIBBggqhkjOPQMBBwNCAARNSaTugowp/Y4XcY7Hrs+m3oE/j8B/jIp3 9 | H8thNhYUdkHX69wNsRB6v/vElHn6CPjUHpNAivbXw9dIz7X3aI/Xo18wXTAOBgNV 10 | HQ8BAf8EBAMCAaYwDwYDVR0lBAgwBgYEVR0lADAPBgNVHRMBAf8EBTADAQH/MCkG 11 | A1UdDgQiBCBNSnciFRaLZZTIfoJlDkOPHzfDA+FLX55vPuBswruCOjAKBggqhkjO 12 | PQQDAgNHADBEAiBa6k7Cax+McCHy61Jma1vLuFZswBbnsC6DqbveiKdUoAIgeyAf 13 | HzWxMoVrLfPFwF75PqCjae7xnYq+RWlsHZlMGFU= 14 | -----END CERTIFICATE----- 15 | -------------------------------------------------------------------------------- /chaincode/channel/crypto-config/ordererOrganizations/ordererOrg1/msp/cacerts/peerOrg0.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIIBbDCCARKgAwIBAwICA+gwCgYIKoZIzj0EAwIwEzERMA8GA1UEAwwIcGVlck9y 3 | ZzAwHhcNMTcwMjIwMTkwNjEwWhcNMTgwMjIwMTkwNjEwWjATMREwDwYDVQQDDAhw 4 | ZWVyT3JnMDBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABKJfDc/CcaiHRipTG2AB 5 | K5fA0LO9SOlbtC9bZcjLo/xsL157p+3QB3UVF3gt7nkwgMs/ul3FhSEFTk2EVNlF 6 | 1QCjVjBUMBIGA1UdEwEB/wQIMAYBAf8CAQAwHQYDVR0OBBYEFFQzuQR1RZP/Qn/B 7 | NDtGSa8n4eN/MB8GA1UdIwQYMBaAFFQzuQR1RZP/Qn/BNDtGSa8n4eN/MAoGCCqG 8 | SM49BAMCA0gAMEUCIAuG+/Fy3x9JXAD1/rFsu3ZpCKbXiXZLGF7P6Gma8is5AiEA 9 | pSQpRcdukxe4zvcfRmNBjMbNLWCoWlHSQA2jD678QGE= 10 | -----END CERTIFICATE----- 11 | -------------------------------------------------------------------------------- /chaincode/channel/crypto-config/ordererOrganizations/ordererOrg1/msp/cacerts/peerOrg1.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIIBbDCCARKgAwIBAwICA+gwCgYIKoZIzj0EAwIwEzERMA8GA1UEAwwIcGVlck9y 3 | ZzEwHhcNMTcwMjIwMTkwNjEwWhcNMTgwMjIwMTkwNjEwWjATMREwDwYDVQQDDAhw 4 | ZWVyT3JnMTBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABJ2S+UvyFgFZYL6qcrKo 5 | zy72Nkc/RQVzg1VfwC3X7QcnHEVBuCzba1nxdDVE8XPnhmKBWLKh0adn6GKUZpyf 6 | mbKjVjBUMBIGA1UdEwEB/wQIMAYBAf8CAQAwHQYDVR0OBBYEFAQlMVsXlKGMEWPf 7 | KMMM6QVASnlPMB8GA1UdIwQYMBaAFAQlMVsXlKGMEWPfKMMM6QVASnlPMAoGCCqG 8 | SM49BAMCA0gAMEUCIHr4AD6Xx3R6zFCsveIMnWao9Us88/0uGHoT4ELmMhA1AiEA 9 | yzfXU5qHp3xBJ1BrKOGi71UmQZVwWfO26INhxcfpCAg= 10 | -----END CERTIFICATE----- 11 | -------------------------------------------------------------------------------- /chaincode/channel/crypto-config/ordererOrganizations/ordererOrg1/msp/cacerts/peerOrg2.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIIBbDCCARKgAwIBAwICA+gwCgYIKoZIzj0EAwIwEzERMA8GA1UEAwwIcGVlck9y 3 | ZzIwHhcNMTcwMjIwMTkwNjExWhcNMTgwMjIwMTkwNjExWjATMREwDwYDVQQDDAhw 4 | ZWVyT3JnMjBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABH3IweQK1AJdcV3FF27a 5 | gNKhy13Nz2OguzsmUbW85/7pReenAWzs89rEApHXoJqUtNzdZfaLkcq32E1Ilk3N 6 | oN2jVjBUMBIGA1UdEwEB/wQIMAYBAf8CAQAwHQYDVR0OBBYEFEhOilIyGA53r9Zo 7 | O5GQP0RSZcQ1MB8GA1UdIwQYMBaAFEhOilIyGA53r9ZoO5GQP0RSZcQ1MAoGCCqG 8 | SM49BAMCA0gAMEUCIQD+/5z68ewJarixMgYrg/MwyTMwX7ikCaCgU5TN2MU1PQIg 9 | Qe+klrq6COxsmrctClV64Wj4zhGTOhaZG1yN24OXukQ= 10 | -----END CERTIFICATE----- 11 | -------------------------------------------------------------------------------- /chaincode/channel/crypto-config/ordererOrganizations/ordererOrg1/msp/signcerts/ordererOrg1-cert.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIICKTCCAdCgAwIBAgIRALz4qIofOY8ff94YDATVyGIwCgYIKoZIzj0EAwIwZjEL 3 | MAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcTDVNhbiBG 4 | cmFuY2lzY28xFDASBgNVBAoTC29yZGVyZXJPcmcxMRQwEgYDVQQDEwtvcmRlcmVy 5 | T3JnMTAeFw0xNzAzMDExNzM2NDFaFw0yNzAyMjcxNzM2NDFaMGYxCzAJBgNVBAYT 6 | AlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlhMRYwFAYDVQQHEw1TYW4gRnJhbmNpc2Nv 7 | MRQwEgYDVQQKEwtvcmRlcmVyT3JnMTEUMBIGA1UEAxMLb3JkZXJlck9yZzEwWTAT 8 | BgcqhkjOPQIBBggqhkjOPQMBBwNCAARNSaTugowp/Y4XcY7Hrs+m3oE/j8B/jIp3 9 | H8thNhYUdkHX69wNsRB6v/vElHn6CPjUHpNAivbXw9dIz7X3aI/Xo18wXTAOBgNV 10 | HQ8BAf8EBAMCAaYwDwYDVR0lBAgwBgYEVR0lADAPBgNVHRMBAf8EBTADAQH/MCkG 11 | A1UdDgQiBCBNSnciFRaLZZTIfoJlDkOPHzfDA+FLX55vPuBswruCOjAKBggqhkjO 12 | PQQDAgNHADBEAiBa6k7Cax+McCHy61Jma1vLuFZswBbnsC6DqbveiKdUoAIgeyAf 13 | HzWxMoVrLfPFwF75PqCjae7xnYq+RWlsHZlMGFU= 14 | -----END CERTIFICATE----- 15 | -------------------------------------------------------------------------------- /chaincode/channel/crypto-config/ordererOrganizations/ordererOrg1/orderers/ordererOrg1orderer1/admincerts/ordererOrg1-cert.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIICKTCCAdCgAwIBAgIRALz4qIofOY8ff94YDATVyGIwCgYIKoZIzj0EAwIwZjEL 3 | MAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcTDVNhbiBG 4 | cmFuY2lzY28xFDASBgNVBAoTC29yZGVyZXJPcmcxMRQwEgYDVQQDEwtvcmRlcmVy 5 | T3JnMTAeFw0xNzAzMDExNzM2NDFaFw0yNzAyMjcxNzM2NDFaMGYxCzAJBgNVBAYT 6 | AlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlhMRYwFAYDVQQHEw1TYW4gRnJhbmNpc2Nv 7 | MRQwEgYDVQQKEwtvcmRlcmVyT3JnMTEUMBIGA1UEAxMLb3JkZXJlck9yZzEwWTAT 8 | BgcqhkjOPQIBBggqhkjOPQMBBwNCAARNSaTugowp/Y4XcY7Hrs+m3oE/j8B/jIp3 9 | H8thNhYUdkHX69wNsRB6v/vElHn6CPjUHpNAivbXw9dIz7X3aI/Xo18wXTAOBgNV 10 | HQ8BAf8EBAMCAaYwDwYDVR0lBAgwBgYEVR0lADAPBgNVHRMBAf8EBTADAQH/MCkG 11 | A1UdDgQiBCBNSnciFRaLZZTIfoJlDkOPHzfDA+FLX55vPuBswruCOjAKBggqhkjO 12 | PQQDAgNHADBEAiBa6k7Cax+McCHy61Jma1vLuFZswBbnsC6DqbveiKdUoAIgeyAf 13 | HzWxMoVrLfPFwF75PqCjae7xnYq+RWlsHZlMGFU= 14 | -----END CERTIFICATE----- 15 | -------------------------------------------------------------------------------- /chaincode/channel/crypto-config/ordererOrganizations/ordererOrg1/orderers/ordererOrg1orderer1/cacerts/ordererOrg1-cert.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIICKTCCAdCgAwIBAgIRALz4qIofOY8ff94YDATVyGIwCgYIKoZIzj0EAwIwZjEL 3 | MAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcTDVNhbiBG 4 | cmFuY2lzY28xFDASBgNVBAoTC29yZGVyZXJPcmcxMRQwEgYDVQQDEwtvcmRlcmVy 5 | T3JnMTAeFw0xNzAzMDExNzM2NDFaFw0yNzAyMjcxNzM2NDFaMGYxCzAJBgNVBAYT 6 | AlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlhMRYwFAYDVQQHEw1TYW4gRnJhbmNpc2Nv 7 | MRQwEgYDVQQKEwtvcmRlcmVyT3JnMTEUMBIGA1UEAxMLb3JkZXJlck9yZzEwWTAT 8 | BgcqhkjOPQIBBggqhkjOPQMBBwNCAARNSaTugowp/Y4XcY7Hrs+m3oE/j8B/jIp3 9 | H8thNhYUdkHX69wNsRB6v/vElHn6CPjUHpNAivbXw9dIz7X3aI/Xo18wXTAOBgNV 10 | HQ8BAf8EBAMCAaYwDwYDVR0lBAgwBgYEVR0lADAPBgNVHRMBAf8EBTADAQH/MCkG 11 | A1UdDgQiBCBNSnciFRaLZZTIfoJlDkOPHzfDA+FLX55vPuBswruCOjAKBggqhkjO 12 | PQQDAgNHADBEAiBa6k7Cax+McCHy61Jma1vLuFZswBbnsC6DqbveiKdUoAIgeyAf 13 | HzWxMoVrLfPFwF75PqCjae7xnYq+RWlsHZlMGFU= 14 | -----END CERTIFICATE----- 15 | -------------------------------------------------------------------------------- /chaincode/channel/crypto-config/ordererOrganizations/ordererOrg1/orderers/ordererOrg1orderer1/keystore/9707908924f92bbaa5c8a6961c260dc4992ad2fd7043cccf3f3948ffbea989e1_sk: -------------------------------------------------------------------------------- 1 | -----BEGIN ECDSA PRIVATE KEY----- 2 | MHcCAQEEIO0ReZyfrYE1gpMCEp6xU+KK2rmA8oxwB+oMOt0H1ewtoAoGCCqGSM49 3 | AwEHoUQDQgAEqU74c/nK+RcqBb9RRMeBr1RrD7L8EBkmGjDza+CmsdHmIzQfbRYe 4 | /0erI/KbGx0DvN+sE3QDNbReQUp2aUjaRg== 5 | -----END ECDSA PRIVATE KEY----- 6 | -------------------------------------------------------------------------------- /chaincode/channel/crypto-config/ordererOrganizations/ordererOrg1/orderers/ordererOrg1orderer1/signcerts/ordererOrg1orderer1-cert.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIICHTCCAcSgAwIBAgIQZKA22ytt3J3VxFVLHM5UBzAKBggqhkjOPQQDAjBmMQsw 3 | CQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTEWMBQGA1UEBxMNU2FuIEZy 4 | YW5jaXNjbzEUMBIGA1UEChMLb3JkZXJlck9yZzExFDASBgNVBAMTC29yZGVyZXJP 5 | cmcxMB4XDTE3MDMwMTE3MzY0MVoXDTI3MDIyNzE3MzY0MVowWDELMAkGA1UEBhMC 6 | VVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcTDVNhbiBGcmFuY2lzY28x 7 | HDAaBgNVBAMTE29yZGVyZXJPcmcxb3JkZXJlcjEwWTATBgcqhkjOPQIBBggqhkjO 8 | PQMBBwNCAASpTvhz+cr5FyoFv1FEx4GvVGsPsvwQGSYaMPNr4Kax0eYjNB9tFh7/ 9 | R6sj8psbHQO836wTdAM1tF5BSnZpSNpGo2IwYDAOBgNVHQ8BAf8EBAMCBaAwEwYD 10 | VR0lBAwwCgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADArBgNVHSMEJDAigCBNSnci 11 | FRaLZZTIfoJlDkOPHzfDA+FLX55vPuBswruCOjAKBggqhkjOPQQDAgNHADBEAiA0 12 | YjwUHXbfNmEYutDdaCc7tOrSaqMUksGpqkFO3dSi5wIgLCPJKjaDYIL5qtR+uCSP 13 | ybLGGa4Tg4Oy0QgMDyrzudA= 14 | -----END CERTIFICATE----- 15 | -------------------------------------------------------------------------------- /chaincode/channel/crypto-config/peerOrganizations/peerOrg1/ca/d8a5b3cac1b821f6e4b487ceaf1fd239cdcfc310894150908b90f05e9179556a_sk: -------------------------------------------------------------------------------- 1 | -----BEGIN ECDSA PRIVATE KEY----- 2 | MHcCAQEEIN8gOECqqqNMYdWZVhaQ8OAjuaZdbFqOHJ3zQyzPIl5DoAoGCCqGSM49 3 | AwEHoUQDQgAE140SbgwoL+7Mr6WTFcXmvhoanwZqX2/dD0QZcmw2TvMKcvUcPUbE 4 | OPD0VzmA0GC9fUJwWdBhXdVegk6Mw6xxjg== 5 | -----END ECDSA PRIVATE KEY----- 6 | -------------------------------------------------------------------------------- /chaincode/channel/crypto-config/peerOrganizations/peerOrg1/ca/peerOrg1-cert.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIICHTCCAcOgAwIBAgIQMnFCpjSdv8WBC9VnEvJ4JTAKBggqhkjOPQQDAjBgMQsw 3 | CQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTEWMBQGA1UEBxMNU2FuIEZy 4 | YW5jaXNjbzERMA8GA1UEChMIcGVlck9yZzExETAPBgNVBAMTCHBlZXJPcmcxMB4X 5 | DTE3MDMwMTE3MzY0MVoXDTI3MDIyNzE3MzY0MVowYDELMAkGA1UEBhMCVVMxEzAR 6 | BgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcTDVNhbiBGcmFuY2lzY28xETAPBgNV 7 | BAoTCHBlZXJPcmcxMREwDwYDVQQDEwhwZWVyT3JnMTBZMBMGByqGSM49AgEGCCqG 8 | SM49AwEHA0IABNeNEm4MKC/uzK+lkxXF5r4aGp8Gal9v3Q9EGXJsNk7zCnL1HD1G 9 | xDjw9Fc5gNBgvX1CcFnQYV3VXoJOjMOscY6jXzBdMA4GA1UdDwEB/wQEAwIBpjAP 10 | BgNVHSUECDAGBgRVHSUAMA8GA1UdEwEB/wQFMAMBAf8wKQYDVR0OBCIEINils8rB 11 | uCH25LSHzq8f0jnNz8MQiUFQkIuQ8F6ReVVqMAoGCCqGSM49BAMCA0gAMEUCIQC0 12 | dL7pz5np3hoAaE41n/0c0Tjjs6zVk+zxysz3u9exKwIgBnhrJFK1rV13VUz+W8sp 13 | 8lrz5ZETok8lPoisXwRIe/E= 14 | -----END CERTIFICATE----- 15 | -------------------------------------------------------------------------------- /chaincode/channel/crypto-config/peerOrganizations/peerOrg1/msp/admincerts/peerOrg1-cert.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIICHTCCAcOgAwIBAgIQMnFCpjSdv8WBC9VnEvJ4JTAKBggqhkjOPQQDAjBgMQsw 3 | CQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTEWMBQGA1UEBxMNU2FuIEZy 4 | YW5jaXNjbzERMA8GA1UEChMIcGVlck9yZzExETAPBgNVBAMTCHBlZXJPcmcxMB4X 5 | DTE3MDMwMTE3MzY0MVoXDTI3MDIyNzE3MzY0MVowYDELMAkGA1UEBhMCVVMxEzAR 6 | BgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcTDVNhbiBGcmFuY2lzY28xETAPBgNV 7 | BAoTCHBlZXJPcmcxMREwDwYDVQQDEwhwZWVyT3JnMTBZMBMGByqGSM49AgEGCCqG 8 | SM49AwEHA0IABNeNEm4MKC/uzK+lkxXF5r4aGp8Gal9v3Q9EGXJsNk7zCnL1HD1G 9 | xDjw9Fc5gNBgvX1CcFnQYV3VXoJOjMOscY6jXzBdMA4GA1UdDwEB/wQEAwIBpjAP 10 | BgNVHSUECDAGBgRVHSUAMA8GA1UdEwEB/wQFMAMBAf8wKQYDVR0OBCIEINils8rB 11 | uCH25LSHzq8f0jnNz8MQiUFQkIuQ8F6ReVVqMAoGCCqGSM49BAMCA0gAMEUCIQC0 12 | dL7pz5np3hoAaE41n/0c0Tjjs6zVk+zxysz3u9exKwIgBnhrJFK1rV13VUz+W8sp 13 | 8lrz5ZETok8lPoisXwRIe/E= 14 | -----END CERTIFICATE----- 15 | -------------------------------------------------------------------------------- /chaincode/channel/crypto-config/peerOrganizations/peerOrg1/msp/cacerts/peerOrg0.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIIBbDCCARKgAwIBAwICA+gwCgYIKoZIzj0EAwIwEzERMA8GA1UEAwwIcGVlck9y 3 | ZzAwHhcNMTcwMjIwMTkwNjEwWhcNMTgwMjIwMTkwNjEwWjATMREwDwYDVQQDDAhw 4 | ZWVyT3JnMDBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABKJfDc/CcaiHRipTG2AB 5 | K5fA0LO9SOlbtC9bZcjLo/xsL157p+3QB3UVF3gt7nkwgMs/ul3FhSEFTk2EVNlF 6 | 1QCjVjBUMBIGA1UdEwEB/wQIMAYBAf8CAQAwHQYDVR0OBBYEFFQzuQR1RZP/Qn/B 7 | NDtGSa8n4eN/MB8GA1UdIwQYMBaAFFQzuQR1RZP/Qn/BNDtGSa8n4eN/MAoGCCqG 8 | SM49BAMCA0gAMEUCIAuG+/Fy3x9JXAD1/rFsu3ZpCKbXiXZLGF7P6Gma8is5AiEA 9 | pSQpRcdukxe4zvcfRmNBjMbNLWCoWlHSQA2jD678QGE= 10 | -----END CERTIFICATE----- 11 | -------------------------------------------------------------------------------- /chaincode/channel/crypto-config/peerOrganizations/peerOrg1/msp/cacerts/peerOrg1-cert.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIICHTCCAcOgAwIBAgIQMnFCpjSdv8WBC9VnEvJ4JTAKBggqhkjOPQQDAjBgMQsw 3 | CQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTEWMBQGA1UEBxMNU2FuIEZy 4 | YW5jaXNjbzERMA8GA1UEChMIcGVlck9yZzExETAPBgNVBAMTCHBlZXJPcmcxMB4X 5 | DTE3MDMwMTE3MzY0MVoXDTI3MDIyNzE3MzY0MVowYDELMAkGA1UEBhMCVVMxEzAR 6 | BgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcTDVNhbiBGcmFuY2lzY28xETAPBgNV 7 | BAoTCHBlZXJPcmcxMREwDwYDVQQDEwhwZWVyT3JnMTBZMBMGByqGSM49AgEGCCqG 8 | SM49AwEHA0IABNeNEm4MKC/uzK+lkxXF5r4aGp8Gal9v3Q9EGXJsNk7zCnL1HD1G 9 | xDjw9Fc5gNBgvX1CcFnQYV3VXoJOjMOscY6jXzBdMA4GA1UdDwEB/wQEAwIBpjAP 10 | BgNVHSUECDAGBgRVHSUAMA8GA1UdEwEB/wQFMAMBAf8wKQYDVR0OBCIEINils8rB 11 | uCH25LSHzq8f0jnNz8MQiUFQkIuQ8F6ReVVqMAoGCCqGSM49BAMCA0gAMEUCIQC0 12 | dL7pz5np3hoAaE41n/0c0Tjjs6zVk+zxysz3u9exKwIgBnhrJFK1rV13VUz+W8sp 13 | 8lrz5ZETok8lPoisXwRIe/E= 14 | -----END CERTIFICATE----- 15 | -------------------------------------------------------------------------------- /chaincode/channel/crypto-config/peerOrganizations/peerOrg1/msp/signcerts/peerOrg1-cert.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIICHTCCAcOgAwIBAgIQMnFCpjSdv8WBC9VnEvJ4JTAKBggqhkjOPQQDAjBgMQsw 3 | CQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTEWMBQGA1UEBxMNU2FuIEZy 4 | YW5jaXNjbzERMA8GA1UEChMIcGVlck9yZzExETAPBgNVBAMTCHBlZXJPcmcxMB4X 5 | DTE3MDMwMTE3MzY0MVoXDTI3MDIyNzE3MzY0MVowYDELMAkGA1UEBhMCVVMxEzAR 6 | BgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcTDVNhbiBGcmFuY2lzY28xETAPBgNV 7 | BAoTCHBlZXJPcmcxMREwDwYDVQQDEwhwZWVyT3JnMTBZMBMGByqGSM49AgEGCCqG 8 | SM49AwEHA0IABNeNEm4MKC/uzK+lkxXF5r4aGp8Gal9v3Q9EGXJsNk7zCnL1HD1G 9 | xDjw9Fc5gNBgvX1CcFnQYV3VXoJOjMOscY6jXzBdMA4GA1UdDwEB/wQEAwIBpjAP 10 | BgNVHSUECDAGBgRVHSUAMA8GA1UdEwEB/wQFMAMBAf8wKQYDVR0OBCIEINils8rB 11 | uCH25LSHzq8f0jnNz8MQiUFQkIuQ8F6ReVVqMAoGCCqGSM49BAMCA0gAMEUCIQC0 12 | dL7pz5np3hoAaE41n/0c0Tjjs6zVk+zxysz3u9exKwIgBnhrJFK1rV13VUz+W8sp 13 | 8lrz5ZETok8lPoisXwRIe/E= 14 | -----END CERTIFICATE----- 15 | -------------------------------------------------------------------------------- /chaincode/channel/crypto-config/peerOrganizations/peerOrg1/peers/peerOrg1Peer1/admincerts/peerOrg1-cert.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIICHTCCAcOgAwIBAgIQMnFCpjSdv8WBC9VnEvJ4JTAKBggqhkjOPQQDAjBgMQsw 3 | CQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTEWMBQGA1UEBxMNU2FuIEZy 4 | YW5jaXNjbzERMA8GA1UEChMIcGVlck9yZzExETAPBgNVBAMTCHBlZXJPcmcxMB4X 5 | DTE3MDMwMTE3MzY0MVoXDTI3MDIyNzE3MzY0MVowYDELMAkGA1UEBhMCVVMxEzAR 6 | BgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcTDVNhbiBGcmFuY2lzY28xETAPBgNV 7 | BAoTCHBlZXJPcmcxMREwDwYDVQQDEwhwZWVyT3JnMTBZMBMGByqGSM49AgEGCCqG 8 | SM49AwEHA0IABNeNEm4MKC/uzK+lkxXF5r4aGp8Gal9v3Q9EGXJsNk7zCnL1HD1G 9 | xDjw9Fc5gNBgvX1CcFnQYV3VXoJOjMOscY6jXzBdMA4GA1UdDwEB/wQEAwIBpjAP 10 | BgNVHSUECDAGBgRVHSUAMA8GA1UdEwEB/wQFMAMBAf8wKQYDVR0OBCIEINils8rB 11 | uCH25LSHzq8f0jnNz8MQiUFQkIuQ8F6ReVVqMAoGCCqGSM49BAMCA0gAMEUCIQC0 12 | dL7pz5np3hoAaE41n/0c0Tjjs6zVk+zxysz3u9exKwIgBnhrJFK1rV13VUz+W8sp 13 | 8lrz5ZETok8lPoisXwRIe/E= 14 | -----END CERTIFICATE----- 15 | -------------------------------------------------------------------------------- /chaincode/channel/crypto-config/peerOrganizations/peerOrg1/peers/peerOrg1Peer1/cacerts/peerOrg1-cert.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIICHTCCAcOgAwIBAgIQMnFCpjSdv8WBC9VnEvJ4JTAKBggqhkjOPQQDAjBgMQsw 3 | CQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTEWMBQGA1UEBxMNU2FuIEZy 4 | YW5jaXNjbzERMA8GA1UEChMIcGVlck9yZzExETAPBgNVBAMTCHBlZXJPcmcxMB4X 5 | DTE3MDMwMTE3MzY0MVoXDTI3MDIyNzE3MzY0MVowYDELMAkGA1UEBhMCVVMxEzAR 6 | BgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcTDVNhbiBGcmFuY2lzY28xETAPBgNV 7 | BAoTCHBlZXJPcmcxMREwDwYDVQQDEwhwZWVyT3JnMTBZMBMGByqGSM49AgEGCCqG 8 | SM49AwEHA0IABNeNEm4MKC/uzK+lkxXF5r4aGp8Gal9v3Q9EGXJsNk7zCnL1HD1G 9 | xDjw9Fc5gNBgvX1CcFnQYV3VXoJOjMOscY6jXzBdMA4GA1UdDwEB/wQEAwIBpjAP 10 | BgNVHSUECDAGBgRVHSUAMA8GA1UdEwEB/wQFMAMBAf8wKQYDVR0OBCIEINils8rB 11 | uCH25LSHzq8f0jnNz8MQiUFQkIuQ8F6ReVVqMAoGCCqGSM49BAMCA0gAMEUCIQC0 12 | dL7pz5np3hoAaE41n/0c0Tjjs6zVk+zxysz3u9exKwIgBnhrJFK1rV13VUz+W8sp 13 | 8lrz5ZETok8lPoisXwRIe/E= 14 | -----END CERTIFICATE----- 15 | -------------------------------------------------------------------------------- /chaincode/channel/crypto-config/peerOrganizations/peerOrg1/peers/peerOrg1Peer1/keystore/5e67f35124df6a9124bf3659365b8476af4090f73c82c9b626efc15f12739d5d_sk: -------------------------------------------------------------------------------- 1 | -----BEGIN ECDSA PRIVATE KEY----- 2 | MHcCAQEEICKPEUyZLQFfJwgXQ9dDNnsLdYDSBSUAAGzc//SuMkyzoAoGCCqGSM49 3 | AwEHoUQDQgAEtITvAvKYfj4hZGIpHVQCv8wndnJMW+puW0zqueFbVke8G3T7rvXY 4 | yAk2kTk1Jn3qABxetKJf2f6Xp0fxunIaig== 5 | -----END ECDSA PRIVATE KEY----- 6 | -------------------------------------------------------------------------------- /chaincode/channel/crypto-config/peerOrganizations/peerOrg1/peers/peerOrg1Peer1/signcerts/peerOrg1Peer1-cert.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIICEjCCAbigAwIBAgIQPjb63mDL4e062MPjtcA1CDAKBggqhkjOPQQDAjBgMQsw 3 | CQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTEWMBQGA1UEBxMNU2FuIEZy 4 | YW5jaXNjbzERMA8GA1UEChMIcGVlck9yZzExETAPBgNVBAMTCHBlZXJPcmcxMB4X 5 | DTE3MDMwMTE3MzY0MVoXDTI3MDIyNzE3MzY0MVowUjELMAkGA1UEBhMCVVMxEzAR 6 | BgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcTDVNhbiBGcmFuY2lzY28xFjAUBgNV 7 | BAMTDXBlZXJPcmcxUGVlcjEwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAAS0hO8C 8 | 8ph+PiFkYikdVAK/zCd2ckxb6m5bTOq54VtWR7wbdPuu9djICTaROTUmfeoAHF60 9 | ol/Z/penR/G6chqKo2IwYDAOBgNVHQ8BAf8EBAMCBaAwEwYDVR0lBAwwCgYIKwYB 10 | BQUHAwEwDAYDVR0TAQH/BAIwADArBgNVHSMEJDAigCDYpbPKwbgh9uS0h86vH9I5 11 | zc/DEIlBUJCLkPBekXlVajAKBggqhkjOPQQDAgNIADBFAiEAmGS3LTaqCkWV+myl 12 | lhg9ovtLJABuxQLnajMJYQOXURgCIHLVNrDbEF0KpEmFwXIBYMFdsKGRAF0kC43M 13 | bpq87UJq 14 | -----END CERTIFICATE----- 15 | -------------------------------------------------------------------------------- /chaincode/channel/crypto-config/peerOrganizations/peerOrg1/peers/peerOrg1Peer2/admincerts/peerOrg1-cert.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIICHTCCAcOgAwIBAgIQMnFCpjSdv8WBC9VnEvJ4JTAKBggqhkjOPQQDAjBgMQsw 3 | CQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTEWMBQGA1UEBxMNU2FuIEZy 4 | YW5jaXNjbzERMA8GA1UEChMIcGVlck9yZzExETAPBgNVBAMTCHBlZXJPcmcxMB4X 5 | DTE3MDMwMTE3MzY0MVoXDTI3MDIyNzE3MzY0MVowYDELMAkGA1UEBhMCVVMxEzAR 6 | BgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcTDVNhbiBGcmFuY2lzY28xETAPBgNV 7 | BAoTCHBlZXJPcmcxMREwDwYDVQQDEwhwZWVyT3JnMTBZMBMGByqGSM49AgEGCCqG 8 | SM49AwEHA0IABNeNEm4MKC/uzK+lkxXF5r4aGp8Gal9v3Q9EGXJsNk7zCnL1HD1G 9 | xDjw9Fc5gNBgvX1CcFnQYV3VXoJOjMOscY6jXzBdMA4GA1UdDwEB/wQEAwIBpjAP 10 | BgNVHSUECDAGBgRVHSUAMA8GA1UdEwEB/wQFMAMBAf8wKQYDVR0OBCIEINils8rB 11 | uCH25LSHzq8f0jnNz8MQiUFQkIuQ8F6ReVVqMAoGCCqGSM49BAMCA0gAMEUCIQC0 12 | dL7pz5np3hoAaE41n/0c0Tjjs6zVk+zxysz3u9exKwIgBnhrJFK1rV13VUz+W8sp 13 | 8lrz5ZETok8lPoisXwRIe/E= 14 | -----END CERTIFICATE----- 15 | -------------------------------------------------------------------------------- /chaincode/channel/crypto-config/peerOrganizations/peerOrg1/peers/peerOrg1Peer2/cacerts/peerOrg1-cert.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIICHTCCAcOgAwIBAgIQMnFCpjSdv8WBC9VnEvJ4JTAKBggqhkjOPQQDAjBgMQsw 3 | CQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTEWMBQGA1UEBxMNU2FuIEZy 4 | YW5jaXNjbzERMA8GA1UEChMIcGVlck9yZzExETAPBgNVBAMTCHBlZXJPcmcxMB4X 5 | DTE3MDMwMTE3MzY0MVoXDTI3MDIyNzE3MzY0MVowYDELMAkGA1UEBhMCVVMxEzAR 6 | BgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcTDVNhbiBGcmFuY2lzY28xETAPBgNV 7 | BAoTCHBlZXJPcmcxMREwDwYDVQQDEwhwZWVyT3JnMTBZMBMGByqGSM49AgEGCCqG 8 | SM49AwEHA0IABNeNEm4MKC/uzK+lkxXF5r4aGp8Gal9v3Q9EGXJsNk7zCnL1HD1G 9 | xDjw9Fc5gNBgvX1CcFnQYV3VXoJOjMOscY6jXzBdMA4GA1UdDwEB/wQEAwIBpjAP 10 | BgNVHSUECDAGBgRVHSUAMA8GA1UdEwEB/wQFMAMBAf8wKQYDVR0OBCIEINils8rB 11 | uCH25LSHzq8f0jnNz8MQiUFQkIuQ8F6ReVVqMAoGCCqGSM49BAMCA0gAMEUCIQC0 12 | dL7pz5np3hoAaE41n/0c0Tjjs6zVk+zxysz3u9exKwIgBnhrJFK1rV13VUz+W8sp 13 | 8lrz5ZETok8lPoisXwRIe/E= 14 | -----END CERTIFICATE----- 15 | -------------------------------------------------------------------------------- /chaincode/channel/crypto-config/peerOrganizations/peerOrg1/peers/peerOrg1Peer2/keystore/707c2b3c02ddd36a6c4a17771769b54a3dc9066e05be1e76582cabd65c110e4e_sk: -------------------------------------------------------------------------------- 1 | -----BEGIN ECDSA PRIVATE KEY----- 2 | MHcCAQEEII0oxsh+lV49AVCyYfqXr3QfvQ19rJl7VN/8g6nLCiCroAoGCCqGSM49 3 | AwEHoUQDQgAEZibYpTur7h/LIkZkV1yr11mP0M4Hts+ARrky3r97WihvF0+TgxUI 4 | UrFjEe4Yv+SIlz5+IE6BlNemaF67nUeD+Q== 5 | -----END ECDSA PRIVATE KEY----- 6 | -------------------------------------------------------------------------------- /chaincode/channel/crypto-config/peerOrganizations/peerOrg1/peers/peerOrg1Peer2/signcerts/peerOrg1Peer2-cert.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIICEjCCAbmgAwIBAgIRANgd5gwHKxNyqxptv40oPEkwCgYIKoZIzj0EAwIwYDEL 3 | MAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcTDVNhbiBG 4 | cmFuY2lzY28xETAPBgNVBAoTCHBlZXJPcmcxMREwDwYDVQQDEwhwZWVyT3JnMTAe 5 | Fw0xNzAzMDExNzM2NDFaFw0yNzAyMjcxNzM2NDFaMFIxCzAJBgNVBAYTAlVTMRMw 6 | EQYDVQQIEwpDYWxpZm9ybmlhMRYwFAYDVQQHEw1TYW4gRnJhbmNpc2NvMRYwFAYD 7 | VQQDEw1wZWVyT3JnMVBlZXIyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEZibY 8 | pTur7h/LIkZkV1yr11mP0M4Hts+ARrky3r97WihvF0+TgxUIUrFjEe4Yv+SIlz5+ 9 | IE6BlNemaF67nUeD+aNiMGAwDgYDVR0PAQH/BAQDAgWgMBMGA1UdJQQMMAoGCCsG 10 | AQUFBwMBMAwGA1UdEwEB/wQCMAAwKwYDVR0jBCQwIoAg2KWzysG4IfbktIfOrx/S 11 | Oc3PwxCJQVCQi5DwXpF5VWowCgYIKoZIzj0EAwIDRwAwRAIgJ6zmGTYWeAjaa8zV 12 | I73t3Zop/mF790NwkH2SSlt4SAMCIG9yeH7K8YdD8Ao3kBiARyjI+QpiWqi1K8qS 13 | b6EWptg2 14 | -----END CERTIFICATE----- 15 | -------------------------------------------------------------------------------- /chaincode/channel/crypto-config/peerOrganizations/peerOrg2/ca/96bdb57f4efbdcf201a269899eb47e2a73fbb728ae14d47d0d5afb75ddea71de_sk: -------------------------------------------------------------------------------- 1 | -----BEGIN ECDSA PRIVATE KEY----- 2 | MHcCAQEEIBxAH3LK1l03gaOwzNhPWfxBVZDQvWknmViEyTXSwFMqoAoGCCqGSM49 3 | AwEHoUQDQgAEK5qTfIT6ai4QxQZcgRjjwNYbT7HK59PdUBKqbt/wT4VR2dCvIC2a 4 | bxf5A7CtuLgKKL8xMsseh/0WD5dSiIBB1g== 5 | -----END ECDSA PRIVATE KEY----- 6 | -------------------------------------------------------------------------------- /chaincode/channel/crypto-config/peerOrganizations/peerOrg2/ca/peerOrg2-cert.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIICHTCCAcSgAwIBAgIRALakYEdO1ZkArcOQHj85ay8wCgYIKoZIzj0EAwIwYDEL 3 | MAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcTDVNhbiBG 4 | cmFuY2lzY28xETAPBgNVBAoTCHBlZXJPcmcyMREwDwYDVQQDEwhwZWVyT3JnMjAe 5 | Fw0xNzAzMDExNzM2NDFaFw0yNzAyMjcxNzM2NDFaMGAxCzAJBgNVBAYTAlVTMRMw 6 | EQYDVQQIEwpDYWxpZm9ybmlhMRYwFAYDVQQHEw1TYW4gRnJhbmNpc2NvMREwDwYD 7 | VQQKEwhwZWVyT3JnMjERMA8GA1UEAxMIcGVlck9yZzIwWTATBgcqhkjOPQIBBggq 8 | hkjOPQMBBwNCAAQrmpN8hPpqLhDFBlyBGOPA1htPscrn091QEqpu3/BPhVHZ0K8g 9 | LZpvF/kDsK24uAoovzEyyx6H/RYPl1KIgEHWo18wXTAOBgNVHQ8BAf8EBAMCAaYw 10 | DwYDVR0lBAgwBgYEVR0lADAPBgNVHRMBAf8EBTADAQH/MCkGA1UdDgQiBCCWvbV/ 11 | Tvvc8gGiaYmetH4qc/u3KK4U1H0NWvt13epx3jAKBggqhkjOPQQDAgNHADBEAiAe 12 | 1/wXZht2Gg6KVxf5lPdAOeoBWZzG0/TQN1KxTH7/QwIgMdJoWxbq2EzihNJlA/U0 13 | 3+aFesZjYUGvuvOA0ijYFgA= 14 | -----END CERTIFICATE----- 15 | -------------------------------------------------------------------------------- /chaincode/channel/crypto-config/peerOrganizations/peerOrg2/msp/admincerts/peerOrg2-cert.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIICHTCCAcSgAwIBAgIRALakYEdO1ZkArcOQHj85ay8wCgYIKoZIzj0EAwIwYDEL 3 | MAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcTDVNhbiBG 4 | cmFuY2lzY28xETAPBgNVBAoTCHBlZXJPcmcyMREwDwYDVQQDEwhwZWVyT3JnMjAe 5 | Fw0xNzAzMDExNzM2NDFaFw0yNzAyMjcxNzM2NDFaMGAxCzAJBgNVBAYTAlVTMRMw 6 | EQYDVQQIEwpDYWxpZm9ybmlhMRYwFAYDVQQHEw1TYW4gRnJhbmNpc2NvMREwDwYD 7 | VQQKEwhwZWVyT3JnMjERMA8GA1UEAxMIcGVlck9yZzIwWTATBgcqhkjOPQIBBggq 8 | hkjOPQMBBwNCAAQrmpN8hPpqLhDFBlyBGOPA1htPscrn091QEqpu3/BPhVHZ0K8g 9 | LZpvF/kDsK24uAoovzEyyx6H/RYPl1KIgEHWo18wXTAOBgNVHQ8BAf8EBAMCAaYw 10 | DwYDVR0lBAgwBgYEVR0lADAPBgNVHRMBAf8EBTADAQH/MCkGA1UdDgQiBCCWvbV/ 11 | Tvvc8gGiaYmetH4qc/u3KK4U1H0NWvt13epx3jAKBggqhkjOPQQDAgNHADBEAiAe 12 | 1/wXZht2Gg6KVxf5lPdAOeoBWZzG0/TQN1KxTH7/QwIgMdJoWxbq2EzihNJlA/U0 13 | 3+aFesZjYUGvuvOA0ijYFgA= 14 | -----END CERTIFICATE----- 15 | -------------------------------------------------------------------------------- /chaincode/channel/crypto-config/peerOrganizations/peerOrg2/msp/cacerts/peerOrg1.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIIBbDCCARKgAwIBAwICA+gwCgYIKoZIzj0EAwIwEzERMA8GA1UEAwwIcGVlck9y 3 | ZzEwHhcNMTcwMjIwMTkwNjEwWhcNMTgwMjIwMTkwNjEwWjATMREwDwYDVQQDDAhw 4 | ZWVyT3JnMTBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABJ2S+UvyFgFZYL6qcrKo 5 | zy72Nkc/RQVzg1VfwC3X7QcnHEVBuCzba1nxdDVE8XPnhmKBWLKh0adn6GKUZpyf 6 | mbKjVjBUMBIGA1UdEwEB/wQIMAYBAf8CAQAwHQYDVR0OBBYEFAQlMVsXlKGMEWPf 7 | KMMM6QVASnlPMB8GA1UdIwQYMBaAFAQlMVsXlKGMEWPfKMMM6QVASnlPMAoGCCqG 8 | SM49BAMCA0gAMEUCIHr4AD6Xx3R6zFCsveIMnWao9Us88/0uGHoT4ELmMhA1AiEA 9 | yzfXU5qHp3xBJ1BrKOGi71UmQZVwWfO26INhxcfpCAg= 10 | -----END CERTIFICATE----- 11 | -------------------------------------------------------------------------------- /chaincode/channel/crypto-config/peerOrganizations/peerOrg2/msp/cacerts/peerOrg2-cert.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIICHTCCAcSgAwIBAgIRALakYEdO1ZkArcOQHj85ay8wCgYIKoZIzj0EAwIwYDEL 3 | MAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcTDVNhbiBG 4 | cmFuY2lzY28xETAPBgNVBAoTCHBlZXJPcmcyMREwDwYDVQQDEwhwZWVyT3JnMjAe 5 | Fw0xNzAzMDExNzM2NDFaFw0yNzAyMjcxNzM2NDFaMGAxCzAJBgNVBAYTAlVTMRMw 6 | EQYDVQQIEwpDYWxpZm9ybmlhMRYwFAYDVQQHEw1TYW4gRnJhbmNpc2NvMREwDwYD 7 | VQQKEwhwZWVyT3JnMjERMA8GA1UEAxMIcGVlck9yZzIwWTATBgcqhkjOPQIBBggq 8 | hkjOPQMBBwNCAAQrmpN8hPpqLhDFBlyBGOPA1htPscrn091QEqpu3/BPhVHZ0K8g 9 | LZpvF/kDsK24uAoovzEyyx6H/RYPl1KIgEHWo18wXTAOBgNVHQ8BAf8EBAMCAaYw 10 | DwYDVR0lBAgwBgYEVR0lADAPBgNVHRMBAf8EBTADAQH/MCkGA1UdDgQiBCCWvbV/ 11 | Tvvc8gGiaYmetH4qc/u3KK4U1H0NWvt13epx3jAKBggqhkjOPQQDAgNHADBEAiAe 12 | 1/wXZht2Gg6KVxf5lPdAOeoBWZzG0/TQN1KxTH7/QwIgMdJoWxbq2EzihNJlA/U0 13 | 3+aFesZjYUGvuvOA0ijYFgA= 14 | -----END CERTIFICATE----- 15 | -------------------------------------------------------------------------------- /chaincode/channel/crypto-config/peerOrganizations/peerOrg2/msp/signcerts/peerOrg2-cert.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIICHTCCAcSgAwIBAgIRALakYEdO1ZkArcOQHj85ay8wCgYIKoZIzj0EAwIwYDEL 3 | MAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcTDVNhbiBG 4 | cmFuY2lzY28xETAPBgNVBAoTCHBlZXJPcmcyMREwDwYDVQQDEwhwZWVyT3JnMjAe 5 | Fw0xNzAzMDExNzM2NDFaFw0yNzAyMjcxNzM2NDFaMGAxCzAJBgNVBAYTAlVTMRMw 6 | EQYDVQQIEwpDYWxpZm9ybmlhMRYwFAYDVQQHEw1TYW4gRnJhbmNpc2NvMREwDwYD 7 | VQQKEwhwZWVyT3JnMjERMA8GA1UEAxMIcGVlck9yZzIwWTATBgcqhkjOPQIBBggq 8 | hkjOPQMBBwNCAAQrmpN8hPpqLhDFBlyBGOPA1htPscrn091QEqpu3/BPhVHZ0K8g 9 | LZpvF/kDsK24uAoovzEyyx6H/RYPl1KIgEHWo18wXTAOBgNVHQ8BAf8EBAMCAaYw 10 | DwYDVR0lBAgwBgYEVR0lADAPBgNVHRMBAf8EBTADAQH/MCkGA1UdDgQiBCCWvbV/ 11 | Tvvc8gGiaYmetH4qc/u3KK4U1H0NWvt13epx3jAKBggqhkjOPQQDAgNHADBEAiAe 12 | 1/wXZht2Gg6KVxf5lPdAOeoBWZzG0/TQN1KxTH7/QwIgMdJoWxbq2EzihNJlA/U0 13 | 3+aFesZjYUGvuvOA0ijYFgA= 14 | -----END CERTIFICATE----- 15 | -------------------------------------------------------------------------------- /chaincode/channel/crypto-config/peerOrganizations/peerOrg2/peers/peerOrg2Peer1/admincerts/peerOrg2-cert.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIICHTCCAcSgAwIBAgIRALakYEdO1ZkArcOQHj85ay8wCgYIKoZIzj0EAwIwYDEL 3 | MAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcTDVNhbiBG 4 | cmFuY2lzY28xETAPBgNVBAoTCHBlZXJPcmcyMREwDwYDVQQDEwhwZWVyT3JnMjAe 5 | Fw0xNzAzMDExNzM2NDFaFw0yNzAyMjcxNzM2NDFaMGAxCzAJBgNVBAYTAlVTMRMw 6 | EQYDVQQIEwpDYWxpZm9ybmlhMRYwFAYDVQQHEw1TYW4gRnJhbmNpc2NvMREwDwYD 7 | VQQKEwhwZWVyT3JnMjERMA8GA1UEAxMIcGVlck9yZzIwWTATBgcqhkjOPQIBBggq 8 | hkjOPQMBBwNCAAQrmpN8hPpqLhDFBlyBGOPA1htPscrn091QEqpu3/BPhVHZ0K8g 9 | LZpvF/kDsK24uAoovzEyyx6H/RYPl1KIgEHWo18wXTAOBgNVHQ8BAf8EBAMCAaYw 10 | DwYDVR0lBAgwBgYEVR0lADAPBgNVHRMBAf8EBTADAQH/MCkGA1UdDgQiBCCWvbV/ 11 | Tvvc8gGiaYmetH4qc/u3KK4U1H0NWvt13epx3jAKBggqhkjOPQQDAgNHADBEAiAe 12 | 1/wXZht2Gg6KVxf5lPdAOeoBWZzG0/TQN1KxTH7/QwIgMdJoWxbq2EzihNJlA/U0 13 | 3+aFesZjYUGvuvOA0ijYFgA= 14 | -----END CERTIFICATE----- 15 | -------------------------------------------------------------------------------- /chaincode/channel/crypto-config/peerOrganizations/peerOrg2/peers/peerOrg2Peer1/cacerts/peerOrg2-cert.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIICHTCCAcSgAwIBAgIRALakYEdO1ZkArcOQHj85ay8wCgYIKoZIzj0EAwIwYDEL 3 | MAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcTDVNhbiBG 4 | cmFuY2lzY28xETAPBgNVBAoTCHBlZXJPcmcyMREwDwYDVQQDEwhwZWVyT3JnMjAe 5 | Fw0xNzAzMDExNzM2NDFaFw0yNzAyMjcxNzM2NDFaMGAxCzAJBgNVBAYTAlVTMRMw 6 | EQYDVQQIEwpDYWxpZm9ybmlhMRYwFAYDVQQHEw1TYW4gRnJhbmNpc2NvMREwDwYD 7 | VQQKEwhwZWVyT3JnMjERMA8GA1UEAxMIcGVlck9yZzIwWTATBgcqhkjOPQIBBggq 8 | hkjOPQMBBwNCAAQrmpN8hPpqLhDFBlyBGOPA1htPscrn091QEqpu3/BPhVHZ0K8g 9 | LZpvF/kDsK24uAoovzEyyx6H/RYPl1KIgEHWo18wXTAOBgNVHQ8BAf8EBAMCAaYw 10 | DwYDVR0lBAgwBgYEVR0lADAPBgNVHRMBAf8EBTADAQH/MCkGA1UdDgQiBCCWvbV/ 11 | Tvvc8gGiaYmetH4qc/u3KK4U1H0NWvt13epx3jAKBggqhkjOPQQDAgNHADBEAiAe 12 | 1/wXZht2Gg6KVxf5lPdAOeoBWZzG0/TQN1KxTH7/QwIgMdJoWxbq2EzihNJlA/U0 13 | 3+aFesZjYUGvuvOA0ijYFgA= 14 | -----END CERTIFICATE----- 15 | -------------------------------------------------------------------------------- /chaincode/channel/crypto-config/peerOrganizations/peerOrg2/peers/peerOrg2Peer1/keystore/26d8ff264dd3956922ff23e2fa2bca59817df114630f95adce343388f9fffe7a_sk: -------------------------------------------------------------------------------- 1 | -----BEGIN ECDSA PRIVATE KEY----- 2 | MHcCAQEEII4qcK71QQn3MUVdx84AsHaFOZJ2Coyz5uaFhBjPQWkioAoGCCqGSM49 3 | AwEHoUQDQgAE4uF+T15H10YdHK8ZDAP9T6zJuPHPqBCwZAXfU3dkR06uW+JEn1f2 4 | 8VWYRgtcf8oYnXcgYCTcWwdzckChOyBkZw== 5 | -----END ECDSA PRIVATE KEY----- 6 | -------------------------------------------------------------------------------- /chaincode/channel/crypto-config/peerOrganizations/peerOrg2/peers/peerOrg2Peer1/signcerts/peerOrg2Peer1-cert.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIICEjCCAbmgAwIBAgIRANUoapuJGF/Om0hyk45bQiQwCgYIKoZIzj0EAwIwYDEL 3 | MAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcTDVNhbiBG 4 | cmFuY2lzY28xETAPBgNVBAoTCHBlZXJPcmcyMREwDwYDVQQDEwhwZWVyT3JnMjAe 5 | Fw0xNzAzMDExNzM2NDFaFw0yNzAyMjcxNzM2NDFaMFIxCzAJBgNVBAYTAlVTMRMw 6 | EQYDVQQIEwpDYWxpZm9ybmlhMRYwFAYDVQQHEw1TYW4gRnJhbmNpc2NvMRYwFAYD 7 | VQQDEw1wZWVyT3JnMlBlZXIxMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE4uF+ 8 | T15H10YdHK8ZDAP9T6zJuPHPqBCwZAXfU3dkR06uW+JEn1f28VWYRgtcf8oYnXcg 9 | YCTcWwdzckChOyBkZ6NiMGAwDgYDVR0PAQH/BAQDAgWgMBMGA1UdJQQMMAoGCCsG 10 | AQUFBwMBMAwGA1UdEwEB/wQCMAAwKwYDVR0jBCQwIoAglr21f0773PIBommJnrR+ 11 | KnP7tyiuFNR9DVr7dd3qcd4wCgYIKoZIzj0EAwIDRwAwRAIgA0mw/fZ5YBX73LFO 12 | RjKXfWVXfXdEoq8mgWa6ir11QloCIB9mpenM34EsuH9AZR83cIMZZC2HiQbfFNAa 13 | 5zKksj3o 14 | -----END CERTIFICATE----- 15 | -------------------------------------------------------------------------------- /chaincode/channel/crypto-config/peerOrganizations/peerOrg2/peers/peerOrg2Peer2/admincerts/peerOrg2-cert.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIICHTCCAcSgAwIBAgIRALakYEdO1ZkArcOQHj85ay8wCgYIKoZIzj0EAwIwYDEL 3 | MAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcTDVNhbiBG 4 | cmFuY2lzY28xETAPBgNVBAoTCHBlZXJPcmcyMREwDwYDVQQDEwhwZWVyT3JnMjAe 5 | Fw0xNzAzMDExNzM2NDFaFw0yNzAyMjcxNzM2NDFaMGAxCzAJBgNVBAYTAlVTMRMw 6 | EQYDVQQIEwpDYWxpZm9ybmlhMRYwFAYDVQQHEw1TYW4gRnJhbmNpc2NvMREwDwYD 7 | VQQKEwhwZWVyT3JnMjERMA8GA1UEAxMIcGVlck9yZzIwWTATBgcqhkjOPQIBBggq 8 | hkjOPQMBBwNCAAQrmpN8hPpqLhDFBlyBGOPA1htPscrn091QEqpu3/BPhVHZ0K8g 9 | LZpvF/kDsK24uAoovzEyyx6H/RYPl1KIgEHWo18wXTAOBgNVHQ8BAf8EBAMCAaYw 10 | DwYDVR0lBAgwBgYEVR0lADAPBgNVHRMBAf8EBTADAQH/MCkGA1UdDgQiBCCWvbV/ 11 | Tvvc8gGiaYmetH4qc/u3KK4U1H0NWvt13epx3jAKBggqhkjOPQQDAgNHADBEAiAe 12 | 1/wXZht2Gg6KVxf5lPdAOeoBWZzG0/TQN1KxTH7/QwIgMdJoWxbq2EzihNJlA/U0 13 | 3+aFesZjYUGvuvOA0ijYFgA= 14 | -----END CERTIFICATE----- 15 | -------------------------------------------------------------------------------- /chaincode/channel/crypto-config/peerOrganizations/peerOrg2/peers/peerOrg2Peer2/cacerts/peerOrg2-cert.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIICHTCCAcSgAwIBAgIRALakYEdO1ZkArcOQHj85ay8wCgYIKoZIzj0EAwIwYDEL 3 | MAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcTDVNhbiBG 4 | cmFuY2lzY28xETAPBgNVBAoTCHBlZXJPcmcyMREwDwYDVQQDEwhwZWVyT3JnMjAe 5 | Fw0xNzAzMDExNzM2NDFaFw0yNzAyMjcxNzM2NDFaMGAxCzAJBgNVBAYTAlVTMRMw 6 | EQYDVQQIEwpDYWxpZm9ybmlhMRYwFAYDVQQHEw1TYW4gRnJhbmNpc2NvMREwDwYD 7 | VQQKEwhwZWVyT3JnMjERMA8GA1UEAxMIcGVlck9yZzIwWTATBgcqhkjOPQIBBggq 8 | hkjOPQMBBwNCAAQrmpN8hPpqLhDFBlyBGOPA1htPscrn091QEqpu3/BPhVHZ0K8g 9 | LZpvF/kDsK24uAoovzEyyx6H/RYPl1KIgEHWo18wXTAOBgNVHQ8BAf8EBAMCAaYw 10 | DwYDVR0lBAgwBgYEVR0lADAPBgNVHRMBAf8EBTADAQH/MCkGA1UdDgQiBCCWvbV/ 11 | Tvvc8gGiaYmetH4qc/u3KK4U1H0NWvt13epx3jAKBggqhkjOPQQDAgNHADBEAiAe 12 | 1/wXZht2Gg6KVxf5lPdAOeoBWZzG0/TQN1KxTH7/QwIgMdJoWxbq2EzihNJlA/U0 13 | 3+aFesZjYUGvuvOA0ijYFgA= 14 | -----END CERTIFICATE----- 15 | -------------------------------------------------------------------------------- /chaincode/channel/crypto-config/peerOrganizations/peerOrg2/peers/peerOrg2Peer2/keystore/cc80356f4275390b2090bf0a62b26d3c5e9420c022d196267990eed7014bfcec_sk: -------------------------------------------------------------------------------- 1 | -----BEGIN ECDSA PRIVATE KEY----- 2 | MHcCAQEEILzFjZgOVuJ4nMdNxJqiLQr3RVEUwykkx4m7xb+AnLKsoAoGCCqGSM49 3 | AwEHoUQDQgAEW+vZBJb2GMwSQt76Sreg1lUClTUaJKgJoEI73PsPktRixgQxnAtG 4 | L3eB2o7Hzt3AEu2BGEjkR7H085aeAVlT0A== 5 | -----END ECDSA PRIVATE KEY----- 6 | -------------------------------------------------------------------------------- /chaincode/channel/crypto-config/peerOrganizations/peerOrg2/peers/peerOrg2Peer2/signcerts/peerOrg2Peer2-cert.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIICETCCAbigAwIBAgIQShO6B/mOsuBkRKow0G8U8TAKBggqhkjOPQQDAjBgMQsw 3 | CQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTEWMBQGA1UEBxMNU2FuIEZy 4 | YW5jaXNjbzERMA8GA1UEChMIcGVlck9yZzIxETAPBgNVBAMTCHBlZXJPcmcyMB4X 5 | DTE3MDMwMTE3MzY0MVoXDTI3MDIyNzE3MzY0MVowUjELMAkGA1UEBhMCVVMxEzAR 6 | BgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcTDVNhbiBGcmFuY2lzY28xFjAUBgNV 7 | BAMTDXBlZXJPcmcyUGVlcjIwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAARb69kE 8 | lvYYzBJC3vpKt6DWVQKVNRokqAmgQjvc+w+S1GLGBDGcC0Yvd4HajsfO3cAS7YEY 9 | SORHsfTzlp4BWVPQo2IwYDAOBgNVHQ8BAf8EBAMCBaAwEwYDVR0lBAwwCgYIKwYB 10 | BQUHAwEwDAYDVR0TAQH/BAIwADArBgNVHSMEJDAigCCWvbV/Tvvc8gGiaYmetH4q 11 | c/u3KK4U1H0NWvt13epx3jAKBggqhkjOPQQDAgNHADBEAiB6z75qAEH6/RMAJ8zi 12 | BptJ22zK+l7zPUkzI43jhEU8JAIgUJRBA9/IEkpMPCCmrFlBKaaOKk3LxUovAO01 13 | yuHGA5I= 14 | -----END CERTIFICATE----- 15 | -------------------------------------------------------------------------------- /chaincode/channel/generateCfgTrx.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | CHANNEL_NAME=$1 4 | if [ -z "$1" ]; then 5 | echo "Setting channel to default name 'mychannel'" 6 | CHANNEL_NAME="mychannel" 7 | fi 8 | 9 | echo "Channel name - "$CHANNEL_NAME 10 | echo 11 | 12 | #Backup the original configtx.yaml 13 | cp $GOPATH/src/github.com/hyperledger/fabric/common/configtx/tool/configtx.yaml $GOPATH/src/github.com/hyperledger/fabric/common/configtx/tool/configtx.yaml.orig 14 | cp configtx.yaml $GOPATH/src/github.com/hyperledger/fabric/common/configtx/tool/configtx.yaml 15 | 16 | cd $GOPATH/src/github.com/hyperledger/fabric/ 17 | echo "Building configtxgen" 18 | make configtxgen 19 | 20 | echo "Generating genesis block" 21 | ./build/bin/configtxgen -profile TwoOrgs -outputBlock orderer.block 22 | mv orderer.block $GOPATH/src/datachain/jutian-backend/chaincode/channel/orderer.block 23 | 24 | echo "Generating channel configuration transaction" 25 | ./build/bin/configtxgen -profile TwoOrgs -outputCreateChannelTx channel.tx -channelID $CHANNEL_NAME 26 | mv channel.tx $GOPATH/src/datachain/jutian-backend/chaincode/channel/$CHANNEL_NAME 27 | 28 | #reset configtx.yaml file to its original 29 | cp common/configtx/tool/configtx.yaml.orig common/configtx/tool/configtx.yaml 30 | rm common/configtx/tool/configtx.yaml.orig 31 | -------------------------------------------------------------------------------- /chaincode/channel/jutian: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CBD-Forum/N0041-argiculture-supplychain/1076f95ebb67df8f3246f99a49a0f3c247d39647/chaincode/channel/jutian -------------------------------------------------------------------------------- /chaincode/channel/jutianA: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CBD-Forum/N0041-argiculture-supplychain/1076f95ebb67df8f3246f99a49a0f3c247d39647/chaincode/channel/jutianA -------------------------------------------------------------------------------- /chaincode/channel/jutianaaa: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CBD-Forum/N0041-argiculture-supplychain/1076f95ebb67df8f3246f99a49a0f3c247d39647/chaincode/channel/jutianaaa -------------------------------------------------------------------------------- /chaincode/channel/jutianchannel: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CBD-Forum/N0041-argiculture-supplychain/1076f95ebb67df8f3246f99a49a0f3c247d39647/chaincode/channel/jutianchannel -------------------------------------------------------------------------------- /chaincode/channel/mychannel.tx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CBD-Forum/N0041-argiculture-supplychain/1076f95ebb67df8f3246f99a49a0f3c247d39647/chaincode/channel/mychannel.tx -------------------------------------------------------------------------------- /chaincode/channel/orderer.block: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CBD-Forum/N0041-argiculture-supplychain/1076f95ebb67df8f3246f99a49a0f3c247d39647/chaincode/channel/orderer.block -------------------------------------------------------------------------------- /chaincode/channel/twoorgs.orderer.block: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CBD-Forum/N0041-argiculture-supplychain/1076f95ebb67df8f3246f99a49a0f3c247d39647/chaincode/channel/twoorgs.orderer.block -------------------------------------------------------------------------------- /chaincode/channelchannel.tx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CBD-Forum/N0041-argiculture-supplychain/1076f95ebb67df8f3246f99a49a0f3c247d39647/chaincode/channelchannel.tx -------------------------------------------------------------------------------- /chaincode/cloudant.json: -------------------------------------------------------------------------------- 1 | { 2 | "cloudant-username" : "1421acc7-6faa-491a-8e10-951e2e190684-bluemix", 3 | "cloudant-password" : "7179ef7a72602189243deeabe207889bde1c2fada173ae1022b5592e5a79dacc", 4 | "key-value-store" : "fabric-client/lib/impl/CouchDBKeyValueStore.js" 5 | } -------------------------------------------------------------------------------- /chaincode/couchdb.json: -------------------------------------------------------------------------------- 1 | { 2 | "couchdb-ip-addr" : "http://localhost", 3 | "couchdb-port" : "5984", 4 | "key-value-store" : "fabric-client/lib/impl/CouchDBKeyValueStore.js" 5 | } 6 | -------------------------------------------------------------------------------- /chaincode/docker-compose-marbles.yml: -------------------------------------------------------------------------------- 1 | orderer: 2 | image: hyperledger/fabric-orderer 3 | environment: 4 | - ORDERER_GENERAL_LEDGERTYPE=ram 5 | - ORDERER_GENERAL_BATCHTIMEOUT=10s 6 | - ORDERER_GENERAL_MAXMESSAGECOUNT=2 7 | - ORDERER_GENERAL_MAXWINDOWSIZE=1000 8 | - ORDERER_GENERAL_ORDERERTYPE=solo 9 | - ORDERER_GENERAL_LISTENADDRESS=0.0.0.0 10 | - ORDERER_RAMLEDGER_HISTORY_SIZE=100 11 | working_dir: /opt/gopath/src/github.com/hyperledger/fabric/orderer 12 | command: orderer 13 | ports: 14 | - 7050:7050 15 | 16 | couchdb0: 17 | image: klaemo/couchdb:2.0.0 18 | command: tini -- /docker-entrypoint.sh /opt/couchdb/bin/couchdb 19 | ports: 20 | - 5984:5984 21 | 22 | couchdb1: 23 | image: klaemo/couchdb:2.0.0 24 | command: tini -- /docker-entrypoint.sh /opt/couchdb/bin/couchdb 25 | 26 | vp0: 27 | image: hyperledger/fabric-peer 28 | environment: 29 | - CORE_PEER_ADDRESSAUTODETECT=true 30 | - CORE_VM_ENDPOINT=unix:///host/var/run/docker.sock 31 | - CORE_PEER_NETWORKID=${CORE_PEER_ID} 32 | - CORE_NEXT=true 33 | - CORE_PEER_ENDORSER_ENABLED=true 34 | - CORE_PEER_COMMITTER_ENABLED=true 35 | - CORE_PEER_ID=vp0 36 | - CORE_PEER_COMMITTER_LEDGER_ORDERER=orderer:7050 37 | - CORE_PEER_GOSSIP_ORGLEADER=true 38 | - CORE_LEDGER_STATE_STATEDATABASE=CouchDB 39 | - CORE_LEDGER_STATE_COUCHDBCONFIG_COUCHDBADDRESS=couchdb0:5984 40 | volumes: 41 | - /var/run/:/host/var/run/ 42 | ports: 43 | - 7051:7051 44 | links: 45 | - orderer 46 | - couchdb0 47 | 48 | vp1: 49 | image: hyperledger/fabric-peer 50 | environment: 51 | - CORE_PEER_ADDRESSAUTODETECT=true 52 | - CORE_VM_ENDPOINT=unix:///host/var/run/docker.sock 53 | - CORE_PEER_NETWORKID=${CORE_PEER_ID} 54 | - CORE_NEXT=true 55 | - CORE_PEER_ENDORSER_ENABLED=true 56 | - CORE_PEER_COMMITTER_ENABLED=true 57 | - CORE_PEER_ID=vp1 58 | - CORE_PEER_GOSSIP_BOOTSTRAP=vp0:7051 59 | - CORE_PEER_GOSSIP_ORGLEADER=false 60 | - CORE_LEDGER_STATE_STATEDATABASE=CouchDB 61 | - CORE_LEDGER_STATE_COUCHDBCONFIG_COUCHDBADDRESS=couchdb1:5984 62 | volumes: 63 | - /var/run/:/host/var/run/ 64 | ports: 65 | - 7056:7051 66 | links: 67 | - vp0 68 | - couchdb1 69 | 70 | -------------------------------------------------------------------------------- /chaincode/fabricca/tlsOrg1/fabric-ca-server.db: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CBD-Forum/N0041-argiculture-supplychain/1076f95ebb67df8f3246f99a49a0f3c247d39647/chaincode/fabricca/tlsOrg1/fabric-ca-server.db -------------------------------------------------------------------------------- /chaincode/fabricca/tlsOrg2/fabric-ca-server.db: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CBD-Forum/N0041-argiculture-supplychain/1076f95ebb67df8f3246f99a49a0f3c247d39647/chaincode/fabricca/tlsOrg2/fabric-ca-server.db -------------------------------------------------------------------------------- /chaincode/fabriccop/ecert.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIIB8zCCAZqgAwIBAgIUWvyWRhnNjkgI240frgUO1ajr/qMwCgYIKoZIzj0EAwIw 3 | YzELMAkGA1UEBhMCVVMxFzAVBgNVBAgTDk5vcnRoIENhcm9saW5hMRAwDgYDVQQH 4 | EwdSYWxlaWdoMRswGQYDVQQKExJIeXBlcmxlZGdlciBGYWJyaWMxDDAKBgNVBAsT 5 | A0NPUDAeFw0xNjExMjcxMjI0MDBaFw0xNzExMjcxMjI0MDBaMBAxDjAMBgNVBAMT 6 | BWFkbWluMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEnrhMQCKVUaJVZywJtkeb 7 | dg4HHoYz7lb6knfglfX3R7OuX504snLlgCsSL8FgjMEMWINVQRA/NtT9kec2j5I7 8 | OaN/MH0wDgYDVR0PAQH/BAQDAgWgMB0GA1UdJQQWMBQGCCsGAQUFBwMBBggrBgEF 9 | BQcDAjAMBgNVHRMBAf8EAjAAMB0GA1UdDgQWBBSMVEXbf7pQjqpf2G/bW6S6DTHD 10 | HjAfBgNVHSMEGDAWgBTg2/DcHUvWopkCVxLow6n63y/9QjAKBggqhkjOPQQDAgNH 11 | ADBEAiBH2XyV4MxNb11tyljqo+4iF53GjF26w+JBxHg5T/oOxwIgSUpFO4z0Zd0O 12 | b/f7YhvdYtAhJqqJDv5u21oZrugjXIw= 13 | -----END CERTIFICATE----- 14 | -------------------------------------------------------------------------------- /chaincode/fabriccop/enroll-csr.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE REQUEST----- 2 | MIHQMHUCAQAwEzERMA8GA1UEAwwIdGVzdFVzZXIwWTATBgcqhkjOPQIBBggqhkjO 3 | PQMBBwNCAASSduelwzsHgCoVVJtMqaEbqkDVXQZiE68ffFc2OMnljKlx0/ndzB2H 4 | jWU9GhEG+zmjMBcARr6b/xas96wZeQ7LoAAwDAYIKoZIzj0EAwIFAANJADBGAiEA 5 | 8ODGpt+sqGIMj517SFkNtpMMAlcharmLFsDMWhxlcioCIQDfSU0pOkaEEn0/pWOU 6 | LxB2qFcakcohWyEFQHHDNJVFRw== 7 | -----END CERTIFICATE REQUEST----- -------------------------------------------------------------------------------- /chaincode/local.json: -------------------------------------------------------------------------------- 1 | { 2 | "request-timeout" : 7000, 3 | "tcert-batch-size" : 30, 4 | "ssl-target-name-override" : "localca", 5 | "default-authority" : "localca", 6 | "test-1": "local", 7 | "test-2": "local", 8 | "test-3": "local", 9 | "test-4": "local", 10 | "test-5": "local", 11 | "test-6": "local" 12 | } 13 | -------------------------------------------------------------------------------- /chaincode/msp/local/keystore/admin.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN PRIVATE KEY----- 2 | MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg2HxfPVxvwHYM5X8o 3 | /tEoDZ54Rl9uW13U6RElpnFOCruhRANCAATx8pv9DCChfwHoa7IRUf2z7GTmC3k2 4 | Tl8e7DWA9fZ4cpL9vdk0ZMgQZKo8Gm61NSTuHMZ8zp3uZn7QOcCmwuDg 5 | -----END PRIVATE KEY----- 6 | -------------------------------------------------------------------------------- /chaincode/msp/local/signcerts/admin.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIIB8TCCAZegAwIBAgIUasxwoRvBrGrdyg9+HtdJ3brpcuMwCgYIKoZIzj0EAwIw 3 | fzELMAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcTDVNh 4 | biBGcmFuY2lzY28xHzAdBgNVBAoTFkludGVybmV0IFdpZGdldHMsIEluYy4xDDAK 5 | BgNVBAsTA1dXVzEUMBIGA1UEAxMLZXhhbXBsZS5jb20wHhcNMTcwMTE5MTk1NjAw 6 | WhcNMTcxMjE5MDM1NjAwWjAQMQ4wDAYDVQQDEwVhZG1pbjBZMBMGByqGSM49AgEG 7 | CCqGSM49AwEHA0IABPHym/0MIKF/AehrshFR/bPsZOYLeTZOXx7sNYD19nhykv29 8 | 2TRkyBBkqjwabrU1JO4cxnzOne5mftA5wKbC4OCjYDBeMA4GA1UdDwEB/wQEAwIC 9 | BDAMBgNVHRMBAf8EAjAAMB0GA1UdDgQWBBQtEfVCvKOzNSiTgpaWzaYVm6eaBzAf 10 | BgNVHSMEGDAWgBQXZ0I9qp6CP8TFHZ9bw5nRtZxIEDAKBggqhkjOPQQDAgNIADBF 11 | AiEAvGd5YDIBeQZWpP9wEHFmezvSCjrzy8VcvH/7Yuv3vcoCICy5ssNrEHEyWXqB 12 | qeKfU/zrPhHsWJFIaJEDQLRQE05l 13 | -----END CERTIFICATE----- -------------------------------------------------------------------------------- /chaincode/msp/org0/admincerts/admin.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIIBwTCCAWegAwIBAgIUS34H+bjGij1WZvTbc63YLlPEMCUwCgYIKoZIzj0EAwIw 3 | TzELMAkGA1UEBhMCVVMxFDASBgNVBAoTC0h5cGVybGVkZ2VyMSowKAYDVQQDEyFU 4 | cmFuc2FjdGlvbiBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkwHhcNMTcwMjEwMTgyNzAw 5 | WhcNMTgwMTEwMDIyNzAwWjAQMQ4wDAYDVQQDEwVhZG1pbjBZMBMGByqGSM49AgEG 6 | CCqGSM49AwEHA0IABGtQi+dqAwv4pReiz/4XR2Zi8VjyjsRqKvHNufWwQYQ9cQ/L 7 | r9LBorlbRfcv00JsFRJb3DU8edNSCXGgFMnPMmujYDBeMA4GA1UdDwEB/wQEAwIC 8 | BDAMBgNVHRMBAf8EAjAAMB0GA1UdDgQWBBQVz3t/i3/zn1XifsVTynRM7BVnoDAf 9 | BgNVHSMEGDAWgBSRULWdqUi+VpEMgeU8F/q9FGCZjzAKBggqhkjOPQQDAgNIADBF 10 | AiEAjb/mObUaf04qgyQHMsawn6ddPBeBqT3HM1XsuEsviSwCICz6kxz4tzZLxQPk 11 | risyGwYi7oazS3o8IEvIAAQH6m2B 12 | -----END CERTIFICATE----- -------------------------------------------------------------------------------- /chaincode/msp/org0/cacerts/org_ca.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIICQTCCAcagAwIBAgIUQel8iXQdKaVJJABbwbekcZj37PQwCgYIKoZIzj0EAwMw 3 | TzELMAkGA1UEBhMCVVMxFDASBgNVBAoTC0h5cGVybGVkZ2VyMSowKAYDVQQDEyFU 4 | cmFuc2FjdGlvbiBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkwHhcNMTcwMjEwMTgyMDAw 5 | WhcNMjIwMjA5MTgyMDAwWjBPMQswCQYDVQQGEwJVUzEUMBIGA1UEChMLSHlwZXJs 6 | ZWRnZXIxKjAoBgNVBAMTIVRyYW5zYWN0aW9uIENlcnRpZmljYXRlIEF1dGhvcml0 7 | eTB2MBAGByqGSM49AgEGBSuBBAAiA2IABD5gsruQ5klLZVECSW1y4e1VdgrpFNEa 8 | yWCgA6d9uvx96/C6fD4cXgvlM4V9BXkbeHTsQjtO0vd6Aimi0vhdOu2tzKVAwSEq 9 | +YDpaVOuZMYlAuaLdpU9lee9gjbFGyXQOqNjMGEwDgYDVR0PAQH/BAQDAgEGMA8G 10 | A1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFJFQtZ2pSL5WkQyB5TwX+r0UYJmPMB8G 11 | A1UdIwQYMBaAFJFQtZ2pSL5WkQyB5TwX+r0UYJmPMAoGCCqGSM49BAMDA2kAMGYC 12 | MQDxtLRjPNMF7xPMC/tNzr2hdmGhREw6xw0fU54IudNE8wn+qYbH2bMezdZz1vSd 13 | /kYCMQDuG6NCaBXYzltRh5mslAyanYw/xKvT8S3SNNB1av8kGB2HO7TKleqm6OC9 14 | 9lgKK4w= 15 | -----END CERTIFICATE----- 16 | -------------------------------------------------------------------------------- /chaincode/msp/org1/admincerts/admin.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIIBwTCCAWegAwIBAgIUJfcDpoSSnoUrWjqHunlel/F7It8wCgYIKoZIzj0EAwIw 3 | TzELMAkGA1UEBhMCVUsxFDASBgNVBAoTC0h5cGVybGVkZ2VyMSowKAYDVQQDEyFU 4 | cmFuc2FjdGlvbiBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkwHhcNMTcwMjEwMTgzNTAw 5 | WhcNMTgwMTEwMDIzNTAwWjAQMQ4wDAYDVQQDEwVhZG1pbjBZMBMGByqGSM49AgEG 6 | CCqGSM49AwEHA0IABE8V7+p+gdNZtiGPZnJ0DNCLsXOEiMa1xj2eGo8geyVjXt3T 7 | Qjl5nCXyu4Hp6luchZnynEKH9BskVWf9bCAD5qijYDBeMA4GA1UdDwEB/wQEAwIC 8 | BDAMBgNVHRMBAf8EAjAAMB0GA1UdDgQWBBRHwo2hSZl2ZsXfihAsK+yehg5jTDAf 9 | BgNVHSMEGDAWgBTVtYvw7nizPfbI47cMyKy87ib4XTAKBggqhkjOPQQDAgNIADBF 10 | AiEA7WxrA2jFX0zfrobmSlC2sbLpicNxn1UrNS/cXVNXM/sCIGmZCysSDQ0tdKqY 11 | M2ECTOmfRcE1kEgNX2JbajR5F/12 12 | -----END CERTIFICATE----- -------------------------------------------------------------------------------- /chaincode/msp/org1/cacerts/org_ca.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIIBDjCBtQICA+gwCgYIKoZIzj0EAwIwEzERMA8GA1UEAwwIcGVlck9yZzEwHhcN 3 | MTcwMTI0MTk1NTQ1WhcNMTgwMTI0MTk1NTQ1WjATMREwDwYDVQQDDAhwZWVyT3Jn 4 | MTBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABPi8WnwoK2C3n+vDktN1jPan9Ac8 5 | TeL9qQynMFZ15fdD8eOlhi2pk1koX8dfWfJuG3FU1cCvBM8YCNbqaNFYU2YwCgYI 6 | KoZIzj0EAwIDSAAwRQIgaSOImd20mKZeddceGMrgtBU12mE1oQl3zt6xyJcV5PQC 7 | IQCXmOyvtyRqiVop3BOVXAbnFvWTHjNs9UFRk7Hpc2vWAA== 8 | -----END CERTIFICATE----- 9 | -------------------------------------------------------------------------------- /chaincode/src/jutian_cc/Dockerfile: -------------------------------------------------------------------------------- 1 | from hyperledger/fabric-ccenv 2 | COPY . $GOPATH/src/build-chaincode/ 3 | WORKDIR $GOPATH 4 | 5 | COPY ./vendor/github.com $GOPATH/src/github.com 6 | 7 | RUN go get github.com/op/go-logging 8 | RUN go install build-chaincode && mv $GOPATH/bin/build-chaincode $GOPATH/bin/assets_unit_test -------------------------------------------------------------------------------- /chaincode/src/jutian_cc/account_db.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "encoding/json" 5 | "fmt" 6 | "strconv" 7 | 8 | "github.com/hyperledger/fabric/core/chaincode/shim" 9 | 10 | "errors" 11 | ) 12 | 13 | type Account struct { 14 | AccountID string 15 | UserName string 16 | Password string 17 | UserType int 18 | } 19 | 20 | type UserInfo struct { 21 | ObjectType string 22 | Type int 23 | OwnerID string 24 | RealName string 25 | IdentityID string 26 | Location string 27 | UserType int 28 | CreditScore int 29 | } 30 | 31 | const ( 32 | UserTypeFarmer = 1 33 | UserTypePackager = 2 34 | UserTypeWarehouse = 3 35 | UserTypeLogistic = 4 36 | UserTypeMerchant = 5 37 | ) 38 | 39 | //AccountInfo 账户信息 40 | type AccountInfo struct { 41 | UserInfo *UserInfo 42 | Temperature int 43 | Equipment string 44 | Money *AccountMoney 45 | Balance *AccountBalance 46 | LoanApply *LoanApply 47 | } 48 | 49 | const ( 50 | AccountTypeFarmer = 1 51 | ) 52 | 53 | var accountObjectType = "AccountObjectType" 54 | var userInfoIDPrefix = "userInfo:" 55 | var accountPrefix = "account-password:" 56 | 57 | func insertAccountToDb(stub shim.ChaincodeStubInterface, acc *Account) error { 58 | key := accountPrefix + acc.AccountID 59 | accountBytes, err := json.Marshal(&acc) 60 | if err != nil { 61 | return errors.New("cannot convert account to json bytes: " + err.Error()) 62 | } 63 | err = stub.PutState(key, accountBytes) 64 | if err != nil { 65 | return errors.New("cannot save account to state db: " + err.Error()) 66 | } 67 | 68 | userNameKey := accountPrefix + acc.UserName 69 | err = stub.PutState(userNameKey, accountBytes) 70 | if err != nil { 71 | return errors.New("cannot save account to state db: " + err.Error()) 72 | } 73 | 74 | return nil 75 | } 76 | 77 | func getAccountFromDb(stub shim.ChaincodeStubInterface, AccountID string) (*Account, error) { 78 | key := accountPrefix + AccountID 79 | acc := &Account{} 80 | 81 | accountBytes, err := stub.GetState(key) 82 | if err != nil { 83 | return acc, errors.New("cannot get account from state db, key is " + key + ", err:" + err.Error()) 84 | } else if accountBytes == nil { 85 | return acc, nil 86 | } 87 | 88 | err = json.Unmarshal(accountBytes, acc) 89 | if err != nil { 90 | return acc, errors.New("cannot convert bytes to account: " + err.Error()) 91 | } 92 | 93 | return acc, nil 94 | } 95 | 96 | func getAccountByUserNameFromDb(stub shim.ChaincodeStubInterface, userName string) (*Account, error) { 97 | key := accountPrefix + userName 98 | acc := &Account{} 99 | 100 | accountBytes, err := stub.GetState(key) 101 | if err != nil { 102 | return acc, errors.New("cannot get account from state db, key is " + key + ", err:" + err.Error()) 103 | } else if accountBytes == nil { 104 | return acc, nil 105 | } 106 | 107 | err = json.Unmarshal(accountBytes, acc) 108 | if err != nil { 109 | return acc, errors.New("cannot convert bytes to account: " + err.Error()) 110 | } 111 | 112 | return acc, nil 113 | } 114 | 115 | func insertUserInfoToDb(stub shim.ChaincodeStubInterface, acc *UserInfo) error { 116 | key := userInfoIDPrefix + acc.OwnerID 117 | accountBytes, err := json.Marshal(&acc) 118 | if err != nil { 119 | return errors.New("cannot convert account to json bytes: " + err.Error()) 120 | } 121 | 122 | fmt.Println(acc) 123 | err = stub.PutState(key, accountBytes) 124 | if err != nil { 125 | return errors.New("cannot save account to state db: " + err.Error()) 126 | } 127 | return nil 128 | } 129 | 130 | func getUserInfoFromDb(stub shim.ChaincodeStubInterface, ownerID string) (*UserInfo, error) { 131 | key := userInfoIDPrefix + ownerID 132 | acc := &UserInfo{} 133 | 134 | accountBytes, err := stub.GetState(key) 135 | if err != nil { 136 | return acc, errors.New("cannot get account from state db, key is " + key + ", err:" + err.Error()) 137 | } else if accountBytes == nil { 138 | return acc, nil 139 | } 140 | 141 | err = json.Unmarshal(accountBytes, acc) 142 | if err != nil { 143 | return acc, errors.New("cannot convert bytes to account: " + err.Error()) 144 | } 145 | 146 | return acc, nil 147 | } 148 | 149 | // 温度 150 | 151 | var temperaturePrefix = "account_temperature:" 152 | 153 | func insertTemperatureToDb(stub shim.ChaincodeStubInterface, accountID string, temperature int) error { 154 | var key = temperaturePrefix + accountID 155 | var temperatureString = strconv.Itoa(temperature) 156 | err := stub.PutState(key, []byte(temperatureString)) 157 | if err != nil { 158 | return errors.New("cannnt put temperatore to state db: " + err.Error()) 159 | } 160 | return nil 161 | } 162 | 163 | func getTemperatureFromDb(stub shim.ChaincodeStubInterface, accountID string) (int, error) { 164 | var key = temperaturePrefix + accountID 165 | resBytes, err := stub.GetState(key) 166 | if err != nil { 167 | return 0, errors.New("cannot get temperature from state db, err: " + err.Error()) 168 | } else if resBytes == nil { 169 | stub.PutState(key, []byte("0")) 170 | return 0, nil 171 | } 172 | return strconv.Atoi(string(resBytes)) 173 | } 174 | 175 | const ( 176 | EquipmentStatusFault = "故障" 177 | EquipmentStatusException = "异常" 178 | EquipmentStatusGOOD = "良好" 179 | ) 180 | 181 | var equipmentPrefix = "account_equipment:" 182 | 183 | func insertEquipmentToDb(stub shim.ChaincodeStubInterface, accountID string, status string) error { 184 | var key = temperaturePrefix + accountID 185 | err := stub.PutState(key, []byte(status)) 186 | if err != nil { 187 | return errors.New("cannnt put equipment status to state db: " + err.Error()) 188 | } 189 | return nil 190 | } 191 | 192 | func getEquipmentFromDb(stub shim.ChaincodeStubInterface, accountID string) (string, error) { 193 | var key = temperaturePrefix + accountID 194 | resBytes, err := stub.GetState(key) 195 | if err != nil { 196 | return "未知", errors.New("cannot get equipment status from state db, err: " + err.Error()) 197 | } else if resBytes == nil { 198 | return "未知", nil 199 | } 200 | return string(resBytes), nil 201 | } 202 | -------------------------------------------------------------------------------- /chaincode/src/jutian_cc/account_money_db.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "encoding/json" 5 | "errors" 6 | 7 | "github.com/hyperledger/fabric/core/chaincode/shim" 8 | ) 9 | 10 | type AccountMoney struct { 11 | OwnerID string 12 | Money int 13 | FlowIDs []string 14 | FlowType int 15 | CreateDate int64 16 | } 17 | 18 | type AccountMoneyHistory struct { 19 | AccountMoney *AccountMoney 20 | Flows []interface{} 21 | } 22 | 23 | type AccountBalance struct { 24 | OwnerID string 25 | Loan int 26 | } 27 | 28 | var accountBalancePrefix = "accountBalance:" 29 | 30 | const ( 31 | AccountMoneyFlowTypeOrder = 1 32 | AccountMoneyFlowTypeBigPackage = 2 33 | AccountMoneyFlowTypeWarehouse = 3 34 | AccountMoneyFlowTypeLogistic = 4 35 | AccountMoneyFlowTypeMerchandise = 5 36 | AccountMoneyFlowTypeLoan = 6 37 | AccountMoneyFlowTypeRepayment = 7 38 | AccountMoneyFlowTypeAsset = 8 39 | ) 40 | 41 | var moneyKeyPrefix = "usermoney:" 42 | 43 | func insertMoneyToDb(stub shim.ChaincodeStubInterface, accountMoney *AccountMoney) error { 44 | var key = moneyKeyPrefix + accountMoney.OwnerID 45 | accountMoney.CreateDate = MakeTimestamp() 46 | moneyBytes, err := json.Marshal(accountMoney) 47 | if err != nil { 48 | return errors.New("cannot convert user money to json bytes, err " + err.Error()) 49 | } 50 | 51 | err = stub.PutState(key, moneyBytes) 52 | if err != nil { 53 | return errors.New("cannot insert user money to state db, err " + err.Error()) 54 | } 55 | 56 | return nil 57 | } 58 | 59 | func getMoneyFromDb(stub shim.ChaincodeStubInterface, ownerID string) (*AccountMoney, error) { 60 | var key = moneyKeyPrefix + ownerID 61 | var money = &AccountMoney{} 62 | moneyBytes, err := stub.GetState(key) 63 | if err != nil { 64 | return money, errors.New("cannot get account money, err " + err.Error()) 65 | } else if moneyBytes == nil { 66 | return money, nil 67 | } 68 | 69 | err = json.Unmarshal(moneyBytes, money) 70 | if err != nil { 71 | return money, errors.New("cannot convert bytes to usermoney, err " + err.Error() + ", data is " + string(moneyBytes) + "key is " + key) 72 | } 73 | return money, nil 74 | } 75 | 76 | func getMoneyHistory(stub shim.ChaincodeStubInterface, ownerID string) ([]*AccountMoney, error) { 77 | moneyHistory := make([]*AccountMoney, 0) 78 | var key = moneyKeyPrefix + ownerID 79 | resultsIterator, err := stub.GetHistoryForKey(key) 80 | if err != nil { 81 | return moneyHistory, errors.New("cannot get money history, err " + err.Error()) 82 | } 83 | defer resultsIterator.Close() 84 | 85 | for resultsIterator.HasNext() { 86 | _, historicValue, err := resultsIterator.Next() 87 | if err != nil { 88 | return moneyHistory, errors.New("cannot get money history from iterator, err " + err.Error()) 89 | } 90 | 91 | var money AccountMoney 92 | err = json.Unmarshal(historicValue, &money) 93 | if err != nil { 94 | return moneyHistory, errors.New("cannot convert money history to UserMoney, err " + err.Error()) 95 | } 96 | moneyHistory = append(moneyHistory, &money) 97 | } 98 | return moneyHistory, nil 99 | } 100 | 101 | func insertAccountBalanceToDb(stub shim.ChaincodeStubInterface, balance *AccountBalance) error { 102 | var key = accountBalancePrefix + balance.OwnerID 103 | moneyBytes, err := json.Marshal(balance) 104 | if err != nil { 105 | return errors.New("cannot convert AccountBalance to json bytes, err " + err.Error()) 106 | } 107 | 108 | err = stub.PutState(key, moneyBytes) 109 | if err != nil { 110 | return errors.New("cannot insert AccountBalance to state db, err " + err.Error()) 111 | } 112 | 113 | return nil 114 | } 115 | 116 | func getAccountBalanceFromDb(stub shim.ChaincodeStubInterface, ownerID string) (*AccountBalance, error) { 117 | balance := &AccountBalance{} 118 | var key = accountBalancePrefix + ownerID 119 | moneyBytes, err := stub.GetState(key) 120 | if err != nil { 121 | return balance, errors.New("cannot get AccountBalance from state db, err " + err.Error()) 122 | } else if moneyBytes == nil { 123 | return balance, nil 124 | } 125 | 126 | err = json.Unmarshal(moneyBytes, balance) 127 | if err != nil { 128 | return balance, errors.New("cannot convert bytes to AccountBalance, err " + err.Error() + ", data is " + string(moneyBytes) + "key is " + key) 129 | } 130 | return balance, nil 131 | } 132 | -------------------------------------------------------------------------------- /chaincode/src/jutian_cc/farmer_asset_db.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "encoding/json" 5 | "errors" 6 | 7 | "github.com/hyperledger/fabric/core/chaincode/shim" 8 | ) 9 | 10 | type FarmerAsset struct { 11 | ObjectType string 12 | AssetID string 13 | OwnerID string 14 | CategoryID string 15 | Amount int 16 | MaterialUnitCost int 17 | LaborUnitCost int 18 | CreateDate int64 19 | FarmerName string 20 | Location string 21 | } 22 | 23 | var farmerAssetMaterialUnitCost = 2 // 预设的成本 24 | var farmerAssetLaborlUnitCost = 1 // 预设的成本 25 | 26 | var farmerAssetObjectType = "farmerAsset" 27 | 28 | var farmerAssetPrefix = "farmerAsset:" 29 | 30 | var farmerAssetObjectTypeIdx = "objectType~assetID" 31 | var farmerAssetOwnerIdx = "ownerID~assetID" 32 | 33 | var farmerAssetCatNOwnIdx = "ownerID~categoryID" // key是如此。保存的是assetID 34 | 35 | func insertFarmerAssetToDb(stub shim.ChaincodeStubInterface, asset *FarmerAsset) error { 36 | asset.CreateDate = MakeTimestamp() 37 | if asset.AssetID == "" { 38 | asset.AssetID = GenerateRandom(32) 39 | } 40 | 41 | var key = farmerAssetPrefix + asset.AssetID 42 | assetJSONBytes, err := json.Marshal(asset) 43 | if err != nil { 44 | return errors.New("cannot convert farmer asset to json bytes, err is " + err.Error()) 45 | } 46 | err = stub.PutState(key, assetJSONBytes) 47 | if err != nil { 48 | return errors.New("cannot put farmer asset to state, err is " + err.Error()) 49 | } 50 | 51 | objectIdx, err := stub.CreateCompositeKey(farmerAssetObjectTypeIdx, []string{farmerAssetObjectType, asset.AssetID}) 52 | if err != nil { 53 | return errors.New("create item composite key err, " + err.Error()) 54 | } 55 | value := []byte{0x00} 56 | stub.PutState(objectIdx, value) 57 | 58 | ownIdx, err := stub.CreateCompositeKey(farmerAssetOwnerIdx, []string{asset.OwnerID, asset.AssetID}) 59 | if err != nil { 60 | return errors.New("create item composite key err, " + err.Error()) 61 | } 62 | stub.PutState(ownIdx, value) 63 | 64 | // 保存类别。目前每个人每个分类只有一种 65 | catOwnKey := asset.OwnerID + "~" + asset.CategoryID 66 | stub.PutState(catOwnKey, []byte(asset.AssetID)) 67 | 68 | return nil 69 | } 70 | 71 | //只更新部分数据 72 | func updateFarmerAssetToDb(stub shim.ChaincodeStubInterface, asset *FarmerAsset) error { 73 | var key = farmerAssetPrefix + asset.AssetID 74 | assetJSONBytes, err := json.Marshal(asset) 75 | if err != nil { 76 | return errors.New("cannot convert farmer asset to json bytes, err is " + err.Error()) 77 | } 78 | err = stub.PutState(key, assetJSONBytes) 79 | if err != nil { 80 | return errors.New("cannot put farmer asset to state, err is " + err.Error()) 81 | } 82 | return nil 83 | } 84 | 85 | func getAssetByCategoryNOwnFromDb(stub shim.ChaincodeStubInterface, categoryID, ownerID string) (*FarmerAsset, error) { 86 | asset := &FarmerAsset{} 87 | 88 | catOwnKey := ownerID + "~" + categoryID 89 | assetID, err := stub.GetState(catOwnKey) 90 | if err != nil { 91 | return asset, errors.New("cannot find asset by category and ownerId " + ownerID + "," + categoryID + ",err: " + err.Error()) 92 | } 93 | if assetID == nil { 94 | return asset, nil 95 | } 96 | return getFarmerAssetFromDb(stub, string(assetID)) 97 | } 98 | 99 | func getFarmerAssetFromDb(stub shim.ChaincodeStubInterface, assetID string) (*FarmerAsset, error) { 100 | farmerAsset := &FarmerAsset{} 101 | var key = farmerAssetPrefix + assetID 102 | assBytes, err := stub.GetState(key) 103 | if err != nil { 104 | return farmerAsset, errors.New("cannot get farmer asset from state, err is " + err.Error()) 105 | } else if assBytes == nil { 106 | return farmerAsset, nil 107 | } 108 | 109 | err = json.Unmarshal(assBytes, farmerAsset) 110 | if err != nil { 111 | return farmerAsset, errors.New("cannot convert farmer asset json bytes to Asset, err is " + err.Error()) 112 | } 113 | return farmerAsset, nil 114 | } 115 | 116 | // 获取某个农民的所有资产 117 | func getFarmerAssetsByOwnerFromDb(stub shim.ChaincodeStubInterface, ownerID string) ([]*FarmerAsset, error) { 118 | ownIterator, err := stub.GetStateByPartialCompositeKey(farmerAssetOwnerIdx, []string{ownerID}) 119 | defer ownIterator.Close() 120 | if err != nil { 121 | return nil, errors.New("cannot get assets by owner, err " + err.Error()) 122 | } 123 | 124 | assets := make([]*FarmerAsset, 0) 125 | var i int 126 | for i = 0; ownIterator.HasNext(); i++ { 127 | ownerKey, _, err := ownIterator.Next() 128 | if err != nil { 129 | return assets, errors.New("get owner key from asset err, " + err.Error()) 130 | } 131 | _, compositeKeys, err := stub.SplitCompositeKey(ownerKey) 132 | if err != nil { 133 | return assets, errors.New("canot get compositeKeys, err " + err.Error()) 134 | } 135 | 136 | assetID := compositeKeys[1] 137 | asset, err := getFarmerAssetFromDb(stub, assetID) 138 | if err != nil { 139 | return assets, err 140 | } 141 | assets = append(assets, asset) 142 | } 143 | return assets, nil 144 | } 145 | -------------------------------------------------------------------------------- /chaincode/src/jutian_cc/financial_db.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "encoding/json" 5 | "errors" 6 | 7 | "github.com/hyperledger/fabric/core/chaincode/shim" 8 | ) 9 | 10 | type LoanApply struct { 11 | ObjectType string 12 | FarmerID string 13 | FarmerName string 14 | Money int 15 | LoanableMoney int // 可放款额度 16 | CreateDate int64 17 | } 18 | 19 | var loanApplyPrefix = "loanApply:" 20 | var LoanApplyObjectType = "loanApply" 21 | var loanApplyObjIdx = "objectType~farmerID" 22 | 23 | func insertLoanApplyToDb(stub shim.ChaincodeStubInterface, l *LoanApply) error { 24 | l.ObjectType = LoanApplyObjectType 25 | var key = loanApplyPrefix + l.FarmerID 26 | wBytes, err := stub.GetState(key) 27 | if err != nil { 28 | return errors.New("cannot get LoanApply from state db, err: " + err.Error()) 29 | } else if wBytes != nil { 30 | return errors.New("LoanApply already exists, " + l.FarmerID) 31 | } 32 | 33 | wBytes, err = json.Marshal(l) 34 | if err != nil { 35 | return errors.New("cannot convert LoanApply to bytes: " + err.Error()) 36 | } 37 | 38 | err = stub.PutState(key, wBytes) 39 | if err != nil { 40 | return errors.New("cannot put LoanApply to state db, err: " + err.Error()) 41 | } 42 | 43 | // create index 44 | value := []byte{0x00} 45 | objIdx, err := stub.CreateCompositeKey(loanApplyObjIdx, []string{LoanApplyObjectType, l.FarmerID}) 46 | if err != nil { 47 | return errors.New("create LoanApply composite key err, " + err.Error()) 48 | } 49 | stub.PutState(objIdx, value) 50 | 51 | return nil 52 | } 53 | 54 | func getLoanApplyByFarmerFromDb(stub shim.ChaincodeStubInterface, farmerID string) (*LoanApply, error) { 55 | l := &LoanApply{} 56 | 57 | key := loanApplyPrefix + farmerID 58 | wBytes, err := stub.GetState(key) 59 | if err != nil { 60 | return l, errors.New("cannot get LoanApply from state db, err: " + err.Error()) 61 | } else if wBytes == nil { 62 | return l, nil 63 | } 64 | 65 | err = json.Unmarshal(wBytes, l) 66 | if err != nil { 67 | return l, errors.New("cannot convert json bytes to LoanApply, err: " + err.Error()) 68 | } 69 | return l, nil 70 | } 71 | 72 | func delLoanApply(stub shim.ChaincodeStubInterface, farmerID string) error { 73 | key := loanApplyPrefix + farmerID 74 | 75 | err := stub.PutState(key, nil) 76 | if err != nil { 77 | return err 78 | } 79 | 80 | objIdx, err := stub.CreateCompositeKey(loanApplyObjIdx, []string{LoanApplyObjectType, farmerID}) 81 | if err != nil { 82 | return errors.New("create LoanApply composite key err, " + err.Error()) 83 | } 84 | 85 | err = stub.PutState(objIdx, nil) 86 | if err != nil { 87 | return err 88 | } 89 | return nil 90 | } 91 | 92 | func getLoanApplyListFromDb(stub shim.ChaincodeStubInterface) ([]*LoanApply, error) { 93 | iterator, err := stub.GetStateByPartialCompositeKey(loanApplyObjIdx, []string{LoanApplyObjectType}) 94 | defer iterator.Close() 95 | if err != nil { 96 | return nil, errors.New("cannot get Logistic LoanApply by ownerID, err:" + err.Error()) 97 | } 98 | 99 | return _getLoanApplyFromIdxIterator(stub, iterator) 100 | } 101 | 102 | //从iterator获取列表 103 | func _getLoanApplyFromIdxIterator(stub shim.ChaincodeStubInterface, iterator shim.StateQueryIteratorInterface) ([]*LoanApply, error) { 104 | ws := make([]*LoanApply, 0) 105 | for iterator.HasNext() { 106 | key, _, err := iterator.Next() 107 | if err != nil { 108 | return nil, errors.New("get key from LoanApply err, " + err.Error()) 109 | } 110 | _, compositeKeys, err := stub.SplitCompositeKey(key) 111 | if err != nil { 112 | return nil, errors.New("canot get compositeKeys, err " + err.Error()) 113 | } 114 | 115 | farmerID := compositeKeys[1] 116 | w, err := getLoanApplyByFarmerFromDb(stub, farmerID) 117 | if err != nil { 118 | return nil, err 119 | } 120 | ws = append(ws, w) 121 | } 122 | return ws, nil 123 | } 124 | -------------------------------------------------------------------------------- /chaincode/src/jutian_cc/logistic_db.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "encoding/json" 5 | "errors" 6 | 7 | "github.com/hyperledger/fabric/core/chaincode/shim" 8 | ) 9 | 10 | type Logistic struct { 11 | ObjectType string 12 | BigPackageID string 13 | OwnerID string 14 | OrderID string 15 | StartLocation string 16 | EndLocation string 17 | Cost int 18 | CreateDate int64 19 | Delivered bool 20 | } 21 | 22 | var logisticCost = 2 23 | 24 | var logisticObjectType = "logistic" 25 | 26 | var logisticPrefix = "logistic:" 27 | 28 | var logisticOwnIdx = "ownerID~logisticID" 29 | var logisticObjIdx = "objectType~logisticID" 30 | var logisticOrderIdx = "orderID~logisticID" 31 | 32 | func insertLogisticToDb(stub shim.ChaincodeStubInterface, l *Logistic) error { 33 | var key = logisticPrefix + l.BigPackageID 34 | wBytes, err := stub.GetState(key) 35 | if err != nil { 36 | return errors.New("cannot get Logistic from state db, err: " + err.Error()) 37 | } else if wBytes != nil { 38 | return errors.New("Logistic already exists, " + l.BigPackageID) 39 | } 40 | 41 | wBytes, err = json.Marshal(l) 42 | if err != nil { 43 | return errors.New("cannot convert Logistic to bytes: " + err.Error()) 44 | } 45 | 46 | err = stub.PutState(key, wBytes) 47 | if err != nil { 48 | return errors.New("cannot put Logistic to state db, err: " + err.Error()) 49 | } 50 | 51 | // create index 52 | value := []byte{0x00} 53 | 54 | ownIdx, err := stub.CreateCompositeKey(logisticOwnIdx, []string{l.OwnerID, l.BigPackageID}) 55 | if err != nil { 56 | return errors.New("create Logistic composite key err, " + err.Error()) 57 | } 58 | stub.PutState(ownIdx, value) 59 | 60 | objIdx, err := stub.CreateCompositeKey(logisticObjIdx, []string{logisticObjectType, l.BigPackageID}) 61 | if err != nil { 62 | return errors.New("create Logistic composite key err, " + err.Error()) 63 | } 64 | stub.PutState(objIdx, value) 65 | 66 | objOrdIdx, err := stub.CreateCompositeKey(logisticOrderIdx, []string{l.OrderID, l.BigPackageID}) 67 | if err != nil { 68 | return errors.New("create Logistic composite key err, " + err.Error()) 69 | } 70 | stub.PutState(objOrdIdx, value) 71 | 72 | return nil 73 | } 74 | 75 | func updateLogisticToDb(stub shim.ChaincodeStubInterface, l *Logistic) error { 76 | var key = logisticPrefix + l.BigPackageID 77 | wBytes, err := stub.GetState(key) 78 | if err != nil { 79 | return errors.New("cannot get Logistic from state db, err: " + err.Error()) 80 | } else if wBytes == nil { 81 | return errors.New("Logistic not exists, " + l.BigPackageID) 82 | } 83 | 84 | wBytes, err = json.Marshal(l) 85 | if err != nil { 86 | return errors.New("cannot convert Logistic to bytes: " + err.Error()) 87 | } 88 | 89 | err = stub.PutState(key, wBytes) 90 | if err != nil { 91 | return errors.New("cannot put Logistic to state db, err: " + err.Error()) 92 | } 93 | return nil 94 | } 95 | 96 | func getLogisticFromDb(stub shim.ChaincodeStubInterface, bigPackageID string) (*Logistic, error) { 97 | l := &Logistic{} 98 | 99 | var key = logisticPrefix + bigPackageID 100 | wBytes, err := stub.GetState(key) 101 | if err != nil { 102 | return l, errors.New("cannot get Logistic from state db, err: " + err.Error()) 103 | } else if wBytes == nil { 104 | return l, nil 105 | } 106 | 107 | err = json.Unmarshal(wBytes, l) 108 | if err != nil { 109 | return l, errors.New("cannot convert json bytes to Logistic, err: " + err.Error()) 110 | } 111 | return l, nil 112 | } 113 | 114 | func getLogisticByOwnFromDb(stub shim.ChaincodeStubInterface, ownerID string) ([]*Logistic, error) { 115 | iterator, err := stub.GetStateByPartialCompositeKey(logisticOwnIdx, []string{ownerID}) 116 | defer iterator.Close() 117 | if err != nil { 118 | return nil, errors.New("cannot get Logistic CreateCompositeKey by ownerID, err:" + err.Error()) 119 | } 120 | 121 | return _getLogisticsFromIdxIterator(stub, iterator) 122 | } 123 | 124 | func getLogisticByOrderFromDb(stub shim.ChaincodeStubInterface, orderID string) ([]*Logistic, error) { 125 | iterator, err := stub.GetStateByPartialCompositeKey(logisticOrderIdx, []string{orderID}) 126 | defer iterator.Close() 127 | if err != nil { 128 | return nil, errors.New("cannot get Logistic CreateCompositeKey by ownerID, err:" + err.Error()) 129 | } 130 | 131 | return _getLogisticsFromIdxIterator(stub, iterator) 132 | } 133 | 134 | //从iterator获取warehouse store in 列表 135 | func _getLogisticsFromIdxIterator(stub shim.ChaincodeStubInterface, iterator shim.StateQueryIteratorInterface) ([]*Logistic, error) { 136 | ws := make([]*Logistic, 0) 137 | for iterator.HasNext() { 138 | key, _, err := iterator.Next() 139 | if err != nil { 140 | return nil, errors.New("get key from Logistic err, " + err.Error()) 141 | } 142 | _, compositeKeys, err := stub.SplitCompositeKey(key) 143 | if err != nil { 144 | return nil, errors.New("canot get compositeKeys, err " + err.Error()) 145 | } 146 | 147 | bigPackageID := compositeKeys[1] 148 | w, err := getLogisticFromDb(stub, bigPackageID) 149 | if err != nil { 150 | return nil, err 151 | } 152 | ws = append(ws, w) 153 | } 154 | return ws, nil 155 | } 156 | -------------------------------------------------------------------------------- /chaincode/src/jutian_cc/merchant_db.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "encoding/json" 5 | "errors" 6 | 7 | "github.com/hyperledger/fabric/core/chaincode/shim" 8 | ) 9 | 10 | type Merchandise struct { 11 | ObjectType string 12 | PackageID string 13 | OwnerID string 14 | CategoryID string 15 | Amount int 16 | Price int 17 | SoldOut bool 18 | CreateDate int64 19 | } 20 | 21 | var merchandisePrice = 50 22 | 23 | var merchandiseObjectType = "merchandise" 24 | 25 | var merchandisePrefix = "merchandise:" 26 | 27 | var merchandiseObjIdx = "objectType~packageID" 28 | var merchandiseOwnIdx = "ownerID~packageID" 29 | 30 | func insertMerchandiseToDb(stub shim.ChaincodeStubInterface, m *Merchandise) error { 31 | var key = merchandisePrefix + m.PackageID 32 | wBytes, err := stub.GetState(key) 33 | if err != nil { 34 | return errors.New("cannot get Merchandise from state db, err: " + err.Error()) 35 | } else if wBytes != nil { 36 | return errors.New("Merchandise already exists, " + m.PackageID) 37 | } 38 | 39 | wBytes, err = json.Marshal(m) 40 | if err != nil { 41 | return errors.New("cannot convert Merchandise to bytes: " + err.Error()) 42 | } 43 | 44 | err = stub.PutState(key, wBytes) 45 | if err != nil { 46 | return errors.New("cannot put Merchandise to state db, err: " + err.Error()) 47 | } 48 | 49 | // create index 50 | value := []byte{0x00} 51 | 52 | objIdx, err := stub.CreateCompositeKey(merchandiseObjIdx, []string{merchandiseObjectType, m.PackageID}) 53 | if err != nil { 54 | return errors.New("create Merchandise composite key err, " + err.Error()) 55 | } 56 | stub.PutState(objIdx, value) 57 | 58 | ownIdx, err := stub.CreateCompositeKey(merchandiseOwnIdx, []string{m.OwnerID, m.PackageID}) 59 | if err != nil { 60 | return errors.New("create Merchandise composite key err, " + err.Error()) 61 | } 62 | stub.PutState(ownIdx, value) 63 | 64 | return nil 65 | } 66 | 67 | func updateMerchandiseToDb(stub shim.ChaincodeStubInterface, m *Merchandise) error { 68 | var key = merchandisePrefix + m.PackageID 69 | wBytes, err := stub.GetState(key) 70 | if err != nil { 71 | return errors.New("cannot get Merchandise from state db, err: " + err.Error()) 72 | } else if wBytes == nil { 73 | return errors.New("Merchandise not exists, " + m.PackageID) 74 | } 75 | 76 | wBytes, err = json.Marshal(m) 77 | if err != nil { 78 | return errors.New("cannot convert Merchandise to bytes: " + err.Error()) 79 | } 80 | 81 | err = stub.PutState(key, wBytes) 82 | if err != nil { 83 | return errors.New("cannot put Merchandise to state db, err: " + err.Error()) 84 | } 85 | 86 | return nil 87 | } 88 | 89 | func getMerchandiseFromDb(stub shim.ChaincodeStubInterface, packageID string) (*Merchandise, error) { 90 | m := &Merchandise{} 91 | 92 | var key = merchandisePrefix + packageID 93 | wBytes, err := stub.GetState(key) 94 | if err != nil { 95 | return m, errors.New("cannot get Merchandise from state db, err: " + err.Error()) 96 | } else if wBytes == nil { 97 | return m, nil 98 | } 99 | 100 | err = json.Unmarshal(wBytes, m) 101 | if err != nil { 102 | return m, errors.New("cannot convert json bytes to Merchandise, err: " + err.Error()) 103 | } 104 | return m, nil 105 | } 106 | 107 | func getMerchandisesByOwnerFromDb(stub shim.ChaincodeStubInterface, ownerID string) ([]*Merchandise, error) { 108 | iterator, err := stub.GetStateByPartialCompositeKey(merchandiseOwnIdx, []string{ownerID}) 109 | defer iterator.Close() 110 | if err != nil { 111 | return nil, errors.New("cannot get Merchandise CreateCompositeKey by ownerID, err:" + err.Error()) 112 | } 113 | 114 | return _getMerchandisesFromIdxIterator(stub, iterator) 115 | } 116 | 117 | //从iterator获取 Merchandise 列表 118 | func _getMerchandisesFromIdxIterator(stub shim.ChaincodeStubInterface, iterator shim.StateQueryIteratorInterface) ([]*Merchandise, error) { 119 | ws := make([]*Merchandise, 0) 120 | for iterator.HasNext() { 121 | key, _, err := iterator.Next() 122 | if err != nil { 123 | return nil, errors.New("get key from Merchandise err, " + err.Error()) 124 | } 125 | _, compositeKeys, err := stub.SplitCompositeKey(key) 126 | if err != nil { 127 | return nil, errors.New("canot get compositeKeys, err " + err.Error()) 128 | } 129 | 130 | packageID := compositeKeys[1] 131 | w, err := getMerchandiseFromDb(stub, packageID) 132 | if err != nil { 133 | return nil, err 134 | } 135 | ws = append(ws, w) 136 | } 137 | return ws, nil 138 | } 139 | -------------------------------------------------------------------------------- /chaincode/src/jutian_cc/order_db.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "encoding/json" 5 | "errors" 6 | 7 | "github.com/hyperledger/fabric/core/chaincode/shim" 8 | ) 9 | 10 | type Order struct { 11 | ObjectType string 12 | OrderID string 13 | OwnerID string 14 | FarmerID string 15 | Title string 16 | CategoryID string 17 | Destination string 18 | Amount int 19 | Price int 20 | Detail string 21 | Status int 22 | Payed bool 23 | CreateDate int64 24 | } 25 | 26 | type FilterOrdersFunc func(order *Order) bool 27 | 28 | const ( 29 | OrderStatusInit = 1 //订单初始化 30 | OrderStatusMatched = 2 //订单被接单 31 | OrderStatusProduced = 3 //订单生产完成 32 | OrderStatusPackaged = 4 //订单打包 33 | OrderStatusPackagedStoreIn = 5 //订单入库 34 | OrderStatusDeliveried = 6 //订单发货 35 | OrderStatusFinished = 7 36 | ) 37 | 38 | var orderObjectType = "order" 39 | var orderPrefix = "order:" 40 | var orderObjIdx = "objectType~orderID" 41 | var orderOwnerIdx = "ownerID~orderID" 42 | var orderFarmerIdx = "farmerID~orderID" 43 | var orderCategoryIdx = "categoryID~orderID" 44 | 45 | func insertOrderToDb(stub shim.ChaincodeStubInterface, order *Order) error { 46 | var key = orderPrefix + order.OrderID 47 | orderBytes, err := stub.GetState(key) 48 | if err != nil { 49 | return errors.New("cannot get order bytes from state db, err: " + err.Error()) 50 | } else if orderBytes != nil { 51 | return errors.New("order already exists, id is " + order.OrderID) 52 | } 53 | 54 | orderBytes, err = json.Marshal(order) 55 | if err != nil { 56 | return errors.New("cannot convert order to bytes: " + err.Error()) 57 | } 58 | 59 | err = stub.PutState(key, orderBytes) 60 | if err != nil { 61 | return errors.New("cannot put order to state db, err: " + err.Error()) 62 | } 63 | 64 | value := []byte{0x00} 65 | 66 | objIdxKey, err := stub.CreateCompositeKey(orderObjIdx, []string{orderObjectType, order.OrderID}) 67 | if err != nil { 68 | return errors.New("create order compsite key err, " + err.Error()) 69 | } 70 | stub.PutState(objIdxKey, value) 71 | 72 | ownerKey, err := stub.CreateCompositeKey(orderOwnerIdx, []string{order.OwnerID, order.OrderID}) 73 | if err != nil { 74 | return errors.New("create order compsite key err, " + err.Error()) 75 | } 76 | stub.PutState(ownerKey, value) 77 | 78 | categoryIDKey, err := stub.CreateCompositeKey(orderCategoryIdx, []string{order.CategoryID, order.OrderID}) 79 | if err != nil { 80 | return errors.New("create order compsite key err, " + err.Error()) 81 | } 82 | stub.PutState(categoryIDKey, value) 83 | 84 | farmerKey, err := stub.CreateCompositeKey(orderFarmerIdx, []string{order.FarmerID, order.OrderID}) 85 | if err != nil { 86 | return errors.New("create order compsite key err, " + err.Error()) 87 | } 88 | stub.PutState(farmerKey, value) 89 | 90 | return nil 91 | } 92 | 93 | // 修改订单,不涉及到分类、农民、商户的修改 94 | func updateOrderToDb(stub shim.ChaincodeStubInterface, order *Order, changeFarmer bool) error { 95 | var key = orderPrefix + order.OrderID 96 | orderBytes, err := stub.GetState(key) 97 | if err != nil { 98 | return errors.New("cannot get order bytes from state db, err: " + err.Error()) 99 | } else if orderBytes == nil { 100 | return errors.New("order not exists, id is " + order.OrderID) 101 | } 102 | 103 | orderBytes, err = json.Marshal(order) 104 | if err != nil { 105 | return errors.New("cannot convert order to bytes: " + err.Error()) 106 | } 107 | 108 | err = stub.PutState(key, orderBytes) 109 | if err != nil { 110 | return errors.New("cannot put order to state db, err: " + err.Error()) 111 | } 112 | 113 | value := []byte{0x00} 114 | farmerKey, err := stub.CreateCompositeKey(orderFarmerIdx, []string{order.FarmerID, order.OrderID}) 115 | if err != nil { 116 | return errors.New("create order compsite key err, " + err.Error()) 117 | } 118 | stub.PutState(farmerKey, value) 119 | 120 | return nil 121 | } 122 | 123 | func getOrderFromDb(stub shim.ChaincodeStubInterface, orderID string) (*Order, error) { 124 | order := &Order{} 125 | 126 | var key = orderPrefix + orderID 127 | orderBytes, err := stub.GetState(key) 128 | if err != nil { 129 | return order, errors.New("cannot get order bytes from state db, err: " + err.Error()) 130 | } else if orderBytes == nil { 131 | return order, nil 132 | } 133 | 134 | err = json.Unmarshal(orderBytes, order) 135 | if err != nil { 136 | return order, errors.New("cannot convert order bytes to order, err: " + err.Error()) 137 | } 138 | return order, nil 139 | } 140 | 141 | // 获取所有的订单 142 | func getOrdersFromDb(stub shim.ChaincodeStubInterface) ([]*Order, error) { 143 | iterator, err := stub.GetStateByPartialCompositeKey(orderObjIdx, []string{orderObjectType}) 144 | defer iterator.Close() 145 | if err != nil { 146 | return nil, errors.New("cannot get orders CreateCompositeKey by objectType, err:" + err.Error()) 147 | } 148 | 149 | return _getOrdersFromIdxIterator(stub, iterator, nil) 150 | } 151 | 152 | // 获取某个商户的订单 153 | func getOrdersByOwnerFromDb(stub shim.ChaincodeStubInterface, ownerID string) ([]*Order, error) { 154 | iterator, err := stub.GetStateByPartialCompositeKey(orderOwnerIdx, []string{ownerID}) 155 | defer iterator.Close() 156 | if err != nil { 157 | return nil, errors.New("cannot get orders CreateCompositeKey by ownerID, err:" + err.Error()) 158 | } 159 | 160 | return _getOrdersFromIdxIterator(stub, iterator, nil) 161 | } 162 | 163 | // 获取农民接的订单 164 | func getOrdersByFarmerFromDb(stub shim.ChaincodeStubInterface, farmerID string) ([]*Order, error) { 165 | iterator, err := stub.GetStateByPartialCompositeKey(orderFarmerIdx, []string{farmerID}) 166 | defer iterator.Close() 167 | if err != nil { 168 | return nil, errors.New("cannot get orders CreateCompositeKey by farmerID, err:" + err.Error()) 169 | } 170 | 171 | return _getOrdersFromIdxIterator(stub, iterator, nil) 172 | } 173 | 174 | // 获取所有的单子,以Status 175 | func getOrdersByStatusFromDb(stub shim.ChaincodeStubInterface, status int) ([]*Order, error) { 176 | iterator, err := stub.GetStateByPartialCompositeKey(orderObjIdx, []string{orderObjectType}) 177 | defer iterator.Close() 178 | if err != nil { 179 | return nil, errors.New("cannot get orders CreateCompositeKey by categoryID, err:" + err.Error()) 180 | } 181 | 182 | var f = func(o *Order) bool { 183 | if o.Status == status { 184 | return true 185 | } 186 | return false 187 | } 188 | return _getOrdersFromIdxIterator(stub, iterator, f) 189 | } 190 | 191 | // 获取某个类别的订单 192 | func getOrdersByCategoryIDFromDb(stub shim.ChaincodeStubInterface, categoryID string) ([]*Order, error) { 193 | iterator, err := stub.GetStateByPartialCompositeKey(orderCategoryIdx, []string{categoryID}) 194 | defer iterator.Close() 195 | if err != nil { 196 | return nil, errors.New("cannot get orders CreateCompositeKey by categoryID, err:" + err.Error()) 197 | } 198 | 199 | return _getOrdersFromIdxIterator(stub, iterator, nil) 200 | } 201 | 202 | //从iterator获取order 列表 203 | func _getOrdersFromIdxIterator(stub shim.ChaincodeStubInterface, iterator shim.StateQueryIteratorInterface, f FilterOrdersFunc) ([]*Order, error) { 204 | orders := make([]*Order, 0) 205 | for iterator.HasNext() { 206 | key, _, err := iterator.Next() 207 | if err != nil { 208 | return nil, errors.New("get key from orders by farmerID err, " + err.Error()) 209 | } 210 | _, compositeKeys, err := stub.SplitCompositeKey(key) 211 | if err != nil { 212 | return nil, errors.New("canot get compositeKeys, err " + err.Error()) 213 | } 214 | 215 | orderID := compositeKeys[1] 216 | order, err := getOrderFromDb(stub, orderID) 217 | if err != nil { 218 | return nil, err 219 | } 220 | if f != nil { 221 | if f(order) { 222 | orders = append(orders, order) 223 | } 224 | } else { 225 | orders = append(orders, order) 226 | } 227 | } 228 | return orders, nil 229 | } 230 | -------------------------------------------------------------------------------- /chaincode/src/jutian_cc/pb_response.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "github.com/hyperledger/fabric/core/chaincode/shim" 5 | pb "github.com/hyperledger/fabric/protos/peer" 6 | ) 7 | 8 | type PbResponse struct { 9 | Success bool 10 | Data interface{} 11 | Err string 12 | } 13 | 14 | func wrapToPbResponse(data []byte, err error) pb.Response { 15 | if err != nil { 16 | response := PbResponse{ 17 | false, 18 | nil, 19 | err.Error(), 20 | } 21 | bytes, err := StructToJSONBytes(response) 22 | if err != nil { 23 | return shim.Error(err.Error()) 24 | } 25 | return shim.Success(bytes) 26 | } 27 | 28 | response := PbResponse{ 29 | true, 30 | data, 31 | "", 32 | } 33 | bytes, err := StructToJSONBytes(response) 34 | if err != nil { 35 | return shim.Error(err.Error()) 36 | } 37 | return shim.Success(bytes) 38 | } 39 | 40 | func wrapStructToPbResponse(data interface{}, err error) pb.Response { 41 | LogStruct(data) 42 | if err != nil { 43 | response := PbResponse{ 44 | false, 45 | nil, 46 | err.Error(), 47 | } 48 | LogStruct(response) 49 | bytes, err := StructToJSONBytes(response) 50 | LogMessage(string(bytes)) 51 | if err != nil { 52 | return shim.Error(err.Error()) 53 | } 54 | return shim.Success(bytes) 55 | } 56 | 57 | response := PbResponse{ 58 | true, 59 | data, 60 | "", 61 | } 62 | LogStruct(response) 63 | bytes, err := StructToJSONBytes(response) 64 | LogMessage(string(bytes)) 65 | if err != nil { 66 | return shim.Error(err.Error()) 67 | } 68 | return shim.Success(bytes) 69 | } 70 | -------------------------------------------------------------------------------- /chaincode/src/jutian_cc/tool.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "encoding/json" 5 | "fmt" 6 | "math/rand" 7 | "time" 8 | ) 9 | 10 | //GenerateRandom 生成随机的字符串 11 | func GenerateRandom(size int) string { 12 | kind := 3 13 | ikind, kinds, result := kind, [][]int{[]int{10, 48}, []int{26, 97}, []int{26, 65}}, make([]byte, size) 14 | is_all := kind > 2 || kind < 0 15 | rand.Seed(time.Now().UnixNano()) 16 | for i := 0; i < size; i++ { 17 | if is_all { // random ikind 18 | ikind = rand.Intn(3) 19 | } 20 | scope, base := kinds[ikind][0], kinds[ikind][1] 21 | result[i] = uint8(base + rand.Intn(scope)) 22 | } 23 | return string(result) 24 | } 25 | 26 | // MakeTimestamp 获取当前时间戳,毫秒 27 | func MakeTimestamp() int64 { 28 | return time.Now().UnixNano() / int64(time.Millisecond) 29 | } 30 | 31 | //StructToJSONBytes 把数据转成json的bytes 32 | func StructToJSONBytes(data interface{}) ([]byte, error) { 33 | b, err := json.Marshal(data) 34 | if err != nil { 35 | fmt.Println(err) 36 | return nil, err 37 | } 38 | return b, nil 39 | } 40 | 41 | func LogMessage(message string) { 42 | fmt.Println(message) 43 | } 44 | 45 | func LogStruct(data interface{}) { 46 | fmt.Printf("%+v\n", data) 47 | } 48 | -------------------------------------------------------------------------------- /chaincode/src/jutian_cc/warehouse_db.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "encoding/json" 5 | "errors" 6 | 7 | "github.com/hyperledger/fabric/core/chaincode/shim" 8 | ) 9 | 10 | type WarehouseStoreIn struct { 11 | ObjectType string 12 | BigPackageID string 13 | OwnerID string 14 | OrderID string 15 | CreateDate int64 16 | Cost int 17 | WarehouseName string 18 | Sent bool 19 | } 20 | 21 | var warehouseCost = 3 22 | 23 | var warehouseStoreInObjectType = "warehouseStoreIn" 24 | var warehousePrefix = "warehouseStoreIn:" 25 | var warehouseOrderIdx = "orderID~bigPackageID" 26 | var warehouseObjIdx = "objectType~bigPackageID" 27 | var warehouseOwnIdx = "ownerID~bigPackageID" 28 | 29 | func insertWarehouseStoreInToDb(stub shim.ChaincodeStubInterface, w *WarehouseStoreIn) error { 30 | w.CreateDate = MakeTimestamp() 31 | var key = warehousePrefix + w.BigPackageID 32 | wBytes, err := stub.GetState(key) 33 | if err != nil { 34 | return errors.New("cannot get warehouse storein from state db, err: " + err.Error()) 35 | } else if wBytes != nil { 36 | return errors.New("warehouse storein already exists, " + w.BigPackageID) 37 | } 38 | 39 | wBytes, err = json.Marshal(w) 40 | if err != nil { 41 | return errors.New("cannot convert warehouse storein to bytes: " + err.Error()) 42 | } 43 | 44 | err = stub.PutState(key, wBytes) 45 | if err != nil { 46 | return errors.New("cannot put warehouse storein to state db, err: " + err.Error()) 47 | } 48 | 49 | // create index 50 | value := []byte{0x00} 51 | 52 | objIdx, err := stub.CreateCompositeKey(warehouseObjIdx, []string{warehouseStoreInObjectType, w.BigPackageID}) 53 | if err != nil { 54 | return errors.New("create warehouse storein composite key err, " + err.Error()) 55 | } 56 | stub.PutState(objIdx, value) 57 | 58 | orderIdx, err := stub.CreateCompositeKey(warehouseOrderIdx, []string{w.OrderID, w.BigPackageID}) 59 | if err != nil { 60 | return errors.New("create warehouse storein composite key err, " + err.Error()) 61 | } 62 | stub.PutState(orderIdx, value) 63 | 64 | ownIdx, err := stub.CreateCompositeKey(warehouseOwnIdx, []string{w.OwnerID, w.BigPackageID}) 65 | if err != nil { 66 | return errors.New("create warehouse storein composite key err, " + err.Error()) 67 | } 68 | stub.PutState(ownIdx, value) 69 | 70 | return nil 71 | } 72 | 73 | func updateWarehouseStoreInToDb(stub shim.ChaincodeStubInterface, w *WarehouseStoreIn) error { 74 | var key = warehousePrefix + w.BigPackageID 75 | wBytes, err := stub.GetState(key) 76 | if err != nil { 77 | return errors.New("cannot get warehouse storein from state db, err: " + err.Error()) 78 | } else if wBytes == nil { 79 | return errors.New("warehouse storein not exists, " + w.BigPackageID) 80 | } 81 | 82 | wBytes, err = json.Marshal(w) 83 | if err != nil { 84 | return errors.New("cannot convert warehouse storein to bytes: " + err.Error()) 85 | } 86 | 87 | err = stub.PutState(key, wBytes) 88 | if err != nil { 89 | return errors.New("cannot put warehouse storein to state db, err: " + err.Error()) 90 | } 91 | return nil 92 | } 93 | 94 | func getWarehouseStoreInFromDb(stub shim.ChaincodeStubInterface, bigPackageID string) (*WarehouseStoreIn, error) { 95 | w := &WarehouseStoreIn{} 96 | 97 | var key = warehousePrefix + bigPackageID 98 | pBytes, err := stub.GetState(key) 99 | if err != nil { 100 | return w, errors.New("cannot get warehouse storein from state db, err: " + err.Error()) 101 | } else if pBytes == nil { 102 | return w, nil 103 | } 104 | 105 | err = json.Unmarshal(pBytes, w) 106 | if err != nil { 107 | return w, errors.New("cannot convert json bytes to warehouse storein, err: " + err.Error()) 108 | } 109 | return w, nil 110 | } 111 | 112 | func getWareshouseStoreInsByOrderFromDb(stub shim.ChaincodeStubInterface, orderID string) ([]*WarehouseStoreIn, error) { 113 | iterator, err := stub.GetStateByPartialCompositeKey(warehouseOrderIdx, []string{orderID}) 114 | defer iterator.Close() 115 | if err != nil { 116 | return nil, errors.New("cannot get warehouse storein CreateCompositeKey by categoryID, err:" + err.Error()) 117 | } 118 | 119 | return _getWarehouseStoreinsFromIdxIterator(stub, iterator) 120 | } 121 | 122 | func getWareshouseStoreInsByOwnFromDb(stub shim.ChaincodeStubInterface, ownerID string) ([]*WarehouseStoreIn, error) { 123 | iterator, err := stub.GetStateByPartialCompositeKey(warehouseOwnIdx, []string{ownerID}) 124 | defer iterator.Close() 125 | if err != nil { 126 | return nil, errors.New("cannot get warehouse storein CreateCompositeKey by categoryID, err:" + err.Error()) 127 | } 128 | 129 | return _getWarehouseStoreinsFromIdxIterator(stub, iterator) 130 | } 131 | 132 | //从iterator获取warehouse store in 列表 133 | func _getWarehouseStoreinsFromIdxIterator(stub shim.ChaincodeStubInterface, iterator shim.StateQueryIteratorInterface) ([]*WarehouseStoreIn, error) { 134 | ws := make([]*WarehouseStoreIn, 0) 135 | for iterator.HasNext() { 136 | key, _, err := iterator.Next() 137 | if err != nil { 138 | return nil, errors.New("get key from bigPackages by farmerID err, " + err.Error()) 139 | } 140 | _, compositeKeys, err := stub.SplitCompositeKey(key) 141 | if err != nil { 142 | return nil, errors.New("canot get compositeKeys, err " + err.Error()) 143 | } 144 | 145 | bigPackageID := compositeKeys[1] 146 | w, err := getWarehouseStoreInFromDb(stub, bigPackageID) 147 | if err != nil { 148 | return nil, err 149 | } 150 | if w.BigPackageID != "" { 151 | ws = append(ws, w) 152 | } 153 | } 154 | return ws, nil 155 | } 156 | -------------------------------------------------------------------------------- /chaincode/tls/orderer/ca-cert.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIIBcjCCARigAwIBAwICA+gwCgYIKoZIzj0EAwIwFjEUMBIGA1UEAwwLb3JkZXJl 3 | ck9yZzAwHhcNMTcwMjIwMTkwNjEwWhcNMTgwMjIwMTkwNjEwWjAWMRQwEgYDVQQD 4 | DAtvcmRlcmVyT3JnMDBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABK8Sv0EA9h06 5 | fmBkUCO+D/b/2INZ2huy+W/HCxSF22c7WGoJbRzQcWtQmW1KqZowUk86RcxVfFqv 6 | jEMFVXzV38SjVjBUMBIGA1UdEwEB/wQIMAYBAf8CAQAwHQYDVR0OBBYEFCVakuvq 7 | xEcK8pYMf/Hw8hsexRMTMB8GA1UdIwQYMBaAFCVakuvqxEcK8pYMf/Hw8hsexRMT 8 | MAoGCCqGSM49BAMCA0gAMEUCIQCmXgDSRTyxpSk+PXg0FNlYZ4ijTVwKgLkYVhod 9 | zZPfngIgO4y0p3Fs/gNsJYrroKaaVDe955KrPp/O55jYDKAD/oY= 10 | -----END CERTIFICATE----- 11 | -------------------------------------------------------------------------------- /chaincode/tls/orderer/cert.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIIBajCCAQ+gAwIBAwICA+gwCgYIKoZIzj0EAwIwFjEUMBIGA1UEAwwLb3JkZXJl 3 | ck9yZzAwHhcNMTcwMjIwMTkwNjEwWhcNMTgwMjIwMTkwNjEwWjATMREwDwYDVQQD 4 | DAhvcmRlcmVyMDBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABH1h6WeFWnBDgPN5 5 | biXbyzqShGrAZ9ztOu4j03xcrqUIenBQASJ/rmAErmq4kilNyRVnwdZwDcGTrAwP 6 | QfAXkVCjUDBOMAwGA1UdEwEB/wQCMAAwHQYDVR0OBBYEFK01/Qm7YoTpXLXjq18D 7 | +X2pExanMB8GA1UdIwQYMBaAFCVakuvqxEcK8pYMf/Hw8hsexRMTMAoGCCqGSM49 8 | BAMCA0kAMEYCIQDXdRYqrZdTAM6F2JBl/eN3nIHoBa7N3gIQDqdUAris8wIhAP6i 9 | f0CgyBN4nWmw2mT+XtxaB0xxWrhYj/j4agiuQzrd 10 | -----END CERTIFICATE----- 11 | -------------------------------------------------------------------------------- /chaincode/tls/orderer/key.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN EC PRIVATE KEY----- 2 | MHcCAQEEIJPtBtNKlilpgVZ5FGUBWB2KH3zBtzkBnkrFMmi6W/80oAoGCCqGSM49 3 | AwEHoUQDQgAEfWHpZ4VacEOA83luJdvLOpKEasBn3O067iPTfFyupQh6cFABIn+u 4 | YASuariSKU3JFWfB1nANwZOsDA9B8BeRUA== 5 | -----END EC PRIVATE KEY----- 6 | -------------------------------------------------------------------------------- /chaincode/tls/peers/peer0/ca-cert.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIIBbDCCARKgAwIBAwICA+gwCgYIKoZIzj0EAwIwEzERMA8GA1UEAwwIcGVlck9y 3 | ZzAwHhcNMTcwMjIwMTkwNjEwWhcNMTgwMjIwMTkwNjEwWjATMREwDwYDVQQDDAhw 4 | ZWVyT3JnMDBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABKJfDc/CcaiHRipTG2AB 5 | K5fA0LO9SOlbtC9bZcjLo/xsL157p+3QB3UVF3gt7nkwgMs/ul3FhSEFTk2EVNlF 6 | 1QCjVjBUMBIGA1UdEwEB/wQIMAYBAf8CAQAwHQYDVR0OBBYEFFQzuQR1RZP/Qn/B 7 | NDtGSa8n4eN/MB8GA1UdIwQYMBaAFFQzuQR1RZP/Qn/BNDtGSa8n4eN/MAoGCCqG 8 | SM49BAMCA0gAMEUCIAuG+/Fy3x9JXAD1/rFsu3ZpCKbXiXZLGF7P6Gma8is5AiEA 9 | pSQpRcdukxe4zvcfRmNBjMbNLWCoWlHSQA2jD678QGE= 10 | -----END CERTIFICATE----- 11 | -------------------------------------------------------------------------------- /chaincode/tls/peers/peer0/cert.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIIBYzCCAQmgAwIBAwICA+gwCgYIKoZIzj0EAwIwEzERMA8GA1UEAwwIcGVlck9y 3 | ZzAwHhcNMTcwMjIwMTkwNjExWhcNMTgwMjIwMTkwNjExWjAQMQ4wDAYDVQQDDAVw 4 | ZWVyMDBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABEF6dfqjqfbIgZuOR+dgoJMl 5 | /FaUlGI70A/ixmVUY83Yp4YtV3FDBSOPiO5O+s8pHnpbwB1LqhrxAx1Plr0M/UWj 6 | UDBOMAwGA1UdEwEB/wQCMAAwHQYDVR0OBBYEFBY2bc84vLEwkX1fSAER2p48jJXw 7 | MB8GA1UdIwQYMBaAFFQzuQR1RZP/Qn/BNDtGSa8n4eN/MAoGCCqGSM49BAMCA0gA 8 | MEUCIQDeDZ71L+OTYcbbqiDNRf0L8OExO59mH1O3xpdwMAM0MgIgXySG4sv9yV31 9 | WcWRFfRFyu7o3T72kqiLZ1nkDuJ8jWI= 10 | -----END CERTIFICATE----- 11 | -------------------------------------------------------------------------------- /chaincode/tls/peers/peer0/key.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN EC PRIVATE KEY----- 2 | MHcCAQEEIKyhczWGQa7NbV1tq9LkZkvqslzoQ1HaEVwA6FCLOfvioAoGCCqGSM49 3 | AwEHoUQDQgAEQXp1+qOp9siBm45H52CgkyX8VpSUYjvQD+LGZVRjzdinhi1XcUMF 4 | I4+I7k76zykeelvAHUuqGvEDHU+WvQz9RQ== 5 | -----END EC PRIVATE KEY----- 6 | -------------------------------------------------------------------------------- /chaincode/tls/peers/peer1/ca-cert.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIIBbDCCARKgAwIBAwICA+gwCgYIKoZIzj0EAwIwEzERMA8GA1UEAwwIcGVlck9y 3 | ZzAwHhcNMTcwMjIwMTkwNjEwWhcNMTgwMjIwMTkwNjEwWjATMREwDwYDVQQDDAhw 4 | ZWVyT3JnMDBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABKJfDc/CcaiHRipTG2AB 5 | K5fA0LO9SOlbtC9bZcjLo/xsL157p+3QB3UVF3gt7nkwgMs/ul3FhSEFTk2EVNlF 6 | 1QCjVjBUMBIGA1UdEwEB/wQIMAYBAf8CAQAwHQYDVR0OBBYEFFQzuQR1RZP/Qn/B 7 | NDtGSa8n4eN/MB8GA1UdIwQYMBaAFFQzuQR1RZP/Qn/BNDtGSa8n4eN/MAoGCCqG 8 | SM49BAMCA0gAMEUCIAuG+/Fy3x9JXAD1/rFsu3ZpCKbXiXZLGF7P6Gma8is5AiEA 9 | pSQpRcdukxe4zvcfRmNBjMbNLWCoWlHSQA2jD678QGE= 10 | -----END CERTIFICATE----- 11 | -------------------------------------------------------------------------------- /chaincode/tls/peers/peer1/cert.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIIBYzCCAQmgAwIBAwICA+gwCgYIKoZIzj0EAwIwEzERMA8GA1UEAwwIcGVlck9y 3 | ZzAwHhcNMTcwMjIwMTkwNjExWhcNMTgwMjIwMTkwNjExWjAQMQ4wDAYDVQQDDAVw 4 | ZWVyMTBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABI9/7z3nMORUeS3rZ+F93ymD 5 | R2jiB6Wm+QSoSz/uQuRavnoksgU6peF5rBMfebk/PfNoVjdR4egCqAHBHIpp7Iuj 6 | UDBOMAwGA1UdEwEB/wQCMAAwHQYDVR0OBBYEFJpxVAXpMAEOHtbNCwvL1m/ku9gt 7 | MB8GA1UdIwQYMBaAFFQzuQR1RZP/Qn/BNDtGSa8n4eN/MAoGCCqGSM49BAMCA0gA 8 | MEUCIQDsQ6lmuLdKmMgnN5+9YjlpCRQEJCoaG3uxRHhrAecZngIgQZlwnvwka+TM 9 | gF/yC3r2MeELK9ocw8c22DAe6x71RT4= 10 | -----END CERTIFICATE----- 11 | -------------------------------------------------------------------------------- /chaincode/tls/peers/peer1/key.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN EC PRIVATE KEY----- 2 | MHcCAQEEIGke7eS6obPUxqqTr3k4svyI+7H2K8vtauJslox/rNjooAoGCCqGSM49 3 | AwEHoUQDQgAEj3/vPecw5FR5Letn4X3fKYNHaOIHpab5BKhLP+5C5Fq+eiSyBTql 4 | 4XmsEx95uT8982hWN1Hh6AKoAcEcimnsiw== 5 | -----END EC PRIVATE KEY----- 6 | -------------------------------------------------------------------------------- /chaincode/tls/peers/peer2/ca-cert.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIIBbDCCARKgAwIBAwICA+gwCgYIKoZIzj0EAwIwEzERMA8GA1UEAwwIcGVlck9y 3 | ZzEwHhcNMTcwMjIwMTkwNjEwWhcNMTgwMjIwMTkwNjEwWjATMREwDwYDVQQDDAhw 4 | ZWVyT3JnMTBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABJ2S+UvyFgFZYL6qcrKo 5 | zy72Nkc/RQVzg1VfwC3X7QcnHEVBuCzba1nxdDVE8XPnhmKBWLKh0adn6GKUZpyf 6 | mbKjVjBUMBIGA1UdEwEB/wQIMAYBAf8CAQAwHQYDVR0OBBYEFAQlMVsXlKGMEWPf 7 | KMMM6QVASnlPMB8GA1UdIwQYMBaAFAQlMVsXlKGMEWPfKMMM6QVASnlPMAoGCCqG 8 | SM49BAMCA0gAMEUCIHr4AD6Xx3R6zFCsveIMnWao9Us88/0uGHoT4ELmMhA1AiEA 9 | yzfXU5qHp3xBJ1BrKOGi71UmQZVwWfO26INhxcfpCAg= 10 | -----END CERTIFICATE----- 11 | -------------------------------------------------------------------------------- /chaincode/tls/peers/peer2/cert.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIIBYzCCAQmgAwIBAwICA+gwCgYIKoZIzj0EAwIwEzERMA8GA1UEAwwIcGVlck9y 3 | ZzEwHhcNMTcwMjIwMTkwNjExWhcNMTgwMjIwMTkwNjExWjAQMQ4wDAYDVQQDDAVw 4 | ZWVyMjBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABLZyoiEc/0aTctk8THKHtQ8W 5 | F2BAG1vgB6kxT+cUaLnEH2El9NTvRYjHmjq8ozM9+/R2JVucEGZelAIQxKD5pXuj 6 | UDBOMAwGA1UdEwEB/wQCMAAwHQYDVR0OBBYEFDdoFJ6jiClMPOVsNx5akist91so 7 | MB8GA1UdIwQYMBaAFAQlMVsXlKGMEWPfKMMM6QVASnlPMAoGCCqGSM49BAMCA0gA 8 | MEUCIQC7wATZy+O/7UIPzSiMSXNgBKCaT2U55+Y/e0FcHQFSoQIgCyKExrm3gtW0 9 | SAN1VofiAZkr3gYndu9goHZe4wVh9eQ= 10 | -----END CERTIFICATE----- 11 | -------------------------------------------------------------------------------- /chaincode/tls/peers/peer2/key.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN EC PRIVATE KEY----- 2 | MHcCAQEEICO7+w9YD/MdNiZHXusiWGhHTOOAXks10aJGuITmZ0wkoAoGCCqGSM49 3 | AwEHoUQDQgAEtnKiIRz/RpNy2TxMcoe1DxYXYEAbW+AHqTFP5xRoucQfYSX01O9F 4 | iMeaOryjMz379HYlW5wQZl6UAhDEoPmlew== 5 | -----END EC PRIVATE KEY----- 6 | -------------------------------------------------------------------------------- /chaincode/tls/peers/peer3/ca-cert.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIIBbDCCARKgAwIBAwICA+gwCgYIKoZIzj0EAwIwEzERMA8GA1UEAwwIcGVlck9y 3 | ZzEwHhcNMTcwMjIwMTkwNjEwWhcNMTgwMjIwMTkwNjEwWjATMREwDwYDVQQDDAhw 4 | ZWVyT3JnMTBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABJ2S+UvyFgFZYL6qcrKo 5 | zy72Nkc/RQVzg1VfwC3X7QcnHEVBuCzba1nxdDVE8XPnhmKBWLKh0adn6GKUZpyf 6 | mbKjVjBUMBIGA1UdEwEB/wQIMAYBAf8CAQAwHQYDVR0OBBYEFAQlMVsXlKGMEWPf 7 | KMMM6QVASnlPMB8GA1UdIwQYMBaAFAQlMVsXlKGMEWPfKMMM6QVASnlPMAoGCCqG 8 | SM49BAMCA0gAMEUCIHr4AD6Xx3R6zFCsveIMnWao9Us88/0uGHoT4ELmMhA1AiEA 9 | yzfXU5qHp3xBJ1BrKOGi71UmQZVwWfO26INhxcfpCAg= 10 | -----END CERTIFICATE----- 11 | -------------------------------------------------------------------------------- /chaincode/tls/peers/peer3/cert.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIIBYzCCAQmgAwIBAwICA+gwCgYIKoZIzj0EAwIwEzERMA8GA1UEAwwIcGVlck9y 3 | ZzEwHhcNMTcwMjIwMTkwNjExWhcNMTgwMjIwMTkwNjExWjAQMQ4wDAYDVQQDDAVw 4 | ZWVyMzBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABMvgApKCXYIEY4YgPTgQKrLM 5 | GMdK/1j8WEl2hijED+onVUF/w/oleiSljNOCxdda3u3X0yXqXz/ozQPJL/d4YL+j 6 | UDBOMAwGA1UdEwEB/wQCMAAwHQYDVR0OBBYEFOzMeVZK5xYzjaeO2uGvz8B7CQS7 7 | MB8GA1UdIwQYMBaAFAQlMVsXlKGMEWPfKMMM6QVASnlPMAoGCCqGSM49BAMCA0gA 8 | MEUCIQCgKtFodSdXcz2yf9MZB90t1nXYytpGUPMAl0/Gy2/yfQIgAcC1KRtaiclr 9 | 9C9tshhXdYdbpvDruVZrwqjJ4drPHik= 10 | -----END CERTIFICATE----- 11 | -------------------------------------------------------------------------------- /chaincode/tls/peers/peer3/key.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN EC PRIVATE KEY----- 2 | MHcCAQEEIPK7O2ZBw9tXDiVd2OM+riCIHT+uQPynGd0z9fjLSUltoAoGCCqGSM49 3 | AwEHoUQDQgAEy+ACkoJdggRjhiA9OBAqsswYx0r/WPxYSXaGKMQP6idVQX/D+iV6 4 | JKWM04LF11re7dfTJepfP+jNA8kv93hgvw== 5 | -----END EC PRIVATE KEY----- 6 | -------------------------------------------------------------------------------- /config/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "config": { 3 | "orderer": { 4 | "url": "grpcs://localhost:7050", 5 | "server-hostname": "orderer0", 6 | "tls_cacerts": "chaincode/tls/orderer/ca-cert.pem" 7 | }, 8 | "org1": { 9 | "name": "peerOrg1", 10 | "mspid": "Org1MSP", 11 | "ca": "http://localhost:7054", 12 | "peer1": { 13 | "requests": "grpcs://localhost:7051", 14 | "events": "grpcs://localhost:7053", 15 | "server-hostname": "peer0", 16 | "tls_cacerts": "chaincode/tls/peers/peer0/ca-cert.pem" 17 | }, 18 | "peer2": { 19 | "requests": "grpcs://localhost:7056", 20 | "events": "grpcs://localhost:7058", 21 | "server-hostname": "peer1", 22 | "tls_cacerts": "chaincode/tls/peers/peer1/ca-cert.pem" 23 | }, 24 | "KVS": "/tmp/hfc-test-kvs-orgs1" 25 | }, 26 | "org2": { 27 | "name": "peerOrg2", 28 | "mspid": "Org2MSP", 29 | "ca": "http://localhost:8054", 30 | "peer1": { 31 | "requests": "grpcs://localhost:8051", 32 | "events": "grpcs://localhost:8053", 33 | "server-hostname": "peer2", 34 | "tls_cacerts": "chaincode/tls/peers/peer2/ca-cert.pem" 35 | }, 36 | "peer2": { 37 | "requests": "grpcs://localhost:8056", 38 | "events": "grpcs://localhost:8058", 39 | "server-hostname": "peer3", 40 | "tls_cacerts": "chaincode/tls/peers/peer3/ca-cert.pem" 41 | }, 42 | "KVS": "/tmp/hfc-test-kvs-orgs2" 43 | }, 44 | "chaincode": { 45 | "channelfile": "jutianaaa", 46 | "channel": "jutianaaa", 47 | "chaincodePath": "jutian_cc", 48 | "chaincodeId": "jutianaaa.2", 49 | "chaincodeVersion": "v0.1.2" 50 | }, 51 | "currOrg": "org1", 52 | "redis": "localhost:6379", 53 | "port": 8081 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /config/credentials.json: -------------------------------------------------------------------------------- 1 | { 2 | "peers": [ 3 | { 4 | "discovery_host": "vp0", 5 | "discovery_port": 7051, 6 | "api_host": "vp0", 7 | "api_port_tls": 7050, 8 | "api_port": 7050, 9 | "event_host": "vp0", 10 | "event_port": 7053, 11 | "api_url": "http://localhost:8080" 12 | } 13 | ], 14 | "ca": { 15 | "c4d1ce242d714845893190e349bbdd3a-ca": { 16 | "discovery_host": "membersrvc", 17 | "discovery_port": 7054 18 | } 19 | }, 20 | "redis": "localhost:6379" 21 | } 22 | -------------------------------------------------------------------------------- /config/local-credentials.json: -------------------------------------------------------------------------------- 1 | { 2 | "peers": [ 3 | { 4 | "discovery_host": "localhost", 5 | "discovery_port": 7051, 6 | "api_host": "localhost", 7 | "api_port_tls": 7050, 8 | "api_port": 7050, 9 | "event_host": "localhost", 10 | "event_port": 7053, 11 | "api_url": "http://localhost:8080" 12 | } 13 | ], 14 | "ca": { 15 | "c4d1ce242d714845893190e349bbdd3a-ca": { 16 | "discovery_host": "localhost", 17 | "discovery_port": 7054 18 | } 19 | }, 20 | "redis": "localhost:6379" 21 | } 22 | -------------------------------------------------------------------------------- /config/server_config.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | let fs = require('fs'); 4 | 5 | //TODO: Change this a be compatible with the Config npm module 6 | 7 | let config = {}; 8 | 9 | //-------------------------------------------------------------------------------------------------------------------- 10 | // Local Config 11 | //-------------------------------------------------------------------------------------------------------------------- 12 | // config.networkProtocol = 'https'; // If deploying locally, this value needs to be changed to 'http' 13 | // config.appProtocol = 'https'; // If deploying locally, this value needs to be changed to 'http' 14 | // config.hfcProtocol = 'grpcs'; // If deploying locally, this value needs to be changed to 'grpc' 15 | 16 | config.networkProtocol = 'http'; // If deploying locally, this value needs to be changed to 'http' 17 | config.appProtocol = 'http'; // If deploying locally, this value needs to be changed to 'http' 18 | config.hfcProtocol = 'grpc'; // If deploying locally, this value needs to be changed to 'grpc' 19 | 20 | 21 | //-------------------------------------------------------------------------------------------------------------------- 22 | // Tracing 23 | //-------------------------------------------------------------------------------------------------------------------- 24 | 25 | config.trace = true; 26 | config.traceFile = __dirname+'/../logs/app_trace.log'; // File where traces should be written to 27 | 28 | 29 | //Settings for the nodeJS application server 30 | config.offlineUrl = 'localhost'; 31 | config.appPort = (process.env.VCAP_APP_PORT) ? process.env.VCAP_APP_PORT : 8080; //Port that the NodeJS server is operating on 32 | 33 | 34 | //-------------------------------------------------------------------------------------------------------------------- 35 | // User information - These credentials are used for HFC to enroll this user and then set them as the registrar to create new users. 36 | //-------------------------------------------------------------------------------------------------------------------- 37 | config.registrar_name = 'WebAppAdmin'; 38 | config.registrar_password = 'DJY27pEnl16d'; 39 | 40 | //-------------------------------------------------------------------------------------------------------------------- 41 | // HFC configuration - Defines what protocol to use for communication, bluemix certificate location and key store location 42 | //-------------------------------------------------------------------------------------------------------------------- 43 | 44 | //Protocol used by HFC to communicate with blockchain peers and CA, need to change this manually. 45 | config.certificate_file_name = 'certificate.pem'; 46 | config.key_store_location = './keyValStore'; 47 | 48 | //-------------------------------------------------------------------------------------------------------------------- 49 | // Chaincode 50 | //-------------------------------------------------------------------------------------------------------------------- 51 | //Chaincode file location 52 | config.vehicle = 'github.com/hyperledger/fabric/vehicle_code'; 53 | 54 | config.users = [ 55 | { 56 | enrollmentID: 'mainuser', 57 | attributes: [ 58 | {name: 'role', value: '1'}, 59 | {name: 'username', value: 'mainuser'} 60 | ], 61 | registrar: {}, 62 | roles: [], 63 | affiliation: 'institution_a' 64 | }, 65 | { 66 | enrollmentID: 'user2', 67 | attributes: [ 68 | {name: 'role', value: '1'}, 69 | {name: 'username', value: 'user2'} 70 | ], 71 | registrar: {}, 72 | roles: [], 73 | affiliation: 'institution_a' 74 | } 75 | ]; 76 | 77 | //-------------------------------------------------------------------------------------------------------------------- 78 | // Defines the exported values to be used by other fields for connecting to peers or the app. These will be overwritten on app.js being run if Bluemix is being used or Network JSON is defined 79 | //-------------------------------------------------------------------------------------------------------------------- 80 | //IP and port configuration 81 | // config.api_ip = config.peers[0].discovery_host; //IP of the peer attempting to be connected to. By default this is the first peer in the peers array. 82 | let credentials; 83 | 84 | if (process.env.VCAP_SERVICES) { 85 | credentials = JSON.parse(process.env.VCAP_SERVICES)['ibm-blockchain-5-prod'][0].credentials; 86 | } else { 87 | credentials = fs.readFileSync(__dirname + '/credentials.json', 'utf8'); 88 | credentials = JSON.parse(credentials); 89 | } 90 | 91 | //When using blockchain on bluemix, api_port_external and api_port_internal will be the same 92 | config.api_port_external = credentials.peers[0].api_port; //port number used when calling api from outside of the vagrant environment 93 | config.api_port_internal = credentials.peers[0].discovery_port; //port number used when calling api from inside vagrant environment - generally used for chaincode calling out to api 94 | config.api_port_discovery = credentials.peers[0].discovery_port; //port number used for HFC 95 | 96 | config.api_ip = credentials.peers[0].discovery_host; 97 | 98 | let ca; 99 | for(let key in credentials.ca) { 100 | ca = credentials.ca[key]; 101 | } 102 | 103 | //IP and port configuration for the Certificate Authority. This is used for enrolling WebAppAdmin and creating all the user via HFC. Default values are for running Hyperledger locally. 104 | config.ca_ip = ca.discovery_host; //IP of the CA attempting to be connected to 105 | config.ca_port = ca.discovery_port; //Discovery port of the Certificate Authority. Used for HFC 106 | 107 | if (credentials.users) { 108 | credentials.users.forEach(function(user) { 109 | if (user.username === config.registrar_name) { 110 | config.bluemix_registrar_password = user.secret; 111 | } 112 | }); 113 | } 114 | 115 | exports.config = config; // Exports for use in other files that require this one 116 | -------------------------------------------------------------------------------- /docker.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | docker pull hyperledger/fabric-orderer:x86_64-1.0.0-alpha 4 | docker pull hyperledger/fabric-peer:x86_64-1.0.0-alpha 5 | docker pull hyperledger/fabric-zookeeper:x86_64-1.0.0-alpha 6 | docker pull hyperledger/fabric-couchdb:x86_64-1.0.0-alpha 7 | docker pull hyperledger/fabric-kafka:x86_64-1.0.0-alpha 8 | docker pull hyperledger/fabric-ca:x86_64-1.0.0-alpha 9 | docker pull hyperledger/fabric-ccenv:x86_64-1.0.0-alpha 10 | docker pull hyperledger/fabric-javaenv:x86_64-1.0.0-alpha 11 | 12 | docker tag hyperledger/fabric-orderer:x86_64-1.0.0-alpha hyperledger/fabric-orderer:latest 13 | docker tag hyperledger/fabric-peer:x86_64-1.0.0-alpha hyperledger/fabric-peer:latest 14 | docker tag hyperledger/fabric-zookeeper:x86_64-1.0.0-alpha hyperledger/fabric-zookeeper:latest 15 | docker tag hyperledger/fabric-couchdb:x86_64-1.0.0-alpha hyperledger/fabric-couchdb:latest 16 | docker tag hyperledger/fabric-kafka:x86_64-1.0.0-alpha hyperledger/fabric-kafka:latest 17 | docker tag hyperledger/fabric-ca:x86_64-1.0.0-alpha hyperledger/fabric-ca:latest 18 | docker tag hyperledger/fabric-ccenv:x86_64-1.0.0-alpha hyperledger/fabric-ccenv:latest 19 | docker tag hyperledger/fabric-javaenv:x86_64-1.0.0-alpha hyperledger/fabric-javaenv:latest 20 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "jutian_backend_demo", 3 | "version": "1.0.0", 4 | "description": "demo for jutian_backend_demo", 5 | "main": "app.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1", 8 | "start": "node app.js" 9 | }, 10 | "keywords": [ 11 | "asset", 12 | "trading", 13 | "datachain", 14 | "blockchain" 15 | ], 16 | "dependencies": { 17 | "async": "0.9.*", 18 | "body-parser": "^1.17.1", 19 | "cf-deployment-tracker-client": "*", 20 | "compression": "^1.6.2", 21 | "cookie-parser": "1.4.*", 22 | "cors": "2.8.*", 23 | "express": "^4.14.1", 24 | "express-session": "1.14.*", 25 | "fabric-ca-client": "^1.0.0-alpha", 26 | "fabric-client": "^1.0.0-alpha", 27 | "grpc": "^1.2.0", 28 | "hfc": "^0.6.5", 29 | "ioredis": "^2.5.0", 30 | "jade": "1.11.*", 31 | "jsrsasign": "^7.1.2", 32 | "md5": "^2.2.1", 33 | "serve-static": "1.11.*", 34 | "tape": "^4.5.1", 35 | "tape-promise": "^1.1.0", 36 | "winston": "2.2.*", 37 | "ws": "1.1.*", 38 | "x509": "" 39 | }, 40 | "engines": { 41 | "node": "^6.9.1", 42 | "npm": "^3.10.8" 43 | }, 44 | "author": "Jason", 45 | "license": "ISC", 46 | "devDependencies": { 47 | "babel-cli": "^6.24.1" 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /pm2.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | pm2 delete jutian_backend_demo 4 | 5 | pm2 start app.js --name jutian_backend_demo -------------------------------------------------------------------------------- /server/chaincode/create-channel.js: -------------------------------------------------------------------------------- 1 | var hfc = require('fabric-client'); 2 | var util = require('util'); 3 | var fs = require('fs'); 4 | var path = require('path'); 5 | 6 | var testUtil = require(__dirname + '/util.js'); 7 | var utils = require('fabric-client/lib/utils.js'); 8 | var Orderer = require('fabric-client/lib/Orderer.js'); 9 | 10 | var the_user = null; 11 | 12 | var logger = utils.getLogger('create-channel'); 13 | 14 | hfc.addConfigFile(path.join(__dirname, '../../config/config.json')); 15 | var ORGS = hfc.getConfigSetting('config'); 16 | 17 | module.exports.createChannel = function() { 18 | return new Promise((resolve, reject) => { 19 | var client = new hfc(); 20 | var chain = client.newChain(ORGS.chaincode.channel); 21 | 22 | var caRootsPath = ORGS.orderer.tls_cacerts; 23 | let data = fs.readFileSync(path.join(__dirname, "../../" + caRootsPath)); 24 | let caroots = Buffer.from(data).toString(); 25 | 26 | chain.addOrderer( 27 | new Orderer( 28 | ORGS.orderer.url, 29 | { 30 | 'pem': caroots, 31 | 'ssl-target-name-override': ORGS.orderer['server-hostname'] 32 | } 33 | ) 34 | ); 35 | 36 | // Acting as a client in org1 when creating the channel 37 | var name = ORGS[ORGS.currOrg].name; 38 | return hfc.newDefaultKeyValueStore({ 39 | path: testUtil.storePathForOrg(name) 40 | }).then((store) => { 41 | client.setStateStore(store); 42 | return testUtil.getSubmitter(client, ORGS.currOrg); 43 | }) 44 | .then((admin) => { 45 | logger.info('Successfully enrolled user \'admin\''); 46 | the_user = admin; 47 | 48 | // readin the envelope to send to the orderer 49 | data = fs.readFileSync(__dirname + '/../../chaincode/channel/' + ORGS.chaincode.channelfile); 50 | var request = { 51 | envelope : data 52 | }; 53 | // send to orderer 54 | return chain.createChannel(request); 55 | }, (err) => { 56 | throw new Error('Failed to enroll user \'admin\'. ' + err); 57 | }) 58 | .then((response) => { 59 | logger.debug(' response ::%j',response); 60 | 61 | if (response && response.status === 'SUCCESS') { 62 | logger.info('Successfully created the channel.'); 63 | return sleep(5000); 64 | } else { 65 | throw new Error('Failed to create the channel. '); 66 | } 67 | }, (err) => { 68 | throw new Error('Failed to initialize the channel: ' + err.stack ? err.stack : err); 69 | }) 70 | .then((nothing) => { 71 | logger.info('Successfully waited to make sure new channel was created.'); 72 | resolve(); 73 | }, (err) => { 74 | reject('Failed to sleep due to error: ' + err.stack ? err.stack : err); 75 | }); 76 | }) 77 | }; 78 | 79 | function sleep(ms) { 80 | return new Promise(resolve => setTimeout(resolve, ms)); 81 | } 82 | -------------------------------------------------------------------------------- /server/chaincode/install-chaincode.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2017 IBM All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | // This is an end-to-end test that focuses on exercising all parts of the fabric APIs 18 | // in a happy-path scenario 19 | 'use strict'; 20 | 21 | 22 | var path = require('path'); 23 | var fs = require('fs'); 24 | var util = require('util'); 25 | 26 | var hfc = require('fabric-client'); 27 | var utils = require('fabric-client/lib/utils.js'); 28 | var Peer = require('fabric-client/lib/Peer.js'); 29 | var Orderer = require('fabric-client/lib/Orderer.js'); 30 | var testUtil = require(__dirname + '/util.js'); 31 | 32 | var logger = utils.getLogger('install-chaincode'); 33 | 34 | hfc.addConfigFile(path.join(__dirname, '../../config/config.json')); 35 | var ORGS = hfc.getConfigSetting('config'); 36 | 37 | var tx_id = null; 38 | var nonce = null; 39 | var the_user = null; 40 | 41 | module.exports.installChaincode = function() { 42 | return new Promise((resolve, reject) => { 43 | var org = ORGS.currOrg; 44 | 45 | var client = new hfc(); 46 | var chain = client.newChain(ORGS.chaincode.channel); 47 | 48 | var caRootsPath = ORGS.orderer.tls_cacerts; 49 | let data = fs.readFileSync(path.join(__dirname, '../../' + caRootsPath)); 50 | let caroots = Buffer.from(data).toString(); 51 | 52 | chain.addOrderer( 53 | new Orderer( 54 | ORGS.orderer.url, 55 | { 56 | 'pem': caroots, 57 | 'ssl-target-name-override': ORGS.orderer['server-hostname'] 58 | } 59 | ) 60 | ); 61 | 62 | var orgName = ORGS[org].name; 63 | 64 | let priameyKeySetted = false; 65 | var targets = []; 66 | for (let key in ORGS[org]) { 67 | if (ORGS[org].hasOwnProperty(key)) { 68 | if (key.indexOf('peer') === 0) { 69 | let data = fs.readFileSync(path.join(__dirname, '../../' + ORGS[org][key]['tls_cacerts'])); 70 | let peer = new Peer( 71 | ORGS[org][key].requests, 72 | { 73 | pem: Buffer.from(data).toString(), 74 | 'ssl-target-name-override': ORGS[org][key]['server-hostname'] 75 | } 76 | ); 77 | 78 | targets.push(peer); 79 | chain.addPeer(peer); 80 | if (!priameyKeySetted) { 81 | chain.setPrimaryPeer(peer); 82 | priameyKeySetted = true; 83 | } 84 | } 85 | } 86 | } 87 | 88 | var name = ORGS[ORGS.currOrg].name; 89 | return hfc.newDefaultKeyValueStore({ 90 | path: testUtil.storePathForOrg(name) 91 | }).then((store) => { 92 | client.setStateStore(store); 93 | return testUtil.getSubmitter(client, org); 94 | }).then((admin) => { 95 | logger.info('Successfully enrolled user \'admin\''); 96 | the_user = admin; 97 | 98 | nonce = utils.getNonce(); 99 | tx_id = chain.buildTransactionID(nonce, the_user); 100 | 101 | // send proposal to endorser 102 | var request = { 103 | targets: targets, 104 | chaincodePath: ORGS.chaincode.chaincodePath, 105 | chaincodeId: ORGS.chaincode.chaincodeId, 106 | chaincodeVersion: ORGS.chaincode.chaincodeVersion, 107 | txId: tx_id, 108 | nonce: nonce 109 | }; 110 | 111 | return chain.sendInstallProposal(request); 112 | }, 113 | (err) => { 114 | logger.error('Failed to enroll user \'admin\'. ' + err); 115 | throw new Error('Failed to enroll user \'admin\'. ' + err); 116 | }).then((results) => { 117 | var proposalResponses = results[0]; 118 | 119 | var proposal = results[1]; 120 | var header = results[2]; 121 | var all_good = true; 122 | for(var i in proposalResponses) { 123 | let one_good = false; 124 | if (proposalResponses && proposalResponses[0].response && proposalResponses[0].response.status === 200) { 125 | one_good = true; 126 | logger.info('install proposal was good'); 127 | } else { 128 | logger.error('install proposal was bad'); 129 | } 130 | all_good = all_good & one_good; 131 | } 132 | if (all_good) { 133 | logger.info(util.format('Successfully sent install Proposal and received ProposalResponse: Status - %s', proposalResponses[0].response.status)); 134 | resolve(); 135 | } else { 136 | reject('Failed to send install Proposal or receive valid response. Response null or status is not 200. exiting...'); 137 | } 138 | }, 139 | (err) => { 140 | logger.error('Failed to send install proposal due to error: ' + err.stack ? err.stack : err); 141 | reject('Failed to send install proposal due to error: ' + err.stack ? err.stack : err); 142 | }); 143 | }) 144 | } -------------------------------------------------------------------------------- /server/chaincode/join-channel.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2016 IBM All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the 'License'); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an 'AS IS' BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | var util = require('util'); 18 | var path = require('path'); 19 | var fs = require('fs'); 20 | var grpc = require('grpc'); 21 | 22 | var hfc = require('fabric-client'); 23 | var utils = require('fabric-client/lib/utils.js'); 24 | var Peer = require('fabric-client/lib/Peer.js'); 25 | var Orderer = require('fabric-client/lib/Orderer.js'); 26 | var EventHub = require('fabric-client/lib/EventHub.js'); 27 | 28 | var testUtil = require(__dirname + '/util.js'); 29 | 30 | var logger = utils.getLogger('join-channel'); 31 | 32 | var the_user = null; 33 | var tx_id = null; 34 | var nonce = null; 35 | 36 | hfc.addConfigFile(path.join(__dirname, '../../config/config.json')); 37 | var ORGS = hfc.getConfigSetting('config'); 38 | 39 | var allEventhubs = []; 40 | 41 | var _commonProto = grpc.load(path.join(__dirname, '../../node_modules/fabric-client/lib/protos/common/common.proto')).common; 42 | 43 | module.exports.joinChannel = function() { 44 | return new Promise((resolve, reject) => { 45 | var org = ORGS.currOrg; 46 | 47 | var client = new hfc(); 48 | var chain = client.newChain(ORGS.chaincode.channel); 49 | 50 | var orgName = ORGS[org].name; 51 | 52 | var targets = [], 53 | eventhubs = []; 54 | 55 | var caRootsPath = ORGS.orderer.tls_cacerts; 56 | let data = fs.readFileSync(path.join(__dirname, '../../' + caRootsPath)); 57 | let caroots = Buffer.from(data).toString(); 58 | 59 | chain.addOrderer( 60 | new Orderer( 61 | ORGS.orderer.url, 62 | { 63 | 'pem': caroots, 64 | 'ssl-target-name-override': ORGS.orderer['server-hostname'] 65 | } 66 | ) 67 | ); 68 | 69 | for (let key in ORGS[org]) { 70 | if (ORGS[org].hasOwnProperty(key)) { 71 | if (key.indexOf('peer') === 0) { 72 | data = fs.readFileSync(path.join(__dirname, "../../" + ORGS[org][key]['tls_cacerts'])); 73 | targets.push( 74 | new Peer( 75 | ORGS[org][key].requests, 76 | { 77 | pem: Buffer.from(data).toString(), 78 | 'ssl-target-name-override': ORGS[org][key]['server-hostname'] 79 | } 80 | ) 81 | ); 82 | 83 | let eh = new EventHub(); 84 | eh.setPeerAddr( 85 | ORGS[org][key].events, 86 | { 87 | pem: Buffer.from(data).toString(), 88 | 'ssl-target-name-override': ORGS[org][key]['server-hostname'] 89 | } 90 | ); 91 | eventhubs.push(eh); 92 | allEventhubs.push(eh); 93 | } 94 | } 95 | } 96 | 97 | var name = ORGS[ORGS.currOrg].name; 98 | return hfc.newDefaultKeyValueStore({ 99 | path: testUtil.storePathForOrg(name) 100 | }).then((store) => { 101 | client.setStateStore(store); 102 | return testUtil.getSubmitter(client, org); 103 | }) 104 | .then((admin) => { 105 | logger.info('Successfully enrolled user \'admin\''); 106 | the_user = admin; 107 | 108 | nonce = utils.getNonce(); 109 | tx_id = chain.buildTransactionID(nonce, the_user); 110 | var request = { 111 | targets : targets, 112 | txId : tx_id, 113 | nonce : nonce 114 | }; 115 | 116 | var eventPromises = []; 117 | eventhubs.forEach((eh) => { 118 | eh.connect(); 119 | let txPromise = new Promise((_resolve, _reject) => { 120 | let handle = setTimeout(_reject, 30000); 121 | 122 | eh.registerBlockEvent((block) => { 123 | eh.disconnect(); 124 | clearTimeout(handle); 125 | 126 | // in real-world situations, a peer may have more than one channels so 127 | // we must check that this block came from the channel we asked the peer to join 128 | if(block.data.data.length === 1) { 129 | // Config block must only contain one transaction 130 | // var envelope = _commonProto.Envelope.decode(block.data.data[0]); 131 | // var payload = _commonProto.Payload.decode(envelope.payload); 132 | // var channel_header = _commonProto.ChannelHeader.decode(payload.header.channel_header); 133 | 134 | // if (channel_header.channel_id === ORGS.chaincode.channel) { 135 | // logger.info('The new channel has been successfully joined on peer '+ eh.ep._endpoint.addr); 136 | // _resolve(); 137 | // } 138 | _resolve(); 139 | } 140 | }); 141 | }); 142 | 143 | eventPromises.push(txPromise); 144 | }); 145 | 146 | sendPromise = chain.joinChannel(request); 147 | return Promise.all([sendPromise].concat(eventPromises)); 148 | }, (err) => { 149 | logger.error('Failed to enroll user \'admin\' due to error: ' + err.stack ? err.stack : err); 150 | throw new Error('Failed to enroll user \'admin\' due to error: ' + err.stack ? err.stack : err); 151 | }).then((results) => { 152 | logger.info(util.format('Join Channel R E S P O N S E : %j', results)); 153 | 154 | if(results[0] && results[0][0] && results[0][0].response && results[0][0].response.status == 200) { 155 | logger.info(util.format('Successfully joined peers in organization %s to join the channel', orgName)); 156 | resolve(); 157 | } else { 158 | logger.error(' Failed to join channel'); 159 | throw new Error('Failed to join channel'); 160 | } 161 | }, (err) => { 162 | reject('Failed to join channel due to error: ' + err.stack ? err.stack : err); 163 | }); 164 | }) 165 | } 166 | 167 | function sleep(ms) { 168 | return new Promise(resolve => setTimeout(resolve, ms)); 169 | } -------------------------------------------------------------------------------- /server/chaincode/util.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2016 IBM All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the 'License'); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an 'AS IS' BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | var path = require('path'); 18 | var fs = require('fs-extra'); 19 | var os = require('os'); 20 | 21 | var jsrsa = require('jsrsasign'); 22 | var KEYUTIL = jsrsa.KEYUTIL; 23 | 24 | var hfc = require('fabric-client'); 25 | var copService = require('fabric-ca-client/lib/FabricCAClientImpl.js'); 26 | var User = require('fabric-client/lib/User.js'); 27 | var CryptoSuite = require('fabric-client/lib/impl/CryptoSuite_ECDSA_AES.js'); 28 | var KeyStore = require('fabric-client/lib/impl/CryptoKeyStore.js'); 29 | var ecdsaKey = require('fabric-client/lib/impl/ecdsa/key.js'); 30 | 31 | module.exports.readFile = readFile; 32 | 33 | hfc.addConfigFile(path.join(__dirname, '../../config/config.json')); 34 | var ORGS = hfc.getConfigSetting('config'); 35 | 36 | // directory for file based KeyValueStore 37 | module.exports.KVS = '/tmp/hfc-test-kvs'; 38 | module.exports.storePathForOrg = function(org) { 39 | return module.exports.KVS + '_' + org; 40 | }; 41 | 42 | function getSubmitter(username, password, client, loadFromConfig, userOrg) { 43 | var caUrl = ORGS[userOrg].ca; 44 | 45 | return client.getUserContext(username) 46 | .then((user) => { 47 | return new Promise((resolve, reject) => { 48 | if (user && user.isEnrolled()) { 49 | console.log('Successfully loaded member from persistence'); 50 | return resolve(user); 51 | } 52 | if (!loadFromConfig) { 53 | var cop = new copService(caUrl); 54 | 55 | var member; 56 | return cop.enroll({ 57 | enrollmentID: username, 58 | enrollmentSecret: password 59 | }).then((enrollment) => { 60 | console.log('Successfully enrolled user \'' + username + '\''); 61 | 62 | member = new User(username, client); 63 | return member.setEnrollment(enrollment.key, enrollment.certificate, ORGS[userOrg].mspid); 64 | }).then(() => { 65 | return client.setUserContext(member); 66 | }).then(() => { 67 | return resolve(member); 68 | }).catch((err) => { 69 | reject('Failed to enroll and persist user. Error: ' + err.stack ? err.stack : err); 70 | }); 71 | } else { 72 | // need to load private key and pre-enrolled certificate from files based on the MSP 73 | // config directory structure: 74 | // 75 | // \_ keystore 76 | // \_ admin.pem <<== this is the private key saved in PEM file 77 | // \_ signcerts 78 | // \_ admin.pem <<== this is the signed certificate saved in PEM file 79 | 80 | // first load the private key and save in the BCCSP's key store 81 | var privKeyPEM = path.join(__dirname, '../chaincode/msp/local/keystore/admin.pem'); 82 | var pemData, member; 83 | return readFile(privKeyPEM) 84 | .then((data) => { 85 | pemData = data; 86 | // default crypto suite uses $HOME/.hfc-key-store as key store 87 | var kspath = CryptoSuite.getDefaultKeyStorePath(); 88 | var testKey; 89 | return new KeyStore({ 90 | path: kspath 91 | }); 92 | }).then((store) => { 93 | var rawKey = KEYUTIL.getKey(pemData.toString()); 94 | testKey = new ecdsaKey(rawKey); 95 | return store.putKey(testKey); 96 | }).then((value) => { 97 | // next save the certificate in a serialized user enrollment in the state store 98 | var certPEM = path.join(__dirname, '../../chaincode/msp/local/signcerts/admin.pem'); 99 | return readFile(certPEM); 100 | }).then((data) => { 101 | member = new User(username, client); 102 | return member.setEnrollment(testKey, data.toString(), ORGS[userOrg].mspid); 103 | }).then(() => { 104 | return client.setUserContext(member); 105 | }).then((user) => { 106 | return resolve(user); 107 | }).catch((err) => { 108 | reject(new Error('Failed to load key or certificate and save to local stores. ' + err)); 109 | }); 110 | } 111 | }); 112 | }); 113 | } 114 | 115 | function readFile(path) { 116 | return new Promise((resolve, reject) => { 117 | fs.readFile(path, (err, data) => { 118 | if (!!err) 119 | reject(new Error('Failed to read file ' + path + ' due to error: ' + err)); 120 | else 121 | resolve(data); 122 | }); 123 | }); 124 | } 125 | 126 | module.exports.getSubmitter = function(client, loadFromConfig, org) { 127 | if (arguments.length < 2) throw new Error('"client" and "test" are both required parameters'); 128 | 129 | var fromConfig, userOrg; 130 | if (typeof loadFromConfig === 'boolean') { 131 | fromConfig = loadFromConfig; 132 | } else { 133 | fromConfig = false; 134 | } 135 | 136 | if (typeof loadFromConfig === 'string') { 137 | userOrg = loadFromConfig; 138 | } else { 139 | if (typeof org === 'string') { 140 | userOrg = org; 141 | } else { 142 | userOrg = 'org1'; 143 | } 144 | } 145 | 146 | return getSubmitter('admin', 'adminpw', client, fromConfig, userOrg); 147 | }; 148 | -------------------------------------------------------------------------------- /server/constant.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | class Constant { 4 | static setAdmin(admin) { 5 | Constant.admin = admin; 6 | } 7 | } 8 | 9 | // Constant.admin = null; 10 | // Constant.chain = null; 11 | // Constant.client = null; 12 | // Constant.ORGS = null; 13 | // Constant.redis = null; 14 | 15 | module.exports = Constant; -------------------------------------------------------------------------------- /server/middleware/tokenvalidation.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | let Constant = require(__dirname + '/../constant.js'); 4 | 5 | let Chaincode = require("../chaincode/chaincode.js"); 6 | 7 | let redisUserIdPrefix = "userId:"; 8 | 9 | class TokenValidation { 10 | static validate(req, res, next) { 11 | if (req.method == 'OPTIONS') { 12 | return next(); 13 | } 14 | let token; 15 | if (req.method == 'GET' || req.method == 'DELETE') 16 | token = req.query.token; 17 | else if (req.method == 'POST' || req.method == 'PUT') 18 | token = req.body.token; 19 | if (!token) 20 | return res.status(501).send("token not provided"); 21 | 22 | Constant.redis.get(token, (err, result) => { 23 | if (err) { 24 | return res.status(501).send(err); 25 | } 26 | if (!result) 27 | return res.status(501).send('token expired'); 28 | 29 | let userId = result; 30 | // Constant.redis.get(redisUserIdPrefix + userId.trim(), (err, result) => { 31 | // let user = JSON.parse(result); 32 | // req.user = user; 33 | // Constant.redis.pexpire(token, 7200000); 34 | // next(); 35 | // }); 36 | 37 | Chaincode.query("getAccount", [userId], Constant.admin) 38 | .then((result) => { 39 | result = JSON.parse(result); 40 | if (!result.Success) { 41 | return res.status(501).send(result.Err); 42 | } 43 | req.user = {id: result.Data.AccountID, type: result.Data.UserType} 44 | Constant.redis.pexpire(token, 7200000); 45 | next(); 46 | }).catch((err) => { 47 | console.log(err); 48 | res.status(500).send({error: err}); 49 | }) 50 | }) 51 | } 52 | } 53 | 54 | module.exports = TokenValidation; -------------------------------------------------------------------------------- /server/model/user.model.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const Tool = require("../tool.js") 4 | 5 | class User { 6 | constructor(username, password, type) { 7 | this.id = Tool.generateRandomString(32); 8 | this.username = username; 9 | this.password = password; 10 | this.type = type; 11 | this.enrollMent = null; 12 | } 13 | 14 | generateRandomId() { 15 | this.id = Tool.generateRandomString(32); 16 | } 17 | } 18 | 19 | module.exports = User; 20 | -------------------------------------------------------------------------------- /server/server.js: -------------------------------------------------------------------------------- 1 | let http = require('http'); 2 | 3 | let UserService = require('./service/user.service.js'); 4 | let AssetService = require('./service/asset.service.js'); 5 | let OrderService = require('./service/order.service.js'); 6 | let PackageService = require('./service/package.service.js'); 7 | let WarehouseService = require('./service/warehouse.service.js'); 8 | let LogisticService = require('./service/logistic.service.js'); 9 | let MerchandiseService = require('./service/merchandise.service.js'); 10 | let BlockchainService = require('./service/blockchain.service.js'); 11 | 12 | let TokenValidation = require(__dirname + '/middleware/tokenvalidation.js'); 13 | 14 | var start = function(app, redis, port) { 15 | app.get('/test', (req, res, next) => { 16 | res.status(200).send('test'); 17 | }); 18 | app.post('/user/types', UserService.getUserType); 19 | app.post('/user', UserService.register); 20 | app.post('/user/login', UserService.login); 21 | 22 | app.use('/session/', TokenValidation.validate); 23 | app.get('/session/test', (req, res, next) => { 24 | res.status(200).send('session test'); 25 | }); 26 | 27 | app.post('/session/user/account', UserService.setAccount); 28 | app.get('/session/user/account', UserService.getUserInfo); 29 | app.get('/session/user/money/history', UserService.getMoneyHistory); 30 | 31 | app.get('/session/user/loan', UserService.getFarmerLoanableMoney); // 农民获取自己的可借款金额 32 | app.post('/session/user/loan', UserService.loanByFarmer); // 农民借款 33 | app.get('/session/loanapplies', UserService.getLoanApplyList); // 金融端获取申请贷款列表 34 | app.post('/session/loan/approve', UserService.loanApprove); // 农民借款审核通过 35 | app.get('/session/orders/receivable', UserService.getReceiveableOrdersByFarmer); // 金融端查看农民的应收账单 36 | app.post('/session/user/orders', UserService.importOrderData); // 农民导入订单 37 | 38 | app.post('/session/order', OrderService.createOrder); 39 | app.get('/session/order', OrderService.getOrder); 40 | app.get('/session/orders/farmer', OrderService.getOrdersByFarmer); // 农民获取自己的订单 41 | app.get('/session/orders/owner', OrderService.getOrdersByOwner); // 商户获取自己的所有订单 42 | app.get('/session/orders/status', OrderService.getOrdersByStatus); // 获取各个阶段的订单,不同角色获取到不同的 43 | app.post('/session/order/match', OrderService.matchOrderByFarmer); // 农民接单 44 | app.post('/session/order/pay', OrderService.payOrder); 45 | 46 | app.get('/session/asset/category', AssetService.getCategory); 47 | app.post('/session/asset', AssetService.createAsset); 48 | app.get('/session/asset', AssetService.getAsset); 49 | app.get('/session/assets', AssetService.getFarmerAssetsByOwner); 50 | app.post('/session/asset/produce', AssetService.produceOrderByFarmer); // 农民生产好了资产, 提交该订单到 待包装 状态 51 | 52 | app.post('/session/package', PackageService.packageOrder); // 包装商打包某个订单 53 | app.get('/session/packages/order', PackageService.getBigPackagesByOrder); // 包装商获取某个订单的包装 54 | app.get('/session/packages', PackageService.getBigPackagesByOwner); // 包装商获取自己的包装 55 | app.get('/session/packages/status', PackageService.getBigPackageByOrderStatus); // 不同角色查看流转到自己的包装 56 | 57 | app.post('/session/warehouse', WarehouseService.insertWarehouseStoreIn); // 仓库把包装入库 58 | app.get('/session/warehouses/order', WarehouseService.getWarehousesByOrder); // 获取某个订单的库存 59 | app.get('/session/warehouses', WarehouseService.getWarehousesByOwner); // 获取自己的所有仓库信息 60 | 61 | app.post('/session/logistic', LogisticService.insertLogistic); // 物流把物品发货 62 | app.get('/session/logistics', LogisticService.getLogisticsByOwner); // 物流查看自己的所有物流 63 | app.get('/session/logistics/order', LogisticService.getLogisticByOrder); // 查看某个订单的物流 64 | 65 | app.post('/session/merchandise', MerchandiseService.insertMechandise); // 商户收货 66 | app.get('/session/merchandises', MerchandiseService.getMerchandiseByOwner); // 商户查看自己的所有物品 67 | app.get('/session/merchandise/flow', MerchandiseService.getMerchandiseFlow); // 商品溯源 68 | app.post('/session/merchandise/buy', MerchandiseService.purchaseMechandise); // 模拟用户购买商品 69 | 70 | app.get('/block/height', BlockchainService.getBlockHeight); 71 | app.get('/block/num', BlockchainService.getBlockByNumber); 72 | app.get('/block/hash', BlockchainService.getBlockByHash); 73 | 74 | app.use(function (req, res, next) { 75 | let err = new Error('Not Found'); 76 | err.status = 404; 77 | next(err); 78 | }); 79 | 80 | app.use(function (err, req, res, next) { // = development error handler, print stack trace 81 | // console.log('Error Handler -', req.url, err); 82 | let errorCode = err.status || 500; 83 | res.status(errorCode); 84 | if (req.bag) { 85 | req.bag.error = {msg: err.stack, status: errorCode}; 86 | if (req.bag.error.status === 404) { 87 | req.bag.error.msg = 'Sorry, I cannot locate that file'; 88 | } 89 | } 90 | //res.render('template/error', {bag: req.bag}); 91 | res.send({'message':err}); 92 | }); 93 | 94 | let server = http.createServer(app).listen(port, function () { 95 | console.log('Server Up'); 96 | console.log('INFO', 'Startup complete on port', server.address().port); 97 | }); 98 | server.timeout = 2400000; 99 | } 100 | 101 | module.exports.start = start; -------------------------------------------------------------------------------- /server/service/blockchain.service.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | let Constant = require('../constant.js'); 4 | let Chaincode = require("../chaincode/chaincode.js"); 5 | 6 | let Tool = require("../tool.js") 7 | let UserService = require("./user.service.js"); 8 | 9 | class BlockchainService { 10 | static getInfo(req, res, next) { 11 | Constant.chain.queryInfo() 12 | .then((result) => { 13 | console.log(result); 14 | return res.status(200).send(result); 15 | }).catch((err) => { 16 | res.status(500).send(err); 17 | }) 18 | } 19 | 20 | static getBlockHeight(req, res, next) { 21 | Constant.chain.queryInfo() 22 | .then((result) => { 23 | console.log(result.height) 24 | return res.status(200).send(result.height.low + ""); 25 | }).catch((err) => { 26 | res.status(500).send(err); 27 | }) 28 | } 29 | 30 | static getBlockByNumber(req, res, next) { 31 | if (!req.query || !req.query.height) { 32 | return res.status(501).send('height not provided, payload is ' + JSON.stringify(req.body)); 33 | } 34 | var height = parseInt(req.query.height); 35 | if (isNaN(height)) 36 | return res.status(501).send('height err' + req.query.height); 37 | 38 | Constant.chain.queryBlock(height) 39 | .then((result) => { 40 | result.header.previous_hash = result.header.previous_hash.toString('base64'); 41 | result.header.data_hash = result.header.data_hash.toString('base64'); 42 | result.data.data[0] = result.data.data[0].toString('base64'); 43 | // result.header.previous_hash.buffer = result.header.previous_hash.buffer.toString(); 44 | // result.header.data_hash.buffer = result.header.data_hash.buffer.toString(); 45 | // result.data.data[0].buffer = result.data.data[0].buffer.toString(); 46 | for (var i = result.metadata.metadata.length - 1; i >= 0; i--) { 47 | result.metadata.metadata[i] = result.metadata.metadata[i].toString('base64'); 48 | } 49 | return res.status(200).send(result); 50 | }).catch((err) => { 51 | res.status(500).send(err); 52 | }) 53 | } 54 | 55 | static getBlockByHash(req, res, next) { 56 | if (!req.query || !req.query.hash) { 57 | return res.status(501).send('hash not provided, payload is ' + JSON.stringify(req.body)); 58 | } 59 | var hash = req.query.hash; 60 | 61 | Constant.chain.queryBlockByHash(hash) 62 | .then((result) => { 63 | result.header.previous_hash = result.header.previous_hash.toString('base64'); 64 | result.header.data_hash = result.header.data_hash.toString('base64'); 65 | result.data.data[0] = result.data.data[0].toString('base64'); 66 | for (var i = result.metadata.metadata.length - 1; i >= 0; i--) { 67 | result.metadata.metadata[i] = result.metadata.metadata[i].toString('base64'); 68 | } 69 | return res.status(200).send(result); 70 | }).catch((err) => { 71 | res.status(500).send(err); 72 | }) 73 | } 74 | } 75 | 76 | module.exports = BlockchainService -------------------------------------------------------------------------------- /server/service/logistic.service.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | let Constant = require('../constant.js'); 4 | let Chaincode = require("../chaincode/chaincode.js"); 5 | 6 | let Tool = require("../tool.js") 7 | let UserService = require("./user.service.js"); 8 | let AssetService = require("./asset.service.js"); 9 | 10 | class LogisticService { 11 | 12 | static _getLogisticProviders() { 13 | return [ 14 | "圆圆通物流", 15 | "申通通物流", 16 | "千里眼物流", 17 | "哒哒哒物流" 18 | ] 19 | } 20 | 21 | static _getLogisticProvider() { 22 | let num = (Math.random() * 100) % 4; 23 | return LogisticService._getLogisticProviders()[num]; 24 | } 25 | 26 | static _getTruck() { 27 | let num = parseInt(Math.random() * 90) + 10; 28 | return "货车" + num + "号"; 29 | } 30 | 31 | static insertLogistic(req, res, next) { 32 | if (!req.body || !req.body.bigPackageIDs) { 33 | return res.status(501).send('bigPackageIDs not provided'); 34 | } 35 | let currUser = req.user; 36 | if (currUser.type != UserService.UserTypeLogistic) 37 | return res.status(501).send('身份错误,这个API只允许物流调用'); 38 | 39 | let bigPackageIDs = req.body.bigPackageIDs; 40 | let truck = LogisticService._getTruck(); 41 | 42 | let ownerID = req.user.id; 43 | let args = [ownerID, truck]; 44 | for (let key in bigPackageIDs) { 45 | args.push(bigPackageIDs[key]) 46 | } 47 | 48 | Chaincode.invoke("insertLogisticList", args, Constant.admin) 49 | .then((result) => { 50 | result = JSON.parse(result); 51 | if (result.Success) { 52 | return res.status(200).send(result.Data); 53 | } 54 | return res.status(501).send(result.Err); 55 | }).catch((err) => { 56 | res.status(500).send(err); 57 | }) 58 | } 59 | 60 | static getLogisticsByOwner(req, res, next) { 61 | let ownerID = req.user.id; 62 | let currUser = req.user; 63 | if (currUser.type != UserService.UserTypeLogistic && 64 | currUser.type != UserService.UserTypeMerchant) 65 | return res.status(501).send('身份错误,这个API只允许物流调用'); 66 | 67 | Chaincode.query("getLogisticByOwner", [ownerID], Constant.admin) 68 | .then((result) => { 69 | result = JSON.parse(result); 70 | if (result.Success) { 71 | return res.status(200).send(result.Data); 72 | } 73 | return res.status(501).send(result.Err); 74 | }).catch((err) => { 75 | res.status(500).send(err); 76 | }) 77 | } 78 | 79 | static getLogisticByOrder(req, res, next) { 80 | if (!req.query || !req.query.orderID) { 81 | return res.status(501).send('orderID not provided'); 82 | } 83 | let currUser = req.user; 84 | if (currUser.type != UserService.UserTypeLogistic && 85 | currUser.type != UserService.UserTypeMerchant) 86 | return res.status(501).send('身份错误,这个API只允许物流调用'); 87 | 88 | let orderID = req.query.orderID; 89 | Chaincode.query("getLogisticByOrder", [orderID], Constant.admin) 90 | .then((result) => { 91 | result = JSON.parse(result); 92 | if (result.Success) { 93 | return res.status(200).send(result.Data); 94 | } 95 | return res.status(501).send(result.Err); 96 | }).catch((err) => { 97 | res.status(500).send(err); 98 | }) 99 | } 100 | } 101 | 102 | module.exports = LogisticService -------------------------------------------------------------------------------- /server/service/merchandise.service.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | let Constant = require('../constant.js'); 4 | let Chaincode = require("../chaincode/chaincode.js"); 5 | 6 | let Tool = require("../tool.js") 7 | let UserService = require("./user.service.js"); 8 | let AssetService = require("./asset.service.js"); 9 | 10 | class MerchandiseService { 11 | 12 | static insertMechandise(req, res, next) { 13 | if (!req.body || !req.body.bigPackageIDs) { 14 | return res.status(501).send('bigPackageIDs not provided'); 15 | } 16 | let currUser = req.user; 17 | if (currUser.type != UserService.UserTypeMerchant) 18 | return res.status(501).send('身份错误,这个API只允许商户调用'); 19 | 20 | let bigPackageIDs = req.body.bigPackageIDs; 21 | 22 | let ownerID = req.user.id; 23 | let args = [ownerID]; 24 | for (let key in bigPackageIDs) { 25 | args.push(bigPackageIDs[key]) 26 | } 27 | 28 | Chaincode.invoke("insertMechandiseList", args, Constant.admin) 29 | .then((result) => { 30 | result = JSON.parse(result); 31 | if (result.Success) { 32 | return res.status(200).send(result.Data); 33 | } 34 | return res.status(501).send(result.Err); 35 | }).catch((err) => { 36 | res.status(500).send(err); 37 | }) 38 | } 39 | 40 | static getMerchandiseByOwner(req, res, next) { 41 | let ownerID = req.user.id; 42 | let currUser = req.user; 43 | if (currUser.type != UserService.UserTypeMerchant) 44 | return res.status(501).send('身份错误,这个API只允许商户调用'); 45 | 46 | Chaincode.query("getMerchandiseByOwner", [ownerID], Constant.admin) 47 | .then((result) => { 48 | result = JSON.parse(result); 49 | if (result.Success) { 50 | for (var i = result.Data.length - 1; i >= 0; i--) { 51 | AssetService.attachCategoryToAsset(result.Data[i]); 52 | } 53 | return res.status(200).send(result.Data); 54 | } 55 | return res.status(501).send(result.Err); 56 | }).catch((err) => { 57 | res.status(500).send(err); 58 | }) 59 | } 60 | 61 | static getMerchandiseFlow(req, res, next) { 62 | if (!req.query || !req.query.packageID) { 63 | return res.status(501).send('packageID not provided'); 64 | } 65 | 66 | let packageID = req.query.packageID; 67 | 68 | Chaincode.query("getMerchandiseFlow", [packageID], Constant.admin) 69 | .then((result) => { 70 | result = JSON.parse(result); 71 | if (result.Success) { 72 | return res.status(200).send(result.Data); 73 | } 74 | return res.status(501).send(result.Err); 75 | }).catch((err) => { 76 | res.status(500).send(err); 77 | }) 78 | } 79 | 80 | static purchaseMechandise(req, res, next) { 81 | if (!req.body || !req.body.packageID) { 82 | return res.status(501).send('packageID not provided'); 83 | } 84 | let packageID = req.body.packageID; 85 | 86 | let ownerID = req.user.id; 87 | let args = [packageID]; 88 | 89 | Chaincode.invoke("purchasePackage", args, Constant.admin) 90 | .then((result) => { 91 | result = JSON.parse(result); 92 | if (result.Success) { 93 | return res.status(200).send(result.Data); 94 | } 95 | return res.status(501).send(result.Err); 96 | }).catch((err) => { 97 | res.status(500).send(err); 98 | }) 99 | } 100 | } 101 | 102 | module.exports = MerchandiseService -------------------------------------------------------------------------------- /server/service/order.service.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | let Constant = require('../constant.js'); 4 | let Chaincode = require("../chaincode/chaincode.js"); 5 | 6 | let Tool = require("../tool.js") 7 | let UserService = require("./user.service.js"); 8 | let AssetService = require("./asset.service.js"); 9 | 10 | class OrderService { 11 | 12 | static _checkStatus(status) { 13 | status = parseInt(status); 14 | if (status != OrderService.OrderStatusInit && 15 | status != OrderService.OrderStatusMatched && 16 | status != OrderService.OrderStatusProduced && 17 | status != OrderService.OrderStatusPackaged && 18 | status != OrderService.OrderStatusPackagedStoreIn && 19 | status != OrderService.OrderStatusDeliveried && 20 | status != OrderService.OrderStatusFinished) 21 | return false; 22 | return true 23 | } 24 | 25 | static createOrder(req, res, next) { 26 | if (!req.body || !req.body.categoryID || !req.body.amount || !req.body.cost || !req.body.destination) { 27 | console.log(req.body) 28 | return res.status(501).send('categoryID or amount or cost or detail or destination not provided'); 29 | } 30 | let currUser = req.user; 31 | if (currUser.type != UserService.UserTypeMerchant) 32 | return res.status(501).send('身份错误,这个API只允许商户调用'); 33 | 34 | let categoryID = req.body.categoryID; 35 | let amount = parseInt(req.body.amount); 36 | let cost = parseInt(req.body.cost); 37 | let destination = req.body.destination; 38 | 39 | if (!AssetService.checkCategoryExists(categoryID)) 40 | return res.status(501).send('categoryID not exists'); 41 | 42 | let ownerID = req.user.id; 43 | let args = [ownerID, "", categoryID, destination, amount, cost, ""]; 44 | 45 | Chaincode.invoke("insertOrder", args, Constant.admin) 46 | .then((result) => { 47 | result = JSON.parse(result); 48 | if (result.Success) { 49 | return res.status(200).send(result.Data); 50 | } 51 | return res.status(501).send(result.Err); 52 | }).catch((err) => { 53 | res.status(500).send(err); 54 | }) 55 | } 56 | 57 | static getOrder(req, res, next) { 58 | let orderID = req.query.orderID; 59 | if (!orderID) 60 | return res.status(501).send('orderID not provided'); 61 | 62 | let args = [orderID]; 63 | Chaincode.query("getOrder", args, Constant.admin) 64 | .then((result) => { 65 | result = JSON.parse(result); 66 | if (result.Success) { 67 | return res.status(200).send(result.Data); 68 | } 69 | return res.status(501).send(result.Err); 70 | }).catch((err) => { 71 | res.status(500).send(err); 72 | }) 73 | } 74 | 75 | static getOrdersByFarmer(req, res, next) { 76 | let farmerId = req.user.id; 77 | let currUser = req.user; 78 | if (currUser.type != UserService.UserTypeFarmer) 79 | return res.status(501).send('身份错误,这个API只允许农民调用'); 80 | 81 | Chaincode.query("getOrdersByFarmer", [farmerId], Constant.admin) 82 | .then((result) => { 83 | result = JSON.parse(result); 84 | if (result.Success) { 85 | return res.status(200).send(result.Data); 86 | } 87 | return res.status(501).send(result.Err); 88 | }).catch((err) => { 89 | res.status(500).send(err); 90 | }) 91 | } 92 | 93 | static getOrdersByOwner(req, res, next) { 94 | let ownerID = req.user.id; 95 | let currUser = req.user; 96 | if (currUser.type != UserService.UserTypeMerchant) 97 | return res.status(501).send('身份错误,这个API只允许商户调用'); 98 | Chaincode.query("getOrdersByOwner", [ownerID], Constant.admin) 99 | .then((result) => { 100 | result = JSON.parse(result); 101 | if (result.Success) { 102 | return res.status(200).send(result.Data); 103 | } 104 | return res.status(501).send(result.Err); 105 | }).catch((err) => { 106 | res.status(500).send(err); 107 | }) 108 | } 109 | 110 | static getOrdersByStatus(req, res, next) { 111 | let ownerID = req.user.id; 112 | let status = req.query.status; 113 | if (!OrderService._checkStatus(status)) 114 | return res.status(501).send("status error"); 115 | 116 | // 判断权限 117 | let currUser = req.user; 118 | if (currUser.type == UserService.UserTypeFarmer) 119 | status = OrderService.OrderStatusInit; 120 | else if (currUser.type == UserService.UserTypePackager) 121 | status = OrderService.OrderStatusProduced; 122 | else if (currUser.type == UserService.UserTypeWarehouse) 123 | status = OrderService.OrderStatusPackaged; 124 | else if (currUser.type == UserService.UserTypeLogistic) 125 | status = OrderService.OrderStatusPackagedStoreIn; 126 | 127 | Chaincode.query("getOrdersByStatus", [status], Constant.admin) 128 | .then((result) => { 129 | result = JSON.parse(result); 130 | if (result.Success) { 131 | return res.status(200).send(result.Data); 132 | } 133 | return res.status(501).send(result.Err); 134 | }).catch((err) => { 135 | res.status(500).send(err); 136 | }) 137 | } 138 | 139 | static payOrder(req, res, next) { 140 | if (!req.body || !req.body.orderID ) { 141 | return res.status(501).send('orderID not provided'); 142 | } 143 | let currUser = req.user; 144 | if (currUser.type != UserService.UserTypeMerchant) 145 | return res.status(501).send('身份错误,这个API只允许商户调用'); 146 | 147 | let orderID = req.body.orderID; 148 | let ownerID = req.user.id; 149 | Chaincode.invoke("payOrder", [ownerID, orderID], Constant.admin) 150 | .then((result) => { 151 | result = JSON.parse(result); 152 | if (result.Success) { 153 | return res.status(200).send(result.Data); 154 | } 155 | return res.status(501).send(result.Err); 156 | }).catch((err) => { 157 | res.status(500).send(err); 158 | }) 159 | } 160 | 161 | static matchOrderByFarmer(req, res, next) { 162 | if (!req.body || !req.body.orderID ) { 163 | return res.status(501).send('orderID not provided'); 164 | } 165 | let currUser = req.user; 166 | if (currUser.type != UserService.UserTypeFarmer) 167 | return res.status(501).send('身份错误,这个API只允许农民调用'); 168 | 169 | let orderID = req.body.orderID; 170 | let farmerID = req.user.id; 171 | Chaincode.invoke("matchOrderByFarmer", [farmerID, orderID], Constant.admin) 172 | .then((result) => { 173 | result = JSON.parse(result); 174 | if (result.Success) { 175 | return res.status(200).send(result.Data); 176 | } 177 | return res.status(501).send(result.Err); 178 | }).catch((err) => { 179 | res.status(500).send(err); 180 | }) 181 | } 182 | 183 | } 184 | 185 | OrderService.OrderStatusInit = 1 //订单初始化 186 | OrderService.OrderStatusMatched = 2 //订单被接单 187 | OrderService.OrderStatusProduced = 3 //订单生产完成 188 | OrderService.OrderStatusPackaged = 4 //订单打包 189 | OrderService.OrderStatusPackagedStoreIn = 5 //订单入库 190 | OrderService.OrderStatusDeliveried = 6 //订单发货 191 | OrderService.OrderStatusFinished = 7 //订单结束 192 | 193 | module.exports = OrderService -------------------------------------------------------------------------------- /server/service/package.service.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | let Constant = require('../constant.js'); 4 | let Chaincode = require("../chaincode/chaincode.js"); 5 | 6 | let Tool = require("../tool.js") 7 | let UserService = require("./user.service.js"); 8 | let AssetService = require("./asset.service.js"); 9 | let OrderService = require("./order.service.js"); 10 | 11 | class PackageService { 12 | 13 | static packageOrder(req, res, next) { 14 | if (!req.body || !req.body.orderID ) { 15 | return res.status(501).send('orderID not provided'); 16 | } 17 | let currUser = req.user; 18 | if (currUser.type != UserService.UserTypePackager) 19 | return res.status(501).send('身份错误,这个API只允许包装商调用'); 20 | 21 | let orderID = req.body.orderID; 22 | let packagerID = req.user.id; 23 | Chaincode.invoke("packageOrder", [packagerID, orderID], Constant.admin) 24 | .then((result) => { 25 | result = JSON.parse(result); 26 | if (result.Success) { 27 | return res.status(200).send(result.Data); 28 | } 29 | return res.status(501).send(result.Err); 30 | }).catch((err) => { 31 | res.status(500).send(err); 32 | }) 33 | } 34 | 35 | static getBigPackagesByOrder(req, res, next) { 36 | if (!req.body || !req.body.orderID ) { 37 | return res.status(501).send('orderID not provided'); 38 | } 39 | let currUser = req.user; 40 | if (currUser.type != UserService.UserTypePackager && 41 | currUser.type != UserService.UserTypeWarehouse && 42 | currUser.type != UserService.UserTypeLogistic && 43 | currUser.type != UserService.UserTypeMerchant) 44 | return res.status(501).send('身份错误,这个API只允许包装商调用'); 45 | 46 | let orderID = req.body.orderID; 47 | let packagerID = req.user.id; 48 | Chaincode.invoke("getBigPackagesByOrder", [packagerID, orderID], Constant.admin) 49 | .then((result) => { 50 | result = JSON.parse(result); 51 | if (result.Success) { 52 | return res.status(200).send(result.Data); 53 | } 54 | return res.status(501).send(result.Err); 55 | }).catch((err) => { 56 | res.status(500).send(err); 57 | }) 58 | } 59 | 60 | static getBigPackagesByOwner(req, res, next) { 61 | let currUser = req.user; 62 | if (currUser.type != UserService.UserTypePackager) 63 | return res.status(501).send('身份错误,这个API只允许包装商调用'); 64 | 65 | let packagerID = req.user.id; 66 | Chaincode.invoke("getBigPackagesByOwner", [packagerID], Constant.admin) 67 | .then((result) => { 68 | result = JSON.parse(result); 69 | if (result.Success) { 70 | return res.status(200).send(result.Data); 71 | } 72 | return res.status(501).send(result.Err); 73 | }).catch((err) => { 74 | res.status(500).send(err); 75 | }) 76 | } 77 | 78 | static getBigPackageByOrderStatus(req, res, next) { 79 | let currUser = req.user; 80 | if (currUser.type != UserService.UserTypePackager && 81 | currUser.type != UserService.UserTypeWarehouse && 82 | currUser.type != UserService.UserTypeLogistic && 83 | currUser.type != UserService.UserTypeMerchant) 84 | return res.status(501).send('身份错误,这个API只允许包装商调用'); 85 | 86 | let status = 0; 87 | // 判断权限 88 | if (currUser.type == UserService.UserTypeFarmer) 89 | status = OrderService.OrderStatusInit; 90 | else if (currUser.type == UserService.UserTypePackager) 91 | status = OrderService.OrderStatusProduced; 92 | else if (currUser.type == UserService.UserTypeWarehouse) 93 | status = OrderService.OrderStatusPackaged; 94 | else if (currUser.type == UserService.UserTypeLogistic) 95 | status = OrderService.OrderStatusPackagedStoreIn; 96 | else if (currUser.type == UserService.UserTypeMerchant) 97 | status = OrderService.OrderStatusDeliveried; 98 | 99 | Chaincode.invoke("getBigPackageByOrderStatus", [status], Constant.admin) 100 | .then((result) => { 101 | result = JSON.parse(result); 102 | if (result.Success) { 103 | return res.status(200).send(result.Data); 104 | } 105 | return res.status(501).send(result.Err); 106 | }).catch((err) => { 107 | res.status(500).send(err); 108 | }) 109 | } 110 | } 111 | 112 | module.exports = PackageService -------------------------------------------------------------------------------- /server/service/warehouse.service.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | let Constant = require('../constant.js'); 4 | let Chaincode = require("../chaincode/chaincode.js"); 5 | 6 | let Tool = require("../tool.js") 7 | let UserService = require("./user.service.js"); 8 | let AssetService = require("./asset.service.js"); 9 | 10 | class WarehouseService { 11 | 12 | static _getWarehouseShelf() { 13 | let num = 10 + parseInt(Math.random() * 20); 14 | return "A号仓" + num + "号货架"; 15 | } 16 | 17 | static insertWarehouseStoreIn(req, res, next) { 18 | if (!req.body || !req.body.bigPackageIDs) { 19 | return res.status(501).send('bigPackageIDs not provided'); 20 | } 21 | let currUser = req.user; 22 | if (currUser.type != UserService.UserTypeWarehouse) 23 | return res.status(501).send('身份错误,这个API只允许仓库调用'); 24 | 25 | let bigPackageIDs = req.body.bigPackageIDs; 26 | let wName = WarehouseService._getWarehouseShelf(); 27 | 28 | let ownerID = req.user.id; 29 | let args = [ownerID, wName]; 30 | for (let key in bigPackageIDs) { 31 | args.push(bigPackageIDs[key]) 32 | } 33 | 34 | Chaincode.invoke("insertWarehouseStoreInList", args, Constant.admin) 35 | .then((result) => { 36 | result = JSON.parse(result); 37 | if (result.Success) { 38 | return res.status(200).send(result.Data); 39 | } 40 | return res.status(501).send(result.Err); 41 | }).catch((err) => { 42 | res.status(500).send(err); 43 | }) 44 | } 45 | 46 | static getWarehousesByOrder(req, res, next) { 47 | let orderID = req.query.orderID; 48 | if (!orderID) 49 | return res.status(501).send('orderID not provided'); 50 | let currUser = req.user; 51 | if (currUser.type != UserService.UserTypeWarehouse && 52 | currUser.type != UserService.UserTypeLogistic) 53 | return res.status(501).send('身份错误,这个API只允许仓库调用'); 54 | 55 | Chaincode.query("getWarehouseByOrder", [orderID], Constant.admin) 56 | .then((result) => { 57 | result = JSON.parse(result); 58 | if (result.Success) { 59 | return res.status(200).send(result.Data); 60 | } 61 | return res.status(501).send(result.Err); 62 | }).catch((err) => { 63 | res.status(500).send(err); 64 | }) 65 | } 66 | 67 | static getWarehousesByOwner(req, res, next) { 68 | let ownerID = req.user.id; 69 | let currUser = req.user; 70 | if (currUser.type != UserService.UserTypeWarehouse) 71 | return res.status(501).send('身份错误,这个API只允许仓库调用'); 72 | 73 | Chaincode.query("getWarehouseByOwner", [ownerID], Constant.admin) 74 | .then((result) => { 75 | result = JSON.parse(result); 76 | if (result.Success) { 77 | return res.status(200).send(result.Data); 78 | } 79 | return res.status(501).send(result.Err); 80 | }).catch((err) => { 81 | res.status(500).send(err); 82 | }) 83 | } 84 | } 85 | 86 | module.exports = WarehouseService -------------------------------------------------------------------------------- /server/tool.js: -------------------------------------------------------------------------------- 1 | class Tool { 2 | static generateRandomString(length) { 3 | let chars = 'ABCDEFGHJKMNPQRSTWXYZabcdefhijkmnprstwxyz'; 4 | let maxPos = chars.length; 5 | let pwd = ''; 6 | for (let i = 0; i < length; i++) { 7 |     pwd += chars.charAt(Math.floor(Math.random() * maxPos)); 8 |    } 9 | return pwd; 10 | } 11 | static getName(){ 12 | let familyNames = new Array( 13 | "赵", "钱", "孙", "李", "周", "吴", "郑", "王", "冯", "陈", 14 | "褚", "卫", "蒋", "沈", "韩", "杨", "朱", "秦", "尤", "许", 15 | "何", "吕", "施", "张", "孔", "曹", "严", "华", "金", "魏", 16 | "陶", "姜", "戚", "谢", "邹", "喻", "柏", "水", "窦", "章", 17 | "云", "苏", "潘", "葛", "奚", "范", "彭", "郎", "鲁", "韦", 18 | "昌", "马", "苗", "凤", "花", "方", "俞", "任", "袁", "柳", 19 | "酆", "鲍", "史", "唐", "费", "廉", "岑", "薛", "雷", "贺", 20 | "倪", "汤", "滕", "殷", "罗", "毕", "郝", "邬", "安", "常", 21 | "乐", "于", "时", "傅", "皮", "卞", "齐", "康", "伍", "余", 22 | "元", "卜", "顾", "孟", "平", "黄", "和", "穆", "萧", "尹" 23 | ); 24 | 25 | let i = parseInt(10 * Math.random())*10 + parseInt(10 * Math.random()); 26 | let familyName = familyNames[i]; 27 | return familyName; 28 | } 29 | } 30 | 31 | module.exports = Tool; -------------------------------------------------------------------------------- /test/response.js: -------------------------------------------------------------------------------- 1 | class Response { 2 | // status(status) { 3 | // a.send = (result) => { 4 | // this.next(status, next); 5 | // } 6 | // return a; 7 | // } 8 | 9 | constructor() { 10 | var self = this; 11 | 12 | this.promise = new Promise((resolve, reject) => { 13 | self.status = (status) => { 14 | var a = {}; 15 | a.send = (result) => { 16 | resolve({ 17 | status: status, 18 | result: result 19 | }); 20 | } 21 | return a; 22 | } 23 | }) 24 | } 25 | 26 | } 27 | 28 | module.exports = Response; -------------------------------------------------------------------------------- /test/test-chaincode-init.js: -------------------------------------------------------------------------------- 1 | var tape = require('tape'); 2 | var _test = require('tape-promise'); 3 | var path = require('path'); 4 | var test = _test(tape); 5 | 6 | process.env.GOPATH = path.resolve(__dirname, '../chaincode'); 7 | 8 | test('\n\n***** Asset Chaincode Test: init chaincode *****\n\n', (t) => { 9 | require(__dirname + "/../server/chaincode/create-channel.js").createChannel() 10 | .then(() => { 11 | t.pass("create channel success") 12 | return require(__dirname + "/../server/chaincode/join-channel.js").joinChannel(); 13 | }).then(() => { 14 | t.pass("join channel success") 15 | return require(__dirname + "/../server/chaincode/install-chaincode.js").installChaincode(); 16 | }).then(() => { 17 | return sleep(5000); 18 | }).then(() => { 19 | t.pass("install chaincode success") 20 | return require(__dirname + "/../server/chaincode/instantiate-chaincode.js").instantiateChaincode(); 21 | }).then(() => { 22 | t.pass("instantiate chaincode success") 23 | console.log("SUCCESS") 24 | t.end(); 25 | }).catch((err) => { 26 | t.fail(err) 27 | console.log(err) 28 | t.end(); 29 | }); 30 | }); 31 | 32 | function sleep(ms) { 33 | return new Promise(resolve => setTimeout(resolve, ms)); 34 | } -------------------------------------------------------------------------------- /test/test-chaincode-upgrade.js: -------------------------------------------------------------------------------- 1 | let fs = require('fs'); 2 | 3 | var tape = require('tape'); 4 | var _test = require('tape-promise'); 5 | var path = require('path'); 6 | var test = _test(tape); 7 | 8 | process.env.GOPATH = path.resolve(__dirname, '../chaincode'); 9 | 10 | let config = fs.readFileSync(__dirname + '/../config/config.json'); 11 | config = JSON.parse(config)["config"]; 12 | 13 | test('\n\n***** Asset Chaincode Test: restart chaincode *****\n\n', (t) => { 14 | return require(__dirname + "/../server/chaincode/install-chaincode.js").installChaincode() 15 | .then(() => { 16 | t.pass("install chaincode success") 17 | return require(__dirname + "/../server/chaincode/instantiate-chaincode.js").instantiateChaincode(); 18 | }).then(() => { 19 | t.pass("instantiate chaincode success") 20 | console.log("SUCCESS") 21 | t.end(); 22 | }).catch((err) => { 23 | t.fail(err) 24 | console.log(err) 25 | t.end(); 26 | }); 27 | }); -------------------------------------------------------------------------------- /test/test-service-blockchain.js: -------------------------------------------------------------------------------- 1 | var tape = require('tape'); 2 | var _test = require('tape-promise'); 3 | var path = require('path'); 4 | var test = _test(tape); 5 | 6 | var util = require("./util.js"); 7 | 8 | var Constant = require("../server/constant.js"); 9 | var UserService = require(__dirname + "/../server/service/user.service.js"); 10 | var BlockchainService = require(__dirname + "/../server/service/blockchain.service.js"); 11 | 12 | var Response = require("./response.js"); 13 | 14 | process.env.GOPATH = path.resolve(__dirname, '../chaincode'); 15 | 16 | let token; 17 | let user; 18 | 19 | 20 | test('\n\n***** Asset Service Test: BlockchainService *****\n\n', (t) => { 21 | var currAdmin = null; 22 | util.enroll("admin", "adminpw") 23 | .then((admin) => { 24 | t.pass("init chaincode success"); 25 | currAdmin = admin; 26 | 27 | t.comment("测试用户账号1初始化") 28 | let registerReq = { body: {username: "ttt", password: "ttt", nickname: "tttnickname"}}; 29 | let res = new Response(); 30 | UserService.register(registerReq, res, null); 31 | return res.promise; 32 | }).then((result) => { 33 | t.pass(JSON.stringify(result)); 34 | 35 | t.comment("测试用户账号2初始化") 36 | let registerReq = { body: {username: "test2", password: "test2", nickname: "tttnickname"}}; 37 | let res = new Response(); 38 | UserService.register(registerReq, res, null); 39 | return res.promise; 40 | }).then((result) => { 41 | t.pass(JSON.stringify(result)); 42 | 43 | t.comment("获取getBlockHeight"); 44 | let req = {}; 45 | let res = new Response(); 46 | BlockchainService.getBlockHeight(req, res, null); 47 | return res.promise; 48 | 49 | }).then((result) => { 50 | t.pass(JSON.stringify(result)); 51 | 52 | t.comment("根据height获取block"); 53 | let req = {query: {height: result.result - 1}}; 54 | let res = new Response(); 55 | BlockchainService.getBlockByNumber(req, res, null); 56 | return res.promise; 57 | 58 | }).then((result) => { 59 | t.pass(JSON.stringify(result)); 60 | t.comment("结束") 61 | t.end(); 62 | }).catch((err) => { 63 | t.fail(err.stack); 64 | t.end(); 65 | }); 66 | }) -------------------------------------------------------------------------------- /test/test-service-logistic.js: -------------------------------------------------------------------------------- 1 | var tape = require('tape'); 2 | var _test = require('tape-promise'); 3 | var path = require('path'); 4 | var test = _test(tape); 5 | 6 | var util = require("./util.js"); 7 | 8 | var Constant = require("../server/constant.js"); 9 | var UserService = require(__dirname + "/../server/service/user.service.js"); 10 | var OrderService = require(__dirname + "/../server/service/order.service.js"); 11 | var AssetService = require(__dirname + "/../server/service/asset.service.js"); 12 | var PackageService = require(__dirname + "/../server/service/package.service.js"); 13 | var WarehouseService = require(__dirname + "/../server/service/warehouse.service.js"); 14 | var LogisticService = require(__dirname + "/../server/service/logistic.service.js"); 15 | 16 | var Response = require("./response.js"); 17 | 18 | process.env.GOPATH = path.resolve(__dirname, '../chaincode'); 19 | 20 | let token; 21 | let user; 22 | 23 | let currOrder 24 | 25 | let bigPackages; 26 | 27 | test('\n\n***** Asset Service Test: LogisticService *****\n\n', (t) => { 28 | var currAdmin = null; 29 | util.enroll("admin", "adminpw") 30 | .then((admin) => { 31 | t.pass("init chaincode success"); 32 | currAdmin = admin; 33 | 34 | t.comment("测试农民账号1初始化") 35 | let registerReq = { body: {username: "logistic1", password: "logistic1", type: UserService.UserTypeLogistic}}; 36 | let res = new Response(); 37 | UserService.register(registerReq, res, null); 38 | return res.promise; 39 | }).then((result) => { 40 | t.pass(JSON.stringify(result)); 41 | 42 | t.comment("测试登录接口"); 43 | let loginReq = { body: {username: "logistic1", password: "logistic1"}} 44 | let res = new Response(); 45 | UserService.login(loginReq, res, null); 46 | return res.promise; 47 | }).then((result) => { 48 | t.pass(JSON.stringify(result)); 49 | 50 | token = result.result.token; 51 | user = result.result; 52 | 53 | t.comment("开始测试设置账号信息"); 54 | let req = { user:user, body: {token: token, name: "物流商编号A", identity: "637687198904047682", location: "内蒙古"}}; 55 | let res = new Response(); 56 | UserService.setAccount(req, res, null); 57 | return res.promise; 58 | 59 | }).then((result) => { 60 | t.pass(JSON.stringify(result)); 61 | 62 | t.comment("获取所有未发货的订单"); 63 | let req = {user:user, query: { status: OrderService.OrderStatusPackagedStoreIn} } 64 | let res = new Response(); 65 | OrderService.getOrdersByStatus(req, res, null); 66 | return res.promise; 67 | 68 | }).then((result) => { 69 | t.pass(JSON.stringify(result)); 70 | 71 | let orderID; 72 | let data = result.result; 73 | orderID = data[0].OrderID; 74 | currOrder = data[0]; 75 | 76 | t.comment("获取订单下的仓库包装信息") 77 | let req = {user:user, query: {orderID: currOrder.OrderID}} 78 | let res = new Response(); 79 | WarehouseService.getWarehousesByOrder(req, res, null); 80 | return res.promise; 81 | 82 | }).then((result) => { 83 | t.pass(JSON.stringify(result)); 84 | bigPackages = result.result; 85 | 86 | t.comment("给第一个大包装发货") 87 | let bigPackage = bigPackages[0]; 88 | let req = {user:user, body: {bigPackageID: bigPackage.BigPackageID, cost: 10}} 89 | let res = new Response(); 90 | LogisticService.insertLogistic(req, res, null); 91 | return res.promise; 92 | 93 | }).then((result) => { 94 | t.pass(JSON.stringify(result)); 95 | 96 | t.comment("查看下当前订单进展") 97 | let req = {user:user, query: {orderID: currOrder.OrderID}}; 98 | let res = new Response(); 99 | OrderService.getOrder(req, res, null); 100 | return res.promise; 101 | 102 | // }).then((result) => { 103 | // t.pass(JSON.stringify(result)); 104 | 105 | // t.comment("给第2个大包装发货") 106 | // let bigPackage = bigPackages[1]; 107 | // let req = {user:user, body: {bigPackageID: bigPackage.BigPackageID, cost: 10}} 108 | // let res = new Response(); 109 | // LogisticService.insertLogistic(req, res, null); 110 | // return res.promise; 111 | 112 | // }).then((result) => { 113 | // t.pass(JSON.stringify(result)); 114 | 115 | // t.comment("查看下当前订单进展") 116 | // let req = {user:user, query: {orderID: currOrder.OrderID}}; 117 | // let res = new Response(); 118 | // OrderService.getOrder(req, res, null); 119 | // return res.promise; 120 | 121 | }).then((result) => { 122 | t.pass(JSON.stringify(result)); 123 | t.comment("结束") 124 | t.end(); 125 | }).catch((err) => { 126 | t.fail(err.stack); 127 | t.end(); 128 | }); 129 | }) -------------------------------------------------------------------------------- /test/test-service-merchandise.js: -------------------------------------------------------------------------------- 1 | var tape = require('tape'); 2 | var _test = require('tape-promise'); 3 | var path = require('path'); 4 | var test = _test(tape); 5 | 6 | var util = require("./util.js"); 7 | 8 | var Constant = require("../server/constant.js"); 9 | var UserService = require(__dirname + "/../server/service/user.service.js"); 10 | var OrderService = require(__dirname + "/../server/service/order.service.js"); 11 | var AssetService = require(__dirname + "/../server/service/asset.service.js"); 12 | var PackageService = require(__dirname + "/../server/service/package.service.js"); 13 | var WarehouseService = require(__dirname + "/../server/service/warehouse.service.js"); 14 | var LogisticService = require(__dirname + "/../server/service/logistic.service.js"); 15 | var MerchandiseService = require(__dirname + "/../server/service/merchandise.service.js"); 16 | 17 | var Response = require("./response.js"); 18 | 19 | process.env.GOPATH = path.resolve(__dirname, '../chaincode'); 20 | 21 | let token; 22 | let user; 23 | 24 | let currOrder 25 | 26 | let bigPackages; 27 | 28 | let merchandises; 29 | 30 | let farmer; 31 | 32 | test('\n\n***** Asset Service Test: MerchandiseService *****\n\n', (t) => { 33 | var currAdmin = null; 34 | util.enroll("admin", "adminpw") 35 | .then((admin) => { 36 | t.pass("init chaincode success"); 37 | currAdmin = admin; 38 | 39 | t.comment("测试农民账号1初始化") 40 | let registerReq = { body: {username: "merchant1", password: "merchant1", type: UserService.UserTypeMerchant}}; 41 | let res = new Response(); 42 | UserService.register(registerReq, res, null); 43 | return res.promise; 44 | }).then((result) => { 45 | t.pass(JSON.stringify(result)); 46 | 47 | t.comment("测试登录接口"); 48 | let loginReq = { body: {username: "merchant1", password: "merchant1"}} 49 | let res = new Response(); 50 | UserService.login(loginReq, res, null); 51 | return res.promise; 52 | }).then((result) => { 53 | t.pass(JSON.stringify(result)); 54 | 55 | token = result.result.token; 56 | user = result.result; 57 | 58 | t.comment("开始测试设置账号信息"); 59 | let req = { user:user, body: {token: token, name: "商户编号A", identity: "637687198904047682", location: "内蒙古"}}; 60 | let res = new Response(); 61 | UserService.setAccount(req, res, null); 62 | return res.promise; 63 | 64 | }).then((result) => { 65 | t.pass(JSON.stringify(result)); 66 | 67 | t.comment("获取所有未到货的订单"); 68 | let req = {user:user, query: { status: OrderService.OrderStatusDeliveried} } 69 | let res = new Response(); 70 | OrderService.getOrdersByStatus(req, res, null); 71 | return res.promise; 72 | 73 | }).then((result) => { 74 | t.pass(JSON.stringify(result)); 75 | 76 | let orderID; 77 | let data = result.result; 78 | orderID = data[0].OrderID; 79 | currOrder = data[0]; 80 | 81 | t.comment("获取订单下的所有物流") 82 | let req = {user:user, query: {orderID: currOrder.OrderID}} 83 | let res = new Response(); 84 | LogisticService.getLogisticByOrder(req, res, null); 85 | return res.promise; 86 | 87 | }).then((result) => { 88 | t.pass(JSON.stringify(result)); 89 | bigPackages = result.result; 90 | 91 | t.comment("给第一个大包装到货") 92 | let bigPackage = bigPackages[0]; 93 | let req = {user:user, body: {bigPackageID: bigPackage.BigPackageID, cost: 10}} 94 | let res = new Response(); 95 | MerchandiseService.insertMechandise(req, res, null); 96 | return res.promise; 97 | 98 | }).then((result) => { 99 | t.pass(JSON.stringify(result)); 100 | 101 | t.comment("查看下当前订单进展") 102 | let req = {user:user, query: {orderID: currOrder.OrderID}}; 103 | let res = new Response(); 104 | OrderService.getOrder(req, res, null); 105 | return res.promise; 106 | 107 | // }).then((result) => { 108 | // t.pass(JSON.stringify(result)); 109 | 110 | // t.comment("给第2个大包装发货") 111 | // let bigPackage = bigPackages[1]; 112 | // let req = {user:user, body: {bigPackageID: bigPackage.BigPackageID, cost: 10}} 113 | // let res = new Response(); 114 | // MerchandiseService.insertMechandise(req, res, null); 115 | // return res.promise; 116 | 117 | // }).then((result) => { 118 | // t.pass(JSON.stringify(result)); 119 | 120 | // t.comment("查看下当前订单进展") 121 | // let req = {user:user, query: {orderID: currOrder.OrderID}}; 122 | // let res = new Response(); 123 | // OrderService.getOrder(req, res, null); 124 | // return res.promise; 125 | 126 | }).then((result) => { 127 | t.pass(JSON.stringify(result)); 128 | 129 | t.comment("测试农民登录接口"); 130 | let loginReq = { body: {username: "farmer2", password: "farmer2"}} 131 | let res = new Response(); 132 | UserService.login(loginReq, res, null); 133 | return res.promise; 134 | 135 | }).then((result) => { 136 | t.pass(JSON.stringify(result)); 137 | 138 | t.comment("农民获取可借款的金额"); 139 | farmer = result.result; 140 | let req = {user:farmer} 141 | let res = new Response(); 142 | UserService.getFarmerLoanableMoney(req, res, null); 143 | return res.promise; 144 | 145 | }).then((result) => { 146 | t.pass(JSON.stringify(result)); 147 | 148 | t.comment("农民借款"); 149 | let loan = result.result; 150 | let req = {user:farmer, body: {loan: loan}} 151 | let res = new Response(); 152 | UserService.loanByFarmer(req, res, null); 153 | return res.promise; 154 | 155 | }).then((result) => { 156 | t.pass(JSON.stringify(result)); 157 | 158 | t.comment("农民获取可借款的金额"); 159 | let req = {user:farmer} 160 | let res = new Response(); 161 | UserService.getFarmerLoanableMoney(req, res, null); 162 | return res.promise; 163 | 164 | }).then((result) => { 165 | t.pass(JSON.stringify(result)); 166 | 167 | t.comment("农民获取钱包"); 168 | let req = {user:farmer} 169 | let res = new Response(); 170 | UserService.getUserInfo(req, res, null); 171 | return res.promise; 172 | 173 | }).then((result) => { 174 | t.pass(JSON.stringify(result)); 175 | 176 | t.comment("获取目前的该商户的所有商品") 177 | let req = {user:user} 178 | let res = new Response(); 179 | MerchandiseService.getMerchandiseByOwner(req, res, null); 180 | return res.promise; 181 | }).then((result) => { 182 | t.pass(JSON.stringify(result)); 183 | 184 | merchandises = result.result; 185 | t.comment("获取物品溯源") 186 | let req = {user:user, query: {packageID: merchandises[0].PackageID}} 187 | let res = new Response(); 188 | MerchandiseService.getMerchandiseFlow(req, res, null); 189 | return res.promise; 190 | 191 | // }).then((result) => { 192 | // t.pass(JSON.stringify(result)); 193 | 194 | // t.comment("支付订单金额") 195 | // let req = {user:user, body: {orderID: currOrder.OrderID}}; 196 | // let res = new Response(); 197 | // OrderService.payOrder(req, res, null); 198 | // return res.promise; 199 | 200 | // }).then((result) => { 201 | // t.pass(JSON.stringify(result)); 202 | 203 | // t.comment("查看自己钱包") 204 | // let req = { user: user }; 205 | // let res = new Response(); 206 | // UserService.getAccount(req, res, null); 207 | // return res.promise; 208 | // }).then((result) => { 209 | // t.pass(JSON.stringify(result)); 210 | 211 | // t.comment("模拟用户购买") 212 | // let req = { user: user, body: {packageID: merchandises[0].PackageID} }; 213 | // let res = new Response(); 214 | // MerchandiseService.purchaseMechandise(req, res, null); 215 | // return res.promise; 216 | 217 | // }).then((result) => { 218 | // t.pass(JSON.stringify(result)); 219 | 220 | // t.comment("查看钱包历史") 221 | // let req = { user: user }; 222 | // let res = new Response(); 223 | // UserService.getMoneyHistory(req, res, null); 224 | // return res.promise; 225 | 226 | }).then((result) => { 227 | t.pass(JSON.stringify(result)); 228 | t.comment("结束") 229 | t.end(); 230 | }).catch((err) => { 231 | t.fail(err.stack); 232 | t.end(); 233 | }); 234 | }) -------------------------------------------------------------------------------- /test/test-service-order.js: -------------------------------------------------------------------------------- 1 | var tape = require('tape'); 2 | var _test = require('tape-promise'); 3 | var path = require('path'); 4 | var test = _test(tape); 5 | 6 | var util = require("./util.js"); 7 | 8 | var Constant = require("../server/constant.js"); 9 | var UserService = require(__dirname + "/../server/service/user.service.js"); 10 | var OrderService = require(__dirname + "/../server/service/order.service.js"); 11 | 12 | var Response = require("./response.js"); 13 | 14 | process.env.GOPATH = path.resolve(__dirname, '../chaincode'); 15 | 16 | let token; 17 | let user; 18 | 19 | test('\n\n***** Asset Service Test: order *****\n\n', (t) => { 20 | var currAdmin = null; 21 | util.enroll("admin", "adminpw") 22 | .then((admin) => { 23 | t.pass("init chaincode success"); 24 | currAdmin = admin; 25 | 26 | t.comment("测试商户账号1初始化") 27 | let registerReq = { body: {username: "merchant1", password: "merchant1", type: UserService.UserTypeMerchant}}; 28 | let res = new Response(); 29 | UserService.register(registerReq, res, null); 30 | return res.promise; 31 | }).then((result) => { 32 | t.pass(JSON.stringify(result)); 33 | 34 | t.comment("测试登录接口"); 35 | let loginReq = { body: {username: "merchant1", password: "merchant1"}} 36 | let res = new Response(); 37 | UserService.login(loginReq, res, null); 38 | return res.promise; 39 | }).then((result) => { 40 | t.pass(JSON.stringify(result)); 41 | 42 | token = result.result.token; 43 | user = result.result; 44 | 45 | t.comment("测试发布订单"); 46 | let req = {user:user, body: {categoryID: 1, amount: 60, cost: 500, destination: "上海"}} 47 | let res = new Response(); 48 | OrderService.createOrder(req, res, null); 49 | return res.promise; 50 | 51 | }).then((result) => { 52 | t.pass(JSON.stringify(result)); 53 | let orderID = result.result.OrderID; 54 | 55 | t.comment("测试获取订单"); 56 | let req = {user: user, query: {orderID: orderID}} 57 | let res = new Response(); 58 | OrderService.getOrder(req, res, null); 59 | return res.promise; 60 | 61 | }).then((result) => { 62 | t.pass(JSON.stringify(result)); 63 | 64 | t.comment("测试发布订单2"); 65 | let req = {user:user, body: {categoryID: 1, amount: 95, cost: 600, destination: "北京"}} 66 | let res = new Response(); 67 | OrderService.createOrder(req, res, null); 68 | return res.promise; 69 | 70 | }).then((result) => { 71 | t.pass(JSON.stringify(result)); 72 | 73 | t.comment("测试获取自己发布的订单"); 74 | let req = {user: user} 75 | let res = new Response(); 76 | OrderService.getOrdersByOwner(req, res, null); 77 | return res.promise; 78 | 79 | }).then((result) => { 80 | t.pass(JSON.stringify(result)); 81 | t.comment("结束") 82 | t.end(); 83 | }).catch((err) => { 84 | t.fail(err.stack); 85 | t.end(); 86 | }); 87 | }) -------------------------------------------------------------------------------- /test/test-service-package.js: -------------------------------------------------------------------------------- 1 | var tape = require('tape'); 2 | var _test = require('tape-promise'); 3 | var path = require('path'); 4 | var test = _test(tape); 5 | 6 | var util = require("./util.js"); 7 | 8 | var Constant = require("../server/constant.js"); 9 | var UserService = require(__dirname + "/../server/service/user.service.js"); 10 | var OrderService = require(__dirname + "/../server/service/order.service.js"); 11 | var AssetService = require(__dirname + "/../server/service/asset.service.js"); 12 | var PackageService = require(__dirname + "/../server/service/package.service.js"); 13 | 14 | var Response = require("./response.js"); 15 | 16 | process.env.GOPATH = path.resolve(__dirname, '../chaincode'); 17 | 18 | let token; 19 | let user; 20 | 21 | let currOrder 22 | 23 | test('\n\n***** Asset Service Test: PackageService *****\n\n', (t) => { 24 | var currAdmin = null; 25 | util.enroll("admin", "adminpw") 26 | .then((admin) => { 27 | t.pass("init chaincode success"); 28 | currAdmin = admin; 29 | 30 | t.comment("测试农民账号1初始化") 31 | let registerReq = { body: {username: "packager1", password: "packager1", type: UserService.UserTypePackager}}; 32 | let res = new Response(); 33 | UserService.register(registerReq, res, null); 34 | return res.promise; 35 | }).then((result) => { 36 | t.pass(JSON.stringify(result)); 37 | 38 | t.comment("测试登录接口"); 39 | let loginReq = { body: {username: "packager1", password: "packager1"}} 40 | let res = new Response(); 41 | UserService.login(loginReq, res, null); 42 | return res.promise; 43 | }).then((result) => { 44 | t.pass(JSON.stringify(result)); 45 | 46 | token = result.result.token; 47 | user = result.result; 48 | 49 | t.comment("开始测试设置账号信息"); 50 | let req = { user:user, body: {token: token, name: "包装商编号A", identity: "637687198904047682", location: "内蒙古"}}; 51 | let res = new Response(); 52 | UserService.setAccount(req, res, null); 53 | return res.promise; 54 | 55 | }).then((result) => { 56 | t.pass(JSON.stringify(result)); 57 | 58 | t.comment("获取所有未包装的订单"); 59 | let req = {user:user, query: { status: OrderService.OrderStatusProduced} } 60 | let res = new Response(); 61 | OrderService.getOrdersByStatus(req, res, null); 62 | return res.promise; 63 | 64 | }).then((result) => { 65 | t.pass(JSON.stringify(result)); 66 | 67 | t.comment("开始包装订单"); 68 | let orderID; 69 | let data = result.result; 70 | orderID = data[0].OrderID; 71 | currOrder = data[0]; 72 | 73 | let req = {user:user, body: {orderID: orderID, cost: 10}} // 每一箱的包装费用 74 | let res = new Response(); 75 | PackageService.packageOrder(req, res, null); 76 | return res.promise; 77 | 78 | }).then((result) => { 79 | t.pass(JSON.stringify(result)); 80 | 81 | t.comment("获取订单下的所有包装信息") 82 | let req = {user:user, body: {orderID: currOrder.OrderID}} 83 | let res = new Response(); 84 | PackageService.getBigPackagesByOrder(req, res, null); 85 | return res.promise; 86 | 87 | }).then((result) => { 88 | t.pass(JSON.stringify(result)); 89 | t.comment("结束") 90 | t.end(); 91 | }).catch((err) => { 92 | t.fail(err.stack); 93 | t.end(); 94 | }); 95 | }) -------------------------------------------------------------------------------- /test/test-service-user.js: -------------------------------------------------------------------------------- 1 | var tape = require('tape'); 2 | var _test = require('tape-promise'); 3 | var path = require('path'); 4 | var test = _test(tape); 5 | 6 | var util = require("./util.js"); 7 | 8 | var Constant = require("../server/constant.js"); 9 | var UserService = require(__dirname + "/../server/service/user.service.js"); 10 | 11 | var Response = require("./response.js"); 12 | 13 | process.env.GOPATH = path.resolve(__dirname, '../chaincode'); 14 | 15 | let token; 16 | let user; 17 | 18 | 19 | test('\n\n***** Asset Service Test: user *****\n\n', (t) => { 20 | var currAdmin = null; 21 | util.enroll("admin", "adminpw") 22 | .then((admin) => { 23 | t.pass("init chaincode success"); 24 | currAdmin = admin; 25 | 26 | t.comment("测试用户账号1初始化") 27 | let registerReq = { body: {username: "test1", password: "test1", type: UserService.UserTypeFarmer}}; 28 | let res = new Response(); 29 | UserService.register(registerReq, res, null); 30 | return res.promise; 31 | }).then((result) => { 32 | t.pass(JSON.stringify(result)); 33 | 34 | t.comment("测试用户账号2初始化") 35 | let registerReq = { body: {username: "test2", password: "test2", type: UserService.UserTypeFarmer}}; 36 | let res = new Response(); 37 | UserService.register(registerReq, res, null); 38 | return res.promise; 39 | }).then((result) => { 40 | t.pass(JSON.stringify(result)); 41 | 42 | t.comment("测试登录接口"); 43 | let loginReq = { body: {username: "test1", password: "test1"}} 44 | let res = new Response(); 45 | UserService.login(loginReq, res, null); 46 | return res.promise; 47 | }).then((result) => { 48 | t.pass(JSON.stringify(result)); 49 | 50 | token = result.result.token; 51 | user = result.result; 52 | 53 | t.comment("开始测试设置账号信息"); 54 | let req = { user:user, body: {token: token, name: "农民编号A", identity: "637687198904047682", location: "内蒙古"}}; 55 | let res = new Response(); 56 | UserService.setAccount(req, res, null); 57 | return res.promise; 58 | 59 | }).then((result) => { 60 | t.pass(JSON.stringify(result)); 61 | 62 | t.comment("开始获取设置账号信息"); 63 | let req = { user: user }; 64 | let res = new Response(); 65 | UserService.getUserInfo(req, res, null); 66 | return res.promise; 67 | 68 | }).then((result) => { 69 | t.pass(JSON.stringify(result)); 70 | t.comment("结束") 71 | t.end(); 72 | }).catch((err) => { 73 | t.fail(err.stack); 74 | t.end(); 75 | }); 76 | }) -------------------------------------------------------------------------------- /test/test-service-warehouse.js: -------------------------------------------------------------------------------- 1 | var tape = require('tape'); 2 | var _test = require('tape-promise'); 3 | var path = require('path'); 4 | var test = _test(tape); 5 | 6 | var util = require("./util.js"); 7 | 8 | var Constant = require("../server/constant.js"); 9 | var UserService = require(__dirname + "/../server/service/user.service.js"); 10 | var OrderService = require(__dirname + "/../server/service/order.service.js"); 11 | var AssetService = require(__dirname + "/../server/service/asset.service.js"); 12 | var PackageService = require(__dirname + "/../server/service/package.service.js"); 13 | var WarehouseService = require(__dirname + "/../server/service/warehouse.service.js"); 14 | 15 | var Response = require("./response.js"); 16 | 17 | process.env.GOPATH = path.resolve(__dirname, '../chaincode'); 18 | 19 | let token; 20 | let user; 21 | 22 | let currOrder 23 | 24 | let bigPackages; 25 | 26 | test('\n\n***** Asset Service Test: WarehouseService *****\n\n', (t) => { 27 | var currAdmin = null; 28 | util.enroll("admin", "adminpw") 29 | .then((admin) => { 30 | t.pass("init chaincode success"); 31 | currAdmin = admin; 32 | 33 | t.comment("测试农民账号1初始化") 34 | let registerReq = { body: {username: "warehouse1", password: "warehouse1", type: UserService.UserTypeWarehouse}}; 35 | let res = new Response(); 36 | UserService.register(registerReq, res, null); 37 | return res.promise; 38 | }).then((result) => { 39 | t.pass(JSON.stringify(result)); 40 | 41 | t.comment("测试登录接口"); 42 | let loginReq = { body: {username: "warehouse1", password: "warehouse1"}} 43 | let res = new Response(); 44 | UserService.login(loginReq, res, null); 45 | return res.promise; 46 | }).then((result) => { 47 | t.pass(JSON.stringify(result)); 48 | 49 | token = result.result.token; 50 | user = result.result; 51 | 52 | t.comment("开始测试设置账号信息"); 53 | let req = { user:user, body: {token: token, name: "仓库商编号A", identity: "637687198904047682", location: "内蒙古"}}; 54 | let res = new Response(); 55 | UserService.setAccount(req, res, null); 56 | return res.promise; 57 | 58 | }).then((result) => { 59 | t.pass(JSON.stringify(result)); 60 | 61 | t.comment("获取所有的未入库的baozhuang") 62 | let req = {user:user} 63 | let res = new Response(); 64 | PackageService.getBigPackageByOrderStatus(req, res, null); 65 | return res.promise; 66 | 67 | }).then((result) => { 68 | t.pass(JSON.stringify(result)); 69 | 70 | t.comment("获取所有未入库的订单"); 71 | let req = {user:user, query: { status: OrderService.OrderStatusPackaged} } 72 | let res = new Response(); 73 | OrderService.getOrdersByStatus(req, res, null); 74 | return res.promise; 75 | 76 | }).then((result) => { 77 | t.pass(JSON.stringify(result)); 78 | 79 | let orderID; 80 | let data = result.result; 81 | orderID = data[0].OrderID; 82 | currOrder = data[0]; 83 | 84 | t.comment("获取订单下的所有包装信息") 85 | let req = {user:user, body: {orderID: currOrder.OrderID}} 86 | let res = new Response(); 87 | PackageService.getBigPackagesByOrder(req, res, null); 88 | return res.promise; 89 | 90 | }).then((result) => { 91 | t.pass(JSON.stringify(result)); 92 | bigPackages = result.result; 93 | 94 | t.comment("给第一个大包装入库") 95 | let bigPackage = bigPackages[0].BigPackage; 96 | let req = {user:user, body: {bigPackageID: bigPackage.BigPackageID, cost: 10}} 97 | let res = new Response(); 98 | WarehouseService.insertWarehouseStoreIn(req, res, null); 99 | return res.promise; 100 | 101 | }).then((result) => { 102 | t.pass(JSON.stringify(result)); 103 | 104 | t.comment("查看下当前订单进展") 105 | let req = {user:user, query: {orderID: currOrder.OrderID}}; 106 | let res = new Response(); 107 | OrderService.getOrder(req, res, null); 108 | return res.promise; 109 | 110 | // }).then((result) => { 111 | // t.pass(JSON.stringify(result)); 112 | 113 | // t.comment("给第2个大包装入库") 114 | // let bigPackage = bigPackages[1].BigPackage; 115 | // let req = {user:user, body: {bigPackageID: bigPackage.BigPackageID, cost: 10}} 116 | // let res = new Response(); 117 | // WarehouseService.insertWarehouseStoreIn(req, res, null); 118 | // return res.promise; 119 | 120 | // }).then((result) => { 121 | // t.pass(JSON.stringify(result)); 122 | 123 | // t.comment("查看下当前订单进展") 124 | // let req = {user:user, query: {orderID: currOrder.OrderID}}; 125 | // let res = new Response(); 126 | // OrderService.getOrder(req, res, null); 127 | // return res.promise; 128 | 129 | }).then((result) => { 130 | t.pass(JSON.stringify(result)); 131 | 132 | t.comment("获取订单下的仓库包装信息") 133 | let req = {user:user, query: {orderID: currOrder.OrderID}} 134 | let res = new Response(); 135 | WarehouseService.getWarehousesByOrder(req, res, null); 136 | return res.promise; 137 | 138 | }).then((result) => { 139 | t.pass(JSON.stringify(result)); 140 | t.comment("结束") 141 | t.end(); 142 | }).catch((err) => { 143 | t.fail(err.stack); 144 | t.end(); 145 | }); 146 | }) -------------------------------------------------------------------------------- /test/util.js: -------------------------------------------------------------------------------- 1 | var hfc = require('fabric-client'); 2 | var util = require('util'); 3 | var fs = require('fs'); 4 | var path = require('path'); 5 | let Redis = require('ioredis'); 6 | 7 | var utils = require('fabric-client/lib/utils.js'); 8 | var Orderer = require('fabric-client/lib/Orderer.js'); 9 | var Peer = require('fabric-client/lib/Peer.js'); 10 | var EventHub = require('fabric-client/lib/EventHub.js'); 11 | var the_user = null; 12 | 13 | var testUtil = require(__dirname + '/../server/chaincode/util.js'); 14 | 15 | var logger = utils.getLogger('test-util'); 16 | 17 | hfc.addConfigFile(path.join(__dirname, '../config/config.json')); 18 | var ORGS = hfc.getConfigSetting('config'); 19 | 20 | let Constant = require(__dirname +'/../server/constant.js'); 21 | let redis = new Redis(ORGS.redis); 22 | Constant.redis = redis; 23 | 24 | module.exports.initChaincode = function () { 25 | return new Promise((resolve, reject) => { 26 | require(__dirname + "/../server/chaincode/create-channel.js").createChannel() 27 | .then(() => { 28 | return require(__dirname + "/../server/chaincode/join-channel.js").joinChannel(); 29 | }).then(() => { 30 | return require(__dirname + "/../server/chaincode/install-chaincode.js").installChaincode(); 31 | }).then(() => { 32 | return require(__dirname + "/../server/chaincode/instantiate-chaincode.js").instantiateChaincode(); 33 | }).then(() => { 34 | console.log("SUCCESS") 35 | resolve(); 36 | }).catch((err) => { 37 | console.log(err) 38 | reject(); 39 | }); 40 | }) 41 | 42 | } 43 | 44 | module.exports.enroll = function (enrollId, enrollSecret) { 45 | return new Promise((resolve, reject) => { 46 | var client = new hfc(); 47 | var chain = client.newChain(ORGS.chaincode.channel); 48 | 49 | var caRootsPath = ORGS.orderer.tls_cacerts; 50 | let data = fs.readFileSync(path.join(__dirname, "../" + caRootsPath)); 51 | let caroots = Buffer.from(data).toString(); 52 | 53 | for (let key in ORGS) { 54 | if (key == ORGS.currOrg && ORGS.hasOwnProperty(key) && typeof ORGS[key].peer1 !== 'undefined') { 55 | let data = fs.readFileSync(path.join(__dirname, '../' + ORGS[key].peer1['tls_cacerts'])); 56 | let peer = new Peer( 57 | ORGS[key].peer1.requests, 58 | { 59 | pem: Buffer.from(data).toString(), 60 | 'ssl-target-name-override': ORGS[key].peer1['server-hostname'] 61 | } 62 | ); 63 | chain.addPeer(peer); 64 | } 65 | } 66 | 67 | chain.addOrderer( 68 | new Orderer( 69 | ORGS.orderer.url, 70 | { 71 | 'pem': caroots, 72 | 'ssl-target-name-override': ORGS.orderer['server-hostname'] 73 | } 74 | ) 75 | ); 76 | 77 | var name = ORGS[ORGS.currOrg].name; 78 | return hfc.newDefaultKeyValueStore({ 79 | path: testUtil.storePathForOrg(name) 80 | }).then((store) => { 81 | client.setStateStore(store); 82 | return testUtil.getSubmitter(client, ORGS.currOrg); 83 | }).then((admin) => { 84 | the_user = admin; 85 | 86 | Constant.admin = admin; 87 | Constant.chain = chain; 88 | Constant.ORGS = ORGS; 89 | 90 | resolve(admin); 91 | }).catch((err) => { 92 | console.log(err.stack); 93 | reject(err); 94 | }) 95 | }) 96 | } --------------------------------------------------------------------------------