From cf79cd1dc1d34c83adb756c8be94b5a1902099db Mon Sep 17 00:00:00 2001 From: Sudheesh Singanamalla Date: Wed, 3 Jan 2018 10:14:51 +0530 Subject: [PATCH 01/29] [FAB-7584] Removes copy of creds to keystore The basic-network sample consists of a initialization script which removes any content inside the hfc-key-store and later copies the content from creds to the keystore. However this creds directory doesnot exist or is ever created in the sample execution. Change-Id: Ia3d07ad78875328f6798290d3f0ab3098b9e85fc Signed-off-by: Sudheesh Singanamalla --- basic-network/init.sh | 1 - 1 file changed, 1 deletion(-) diff --git a/basic-network/init.sh b/basic-network/init.sh index 3ab47473..caf7c76d 100755 --- a/basic-network/init.sh +++ b/basic-network/init.sh @@ -12,4 +12,3 @@ rm -rf ~/.hfc-key-store/* # copy peer admin credentials into the keyValStore mkdir -p ~/.hfc-key-store -cp creds/* ~/.hfc-key-store From e4d776032e89d7731067756d7765e61c123431d9 Mon Sep 17 00:00:00 2001 From: rennman Date: Mon, 12 Mar 2018 12:25:54 -0400 Subject: [PATCH 02/29] [ FAB-8730 ] hyphen breaks fabric-samples The jq script which performs the config update in scripts/run-fabric.sh fails if the orderer name contains a hyphen. It requires modifying the way in which jq interpolates shell variables. Change-Id: Ie4de9459cb17693465613d6efd78b3d98575bbb2 Signed-off-by: rennman --- fabric-ca/scripts/run-fabric.sh | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/fabric-ca/scripts/run-fabric.sh b/fabric-ca/scripts/run-fabric.sh index a4ab0f80..ffe89006 100755 --- a/fabric-ca/scripts/run-fabric.sh +++ b/fabric-ca/scripts/run-fabric.sh @@ -238,8 +238,8 @@ function createConfigUpdatePayloadWithCRL { jq .data.data[0].payload.data.config config_block.json > config.json # Update crl in the config json - crl=$(cat $CORE_PEER_MSPCONFIGPATH/crls/crl*.pem | base64 | tr -d '\n') - cat config.json | jq '.channel_group.groups.Application.groups.'"${ORG}"'.values.MSP.value.config.revocation_list = ["'"${crl}"'"]' > updated_config.json + CRL=$(cat $CORE_PEER_MSPCONFIGPATH/crls/crl*.pem | base64 | tr -d '\n') + cat config.json | jq --arg org "$ORG" --arg crl "$CRL" '.channel_group.groups.Application.groups[$org].values.MSP.value.config.revocation_list = [$crl]' > updated_config.json # Create the config diff protobuf curl -X POST --data-binary @config.json $CTLURL/protolator/encode/common.Config > config.pb @@ -266,6 +266,7 @@ function finish { else logr "Tests did not complete successfully; see $RUN_LOGFILE for more details" touch /$RUN_FAIL_FILE + exit 1 fi } From fcf62adf5791d8535d52aeb6fedf24cac19e7dfd Mon Sep 17 00:00:00 2001 From: David Seybold Date: Tue, 20 Mar 2018 21:57:57 -0400 Subject: [PATCH 03/29] [FAB-8265] Fixed spelling error in registerUser I have fixed a spelling error in registerUser.js, changing "intreact" to "interact". Change-Id: Ib07af36923a5fe652be01e1c83e316d4495d4a46 Signed-off-by: David Seybold --- fabcar/registerUser.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fabcar/registerUser.js b/fabcar/registerUser.js index 4b4c9091..9aa93a9c 100644 --- a/fabcar/registerUser.js +++ b/fabcar/registerUser.js @@ -71,7 +71,7 @@ Fabric_Client.newDefaultKeyValueStore({ path: store_path return fabric_client.setUserContext(member_user); }).then(()=>{ - console.log('User1 was successfully registered and enrolled and is ready to intreact with the fabric network'); + console.log('User1 was successfully registered and enrolled and is ready to interact with the fabric network'); }).catch((err) => { console.error('Failed to register: ' + err); From 4f97717287d9f002a8154f3ce57af7c7264526bb Mon Sep 17 00:00:00 2001 From: Bret Harrison Date: Tue, 20 Mar 2018 11:49:13 -0400 Subject: [PATCH 04/29] FAB-8947 Fabric-Samples remove package lock Remove the package lock file and allow current versions to be installed. Change-Id: I74a4710173e4f2307e87b73c6021ecf20237a974 Signed-off-by: Bret Harrison --- balance-transfer/package-lock.json | 2546 ---------------------------- 1 file changed, 2546 deletions(-) delete mode 100644 balance-transfer/package-lock.json diff --git a/balance-transfer/package-lock.json b/balance-transfer/package-lock.json deleted file mode 100644 index d10a673f..00000000 --- a/balance-transfer/package-lock.json +++ /dev/null @@ -1,2546 +0,0 @@ -{ - "name": "balance-transfer", - "version": "1.0.0", - "lockfileVersion": 1, - "requires": true, - "dependencies": { - "accepts": { - "version": "1.3.4", - "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.4.tgz", - "integrity": "sha1-hiRnWMfdbSGmR0/whKR0DsBesh8=", - "requires": { - "mime-types": "2.1.17", - "negotiator": "0.6.1" - } - }, - "ajv": { - "version": "4.11.8", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-4.11.8.tgz", - "integrity": "sha1-gv+wKynmYq5TvcIK8VlHcGc5xTY=", - "requires": { - "co": "4.6.0", - "json-stable-stringify": "1.0.1" - } - }, - "ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=" - }, - "argparse": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.9.tgz", - "integrity": "sha1-c9g7wmP4bpf4zE9rrhsOkKfSLIY=", - "requires": { - "sprintf-js": "1.0.3" - } - }, - "arguejs": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/arguejs/-/arguejs-0.2.3.tgz", - "integrity": "sha1-tvk59f4OPNHz+T4qqSYkJL8xKvc=" - }, - "array-flatten": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", - "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=" - }, - "ascli": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/ascli/-/ascli-1.0.1.tgz", - "integrity": "sha1-vPpZdKYvGOgcq660lzKrSoj5Brw=", - "requires": { - "colour": "0.7.1", - "optjs": "3.2.2" - } - }, - "asn1": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.3.tgz", - "integrity": "sha1-2sh4dxPJlmhJ/IGAd36+nB3fO4Y=" - }, - "assert-plus": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-0.2.0.tgz", - "integrity": "sha1-104bh+ev/A24qttwIfP+SBAasjQ=" - }, - "async": { - "version": "1.5.2", - "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz", - "integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo=" - }, - "asynckit": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=" - }, - "aws-sign2": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.6.0.tgz", - "integrity": "sha1-FDQt0428yU0OW4fXY81jYSwOeU8=" - }, - "aws4": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.6.0.tgz", - "integrity": "sha1-g+9cqGCysy5KDe7e6MdxudtXRx4=" - }, - "balanced-match": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", - "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" - }, - "base64url": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/base64url/-/base64url-2.0.0.tgz", - "integrity": "sha1-6sFuA+oUOO/5Qj1puqNiYu0fcLs=" - }, - "bcrypt-pbkdf": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.1.tgz", - "integrity": "sha1-Y7xdy2EzG5K8Bf1SiVPDNGKgb40=", - "optional": true, - "requires": { - "tweetnacl": "0.14.5" - } - }, - "bl": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/bl/-/bl-1.2.1.tgz", - "integrity": "sha1-ysMo977kVzDUBLaSID/LWQ4XLV4=", - "requires": { - "readable-stream": "2.3.3" - } - }, - "bn.js": { - "version": "4.11.8", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz", - "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==" - }, - "body-parser": { - "version": "1.18.2", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.18.2.tgz", - "integrity": "sha1-h2eKGdhLR9hZuDGZvVm84iKxBFQ=", - "requires": { - "bytes": "3.0.0", - "content-type": "1.0.4", - "debug": "2.6.9", - "depd": "1.1.1", - "http-errors": "1.6.2", - "iconv-lite": "0.4.19", - "on-finished": "2.3.0", - "qs": "6.5.1", - "raw-body": "2.3.2", - "type-is": "1.6.15" - } - }, - "boom": { - "version": "2.10.1", - "resolved": "https://registry.npmjs.org/boom/-/boom-2.10.1.tgz", - "integrity": "sha1-OciRjO/1eZ+D+UkqhI9iWt0Mdm8=", - "requires": { - "hoek": "2.16.3" - } - }, - "brace-expansion": { - "version": "1.1.8", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.8.tgz", - "integrity": "sha1-wHshHHyVLsH479Uad+8NHTmQopI=", - "requires": { - "balanced-match": "1.0.0", - "concat-map": "0.0.1" - } - }, - "brorand": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", - "integrity": "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=" - }, - "browser-request": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/browser-request/-/browser-request-0.3.3.tgz", - "integrity": "sha1-ns5bWsqJopkyJC4Yv5M975h2zBc=" - }, - "buffer-equal-constant-time": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz", - "integrity": "sha1-+OcRMvf/5uAaXJaXpMbz5I1cyBk=" - }, - "bytebuffer": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/bytebuffer/-/bytebuffer-5.0.1.tgz", - "integrity": "sha1-WC7qSxqHO20CCkjVjfhfC7ps/d0=", - "requires": { - "long": "3.2.0" - } - }, - "bytes": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz", - "integrity": "sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg=" - }, - "callsite": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/callsite/-/callsite-1.0.0.tgz", - "integrity": "sha1-KAOY5dZkvXQDi28JBRU+borxvCA=" - }, - "camelcase": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-2.1.1.tgz", - "integrity": "sha1-fB0W1nmhu+WcoCys7PsBHiAfWh8=" - }, - "caseless": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", - "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=" - }, - "cliui": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-3.2.0.tgz", - "integrity": "sha1-EgYBU3qRbSmUD5NNo7SNWFo5IT0=", - "requires": { - "string-width": "1.0.2", - "strip-ansi": "3.0.1", - "wrap-ansi": "2.1.0" - } - }, - "cloudant-follow": { - "version": "0.13.0", - "resolved": "https://registry.npmjs.org/cloudant-follow/-/cloudant-follow-0.13.0.tgz", - "integrity": "sha1-fs6teQYbADmfXuNUA2jdYGV83Cs=", - "requires": { - "browser-request": "0.3.3", - "debug": "2.6.9", - "request": "2.81.0" - }, - "dependencies": { - "qs": { - "version": "6.4.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.4.0.tgz", - "integrity": "sha1-E+JtKK1rD/qpExLNO/cI7TUecjM=" - }, - "request": { - "version": "2.81.0", - "resolved": "https://registry.npmjs.org/request/-/request-2.81.0.tgz", - "integrity": "sha1-xpKJRqDgbF+Nb4qTM0af/aRimKA=", - "requires": { - "aws-sign2": "0.6.0", - "aws4": "1.6.0", - "caseless": "0.12.0", - "combined-stream": "1.0.5", - "extend": "3.0.1", - "forever-agent": "0.6.1", - "form-data": "2.1.4", - "har-validator": "4.2.1", - "hawk": "3.1.3", - "http-signature": "1.1.1", - "is-typedarray": "1.0.0", - "isstream": "0.1.2", - "json-stringify-safe": "5.0.1", - "mime-types": "2.1.17", - "oauth-sign": "0.8.2", - "performance-now": "0.2.0", - "qs": "6.4.0", - "safe-buffer": "5.1.1", - "stringstream": "0.0.5", - "tough-cookie": "2.3.3", - "tunnel-agent": "0.6.0", - "uuid": "3.1.0" - } - } - } - }, - "co": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", - "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=" - }, - "code-point-at": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", - "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=" - }, - "colors": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/colors/-/colors-1.0.3.tgz", - "integrity": "sha1-BDP0TYCWgP3rYO0mDxsMJi6CpAs=" - }, - "colour": { - "version": "0.7.1", - "resolved": "https://registry.npmjs.org/colour/-/colour-0.7.1.tgz", - "integrity": "sha1-nLFpkX7F0SwHNtPoaFdG3xyt93g=" - }, - "combined-stream": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.5.tgz", - "integrity": "sha1-k4NwpXtKUd6ix3wV1cX9+JUWQAk=", - "requires": { - "delayed-stream": "1.0.0" - } - }, - "concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" - }, - "content-disposition": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.2.tgz", - "integrity": "sha1-DPaLud318r55YcOoUXjLhdunjLQ=" - }, - "content-type": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", - "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==" - }, - "cookie": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.3.1.tgz", - "integrity": "sha1-5+Ch+e9DtMi6klxcWpboBtFoc7s=" - }, - "cookie-parser": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/cookie-parser/-/cookie-parser-1.4.3.tgz", - "integrity": "sha1-D+MfoZ0AC5X0qt8fU/3CuKIDuqU=", - "requires": { - "cookie": "0.3.1", - "cookie-signature": "1.0.6" - } - }, - "cookie-signature": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", - "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=" - }, - "core-util-is": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", - "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" - }, - "cors": { - "version": "2.8.4", - "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.4.tgz", - "integrity": "sha1-K9OB8usgECAQXNUOpZ2mMJBpRoY=", - "requires": { - "object-assign": "4.1.1", - "vary": "1.1.2" - } - }, - "crc": { - "version": "3.4.4", - "resolved": "https://registry.npmjs.org/crc/-/crc-3.4.4.tgz", - "integrity": "sha1-naHpgOO9RPxck79as9ozeNheRms=" - }, - "cryptiles": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/cryptiles/-/cryptiles-2.0.5.tgz", - "integrity": "sha1-O9/s3GCBR8HGcgL6KR59ylnqo7g=", - "requires": { - "boom": "2.10.1" - } - }, - "cycle": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/cycle/-/cycle-1.0.3.tgz", - "integrity": "sha1-IegLK+hYD5i0aPN5QwZisEbDStI=" - }, - "dashdash": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", - "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", - "requires": { - "assert-plus": "1.0.0" - }, - "dependencies": { - "assert-plus": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=" - } - } - }, - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "requires": { - "ms": "2.0.0" - } - }, - "decamelize": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", - "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=" - }, - "delayed-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=" - }, - "depd": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.1.tgz", - "integrity": "sha1-V4O04cRZ8G+lyif5kfPQbnoxA1k=" - }, - "destroy": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz", - "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=" - }, - "ecc-jsbn": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.1.tgz", - "integrity": "sha1-D8c6ntXw1Tw4GTOYUj735UN3dQU=", - "optional": true, - "requires": { - "jsbn": "0.1.1" - } - }, - "ecdsa-sig-formatter": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.9.tgz", - "integrity": "sha1-S8kmJ07Dtau1AW5+HWCSGsJisqE=", - "requires": { - "base64url": "2.0.0", - "safe-buffer": "5.1.1" - } - }, - "ee-first": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", - "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=" - }, - "elliptic": { - "version": "6.4.0", - "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.4.0.tgz", - "integrity": "sha1-ysmvh2LIWDYYcAPI3+GT5eLq5d8=", - "requires": { - "bn.js": "4.11.8", - "brorand": "1.1.0", - "hash.js": "1.1.3", - "hmac-drbg": "1.0.1", - "inherits": "2.0.3", - "minimalistic-assert": "1.0.0", - "minimalistic-crypto-utils": "1.0.1" - } - }, - "encodeurl": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.1.tgz", - "integrity": "sha1-eePVhlU0aQn+bw9Fpd5oEDspTSA=" - }, - "end-of-stream": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.0.tgz", - "integrity": "sha1-epDYM+/abPpurA9JSduw+tOmMgY=", - "requires": { - "once": "1.4.0" - } - }, - "errs": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/errs/-/errs-0.3.2.tgz", - "integrity": "sha1-eYCZstvTfKK8dJ5TinwTB9C1BJk=" - }, - "escape-html": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", - "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=" - }, - "esprima": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.0.tgz", - "integrity": "sha512-oftTcaMu/EGrEIu904mWteKIv8vMuOgGYo7EhVJJN00R/EED9DCua/xxHRdYnKtcECzVg7xOWhflvJMnqcFZjw==" - }, - "etag": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", - "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=" - }, - "express": { - "version": "4.16.2", - "resolved": "https://registry.npmjs.org/express/-/express-4.16.2.tgz", - "integrity": "sha1-41xt/i1kt9ygpc1PIXgb4ymeB2w=", - "requires": { - "accepts": "1.3.4", - "array-flatten": "1.1.1", - "body-parser": "1.18.2", - "content-disposition": "0.5.2", - "content-type": "1.0.4", - "cookie": "0.3.1", - "cookie-signature": "1.0.6", - "debug": "2.6.9", - "depd": "1.1.1", - "encodeurl": "1.0.1", - "escape-html": "1.0.3", - "etag": "1.8.1", - "finalhandler": "1.1.0", - "fresh": "0.5.2", - "merge-descriptors": "1.0.1", - "methods": "1.1.2", - "on-finished": "2.3.0", - "parseurl": "1.3.2", - "path-to-regexp": "0.1.7", - "proxy-addr": "2.0.2", - "qs": "6.5.1", - "range-parser": "1.2.0", - "safe-buffer": "5.1.1", - "send": "0.16.1", - "serve-static": "1.13.1", - "setprototypeof": "1.1.0", - "statuses": "1.3.1", - "type-is": "1.6.15", - "utils-merge": "1.0.1", - "vary": "1.1.2" - }, - "dependencies": { - "setprototypeof": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz", - "integrity": "sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==" - } - } - }, - "express-bearer-token": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/express-bearer-token/-/express-bearer-token-2.1.0.tgz", - "integrity": "sha1-1cgjxNGA+dKwh5j87T3enMnEkG4=" - }, - "express-jwt": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/express-jwt/-/express-jwt-5.3.0.tgz", - "integrity": "sha1-PZDNZYAuYzYlLxnmo98+FJ4MXqA=", - "requires": { - "async": "1.5.2", - "express-unless": "0.3.1", - "jsonwebtoken": "7.4.3", - "lodash.set": "4.3.2" - } - }, - "express-session": { - "version": "1.15.6", - "resolved": "https://registry.npmjs.org/express-session/-/express-session-1.15.6.tgz", - "integrity": "sha512-r0nrHTCYtAMrFwZ0kBzZEXa1vtPVrw0dKvGSrKP4dahwBQ1BJpF2/y1Pp4sCD/0kvxV4zZeclyvfmw0B4RMJQA==", - "requires": { - "cookie": "0.3.1", - "cookie-signature": "1.0.6", - "crc": "3.4.4", - "debug": "2.6.9", - "depd": "1.1.1", - "on-headers": "1.0.1", - "parseurl": "1.3.2", - "uid-safe": "2.1.5", - "utils-merge": "1.0.1" - } - }, - "express-unless": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/express-unless/-/express-unless-0.3.1.tgz", - "integrity": "sha1-JVfBRudb65A+LSR/m1ugFFJpbiA=" - }, - "extend": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.1.tgz", - "integrity": "sha1-p1Xqe8Gt/MWjHOfnYtuq3F5jZEQ=" - }, - "extsprintf": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", - "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=" - }, - "eyes": { - "version": "0.1.8", - "resolved": "https://registry.npmjs.org/eyes/-/eyes-0.1.8.tgz", - "integrity": "sha1-Ys8SAjTGg3hdkCNIqADvPgzCC8A=" - }, - "fabric-ca-client": { - "version": "1.1.0-snapshot.39", - "resolved": "https://registry.npmjs.org/fabric-ca-client/-/fabric-ca-client-1.1.0-snapshot.39.tgz", - "integrity": "sha512-6aG5Y2+ZcVOxEyTdY/AJpJ/hJbJT6NL9mQh8NfigfAy9ywZjWJfr5B5EAYT0eD0YBbu8b5JspytbPVMm4qPxwA==", - "requires": { - "bn.js": "4.11.8", - "elliptic": "6.4.0", - "fs-extra": "0.30.0", - "js-sha3": "0.5.7", - "jsrsasign": "6.2.2", - "jssha": "2.3.1", - "nconf": "0.8.5", - "sjcl": "1.0.7", - "sjcl-codec": "0.1.1", - "url": "0.11.0", - "util": "0.10.3", - "winston": "2.4.0" - }, - "dependencies": { - "fs-extra": { - "version": "0.30.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-0.30.0.tgz", - "integrity": "sha1-8jP/zAjU2n1DLapEl3aYnbHfk/A=", - "requires": { - "graceful-fs": "4.1.11", - "jsonfile": "2.4.0", - "klaw": "1.3.1", - "path-is-absolute": "1.0.1", - "rimraf": "2.6.2" - } - }, - "sjcl": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/sjcl/-/sjcl-1.0.7.tgz", - "integrity": "sha1-MrNlpQ3Ju6JriLo8nfjqNCF9n0U=" - } - } - }, - "fabric-client": { - "version": "1.1.0-snapshot.39", - "resolved": "https://registry.npmjs.org/fabric-client/-/fabric-client-1.1.0-snapshot.39.tgz", - "integrity": "sha512-NKgtVdDI8GuWseUXJVMb528+31bueb0aPKeXps1eyEkZu/bX0JmkSw5/YypWoMPeMlk2x6iiFl5WhTWd2ThXHA==", - "requires": { - "bn.js": "4.11.8", - "callsite": "1.0.0", - "elliptic": "6.4.0", - "fs": "0.0.2", - "fs-extra": "0.30.0", - "grpc": "1.6.6", - "ignore-walk": "3.0.1", - "js-sha3": "0.5.7", - "js-yaml": "3.10.0", - "jsrsasign": "6.2.2", - "jssha": "2.3.1", - "long": "3.2.0", - "nano": "6.4.2", - "nconf": "0.8.5", - "path": "0.12.7", - "pkcs11js": "1.0.10", - "promise-settle": "0.3.0", - "sjcl": "1.0.7", - "sjcl-codec": "0.1.1", - "stream-buffers": "3.0.1", - "tar-stream": "1.5.2", - "url": "0.11.0", - "util": "0.10.3", - "winston": "2.4.0" - }, - "dependencies": { - "fs-extra": { - "version": "0.30.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-0.30.0.tgz", - "integrity": "sha1-8jP/zAjU2n1DLapEl3aYnbHfk/A=", - "requires": { - "graceful-fs": "4.1.11", - "jsonfile": "2.4.0", - "klaw": "1.3.1", - "path-is-absolute": "1.0.1", - "rimraf": "2.6.2" - } - }, - "sjcl": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/sjcl/-/sjcl-1.0.7.tgz", - "integrity": "sha1-MrNlpQ3Ju6JriLo8nfjqNCF9n0U=" - } - } - }, - "fast-deep-equal": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-1.0.0.tgz", - "integrity": "sha1-liVqO8l1WV6zbYLpkp0GDYk0Of8=" - }, - "fast-json-stable-stringify": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz", - "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I=" - }, - "finalhandler": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.0.tgz", - "integrity": "sha1-zgtoVbRYU+eRsvzGgARtiCU91/U=", - "requires": { - "debug": "2.6.9", - "encodeurl": "1.0.1", - "escape-html": "1.0.3", - "on-finished": "2.3.0", - "parseurl": "1.3.2", - "statuses": "1.3.1", - "unpipe": "1.0.0" - } - }, - "forever-agent": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", - "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=" - }, - "form-data": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.1.4.tgz", - "integrity": "sha1-M8GDrPGTJ27KqYFDpp6Uv+4XUNE=", - "requires": { - "asynckit": "0.4.0", - "combined-stream": "1.0.5", - "mime-types": "2.1.17" - } - }, - "forwarded": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.2.tgz", - "integrity": "sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ=" - }, - "fresh": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", - "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=" - }, - "fs": { - "version": "0.0.2", - "resolved": "https://registry.npmjs.org/fs/-/fs-0.0.2.tgz", - "integrity": "sha1-4fJE7zkzwbKmS9R5kTYGDQ9ZFPg=" - }, - "fs-extra": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-2.1.2.tgz", - "integrity": "sha1-BGxwFjzvmq1GsOSn+kZ/si1x3jU=", - "requires": { - "graceful-fs": "4.1.11", - "jsonfile": "2.4.0" - } - }, - "fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" - }, - "getpass": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", - "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", - "requires": { - "assert-plus": "1.0.0" - }, - "dependencies": { - "assert-plus": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=" - } - } - }, - "glob": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", - "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", - "requires": { - "fs.realpath": "1.0.0", - "inflight": "1.0.6", - "inherits": "2.0.3", - "minimatch": "3.0.4", - "once": "1.4.0", - "path-is-absolute": "1.0.1" - } - }, - "graceful-fs": { - "version": "4.1.11", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz", - "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=" - }, - "grpc": { - "version": "1.6.6", - "resolved": "https://registry.npmjs.org/grpc/-/grpc-1.6.6.tgz", - "integrity": "sha1-IFF4T2vWE0aB+ixLXnXcgsbCP/o=", - "requires": { - "arguejs": "0.2.3", - "lodash": "4.17.4", - "nan": "2.7.0", - "node-pre-gyp": "0.6.38", - "protobufjs": "5.0.2" - }, - "dependencies": { - "abbrev": { - "version": "1.1.1", - "bundled": true - }, - "ajv": { - "version": "4.11.8", - "bundled": true, - "requires": { - "co": "4.6.0", - "json-stable-stringify": "1.0.1" - } - }, - "ansi-regex": { - "version": "2.1.1", - "bundled": true - }, - "aproba": { - "version": "1.2.0", - "bundled": true - }, - "are-we-there-yet": { - "version": "1.1.4", - "bundled": true, - "requires": { - "delegates": "1.0.0", - "readable-stream": "2.3.3" - } - }, - "asn1": { - "version": "0.2.3", - "bundled": true - }, - "assert-plus": { - "version": "0.2.0", - "bundled": true - }, - "asynckit": { - "version": "0.4.0", - "bundled": true - }, - "aws-sign2": { - "version": "0.6.0", - "bundled": true - }, - "aws4": { - "version": "1.6.0", - "bundled": true - }, - "balanced-match": { - "version": "1.0.0", - "bundled": true - }, - "bcrypt-pbkdf": { - "version": "1.0.1", - "bundled": true, - "optional": true, - "requires": { - "tweetnacl": "0.14.5" - } - }, - "block-stream": { - "version": "0.0.9", - "bundled": true, - "requires": { - "inherits": "2.0.3" - } - }, - "boom": { - "version": "2.10.1", - "bundled": true, - "requires": { - "hoek": "2.16.3" - } - }, - "brace-expansion": { - "version": "1.1.8", - "bundled": true, - "requires": { - "balanced-match": "1.0.0", - "concat-map": "0.0.1" - } - }, - "caseless": { - "version": "0.12.0", - "bundled": true - }, - "co": { - "version": "4.6.0", - "bundled": true - }, - "code-point-at": { - "version": "1.1.0", - "bundled": true - }, - "combined-stream": { - "version": "1.0.5", - "bundled": true, - "requires": { - "delayed-stream": "1.0.0" - } - }, - "concat-map": { - "version": "0.0.1", - "bundled": true - }, - "console-control-strings": { - "version": "1.1.0", - "bundled": true - }, - "core-util-is": { - "version": "1.0.2", - "bundled": true - }, - "cryptiles": { - "version": "2.0.5", - "bundled": true, - "requires": { - "boom": "2.10.1" - } - }, - "dashdash": { - "version": "1.14.1", - "bundled": true, - "requires": { - "assert-plus": "1.0.0" - }, - "dependencies": { - "assert-plus": { - "version": "1.0.0", - "bundled": true - } - } - }, - "debug": { - "version": "2.6.9", - "bundled": true, - "requires": { - "ms": "2.0.0" - } - }, - "deep-extend": { - "version": "0.4.2", - "bundled": true - }, - "delayed-stream": { - "version": "1.0.0", - "bundled": true - }, - "delegates": { - "version": "1.0.0", - "bundled": true - }, - "ecc-jsbn": { - "version": "0.1.1", - "bundled": true, - "optional": true, - "requires": { - "jsbn": "0.1.1" - } - }, - "extend": { - "version": "3.0.1", - "bundled": true - }, - "extsprintf": { - "version": "1.3.0", - "bundled": true - }, - "forever-agent": { - "version": "0.6.1", - "bundled": true - }, - "form-data": { - "version": "2.1.4", - "bundled": true, - "requires": { - "asynckit": "0.4.0", - "combined-stream": "1.0.5", - "mime-types": "2.1.17" - } - }, - "fs.realpath": { - "version": "1.0.0", - "bundled": true - }, - "fstream": { - "version": "1.0.11", - "bundled": true, - "requires": { - "graceful-fs": "4.1.11", - "inherits": "2.0.3", - "mkdirp": "0.5.1", - "rimraf": "2.6.2" - } - }, - "fstream-ignore": { - "version": "1.0.5", - "bundled": true, - "requires": { - "fstream": "1.0.11", - "inherits": "2.0.3", - "minimatch": "3.0.4" - } - }, - "gauge": { - "version": "2.7.4", - "bundled": true, - "requires": { - "aproba": "1.2.0", - "console-control-strings": "1.1.0", - "has-unicode": "2.0.1", - "object-assign": "4.1.1", - "signal-exit": "3.0.2", - "string-width": "1.0.2", - "strip-ansi": "3.0.1", - "wide-align": "1.1.2" - } - }, - "getpass": { - "version": "0.1.7", - "bundled": true, - "requires": { - "assert-plus": "1.0.0" - }, - "dependencies": { - "assert-plus": { - "version": "1.0.0", - "bundled": true - } - } - }, - "glob": { - "version": "7.1.2", - "bundled": true, - "requires": { - "fs.realpath": "1.0.0", - "inflight": "1.0.6", - "inherits": "2.0.3", - "minimatch": "3.0.4", - "once": "1.4.0", - "path-is-absolute": "1.0.1" - } - }, - "graceful-fs": { - "version": "4.1.11", - "bundled": true - }, - "har-schema": { - "version": "1.0.5", - "bundled": true - }, - "har-validator": { - "version": "4.2.1", - "bundled": true, - "requires": { - "ajv": "4.11.8", - "har-schema": "1.0.5" - } - }, - "has-unicode": { - "version": "2.0.1", - "bundled": true - }, - "hawk": { - "version": "3.1.3", - "bundled": true, - "requires": { - "boom": "2.10.1", - "cryptiles": "2.0.5", - "hoek": "2.16.3", - "sntp": "1.0.9" - } - }, - "hoek": { - "version": "2.16.3", - "bundled": true - }, - "http-signature": { - "version": "1.1.1", - "bundled": true, - "requires": { - "assert-plus": "0.2.0", - "jsprim": "1.4.1", - "sshpk": "1.13.1" - } - }, - "inflight": { - "version": "1.0.6", - "bundled": true, - "requires": { - "once": "1.4.0", - "wrappy": "1.0.2" - } - }, - "inherits": { - "version": "2.0.3", - "bundled": true - }, - "ini": { - "version": "1.3.4", - "bundled": true - }, - "is-fullwidth-code-point": { - "version": "1.0.0", - "bundled": true, - "requires": { - "number-is-nan": "1.0.1" - } - }, - "is-typedarray": { - "version": "1.0.0", - "bundled": true - }, - "isarray": { - "version": "1.0.0", - "bundled": true - }, - "isstream": { - "version": "0.1.2", - "bundled": true - }, - "jsbn": { - "version": "0.1.1", - "bundled": true, - "optional": true - }, - "json-schema": { - "version": "0.2.3", - "bundled": true - }, - "json-stable-stringify": { - "version": "1.0.1", - "bundled": true, - "requires": { - "jsonify": "0.0.0" - } - }, - "json-stringify-safe": { - "version": "5.0.1", - "bundled": true - }, - "jsonify": { - "version": "0.0.0", - "bundled": true - }, - "jsprim": { - "version": "1.4.1", - "bundled": true, - "requires": { - "assert-plus": "1.0.0", - "extsprintf": "1.3.0", - "json-schema": "0.2.3", - "verror": "1.10.0" - }, - "dependencies": { - "assert-plus": { - "version": "1.0.0", - "bundled": true - } - } - }, - "mime-db": { - "version": "1.30.0", - "bundled": true - }, - "mime-types": { - "version": "2.1.17", - "bundled": true, - "requires": { - "mime-db": "1.30.0" - } - }, - "minimatch": { - "version": "3.0.4", - "bundled": true, - "requires": { - "brace-expansion": "1.1.8" - } - }, - "minimist": { - "version": "1.2.0", - "bundled": true - }, - "mkdirp": { - "version": "0.5.1", - "bundled": true, - "requires": { - "minimist": "0.0.8" - }, - "dependencies": { - "minimist": { - "version": "0.0.8", - "bundled": true - } - } - }, - "ms": { - "version": "2.0.0", - "bundled": true - }, - "node-pre-gyp": { - "version": "0.6.38", - "bundled": true, - "requires": { - "hawk": "3.1.3", - "mkdirp": "0.5.1", - "nopt": "4.0.1", - "npmlog": "4.1.2", - "rc": "1.2.1", - "request": "2.81.0", - "rimraf": "2.6.2", - "semver": "5.4.1", - "tar": "2.2.1", - "tar-pack": "3.4.0" - } - }, - "nopt": { - "version": "4.0.1", - "bundled": true, - "requires": { - "abbrev": "1.1.1", - "osenv": "0.1.4" - } - }, - "npmlog": { - "version": "4.1.2", - "bundled": true, - "requires": { - "are-we-there-yet": "1.1.4", - "console-control-strings": "1.1.0", - "gauge": "2.7.4", - "set-blocking": "2.0.0" - } - }, - "number-is-nan": { - "version": "1.0.1", - "bundled": true - }, - "oauth-sign": { - "version": "0.8.2", - "bundled": true - }, - "object-assign": { - "version": "4.1.1", - "bundled": true - }, - "once": { - "version": "1.4.0", - "bundled": true, - "requires": { - "wrappy": "1.0.2" - } - }, - "os-homedir": { - "version": "1.0.2", - "bundled": true - }, - "os-tmpdir": { - "version": "1.0.2", - "bundled": true - }, - "osenv": { - "version": "0.1.4", - "bundled": true, - "requires": { - "os-homedir": "1.0.2", - "os-tmpdir": "1.0.2" - } - }, - "path-is-absolute": { - "version": "1.0.1", - "bundled": true - }, - "performance-now": { - "version": "0.2.0", - "bundled": true - }, - "process-nextick-args": { - "version": "1.0.7", - "bundled": true - }, - "punycode": { - "version": "1.4.1", - "bundled": true - }, - "qs": { - "version": "6.4.0", - "bundled": true - }, - "rc": { - "version": "1.2.1", - "bundled": true, - "requires": { - "deep-extend": "0.4.2", - "ini": "1.3.4", - "minimist": "1.2.0", - "strip-json-comments": "2.0.1" - } - }, - "readable-stream": { - "version": "2.3.3", - "bundled": true, - "requires": { - "core-util-is": "1.0.2", - "inherits": "2.0.3", - "isarray": "1.0.0", - "process-nextick-args": "1.0.7", - "safe-buffer": "5.1.1", - "string_decoder": "1.0.3", - "util-deprecate": "1.0.2" - } - }, - "request": { - "version": "2.81.0", - "bundled": true, - "requires": { - "aws-sign2": "0.6.0", - "aws4": "1.6.0", - "caseless": "0.12.0", - "combined-stream": "1.0.5", - "extend": "3.0.1", - "forever-agent": "0.6.1", - "form-data": "2.1.4", - "har-validator": "4.2.1", - "hawk": "3.1.3", - "http-signature": "1.1.1", - "is-typedarray": "1.0.0", - "isstream": "0.1.2", - "json-stringify-safe": "5.0.1", - "mime-types": "2.1.17", - "oauth-sign": "0.8.2", - "performance-now": "0.2.0", - "qs": "6.4.0", - "safe-buffer": "5.1.1", - "stringstream": "0.0.5", - "tough-cookie": "2.3.3", - "tunnel-agent": "0.6.0", - "uuid": "3.1.0" - } - }, - "rimraf": { - "version": "2.6.2", - "bundled": true, - "requires": { - "glob": "7.1.2" - } - }, - "safe-buffer": { - "version": "5.1.1", - "bundled": true - }, - "semver": { - "version": "5.4.1", - "bundled": true - }, - "set-blocking": { - "version": "2.0.0", - "bundled": true - }, - "signal-exit": { - "version": "3.0.2", - "bundled": true - }, - "sntp": { - "version": "1.0.9", - "bundled": true, - "requires": { - "hoek": "2.16.3" - } - }, - "sshpk": { - "version": "1.13.1", - "bundled": true, - "requires": { - "asn1": "0.2.3", - "assert-plus": "1.0.0", - "bcrypt-pbkdf": "1.0.1", - "dashdash": "1.14.1", - "ecc-jsbn": "0.1.1", - "getpass": "0.1.7", - "jsbn": "0.1.1", - "tweetnacl": "0.14.5" - }, - "dependencies": { - "assert-plus": { - "version": "1.0.0", - "bundled": true - } - } - }, - "string-width": { - "version": "1.0.2", - "bundled": true, - "requires": { - "code-point-at": "1.1.0", - "is-fullwidth-code-point": "1.0.0", - "strip-ansi": "3.0.1" - } - }, - "string_decoder": { - "version": "1.0.3", - "bundled": true, - "requires": { - "safe-buffer": "5.1.1" - } - }, - "stringstream": { - "version": "0.0.5", - "bundled": true - }, - "strip-ansi": { - "version": "3.0.1", - "bundled": true, - "requires": { - "ansi-regex": "2.1.1" - } - }, - "strip-json-comments": { - "version": "2.0.1", - "bundled": true - }, - "tar": { - "version": "2.2.1", - "bundled": true, - "requires": { - "block-stream": "0.0.9", - "fstream": "1.0.11", - "inherits": "2.0.3" - } - }, - "tar-pack": { - "version": "3.4.0", - "bundled": true, - "requires": { - "debug": "2.6.9", - "fstream": "1.0.11", - "fstream-ignore": "1.0.5", - "once": "1.4.0", - "readable-stream": "2.3.3", - "rimraf": "2.6.2", - "tar": "2.2.1", - "uid-number": "0.0.6" - } - }, - "tough-cookie": { - "version": "2.3.3", - "bundled": true, - "requires": { - "punycode": "1.4.1" - } - }, - "tunnel-agent": { - "version": "0.6.0", - "bundled": true, - "requires": { - "safe-buffer": "5.1.1" - } - }, - "tweetnacl": { - "version": "0.14.5", - "bundled": true, - "optional": true - }, - "uid-number": { - "version": "0.0.6", - "bundled": true - }, - "util-deprecate": { - "version": "1.0.2", - "bundled": true - }, - "uuid": { - "version": "3.1.0", - "bundled": true - }, - "verror": { - "version": "1.10.0", - "bundled": true, - "requires": { - "assert-plus": "1.0.0", - "core-util-is": "1.0.2", - "extsprintf": "1.3.0" - }, - "dependencies": { - "assert-plus": { - "version": "1.0.0", - "bundled": true - } - } - }, - "wide-align": { - "version": "1.1.2", - "bundled": true, - "requires": { - "string-width": "1.0.2" - } - }, - "wrappy": { - "version": "1.0.2", - "bundled": true - } - } - }, - "har-schema": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-1.0.5.tgz", - "integrity": "sha1-0mMTX0MwfALGAq/I/pWXDAFRNp4=" - }, - "har-validator": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-4.2.1.tgz", - "integrity": "sha1-M0gdDxu/9gDdID11gSpqX7oALio=", - "requires": { - "ajv": "4.11.8", - "har-schema": "1.0.5" - } - }, - "hash.js": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.3.tgz", - "integrity": "sha512-/UETyP0W22QILqS+6HowevwhEFJ3MBJnwTf75Qob9Wz9t0DPuisL8kW8YZMK62dHAKE1c1p+gY1TtOLY+USEHA==", - "requires": { - "inherits": "2.0.3", - "minimalistic-assert": "1.0.0" - } - }, - "hawk": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/hawk/-/hawk-3.1.3.tgz", - "integrity": "sha1-B4REvXwWQLD+VA0sm3PVlnjo4cQ=", - "requires": { - "boom": "2.10.1", - "cryptiles": "2.0.5", - "hoek": "2.16.3", - "sntp": "1.0.9" - } - }, - "hmac-drbg": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", - "integrity": "sha1-0nRXAQJabHdabFRXk+1QL8DGSaE=", - "requires": { - "hash.js": "1.1.3", - "minimalistic-assert": "1.0.0", - "minimalistic-crypto-utils": "1.0.1" - } - }, - "hoek": { - "version": "2.16.3", - "resolved": "https://registry.npmjs.org/hoek/-/hoek-2.16.3.tgz", - "integrity": "sha1-ILt0A9POo5jpHcRxCo/xuCdKJe0=" - }, - "http-errors": { - "version": "1.6.2", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.2.tgz", - "integrity": "sha1-CgAsyFcHGSp+eUbO7cERVfYOxzY=", - "requires": { - "depd": "1.1.1", - "inherits": "2.0.3", - "setprototypeof": "1.0.3", - "statuses": "1.3.1" - } - }, - "http-signature": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.1.1.tgz", - "integrity": "sha1-33LiZwZs0Kxn+3at+OE0qPvPkb8=", - "requires": { - "assert-plus": "0.2.0", - "jsprim": "1.4.1", - "sshpk": "1.13.1" - } - }, - "iconv-lite": { - "version": "0.4.19", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.19.tgz", - "integrity": "sha512-oTZqweIP51xaGPI4uPa56/Pri/480R+mo7SeU+YETByQNhDG55ycFyNLIgta9vXhILrxXDmF7ZGhqZIcuN0gJQ==" - }, - "ignore-walk": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/ignore-walk/-/ignore-walk-3.0.1.tgz", - "integrity": "sha512-DTVlMx3IYPe0/JJcYP7Gxg7ttZZu3IInhuEhbchuqneY9wWe5Ojy2mXLBaQFUQmo0AW2r3qG7m1mg86js+gnlQ==", - "requires": { - "minimatch": "3.0.4" - } - }, - "inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", - "requires": { - "once": "1.4.0", - "wrappy": "1.0.2" - } - }, - "inherits": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" - }, - "ini": { - "version": "1.3.4", - "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.4.tgz", - "integrity": "sha1-BTfLedr1m1mhpRff9wbIbsA5Fi4=" - }, - "invert-kv": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-1.0.0.tgz", - "integrity": "sha1-EEqOSqym09jNFXqO+L+rLXo//bY=" - }, - "ipaddr.js": { - "version": "1.5.2", - "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.5.2.tgz", - "integrity": "sha1-1LUFvemUaYfM8PxY2QEP+WB+P6A=" - }, - "is-fullwidth-code-point": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", - "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", - "requires": { - "number-is-nan": "1.0.1" - } - }, - "is-typedarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", - "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=" - }, - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" - }, - "isemail": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/isemail/-/isemail-1.2.0.tgz", - "integrity": "sha1-vgPfjMPineTSxd9lASY/H6RZXpo=" - }, - "isstream": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", - "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=" - }, - "joi": { - "version": "6.10.1", - "resolved": "https://registry.npmjs.org/joi/-/joi-6.10.1.tgz", - "integrity": "sha1-TVDDGAeRIgAP5fFq8f+OGRe3fgY=", - "requires": { - "hoek": "2.16.3", - "isemail": "1.2.0", - "moment": "2.19.1", - "topo": "1.1.0" - } - }, - "js-sha3": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.5.7.tgz", - "integrity": "sha1-DU/9gALVMzqrr0oj7tL2N0yfKOc=" - }, - "js-yaml": { - "version": "3.10.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.10.0.tgz", - "integrity": "sha512-O2v52ffjLa9VeM43J4XocZE//WT9N0IiwDa3KSHH7Tu8CtH+1qM8SIZvnsTh6v+4yFy5KUY3BHUVwjpfAWsjIA==", - "requires": { - "argparse": "1.0.9", - "esprima": "4.0.0" - } - }, - "jsbn": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", - "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=", - "optional": true - }, - "json-schema": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", - "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=" - }, - "json-schema-traverse": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.3.1.tgz", - "integrity": "sha1-NJptRMU6Ud6JtAgFxdXlm0F9M0A=" - }, - "json-stable-stringify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json-stable-stringify/-/json-stable-stringify-1.0.1.tgz", - "integrity": "sha1-mnWdOcXy/1A/1TAGRu1EX4jE+a8=", - "requires": { - "jsonify": "0.0.0" - } - }, - "json-stringify-safe": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", - "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=" - }, - "jsonfile": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-2.4.0.tgz", - "integrity": "sha1-NzaitCi4e72gzIO1P6PWM6NcKug=", - "requires": { - "graceful-fs": "4.1.11" - } - }, - "jsonify": { - "version": "0.0.0", - "resolved": "https://registry.npmjs.org/jsonify/-/jsonify-0.0.0.tgz", - "integrity": "sha1-LHS27kHZPKUbe1qu6PUDYx0lKnM=" - }, - "jsonwebtoken": { - "version": "7.4.3", - "resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-7.4.3.tgz", - "integrity": "sha1-d/UCHeBYtgWheD+hKD6ZgS5kVjg=", - "requires": { - "joi": "6.10.1", - "jws": "3.1.4", - "lodash.once": "4.1.1", - "ms": "2.0.0", - "xtend": "4.0.1" - } - }, - "jsprim": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", - "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=", - "requires": { - "assert-plus": "1.0.0", - "extsprintf": "1.3.0", - "json-schema": "0.2.3", - "verror": "1.10.0" - }, - "dependencies": { - "assert-plus": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=" - } - } - }, - "jsrsasign": { - "version": "6.2.2", - "resolved": "https://registry.npmjs.org/jsrsasign/-/jsrsasign-6.2.2.tgz", - "integrity": "sha1-hKD4W6Sqx6ecNYutsm7ZmRMXLbw=" - }, - "jssha": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/jssha/-/jssha-2.3.1.tgz", - "integrity": "sha1-FHshJTaQNcpLL30hDcU58Amz3po=" - }, - "jwa": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/jwa/-/jwa-1.1.5.tgz", - "integrity": "sha1-oFUs4CIHQs1S4VN3SjKQXDDnVuU=", - "requires": { - "base64url": "2.0.0", - "buffer-equal-constant-time": "1.0.1", - "ecdsa-sig-formatter": "1.0.9", - "safe-buffer": "5.1.1" - } - }, - "jws": { - "version": "3.1.4", - "resolved": "https://registry.npmjs.org/jws/-/jws-3.1.4.tgz", - "integrity": "sha1-+ei5M46KhHJ31kRLFGT2GIDgUKI=", - "requires": { - "base64url": "2.0.0", - "jwa": "1.1.5", - "safe-buffer": "5.1.1" - } - }, - "klaw": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/klaw/-/klaw-1.3.1.tgz", - "integrity": "sha1-QIhDO0azsbolnXh4XY6W9zugJDk=", - "requires": { - "graceful-fs": "4.1.11" - } - }, - "lcid": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/lcid/-/lcid-1.0.0.tgz", - "integrity": "sha1-MIrMr6C8SDo4Z7S28rlQYlHRuDU=", - "requires": { - "invert-kv": "1.0.0" - } - }, - "lodash": { - "version": "4.17.4", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.4.tgz", - "integrity": "sha1-eCA6TRwyiuHYbcpkYONptX9AVa4=" - }, - "lodash.once": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz", - "integrity": "sha1-DdOXEhPHxW34gJd9UEyI+0cal6w=" - }, - "lodash.set": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/lodash.set/-/lodash.set-4.3.2.tgz", - "integrity": "sha1-2HV7HagH3eJIFrDWqEvqGnYjCyM=" - }, - "log4js": { - "version": "0.6.38", - "resolved": "https://registry.npmjs.org/log4js/-/log4js-0.6.38.tgz", - "integrity": "sha1-LElBFmldb7JUgJQ9P8hy5mKlIv0=", - "requires": { - "readable-stream": "1.0.34", - "semver": "4.3.6" - }, - "dependencies": { - "isarray": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", - "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=" - }, - "readable-stream": { - "version": "1.0.34", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", - "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=", - "requires": { - "core-util-is": "1.0.2", - "inherits": "2.0.3", - "isarray": "0.0.1", - "string_decoder": "0.10.31" - } - }, - "string_decoder": { - "version": "0.10.31", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", - "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=" - } - } - }, - "long": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/long/-/long-3.2.0.tgz", - "integrity": "sha1-2CG3E4yhy1gcFymQ7xTbIAtcR0s=" - }, - "media-typer": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", - "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=" - }, - "merge-descriptors": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", - "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=" - }, - "methods": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", - "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=" - }, - "mime": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/mime/-/mime-1.4.1.tgz", - "integrity": "sha512-KI1+qOZu5DcW6wayYHSzR/tXKCDC5Om4s1z2QJjDULzLcmf3DvzS7oluY4HCTrc+9FiKmWUgeNLg7W3uIQvxtQ==" - }, - "mime-db": { - "version": "1.30.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.30.0.tgz", - "integrity": "sha1-dMZD2i3Z1qRTmZY0ZbJtXKfXHwE=" - }, - "mime-types": { - "version": "2.1.17", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.17.tgz", - "integrity": "sha1-Cdejk/A+mVp5+K+Fe3Cp4KsWVXo=", - "requires": { - "mime-db": "1.30.0" - } - }, - "minimalistic-assert": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.0.tgz", - "integrity": "sha1-cCvi3aazf0g2vLP121ZkG2Sh09M=" - }, - "minimalistic-crypto-utils": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", - "integrity": "sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo=" - }, - "minimatch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", - "requires": { - "brace-expansion": "1.1.8" - } - }, - "moment": { - "version": "2.19.1", - "resolved": "https://registry.npmjs.org/moment/-/moment-2.19.1.tgz", - "integrity": "sha1-VtoaLRy/AdOLfhr8McELz6GSkWc=" - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" - }, - "nan": { - "version": "2.7.0", - "resolved": "https://registry.npmjs.org/nan/-/nan-2.7.0.tgz", - "integrity": "sha1-2Vv3IeyHfgjbJ27T/G63j5CDrUY=" - }, - "nano": { - "version": "6.4.2", - "resolved": "https://registry.npmjs.org/nano/-/nano-6.4.2.tgz", - "integrity": "sha1-ubD6geuRS4ucY0odVeh44PRbCb8=", - "requires": { - "cloudant-follow": "0.13.0", - "debug": "2.6.9", - "errs": "0.3.2", - "request": "2.83.0", - "underscore": "1.8.3" - } - }, - "nconf": { - "version": "0.8.5", - "resolved": "https://registry.npmjs.org/nconf/-/nconf-0.8.5.tgz", - "integrity": "sha1-8pQeFWGVL6kGu7MjKM+I1MY155Q=", - "requires": { - "async": "1.5.2", - "ini": "1.3.4", - "secure-keys": "1.0.0", - "yargs": "3.32.0" - } - }, - "negotiator": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.1.tgz", - "integrity": "sha1-KzJxhOiZIQEXeyhWP7XnECrNDKk=" - }, - "number-is-nan": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", - "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=" - }, - "oauth-sign": { - "version": "0.8.2", - "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.8.2.tgz", - "integrity": "sha1-Rqarfwrq2N6unsBWV4C31O/rnUM=" - }, - "object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=" - }, - "on-finished": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", - "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=", - "requires": { - "ee-first": "1.1.1" - } - }, - "on-headers": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.1.tgz", - "integrity": "sha1-ko9dD0cNSTQmUepnlLCFfBAGk/c=" - }, - "once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", - "requires": { - "wrappy": "1.0.2" - } - }, - "optjs": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/optjs/-/optjs-3.2.2.tgz", - "integrity": "sha1-aabOicRCpEQDFBrS+bNwvVu29O4=" - }, - "os-locale": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-1.4.0.tgz", - "integrity": "sha1-IPnxeuKe00XoveWDsT0gCYA8FNk=", - "requires": { - "lcid": "1.0.0" - } - }, - "parseurl": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.2.tgz", - "integrity": "sha1-/CidTtiZMRlGDBViUyYs3I3mW/M=" - }, - "path": { - "version": "0.12.7", - "resolved": "https://registry.npmjs.org/path/-/path-0.12.7.tgz", - "integrity": "sha1-1NwqUGxM4hl+tIHr/NWzbAFAsQ8=", - "requires": { - "process": "0.11.10", - "util": "0.10.3" - } - }, - "path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=" - }, - "path-to-regexp": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", - "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=" - }, - "performance-now": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-0.2.0.tgz", - "integrity": "sha1-M+8wxcd9TqIcWlOGnZG1bY8lVeU=" - }, - "pkcs11js": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/pkcs11js/-/pkcs11js-1.0.10.tgz", - "integrity": "sha512-RZQ0MkksFoTTik+hH4JvnICLnVcMA+pjtwt81p3u9yBAtEIIBIUNaJNn0au+jo//wu/BHvVfTXs8XRQloSG79w==", - "requires": { - "nan": "2.7.0" - } - }, - "process": { - "version": "0.11.10", - "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", - "integrity": "sha1-czIwDoQBYb2j5podHZGn1LwW8YI=" - }, - "process-nextick-args": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz", - "integrity": "sha1-FQ4gt1ZZCtP5EJPyWk8q2L/zC6M=" - }, - "promise-settle": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/promise-settle/-/promise-settle-0.3.0.tgz", - "integrity": "sha1-tO/VcqHrdM95T4KM00naQKCOTpY=" - }, - "protobufjs": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-5.0.2.tgz", - "integrity": "sha1-WXSNfc8D0tsiwT2p/rAk4Wq4DJE=", - "requires": { - "ascli": "1.0.1", - "bytebuffer": "5.0.1", - "glob": "7.1.2", - "yargs": "3.32.0" - } - }, - "proxy-addr": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.2.tgz", - "integrity": "sha1-ZXFQT0e7mI7IGAJT+F3X4UlSvew=", - "requires": { - "forwarded": "0.1.2", - "ipaddr.js": "1.5.2" - } - }, - "punycode": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", - "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=" - }, - "qs": { - "version": "6.5.1", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.1.tgz", - "integrity": "sha512-eRzhrN1WSINYCDCbrz796z37LOe3m5tmW7RQf6oBntukAG1nmovJvhnwHHRMAfeoItc1m2Hk02WER2aQ/iqs+A==" - }, - "querystring": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz", - "integrity": "sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA=" - }, - "random-bytes": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/random-bytes/-/random-bytes-1.0.0.tgz", - "integrity": "sha1-T2ih3Arli9P7lYSMMDJNt11kNgs=" - }, - "range-parser": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.0.tgz", - "integrity": "sha1-9JvmtIeJTdxA3MlKMi9hEJLgDV4=" - }, - "raw-body": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.3.2.tgz", - "integrity": "sha1-vNYMd9Prk83gBQKVw/N5OJvIj4k=", - "requires": { - "bytes": "3.0.0", - "http-errors": "1.6.2", - "iconv-lite": "0.4.19", - "unpipe": "1.0.0" - } - }, - "readable-stream": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.3.tgz", - "integrity": "sha512-m+qzzcn7KUxEmd1gMbchF+Y2eIUbieUaxkWtptyHywrX0rE8QEYqPC07Vuy4Wm32/xE16NcdBctb8S0Xe/5IeQ==", - "requires": { - "core-util-is": "1.0.2", - "inherits": "2.0.3", - "isarray": "1.0.0", - "process-nextick-args": "1.0.7", - "safe-buffer": "5.1.1", - "string_decoder": "1.0.3", - "util-deprecate": "1.0.2" - } - }, - "request": { - "version": "2.83.0", - "resolved": "https://registry.npmjs.org/request/-/request-2.83.0.tgz", - "integrity": "sha512-lR3gD69osqm6EYLk9wB/G1W/laGWjzH90t1vEa2xuxHD5KUrSzp9pUSfTm+YC5Nxt2T8nMPEvKlhbQayU7bgFw==", - "requires": { - "aws-sign2": "0.7.0", - "aws4": "1.6.0", - "caseless": "0.12.0", - "combined-stream": "1.0.5", - "extend": "3.0.1", - "forever-agent": "0.6.1", - "form-data": "2.3.1", - "har-validator": "5.0.3", - "hawk": "6.0.2", - "http-signature": "1.2.0", - "is-typedarray": "1.0.0", - "isstream": "0.1.2", - "json-stringify-safe": "5.0.1", - "mime-types": "2.1.17", - "oauth-sign": "0.8.2", - "performance-now": "2.1.0", - "qs": "6.5.1", - "safe-buffer": "5.1.1", - "stringstream": "0.0.5", - "tough-cookie": "2.3.3", - "tunnel-agent": "0.6.0", - "uuid": "3.1.0" - }, - "dependencies": { - "ajv": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-5.3.0.tgz", - "integrity": "sha1-RBT/dKUIecII7l/cgm4ywwNUnto=", - "requires": { - "co": "4.6.0", - "fast-deep-equal": "1.0.0", - "fast-json-stable-stringify": "2.0.0", - "json-schema-traverse": "0.3.1" - } - }, - "assert-plus": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=" - }, - "aws-sign2": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", - "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=" - }, - "boom": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/boom/-/boom-4.3.1.tgz", - "integrity": "sha1-T4owBctKfjiJ90kDD9JbluAdLjE=", - "requires": { - "hoek": "4.2.0" - } - }, - "cryptiles": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/cryptiles/-/cryptiles-3.1.2.tgz", - "integrity": "sha1-qJ+7Ig9c4l7FboxKqKT9e1sNKf4=", - "requires": { - "boom": "5.2.0" - }, - "dependencies": { - "boom": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/boom/-/boom-5.2.0.tgz", - "integrity": "sha512-Z5BTk6ZRe4tXXQlkqftmsAUANpXmuwlsF5Oov8ThoMbQRzdGTA1ngYRW160GexgOgjsFOKJz0LYhoNi+2AMBUw==", - "requires": { - "hoek": "4.2.0" - } - } - } - }, - "form-data": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.1.tgz", - "integrity": "sha1-b7lPvXGIUwbXPRXMSX/kzE7NRL8=", - "requires": { - "asynckit": "0.4.0", - "combined-stream": "1.0.5", - "mime-types": "2.1.17" - } - }, - "har-schema": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", - "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=" - }, - "har-validator": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.0.3.tgz", - "integrity": "sha1-ukAsJmGU8VlW7xXg/PJCmT9qff0=", - "requires": { - "ajv": "5.3.0", - "har-schema": "2.0.0" - } - }, - "hawk": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/hawk/-/hawk-6.0.2.tgz", - "integrity": "sha512-miowhl2+U7Qle4vdLqDdPt9m09K6yZhkLDTWGoUiUzrQCn+mHHSmfJgAyGaLRZbPmTqfFFjRV1QWCW0VWUJBbQ==", - "requires": { - "boom": "4.3.1", - "cryptiles": "3.1.2", - "hoek": "4.2.0", - "sntp": "2.1.0" - } - }, - "hoek": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/hoek/-/hoek-4.2.0.tgz", - "integrity": "sha512-v0XCLxICi9nPfYrS9RL8HbYnXi9obYAeLbSP00BmnZwCK9+Ih9WOjoZ8YoHCoav2csqn4FOz4Orldsy2dmDwmQ==" - }, - "http-signature": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", - "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", - "requires": { - "assert-plus": "1.0.0", - "jsprim": "1.4.1", - "sshpk": "1.13.1" - } - }, - "performance-now": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", - "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=" - }, - "sntp": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/sntp/-/sntp-2.1.0.tgz", - "integrity": "sha512-FL1b58BDrqS3A11lJ0zEdnJ3UOKqVxawAkF3k7F0CVN7VQ34aZrV+G8BZ1WC9ZL7NyrwsW0oviwsWDgRuVYtJg==", - "requires": { - "hoek": "4.2.0" - } - } - } - }, - "rimraf": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.2.tgz", - "integrity": "sha512-lreewLK/BlghmxtfH36YYVg1i8IAce4TI7oao75I1g245+6BctqTVQiBP3YUJ9C6DQOXJmkYR9X9fCLtCOJc5w==", - "requires": { - "glob": "7.1.2" - } - }, - "safe-buffer": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz", - "integrity": "sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg==" - }, - "secure-keys": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/secure-keys/-/secure-keys-1.0.0.tgz", - "integrity": "sha1-8MgtmKOxOah3aogIBQuCRDEIf8o=" - }, - "semver": { - "version": "4.3.6", - "resolved": "https://registry.npmjs.org/semver/-/semver-4.3.6.tgz", - "integrity": "sha1-MAvG4OhjdPe6YQaLWx7NV/xlMto=" - }, - "send": { - "version": "0.16.1", - "resolved": "https://registry.npmjs.org/send/-/send-0.16.1.tgz", - "integrity": "sha512-ElCLJdJIKPk6ux/Hocwhk7NFHpI3pVm/IZOYWqUmoxcgeyM+MpxHHKhb8QmlJDX1pU6WrgaHBkVNm73Sv7uc2A==", - "requires": { - "debug": "2.6.9", - "depd": "1.1.1", - "destroy": "1.0.4", - "encodeurl": "1.0.1", - "escape-html": "1.0.3", - "etag": "1.8.1", - "fresh": "0.5.2", - "http-errors": "1.6.2", - "mime": "1.4.1", - "ms": "2.0.0", - "on-finished": "2.3.0", - "range-parser": "1.2.0", - "statuses": "1.3.1" - } - }, - "serve-static": { - "version": "1.13.1", - "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.13.1.tgz", - "integrity": "sha512-hSMUZrsPa/I09VYFJwa627JJkNs0NrfL1Uzuup+GqHfToR2KcsXFymXSV90hoyw3M+msjFuQly+YzIH/q0MGlQ==", - "requires": { - "encodeurl": "1.0.1", - "escape-html": "1.0.3", - "parseurl": "1.3.2", - "send": "0.16.1" - } - }, - "setprototypeof": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.0.3.tgz", - "integrity": "sha1-ZlZ+NwQ+608E2RvWWMDL77VbjgQ=" - }, - "sjcl-codec": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/sjcl-codec/-/sjcl-codec-0.1.1.tgz", - "integrity": "sha1-aub9c2xOBb/9pLxhoYox9X12HZU=" - }, - "sntp": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/sntp/-/sntp-1.0.9.tgz", - "integrity": "sha1-ZUEYTMkK7qbG57NeJlkIJEPGYZg=", - "requires": { - "hoek": "2.16.3" - } - }, - "sprintf-js": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=" - }, - "sshpk": { - "version": "1.13.1", - "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.13.1.tgz", - "integrity": "sha1-US322mKHFEMW3EwY/hzx2UBzm+M=", - "requires": { - "asn1": "0.2.3", - "assert-plus": "1.0.0", - "bcrypt-pbkdf": "1.0.1", - "dashdash": "1.14.1", - "ecc-jsbn": "0.1.1", - "getpass": "0.1.7", - "jsbn": "0.1.1", - "tweetnacl": "0.14.5" - }, - "dependencies": { - "assert-plus": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=" - } - } - }, - "stack-trace": { - "version": "0.0.10", - "resolved": "https://registry.npmjs.org/stack-trace/-/stack-trace-0.0.10.tgz", - "integrity": "sha1-VHxws0fo0ytOEI6hoqFZ5f3eGcA=" - }, - "statuses": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.3.1.tgz", - "integrity": "sha1-+vUbnrdKrvOzrPStX2Gr8ky3uT4=" - }, - "stream-buffers": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/stream-buffers/-/stream-buffers-3.0.1.tgz", - "integrity": "sha1-aKOMX6re3tef95mI02jj+xMl7wY=" - }, - "string-width": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", - "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", - "requires": { - "code-point-at": "1.1.0", - "is-fullwidth-code-point": "1.0.0", - "strip-ansi": "3.0.1" - } - }, - "string_decoder": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz", - "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==", - "requires": { - "safe-buffer": "5.1.1" - } - }, - "stringstream": { - "version": "0.0.5", - "resolved": "https://registry.npmjs.org/stringstream/-/stringstream-0.0.5.tgz", - "integrity": "sha1-TkhM1N5aC7vuGORjB3EKioFiGHg=" - }, - "strip-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", - "requires": { - "ansi-regex": "2.1.1" - } - }, - "tar-stream": { - "version": "1.5.2", - "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-1.5.2.tgz", - "integrity": "sha1-+8bG6DwaGdTLSMfZYXH8JI7/x78=", - "requires": { - "bl": "1.2.1", - "end-of-stream": "1.4.0", - "readable-stream": "2.3.3", - "xtend": "4.0.1" - } - }, - "topo": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/topo/-/topo-1.1.0.tgz", - "integrity": "sha1-6ddRYV0buH3IZdsYL6HKCl71NtU=", - "requires": { - "hoek": "2.16.3" - } - }, - "tough-cookie": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.3.3.tgz", - "integrity": "sha1-C2GKVWW23qkL80JdBNVe3EdadWE=", - "requires": { - "punycode": "1.4.1" - } - }, - "tunnel-agent": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", - "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", - "requires": { - "safe-buffer": "5.1.1" - } - }, - "tweetnacl": { - "version": "0.14.5", - "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", - "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=", - "optional": true - }, - "type-is": { - "version": "1.6.15", - "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.15.tgz", - "integrity": "sha1-yrEPtJCeRByChC6v4a1kbIGARBA=", - "requires": { - "media-typer": "0.3.0", - "mime-types": "2.1.17" - } - }, - "uid-safe": { - "version": "2.1.5", - "resolved": "https://registry.npmjs.org/uid-safe/-/uid-safe-2.1.5.tgz", - "integrity": "sha512-KPHm4VL5dDXKz01UuEd88Df+KzynaohSL9fBh096KWAxSKZQDI2uBrVqtvRM4rwrIrRRKsdLNML/lnaaVSRioA==", - "requires": { - "random-bytes": "1.0.0" - } - }, - "underscore": { - "version": "1.8.3", - "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.8.3.tgz", - "integrity": "sha1-Tz+1OxBuYJf8+ctBCfKl6b36UCI=" - }, - "unpipe": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", - "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=" - }, - "url": { - "version": "0.11.0", - "resolved": "https://registry.npmjs.org/url/-/url-0.11.0.tgz", - "integrity": "sha1-ODjpfPxgUh63PFJajlW/3Z4uKPE=", - "requires": { - "punycode": "1.3.2", - "querystring": "0.2.0" - }, - "dependencies": { - "punycode": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz", - "integrity": "sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0=" - } - } - }, - "util": { - "version": "0.10.3", - "resolved": "https://registry.npmjs.org/util/-/util-0.10.3.tgz", - "integrity": "sha1-evsa/lCAUkZInj23/g7TeTNqwPk=", - "requires": { - "inherits": "2.0.1" - }, - "dependencies": { - "inherits": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz", - "integrity": "sha1-sX0I0ya0Qj5Wjv9xn5GwscvfafE=" - } - } - }, - "util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" - }, - "utils-merge": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", - "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=" - }, - "uuid": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.1.0.tgz", - "integrity": "sha512-DIWtzUkw04M4k3bf1IcpS2tngXEL26YUD2M0tMDUpnUrz2hgzUBlD55a4FjdLGPvfHxS6uluGWvaVEqgBcVa+g==" - }, - "vary": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", - "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=" - }, - "verror": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", - "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", - "requires": { - "assert-plus": "1.0.0", - "core-util-is": "1.0.2", - "extsprintf": "1.3.0" - }, - "dependencies": { - "assert-plus": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=" - } - } - }, - "window-size": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/window-size/-/window-size-0.1.4.tgz", - "integrity": "sha1-+OGqHuWlPsW/FR/6CXQqatdpeHY=" - }, - "winston": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/winston/-/winston-2.4.0.tgz", - "integrity": "sha1-gIBQuT1SZh7Z+2wms/DIJnCLCu4=", - "requires": { - "async": "1.0.0", - "colors": "1.0.3", - "cycle": "1.0.3", - "eyes": "0.1.8", - "isstream": "0.1.2", - "stack-trace": "0.0.10" - }, - "dependencies": { - "async": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/async/-/async-1.0.0.tgz", - "integrity": "sha1-+PwEyjoTeErenhZBr5hXjPvWR6k=" - } - } - }, - "wrap-ansi": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz", - "integrity": "sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU=", - "requires": { - "string-width": "1.0.2", - "strip-ansi": "3.0.1" - } - }, - "wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" - }, - "xtend": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz", - "integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68=" - }, - "y18n": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-3.2.1.tgz", - "integrity": "sha1-bRX7qITAhnnA136I53WegR4H+kE=" - }, - "yargs": { - "version": "3.32.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-3.32.0.tgz", - "integrity": "sha1-AwiOnr+edWtpdRYR0qXvWRSCyZU=", - "requires": { - "camelcase": "2.1.1", - "cliui": "3.2.0", - "decamelize": "1.2.0", - "os-locale": "1.4.0", - "string-width": "1.0.2", - "window-size": "0.1.4", - "y18n": "3.2.1" - } - } - } -} From 680ff01a5dc7ec9ea4ed3ef0efb9b74da5bb8113 Mon Sep 17 00:00:00 2001 From: alex Date: Thu, 22 Mar 2018 11:24:47 +0800 Subject: [PATCH 05/29] [FAB-8600]Clear hyperledger-related containers only Change-Id: If45759c6db4b6e63aaadd1c86d31f1332a5aee53 Signed-off-by: alex --- first-network/byfn.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/first-network/byfn.sh b/first-network/byfn.sh index 0e68afc4..a10e0a36 100755 --- a/first-network/byfn.sh +++ b/first-network/byfn.sh @@ -87,7 +87,7 @@ function askProceed () { # Obtain CONTAINER_IDS and remove them # TODO Might want to make this optional - could clear other containers function clearContainers () { - CONTAINER_IDS=$(docker ps -aq) + CONTAINER_IDS=$(docker ps -a |awk '($2 ~ /dev-peer.*.mycc.*/) {print $1}') if [ -z "$CONTAINER_IDS" -o "$CONTAINER_IDS" == " " ]; then echo "---- No containers available for deletion ----" else @@ -99,7 +99,7 @@ function clearContainers () { # specifically the following images are often left behind: # TODO list generated image naming patterns function removeUnwantedImages() { - DOCKER_IMAGE_IDS=$(docker images | grep "dev\|none\|test-vp\|peer[0-9]-" | awk '{print $3}') + DOCKER_IMAGE_IDS=$(docker images|awk '($1 ~ /dev-peer.*.mycc.*/) {print $3}') if [ -z "$DOCKER_IMAGE_IDS" -o "$DOCKER_IMAGE_IDS" == " " ]; then echo "---- No images available for deletion ----" else From 8fc0865df4911e0288d506d696b82b42b4ba6ad8 Mon Sep 17 00:00:00 2001 From: Christopher Ferris Date: Tue, 27 Mar 2018 08:36:52 -0400 Subject: [PATCH 06/29] FAB-9185 add /config to .gitignore Change-Id: Ib744a40abaabd0292ee09e101fafc63aebbecb02 Signed-off-by: Christopher Ferris --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 84262045..80150e99 100644 --- a/.gitignore +++ b/.gitignore @@ -6,6 +6,7 @@ .*.sw* # installed platform-specific binaries /bin +/config .DS_Store .project From a080da3e23bbac5a8d251e08e91ebc10fcf40080 Mon Sep 17 00:00:00 2001 From: Salman Baset Date: Mon, 26 Mar 2018 10:18:01 -0400 Subject: [PATCH 07/29] [FAB-8958] Add org3 removal to byfn.sh When running the sample "Adding an Org to a Channel", then upon clean up, ./eyfn.sh -m down script must be run before ./byfn.sh -m down; otherwise, org3 containers and volumes and containers do not get cleaned properly. This patch adds the org3 container and volume cleanup to ./byfn.sh so that a user does not have to worry about the correct execution ordering of ./eyfn.sh and ./byfn.sh scripts. Change-Id: Ieac1adc4081d59943286cfe9139a74395986460b Signed-off-by: Salman Baset --- first-network/byfn.sh | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/first-network/byfn.sh b/first-network/byfn.sh index 0e68afc4..73db136b 100755 --- a/first-network/byfn.sh +++ b/first-network/byfn.sh @@ -232,8 +232,10 @@ function upgradeNetwork () { # Tear down running network function networkDown () { - docker-compose -f $COMPOSE_FILE -f $COMPOSE_FILE_COUCH down --volumes - docker-compose -f $COMPOSE_FILE down --volumes + # stop org3 containers also in addition to org1 and org2, in case we were running sample to add org3 + docker-compose -f $COMPOSE_FILE -f $COMPOSE_FILE_COUCH -f $COMPOSE_FILE_ORG3 down --volumes + docker-compose -f $COMPOSE_FILE -f $COMPOSE_FILE_ORG3 down --volumes + # Don't remove the generated artifacts -- note, the ledgers are always removed if [ "$MODE" != "restart" ]; then # Bring down the network, deleting the volumes @@ -440,6 +442,9 @@ CHANNEL_NAME="mychannel" COMPOSE_FILE=docker-compose-cli.yaml # COMPOSE_FILE_COUCH=docker-compose-couch.yaml +# org3 docker compose file +COMPOSE_FILE_ORG3=docker-compose-org3.yaml +# # use golang as the default language for chaincode LANGUAGE=golang # default image tag From 9d518fb79597a9e9fc3c38f38b44fedc69ebd3bf Mon Sep 17 00:00:00 2001 From: "Robert P. J. Day" Date: Wed, 4 Apr 2018 06:26:20 -0400 Subject: [PATCH 08/29] [FAB-9330] Refactor top-level .gitignore into subdirs Rather than cram most .gitignore content into the top-level .gitignore file, partition it into lower-level .gitignore files, as is already done with a couple subdirectories, just to be consistent. I'm sure these files could be even tidier but this seems sufficient for a first pass. Change-Id: I0cc8cb2a9d7fa82c4f6de1aef9f82107c8cc7a6a Signed-off-by: Robert P. J. Day --- .gitignore | 22 ---------------------- balance-transfer/.gitignore | 3 +++ balance-transfer/typescript/.gitignore | 2 +- chaincode-docker-devmode/.gitignore | 3 +++ fabcar/.gitignore | 3 +++ first-network/.gitignore | 6 ++++++ 6 files changed, 16 insertions(+), 23 deletions(-) create mode 100644 balance-transfer/.gitignore create mode 100644 chaincode-docker-devmode/.gitignore create mode 100644 fabcar/.gitignore create mode 100644 first-network/.gitignore diff --git a/.gitignore b/.gitignore index 80150e99..4b705ae4 100644 --- a/.gitignore +++ b/.gitignore @@ -9,25 +9,3 @@ /config .DS_Store .project - -first-network/channel-artifacts/*.tx -first-network/channel-artifacts/*.block -first-network/crypto-config/* -first-network/docker-compose-e2e.yaml -first-network/ledgers -first-network/ledgers-backup - -chaincode-docker-devmode/myc.block -chaincode-docker-devmode/chaincode/sacc/sacc -chaincode-docker-devmode/chaincode/chaincode_example02/chaincode_example02 - -# fabric sdk node modules -fabcar/node_modules/ -fabcar/package-lock.json -fabcar/hfc-key-store/ - -# balance transfer sample -balance-transfer/.DS_Store -balance-transfer/node_modules/* -balance-transfer/package-lock.json -balance-transfer/fabric-client-kv-org* diff --git a/balance-transfer/.gitignore b/balance-transfer/.gitignore new file mode 100644 index 00000000..5ab9c94c --- /dev/null +++ b/balance-transfer/.gitignore @@ -0,0 +1,3 @@ +/node_modules/* +/package-lock.json +/fabric-client-kv-org* diff --git a/balance-transfer/typescript/.gitignore b/balance-transfer/typescript/.gitignore index 9f22bacf..5e283e61 100644 --- a/balance-transfer/typescript/.gitignore +++ b/balance-transfer/typescript/.gitignore @@ -1,4 +1,4 @@ node_modules package-lock.json dist -types/fabric-client \ No newline at end of file +types/fabric-client diff --git a/chaincode-docker-devmode/.gitignore b/chaincode-docker-devmode/.gitignore new file mode 100644 index 00000000..699c14a5 --- /dev/null +++ b/chaincode-docker-devmode/.gitignore @@ -0,0 +1,3 @@ +/myc.block +/chaincode/sacc/sacc +/chaincode/chaincode_example02/chaincode_example02 diff --git a/fabcar/.gitignore b/fabcar/.gitignore new file mode 100644 index 00000000..1e3d188c --- /dev/null +++ b/fabcar/.gitignore @@ -0,0 +1,3 @@ +/node_modules/ +/package-lock.json +/hfc-key-store/ diff --git a/first-network/.gitignore b/first-network/.gitignore new file mode 100644 index 00000000..715dcea0 --- /dev/null +++ b/first-network/.gitignore @@ -0,0 +1,6 @@ +/channel-artifacts/*.tx +/channel-artifacts/*.block +/crypto-config/* +/docker-compose-e2e.yaml +/ledgers +/ledgers-backup From f5c2eb8ee9fe96f1560ec25186231e96d6dd949c Mon Sep 17 00:00:00 2001 From: Christopher Ferris Date: Wed, 4 Apr 2018 19:25:55 -0400 Subject: [PATCH 09/29] FAB-9362 add CONTRIBUTING.md and CODE_OF_CONDUCT.md Change-Id: I01f2039d9835e6ccccce17c2b719115e8a6f7c1e Signed-off-by: Christopher Ferris --- CODE_OF_CONDUCT.md | 8 ++++++++ CONTRIBUTING.md | 18 ++++++++++++++++++ 2 files changed, 26 insertions(+) create mode 100644 CODE_OF_CONDUCT.md create mode 100644 CONTRIBUTING.md diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md new file mode 100644 index 00000000..2f1f0e36 --- /dev/null +++ b/CODE_OF_CONDUCT.md @@ -0,0 +1,8 @@ +Code of Conduct Guidelines +========================== + +Please review the Hyperledger [Code of +Conduct](https://wiki.hyperledger.org/community/hyperledger-project-code-of-conduct) +before participating. It is important that we keep things civil. + +Creative Commons License
This work is licensed under a Creative Commons Attribution 4.0 International License. diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 00000000..6432cb62 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,18 @@ +## Contributing + +We welcome contributions to the Hyperledger Fabric Project in many forms, and +there's always plenty to do! + +Please visit the +[contributors guide](http://hyperledger-fabric.readthedocs.io/en/latest/CONTRIBUTING.html) in the +docs to learn how to make contributions to this exciting project. + +## Code of Conduct Guidelines + +See our [Code of Conduct Guidelines](../blob/master/CODE_OF_CONDUCT.md). + +## Maintainers + +Should you have any questions or concerns, please reach out to one of the project's [Maintainers](../blob/master/MAINTAINERS.md). + +Creative Commons License
This work is licensed under a Creative Commons Attribution 4.0 International License. From 41f5ab839b51b424bb6f7759e900ca6bcc4ee24a Mon Sep 17 00:00:00 2001 From: foolcage <5533061@qq.com> Date: Sun, 8 Apr 2018 18:03:01 +0800 Subject: [PATCH 10/29] [FAB-9406] Typo in byfn.sh I found "depete" in first-network/byfn.sh. Maybe it should be "delete". Change-Id: Iecdb6f8822b8b99765bc9d93e9b5ab623cb63607 Signed-off-by: foolcage <5533061@qq.com> --- first-network/byfn.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/first-network/byfn.sh b/first-network/byfn.sh index 6daea11e..0c800d07 100755 --- a/first-network/byfn.sh +++ b/first-network/byfn.sh @@ -257,7 +257,7 @@ function networkDown () { # configuration function replacePrivateKey () { # sed on MacOSX does not support -i flag with a null extension. We will use - # 't' for our back-up's extension and depete it at the end of the function + # 't' for our back-up's extension and delete it at the end of the function ARCH=`uname -s | grep Darwin` if [ "$ARCH" == "Darwin" ]; then OPTS="-it" From 77a65685c5dfc9f6fb1f1d44042f920ac255d54e Mon Sep 17 00:00:00 2001 From: Christopher Ferris Date: Mon, 2 Apr 2018 13:56:05 -0400 Subject: [PATCH 11/29] FAB-9294 eliminate excess noise in BYFN eliminate the noise of echoing the environment variables for each command and add -v option to enable the noise for debug purposes for byfn.sh and eyfn.sh in first-network sample also eliminate noise in fabcar Change-Id: I46c377360efbab598fd37c0a31b29a119b99173e Signed-off-by: Christopher Ferris --- basic-network/docker-compose.yml | 10 +++++----- basic-network/teardown.sh | 1 + first-network/byfn.sh | 10 +++++++--- first-network/eyfn.sh | 16 ++++++++++------ first-network/scripts/script.sh | 2 ++ first-network/scripts/step1org3.sh | 2 ++ first-network/scripts/step2org3.sh | 2 ++ first-network/scripts/step3org3.sh | 2 ++ first-network/scripts/testorg3.sh | 2 ++ first-network/scripts/upgrade_to_v11.sh | 2 ++ first-network/scripts/utils.sh | 4 +++- 11 files changed, 38 insertions(+), 15 deletions(-) diff --git a/basic-network/docker-compose.yml b/basic-network/docker-compose.yml index bfad9d95..2ebe3a43 100644 --- a/basic-network/docker-compose.yml +++ b/basic-network/docker-compose.yml @@ -18,7 +18,7 @@ services: - FABRIC_CA_SERVER_CA_KEYFILE=/etc/hyperledger/fabric-ca-server-config/4239aa0dcd76daeeb8ba0cda701851d14504d31aad1b2ddddbac6a57365e497c_sk ports: - "7054:7054" - command: sh -c 'fabric-ca-server start -b admin:adminpw -d' + command: sh -c 'fabric-ca-server start -b admin:adminpw' volumes: - ./crypto-config/peerOrganizations/org1.example.com/ca/:/etc/hyperledger/fabric-ca-server-config container_name: ca.example.com @@ -29,7 +29,7 @@ services: container_name: orderer.example.com image: hyperledger/fabric-orderer environment: - - ORDERER_GENERAL_LOGLEVEL=debug + - ORDERER_GENERAL_LOGLEVEL=info - ORDERER_GENERAL_LISTENADDRESS=0.0.0.0 - ORDERER_GENERAL_GENESISMETHOD=file - ORDERER_GENERAL_GENESISFILE=/etc/hyperledger/configtx/genesis.block @@ -52,8 +52,8 @@ services: environment: - CORE_VM_ENDPOINT=unix:///host/var/run/docker.sock - CORE_PEER_ID=peer0.org1.example.com - - CORE_LOGGING_PEER=debug - - CORE_CHAINCODE_LOGGING_LEVEL=DEBUG + - CORE_LOGGING_PEER=info + - CORE_CHAINCODE_LOGGING_LEVEL=info - CORE_PEER_LOCALMSPID=Org1MSP - CORE_PEER_MSPCONFIGPATH=/etc/hyperledger/msp/peer/ - CORE_PEER_ADDRESS=peer0.org1.example.com:7051 @@ -105,7 +105,7 @@ services: environment: - GOPATH=/opt/gopath - CORE_VM_ENDPOINT=unix:///host/var/run/docker.sock - - CORE_LOGGING_LEVEL=DEBUG + - CORE_LOGGING_LEVEL=info - CORE_PEER_ID=cli - CORE_PEER_ADDRESS=peer0.org1.example.com:7051 - CORE_PEER_LOCALMSPID=Org1MSP diff --git a/basic-network/teardown.sh b/basic-network/teardown.sh index 70367930..189b6070 100755 --- a/basic-network/teardown.sh +++ b/basic-network/teardown.sh @@ -14,6 +14,7 @@ docker-compose -f docker-compose.yml kill && docker-compose -f docker-compose.ym rm -f ~/.hfc-key-store/* # remove chaincode docker images +docker rm $(docker ps -aq) docker rmi $(docker images dev-* -q) # Your system is now clean diff --git a/first-network/byfn.sh b/first-network/byfn.sh index a10e0a36..39d6ce07 100755 --- a/first-network/byfn.sh +++ b/first-network/byfn.sh @@ -30,6 +30,7 @@ # this may be commented out to resolve installed version of tools if desired export PATH=${PWD}/../bin:${PWD}:$PATH export FABRIC_CFG_PATH=${PWD} +export VERBOSE=false # Print the usage message function printHelp () { @@ -49,6 +50,7 @@ function printHelp () { echo " -s - the database backend to use: goleveldb (default) or couchdb" echo " -l - the chaincode language: golang (default) or node" echo " -i - the tag to be used to launch the network (defaults to \"latest\")" + echo " -v - verbose mode" echo echo "Typically, one would first generate the required certificates and " echo "genesis block, then bring up the network. e.g.:" @@ -163,7 +165,7 @@ function networkUp () { exit 1 fi # now run the end to end script - docker exec cli scripts/script.sh $CHANNEL_NAME $CLI_DELAY $LANGUAGE $CLI_TIMEOUT + docker exec cli scripts/script.sh $CHANNEL_NAME $CLI_DELAY $LANGUAGE $CLI_TIMEOUT $VERBOSE if [ $? -ne 0 ]; then echo "ERROR !!!! Test failed" exit 1 @@ -222,7 +224,7 @@ function upgradeNetwork () { docker-compose $COMPOSE_FILES up -d --no-deps $PEER done - docker exec cli scripts/upgrade_to_v11.sh $CHANNEL_NAME $CLI_DELAY $LANGUAGE $CLI_TIMEOUT + docker exec cli scripts/upgrade_to_v11.sh $CHANNEL_NAME $CLI_DELAY $LANGUAGE $CLI_TIMEOUT $VERBOSE if [ $? -ne 0 ]; then echo "ERROR !!!! Test failed" exit 1 @@ -465,7 +467,7 @@ else exit 1 fi -while getopts "h?m:c:t:d:f:s:l:i:" opt; do +while getopts "h?m:c:t:d:f:s:l:i:v" opt; do case "$opt" in h|\?) printHelp @@ -485,6 +487,8 @@ while getopts "h?m:c:t:d:f:s:l:i:" opt; do ;; i) IMAGETAG=`uname -m`"-"$OPTARG ;; + v) VERBOSE=true + ;; esac done diff --git a/first-network/eyfn.sh b/first-network/eyfn.sh index b6783aac..74473888 100755 --- a/first-network/eyfn.sh +++ b/first-network/eyfn.sh @@ -14,6 +14,7 @@ # this may be commented out to resolve installed version of tools if desired export PATH=${PWD}/../bin:${PWD}:$PATH export FABRIC_CFG_PATH=${PWD} +export VERBOSE=false # Print the usage message function printHelp () { @@ -32,6 +33,7 @@ function printHelp () { echo " -s - the database backend to use: goleveldb (default) or couchdb" echo " -l - the chaincode language: golang (default) or node" echo " -i - the tag to be used to launch the network (defaults to \"latest\")" + echo " -v - verbose mode" echo echo "Typically, one would first generate the required certificates and " echo "genesis block, then bring up the network. e.g.:" @@ -80,7 +82,7 @@ function clearContainers () { # specifically the following images are often left behind: # TODO list generated image naming patterns function removeUnwantedImages() { - DOCKER_IMAGE_IDS=$(docker images | grep "dev\|none\|test-vp\|peer[0-9]-" | awk '{print $3}') + DOCKER_IMAGE_IDS=$(docker images|awk '($1 ~ /dev-peer.*.mycc.*/) {print $3}') if [ -z "$DOCKER_IMAGE_IDS" -o "$DOCKER_IMAGE_IDS" == " " ]; then echo "---- No images available for deletion ----" else @@ -110,7 +112,7 @@ function networkUp () { echo "###############################################################" echo "############### Have Org3 peers join network ##################" echo "###############################################################" - docker exec Org3cli ./scripts/step2org3.sh $CHANNEL_NAME $CLI_DELAY $LANGUAGE $CLI_TIMEOUT + docker exec Org3cli ./scripts/step2org3.sh $CHANNEL_NAME $CLI_DELAY $LANGUAGE $CLI_TIMEOUT $VERBOSE if [ $? -ne 0 ]; then echo "ERROR !!!! Unable to have Org3 peers join network" exit 1 @@ -119,13 +121,13 @@ function networkUp () { echo "###############################################################" echo "##### Upgrade chaincode to have Org3 peers on the network #####" echo "###############################################################" - docker exec cli ./scripts/step3org3.sh $CHANNEL_NAME $CLI_DELAY $LANGUAGE $CLI_TIMEOUT + docker exec cli ./scripts/step3org3.sh $CHANNEL_NAME $CLI_DELAY $LANGUAGE $CLI_TIMEOUT $VERBOSE if [ $? -ne 0 ]; then echo "ERROR !!!! Unable to add Org3 peers on network" exit 1 fi # finish by running the test - docker exec Org3cli ./scripts/testorg3.sh $CHANNEL_NAME $CLI_DELAY $LANGUAGE $CLI_TIMEOUT + docker exec Org3cli ./scripts/testorg3.sh $CHANNEL_NAME $CLI_DELAY $LANGUAGE $CLI_TIMEOUT $VERBOSE if [ $? -ne 0 ]; then echo "ERROR !!!! Unable to run test" exit 1 @@ -160,7 +162,7 @@ function createConfigTx () { echo "###############################################################" echo "####### Generate and submit config tx to add Org3 #############" echo "###############################################################" - docker exec cli scripts/step1org3.sh $CHANNEL_NAME $CLI_DELAY $LANGUAGE $CLI_TIMEOUT + docker exec cli scripts/step1org3.sh $CHANNEL_NAME $CLI_DELAY $LANGUAGE $CLI_TIMEOUT $VERBOSE if [ $? -ne 0 ]; then echo "ERROR !!!! Unable to create config tx" exit 1 @@ -271,7 +273,7 @@ else printHelp exit 1 fi -while getopts "h?c:t:d:f:s:l:i:" opt; do +while getopts "h?c:t:d:f:s:l:i:v" opt; do case "$opt" in h|\?) printHelp @@ -291,6 +293,8 @@ while getopts "h?c:t:d:f:s:l:i:" opt; do ;; i) IMAGETAG=$OPTARG ;; + v) VERBOSE=true + ;; esac done diff --git a/first-network/scripts/script.sh b/first-network/scripts/script.sh index 5762cb25..7823d600 100755 --- a/first-network/scripts/script.sh +++ b/first-network/scripts/script.sh @@ -13,10 +13,12 @@ CHANNEL_NAME="$1" DELAY="$2" LANGUAGE="$3" TIMEOUT="$4" +VERBOSE="$5" : ${CHANNEL_NAME:="mychannel"} : ${DELAY:="3"} : ${LANGUAGE:="golang"} : ${TIMEOUT:="10"} +: ${VERBOSE:="false"} LANGUAGE=`echo "$LANGUAGE" | tr [:upper:] [:lower:]` COUNTER=1 MAX_RETRY=5 diff --git a/first-network/scripts/step1org3.sh b/first-network/scripts/step1org3.sh index ad607e35..2efb64da 100755 --- a/first-network/scripts/step1org3.sh +++ b/first-network/scripts/step1org3.sh @@ -15,10 +15,12 @@ CHANNEL_NAME="$1" DELAY="$2" LANGUAGE="$3" TIMEOUT="$4" +VERBOSE="$5" : ${CHANNEL_NAME:="mychannel"} : ${DELAY:="3"} : ${LANGUAGE:="golang"} : ${TIMEOUT:="10"} +: ${VERBOSE:="false"} LANGUAGE=`echo "$LANGUAGE" | tr [:upper:] [:lower:]` COUNTER=1 MAX_RETRY=5 diff --git a/first-network/scripts/step2org3.sh b/first-network/scripts/step2org3.sh index 41268c4b..f4df00d4 100755 --- a/first-network/scripts/step2org3.sh +++ b/first-network/scripts/step2org3.sh @@ -18,10 +18,12 @@ CHANNEL_NAME="$1" DELAY="$2" LANGUAGE="$3" TIMEOUT="$4" +VERBOSE="$5" : ${CHANNEL_NAME:="mychannel"} : ${DELAY:="3"} : ${LANGUAGE:="golang"} : ${TIMEOUT:="10"} +: ${VERBOSE:="false"} LANGUAGE=`echo "$LANGUAGE" | tr [:upper:] [:lower:]` COUNTER=1 MAX_RETRY=5 diff --git a/first-network/scripts/step3org3.sh b/first-network/scripts/step3org3.sh index 585fa203..895a4513 100755 --- a/first-network/scripts/step3org3.sh +++ b/first-network/scripts/step3org3.sh @@ -19,10 +19,12 @@ CHANNEL_NAME="$1" DELAY="$2" LANGUAGE="$3" TIMEOUT="$4" +VERBOSE="$5" : ${CHANNEL_NAME:="mychannel"} : ${DELAY:="3"} : ${LANGUAGE:="golang"} : ${TIMEOUT:="10"} +: ${VERBOSE:="false"} LANGUAGE=`echo "$LANGUAGE" | tr [:upper:] [:lower:]` COUNTER=1 MAX_RETRY=5 diff --git a/first-network/scripts/testorg3.sh b/first-network/scripts/testorg3.sh index 1668f45e..7c3685e8 100755 --- a/first-network/scripts/testorg3.sh +++ b/first-network/scripts/testorg3.sh @@ -24,9 +24,11 @@ CHANNEL_NAME="$1" DELAY="$2" LANGUAGE="$3" TIMEOUT="$4" +VERBOSE="$5" : ${CHANNEL_NAME:="mychannel"} : ${TIMEOUT:="10"} : ${LANGUAGE:="golang"} +: ${VERBOSE:="false"} LANGUAGE=`echo "$LANGUAGE" | tr [:upper:] [:lower:]` COUNTER=1 MAX_RETRY=5 diff --git a/first-network/scripts/upgrade_to_v11.sh b/first-network/scripts/upgrade_to_v11.sh index 69eb2fbd..54ee8905 100755 --- a/first-network/scripts/upgrade_to_v11.sh +++ b/first-network/scripts/upgrade_to_v11.sh @@ -13,10 +13,12 @@ CHANNEL_NAME="$1" DELAY="$2" LANGUAGE="$3" TIMEOUT="$4" +VERBOSE="$5" : ${CHANNEL_NAME:="mychannel"} : ${DELAY:="5"} : ${LANGUAGE:="golang"} : ${TIMEOUT:="10"} +: ${VERBOSE:="false"} LANGUAGE=`echo "$LANGUAGE" | tr [:upper:] [:lower:]` COUNTER=1 MAX_RETRY=5 diff --git a/first-network/scripts/utils.sh b/first-network/scripts/utils.sh index 7509147e..5a4459e9 100755 --- a/first-network/scripts/utils.sh +++ b/first-network/scripts/utils.sh @@ -59,7 +59,9 @@ setGlobals () { echo "================== ERROR !!! ORG Unknown ==================" fi - env |grep CORE + if [ "$VERBOSE" == "true" ]; then + env |grep CORE + fi } From 3a5108f020b77dfe7589180d1299c5aed329d06d Mon Sep 17 00:00:00 2001 From: Nao Nishijima Date: Wed, 11 Apr 2018 13:13:26 -0700 Subject: [PATCH 12/29] [FAB-9475] Fix a dead link in README There is no "samples.html" in latest documents. This patch changes the dead link to "install.html" Change-Id: I431d197c5f4124a979d706f668da28ad1d14b235 Signed-off-by: Nao Nishijima --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 2df26ca2..5f269150 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ ## Hyperledger Fabric Samples -Please visit the [installation instructions](http://hyperledger-fabric.readthedocs.io/en/latest/samples.html). +Please visit the [installation instructions](http://hyperledger-fabric.readthedocs.io/en/latest/install.html). ## License From 2d6386c42188bb22fc8b9f66e43131b5e4f63f61 Mon Sep 17 00:00:00 2001 From: nirro Date: Tue, 17 Apr 2018 15:45:26 +0300 Subject: [PATCH 13/29] [FAB-8245] change first network according to the fix fixed [FAB-8245], and fabric samples have to be changed accordingly. currently, added support for both output formats. Change-Id: I0cac063af44556d6a37f17b25abf20134032540f Signed-off-by: nirro --- fabric-ca/scripts/run-fabric.sh | 8 ++++++++ first-network/scripts/utils.sh | 3 +++ 2 files changed, 11 insertions(+) diff --git a/fabric-ca/scripts/run-fabric.sh b/fabric-ca/scripts/run-fabric.sh index a4ab0f80..50fd542c 100755 --- a/fabric-ca/scripts/run-fabric.sh +++ b/fabric-ca/scripts/run-fabric.sh @@ -157,6 +157,14 @@ function chaincodeQuery { logr "Query of channel '$CHANNEL_NAME' on peer '$PEER_HOST' was successful" set -e return 0 + else + # removed the string "Query Result" from peer chaincode query command result, as a result, have to support both options until the change is merged. + VALUE=$(cat log.txt | egrep '^[0-9]+$') + if [ $? -eq 0 -a "$VALUE" = "$1" ]; then + logr "Query of channel '$CHANNEL_NAME' on peer '$PEER_HOST' was successful" + set -e + return 0 + fi fi echo -n "." done diff --git a/first-network/scripts/utils.sh b/first-network/scripts/utils.sh index 7509147e..cc9008b6 100755 --- a/first-network/scripts/utils.sh +++ b/first-network/scripts/utils.sh @@ -184,6 +184,9 @@ chaincodeQuery () { set +x test $res -eq 0 && VALUE=$(cat log.txt | awk '/Query Result/ {print $NF}') test "$VALUE" = "$EXPECTED_RESULT" && let rc=0 + # removed the string "Query Result" from peer chaincode query command result, as a result, have to support both options until the change is merged. + test $rc -ne 0 && VALUE=$(cat log.txt | egrep '^[0-9]+$') + test "$VALUE" = "$EXPECTED_RESULT" && let rc=0 done echo cat log.txt From 010fcb544fa1988dafd6c06e5669b30b0f66d09b Mon Sep 17 00:00:00 2001 From: "Robert P. J. Day" Date: Sun, 22 Apr 2018 14:01:31 -0400 Subject: [PATCH 14/29] [FAB-9326] Clean up byfn.sh, drop "-m" option Some general cleanup of byfn.sh script: - Given that "-m" is deprecated, remove its normal processing, but retain (for now) its early recognition so that CI passes. - Drop reference to "--help", only "-h" is supported. - Add reference to "upgrade" mode to usage message and comment. Change-Id: If1d6624c8788ec660abca5d13e7c87aafb13ce59 Signed-off-by: Robert P. J. Day --- first-network/byfn.sh | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/first-network/byfn.sh b/first-network/byfn.sh index 5d71bd76..4c582e4d 100755 --- a/first-network/byfn.sh +++ b/first-network/byfn.sh @@ -35,9 +35,8 @@ export VERBOSE=false # Print the usage message function printHelp () { echo "Usage: " - echo " byfn.sh up|down|restart|generate|upgrade [-c ] [-t ] [-d ] [-f ] [-s ] [-i ]" - echo " byfn.sh -h|--help (print this message)" - echo " - one of 'up', 'down', 'restart' or 'generate'" + echo " byfn.sh [-c ] [-t ] [-d ] [-f ] [-s ] [-l ] [-i ] [-v]" + echo " - one of 'up', 'down', 'restart', 'generate' or 'upgrade'" echo " - 'up' - bring up the network with docker-compose up" echo " - 'down' - clear the network with docker-compose down" echo " - 'restart' - restart the network" @@ -51,6 +50,7 @@ function printHelp () { echo " -l - the chaincode language: golang (default) or node" echo " -i - the tag to be used to launch the network (defaults to \"latest\")" echo " -v - verbose mode" + echo " byfn.sh -h (print this message)" echo echo "Typically, one would first generate the required certificates and " echo "genesis block, then bring up the network. e.g.:" @@ -456,7 +456,7 @@ if [ "$1" = "-m" ];then # supports old usage, muscle memory is powerful! shift fi MODE=$1;shift -# Determine whether starting, stopping, restarting or generating for announce +# Determine whether starting, stopping, restarting, generating or upgrading if [ "$MODE" == "up" ]; then EXPMODE="Starting" elif [ "$MODE" == "down" ]; then @@ -472,7 +472,7 @@ else exit 1 fi -while getopts "h?m:c:t:d:f:s:l:i:v" opt; do +while getopts "h?c:t:d:f:s:l:i:v" opt; do case "$opt" in h|\?) printHelp From 146f7bc19342e88b14ca53581dac17fa2c459505 Mon Sep 17 00:00:00 2001 From: Arnaud J Le Hors Date: Tue, 24 Apr 2018 18:23:43 +0200 Subject: [PATCH 15/29] [FAB-9572] Fix README to match new version of BYFN Changed README.md to instruct user to edit byfn.sh instead of docker-compose-cli file since this is where the standard BFYN script is now run. Also added missing Copyright notices. Change-Id: Ib18afe8a23cc3874729031a82480aac5b0a2b555 Signed-off-by: Arnaud J Le Hors --- high-throughput/README.md | 12 +++++++++--- high-throughput/chaincode/high-throughput.go | 4 ++++ high-throughput/scripts/channel-setup.sh | 6 ++++++ high-throughput/scripts/delete-invoke.sh | 6 ++++++ high-throughput/scripts/get-invoke.sh | 6 ++++++ high-throughput/scripts/get-traditional.sh | 6 ++++++ high-throughput/scripts/install-chaincode.sh | 6 ++++++ high-throughput/scripts/instantiate-chaincode.sh | 6 ++++++ high-throughput/scripts/many-updates-traditional.sh | 6 ++++++ high-throughput/scripts/many-updates.sh | 6 ++++++ high-throughput/scripts/prunefast-invoke.sh | 6 ++++++ high-throughput/scripts/prunesafe-invoke.sh | 6 ++++++ high-throughput/scripts/setclienv.sh | 6 ++++++ high-throughput/scripts/update-invoke.sh | 6 ++++++ high-throughput/scripts/upgrade-chaincode.sh | 6 ++++++ 15 files changed, 91 insertions(+), 3 deletions(-) diff --git a/high-throughput/README.md b/high-throughput/README.md index 0956f99d..a899792f 100644 --- a/high-throughput/README.md +++ b/high-throughput/README.md @@ -1,3 +1,9 @@ + + # High-Throughput Network ## Purpose @@ -106,9 +112,9 @@ and run some invocations are provided below. `./scripts:/opt/gopath/src/github.com/hyperledger/fabric/peer/scripts/` --> `./../high-throughput/scripts/:/opt/gopath/src/github.com/hyperledger/fabric/peer/scripts/` - * Finally, comment out the `command` section by placing a `#` before it, e.g. - - `#command: /bin/bash -c './scripts/script.sh ${CHANNEL_NAME}; sleep $TIMEOUT'` + * Finally, comment out the `docker exec cli scripts/script.sh` command from the `byfn.sh` script by placing a `#` before it so that the standard BYFN end to end script doesn't run, e.g. + + `# docker exec cli scripts/script.sh $CHANNEL_NAME $CLI_DELAY $LANGUAGE $CLI_TIMEOUT $VERBOSE` 3. We can now bring our network up by typing in `./byfn.sh -m up -c mychannel` 4. Open a new terminal window and enter the CLI container using `docker exec -it cli bash`, all operations on the network will happen within diff --git a/high-throughput/chaincode/high-throughput.go b/high-throughput/chaincode/high-throughput.go index 90888208..252c9805 100644 --- a/high-throughput/chaincode/high-throughput.go +++ b/high-throughput/chaincode/high-throughput.go @@ -1,4 +1,8 @@ /* + * Copyright IBM Corp All Rights Reserved + * + * SPDX-License-Identifier: Apache-2.0 + * * Demonstrates how to handle data in an application with a high transaction volume where the transactions * all attempt to change the same key-value pair in the ledger. Such an application will have trouble * as multiple transactions may read a value at a certain version, which will then be invalid when the first diff --git a/high-throughput/scripts/channel-setup.sh b/high-throughput/scripts/channel-setup.sh index b9232602..2843ffe8 100755 --- a/high-throughput/scripts/channel-setup.sh +++ b/high-throughput/scripts/channel-setup.sh @@ -1,3 +1,9 @@ +# +# Copyright IBM Corp All Rights Reserved +# +# SPDX-License-Identifier: Apache-2.0 +# + ORDERER_CA=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem # Channel creation diff --git a/high-throughput/scripts/delete-invoke.sh b/high-throughput/scripts/delete-invoke.sh index be892a47..ec08035e 100755 --- a/high-throughput/scripts/delete-invoke.sh +++ b/high-throughput/scripts/delete-invoke.sh @@ -1,2 +1,8 @@ +# +# Copyright IBM Corp All Rights Reserved +# +# SPDX-License-Identifier: Apache-2.0 +# + peer chaincode invoke -o orderer.example.com:7050 --tls $CORE_PEER_TLS_ENABLED --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem -C $CHANNEL_NAME -n $CC_NAME -c '{"Args":["delete","'$1'"]}' diff --git a/high-throughput/scripts/get-invoke.sh b/high-throughput/scripts/get-invoke.sh index aae4eee7..f89bbb2d 100755 --- a/high-throughput/scripts/get-invoke.sh +++ b/high-throughput/scripts/get-invoke.sh @@ -1,2 +1,8 @@ +# +# Copyright IBM Corp All Rights Reserved +# +# SPDX-License-Identifier: Apache-2.0 +# + peer chaincode invoke -o orderer.example.com:7050 --tls $CORE_PEER_TLS_ENABLED --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem -C $CHANNEL_NAME -n $CC_NAME -c '{"Args":["get","'$1'"]}' diff --git a/high-throughput/scripts/get-traditional.sh b/high-throughput/scripts/get-traditional.sh index c5327909..bb0fe522 100755 --- a/high-throughput/scripts/get-traditional.sh +++ b/high-throughput/scripts/get-traditional.sh @@ -1 +1,7 @@ +# +# Copyright IBM Corp All Rights Reserved +# +# SPDX-License-Identifier: Apache-2.0 +# + peer chaincode invoke -o orderer.example.com:7050 --tls $CORE_PEER_TLS_ENABLED --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem -C $CHANNEL_NAME -n $CC_NAME -c '{"Args":["getstandard","'$1'"]}' diff --git a/high-throughput/scripts/install-chaincode.sh b/high-throughput/scripts/install-chaincode.sh index 014ad0fd..7817ae64 100755 --- a/high-throughput/scripts/install-chaincode.sh +++ b/high-throughput/scripts/install-chaincode.sh @@ -1,3 +1,9 @@ +# +# Copyright IBM Corp All Rights Reserved +# +# SPDX-License-Identifier: Apache-2.0 +# + echo "========== Installing chaincode on peer0.org1 ==========" export CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp export CORE_PEER_ADDRESS=peer0.org1.example.com:7051 diff --git a/high-throughput/scripts/instantiate-chaincode.sh b/high-throughput/scripts/instantiate-chaincode.sh index 45eacbc3..25fe046c 100755 --- a/high-throughput/scripts/instantiate-chaincode.sh +++ b/high-throughput/scripts/instantiate-chaincode.sh @@ -1,3 +1,9 @@ +# +# Copyright IBM Corp All Rights Reserved +# +# SPDX-License-Identifier: Apache-2.0 +# + echo "========== Instantiating chaincode v$1 ==========" peer chaincode instantiate -o orderer.example.com:7050 --tls $CORE_PEER_TLS_ENABLED --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem -C $CHANNEL_NAME -n $CC_NAME -c '{"Args": []}' -v $1 -P "OR ('Org1MSP.member','Org2MSP.member')" diff --git a/high-throughput/scripts/many-updates-traditional.sh b/high-throughput/scripts/many-updates-traditional.sh index 3f57e57d..921edc62 100755 --- a/high-throughput/scripts/many-updates-traditional.sh +++ b/high-throughput/scripts/many-updates-traditional.sh @@ -1,3 +1,9 @@ +# +# Copyright IBM Corp All Rights Reserved +# +# SPDX-License-Identifier: Apache-2.0 +# + for (( i = 0; i < 1000; ++i )) do peer chaincode invoke -o orderer.example.com:7050 --tls $CORE_PEER_TLS_ENABLED --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem -C $CHANNEL_NAME -n $CC_NAME -c '{"Args":["putstandard","'$1'","'$i'"]}' diff --git a/high-throughput/scripts/many-updates.sh b/high-throughput/scripts/many-updates.sh index ffedb7c9..13aaf026 100755 --- a/high-throughput/scripts/many-updates.sh +++ b/high-throughput/scripts/many-updates.sh @@ -1,3 +1,9 @@ +# +# Copyright IBM Corp All Rights Reserved +# +# SPDX-License-Identifier: Apache-2.0 +# + for (( i = 0; i < 1000; ++i )) do peer chaincode invoke -o orderer.example.com:7050 --tls $CORE_PEER_TLS_ENABLED --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem -C $CHANNEL_NAME -n $CC_NAME -c '{"Args":["update","'$1'","'$2'","'$3'"]}' & diff --git a/high-throughput/scripts/prunefast-invoke.sh b/high-throughput/scripts/prunefast-invoke.sh index 0db2d9bc..bd7b168c 100755 --- a/high-throughput/scripts/prunefast-invoke.sh +++ b/high-throughput/scripts/prunefast-invoke.sh @@ -1,2 +1,8 @@ +# +# Copyright IBM Corp All Rights Reserved +# +# SPDX-License-Identifier: Apache-2.0 +# + peer chaincode invoke -o orderer.example.com:7050 --tls $CORE_PEER_TLS_ENABLED --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem -C $CHANNEL_NAME -n $CC_NAME -c '{"Args":["prunefast","'$1'"]}' diff --git a/high-throughput/scripts/prunesafe-invoke.sh b/high-throughput/scripts/prunesafe-invoke.sh index 8c39e422..e42019e8 100755 --- a/high-throughput/scripts/prunesafe-invoke.sh +++ b/high-throughput/scripts/prunesafe-invoke.sh @@ -1,2 +1,8 @@ +# +# Copyright IBM Corp All Rights Reserved +# +# SPDX-License-Identifier: Apache-2.0 +# + peer chaincode invoke -o orderer.example.com:7050 --tls $CORE_PEER_TLS_ENABLED --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem -C $CHANNEL_NAME -n $CC_NAME -c '{"Args":["prunesafe","'$1'"]}' diff --git a/high-throughput/scripts/setclienv.sh b/high-throughput/scripts/setclienv.sh index 9e7e8bc8..8e953500 100644 --- a/high-throughput/scripts/setclienv.sh +++ b/high-throughput/scripts/setclienv.sh @@ -1,2 +1,8 @@ +# +# Copyright IBM Corp All Rights Reserved +# +# SPDX-License-Identifier: Apache-2.0 +# + export CHANNEL_NAME=mychannel export CC_NAME=bigdatacc diff --git a/high-throughput/scripts/update-invoke.sh b/high-throughput/scripts/update-invoke.sh index 7f51f9ba..d49b2ccc 100755 --- a/high-throughput/scripts/update-invoke.sh +++ b/high-throughput/scripts/update-invoke.sh @@ -1,2 +1,8 @@ +# +# Copyright IBM Corp All Rights Reserved +# +# SPDX-License-Identifier: Apache-2.0 +# + peer chaincode invoke -o orderer.example.com:7050 --tls $CORE_PEER_TLS_ENABLED --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem -C $CHANNEL_NAME -n $CC_NAME -c '{"Args":["update","'$1'","'$2'","'$3'"]}' diff --git a/high-throughput/scripts/upgrade-chaincode.sh b/high-throughput/scripts/upgrade-chaincode.sh index 78d0b83f..add1b8c7 100755 --- a/high-throughput/scripts/upgrade-chaincode.sh +++ b/high-throughput/scripts/upgrade-chaincode.sh @@ -1,3 +1,9 @@ +# +# Copyright IBM Corp All Rights Reserved +# +# SPDX-License-Identifier: Apache-2.0 +# + echo "========== Upgrade chaincode to version $1 ==========" peer chaincode upgrade -o orderer.example.com:7050 --tls $CORE_PEER_TLS_ENABLED --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem -C $CHANNEL_NAME -n $CC_NAME -c '{"Args": []}' -v $1 -P "OR ('Org1MSP.member','Org2MSP.member')" From b5dad8cd25a778e1c9c957bcab325c7b79ca4a8d Mon Sep 17 00:00:00 2001 From: Will Lahti Date: Wed, 2 May 2018 11:30:41 -0400 Subject: [PATCH 16/29] [FAB-9317] Update first-network with multi endorse This CR updates the first-network (BYFN and EYFN) to use an 'AND (...)' endorsement policy. It also cleans up some of the output and fixes the line length of some comments. Change-Id: I741f41226955ccfcd3eb5369d8ba6eb77e49e89e Signed-off-by: Will Lahti --- first-network/docker-compose-org3.yaml | 2 + first-network/scripts/script.sh | 11 ++- first-network/scripts/step1org3.sh | 1 - first-network/scripts/step2org3.sh | 9 +-- first-network/scripts/step3org3.sh | 1 - first-network/scripts/testorg3.sh | 11 ++- first-network/scripts/upgrade_to_v11.sh | 1 - first-network/scripts/utils.sh | 93 ++++++++++++++++++------- 8 files changed, 85 insertions(+), 44 deletions(-) diff --git a/first-network/docker-compose-org3.yaml b/first-network/docker-compose-org3.yaml index c46ad4e3..49fc939c 100644 --- a/first-network/docker-compose-org3.yaml +++ b/first-network/docker-compose-org3.yaml @@ -82,6 +82,8 @@ services: - /var/run/:/host/var/run/ - ./../chaincode/:/opt/gopath/src/github.com/chaincode - ./org3-artifacts/crypto-config:/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ + - ./crypto-config/peerOrganizations/org1.example.com:/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com + - ./crypto-config/peerOrganizations/org2.example.com:/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com - ./scripts:/opt/gopath/src/github.com/hyperledger/fabric/peer/scripts/ depends_on: - peer0.org3.example.com diff --git a/first-network/scripts/script.sh b/first-network/scripts/script.sh index 7823d600..1d43a37e 100755 --- a/first-network/scripts/script.sh +++ b/first-network/scripts/script.sh @@ -22,7 +22,6 @@ VERBOSE="$5" LANGUAGE=`echo "$LANGUAGE" | tr [:upper:] [:lower:]` COUNTER=1 MAX_RETRY=5 -ORDERER_CA=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem CC_SRC_PATH="github.com/chaincode/chaincode_example02/go/" if [ "$LANGUAGE" = "node" ]; then @@ -50,7 +49,7 @@ createChannel() { fi cat log.txt verifyResult $res "Channel creation failed" - echo "===================== Channel \"$CHANNEL_NAME\" is created successfully ===================== " + echo "===================== Channel '$CHANNEL_NAME' created ===================== " echo } @@ -58,7 +57,7 @@ joinChannel () { for org in 1 2; do for peer in 0 1; do joinChannelWithRetry $peer $org - echo "===================== peer${peer}.org${org} joined on the channel \"$CHANNEL_NAME\" ===================== " + echo "===================== peer${peer}.org${org} joined channel '$CHANNEL_NAME' ===================== " sleep $DELAY echo done @@ -93,9 +92,9 @@ instantiateChaincode 0 2 echo "Querying chaincode on peer0.org1..." chaincodeQuery 0 1 100 -# Invoke chaincode on peer0.org1 -echo "Sending invoke transaction on peer0.org1..." -chaincodeInvoke 0 1 +# Invoke chaincode on peer0.org1 and peer0.org2 +echo "Sending invoke transaction on peer0.org1 peer0.org2..." +chaincodeInvoke 0 1 0 2 ## Install chaincode on peer1.org2 echo "Installing chaincode on peer1.org2..." diff --git a/first-network/scripts/step1org3.sh b/first-network/scripts/step1org3.sh index 2efb64da..bff4d6a0 100755 --- a/first-network/scripts/step1org3.sh +++ b/first-network/scripts/step1org3.sh @@ -24,7 +24,6 @@ VERBOSE="$5" LANGUAGE=`echo "$LANGUAGE" | tr [:upper:] [:lower:]` COUNTER=1 MAX_RETRY=5 -ORDERER_CA=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem CC_SRC_PATH="github.com/chaincode/chaincode_example02/go/" if [ "$LANGUAGE" = "node" ]; then diff --git a/first-network/scripts/step2org3.sh b/first-network/scripts/step2org3.sh index f4df00d4..75745ef9 100755 --- a/first-network/scripts/step2org3.sh +++ b/first-network/scripts/step2org3.sh @@ -27,7 +27,6 @@ VERBOSE="$5" LANGUAGE=`echo "$LANGUAGE" | tr [:upper:] [:lower:]` COUNTER=1 MAX_RETRY=5 -ORDERER_CA=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem CC_SRC_PATH="github.com/chaincode/chaincode_example02/go/" if [ "$LANGUAGE" = "node" ]; then @@ -45,17 +44,15 @@ set +x cat log.txt verifyResult $res "Fetching config block from orderer has Failed" -echo "===================== Having peer0.org3 join the channel ===================== " joinChannelWithRetry 0 3 -echo "===================== peer0.org3 joined the channel \"$CHANNEL_NAME\" ===================== " -echo "===================== Having peer1.org3 join the channel ===================== " +echo "===================== peer0.org3 joined channel '$CHANNEL_NAME' ===================== " joinChannelWithRetry 1 3 -echo "===================== peer1.org3 joined the channel \"$CHANNEL_NAME\" ===================== " +echo "===================== peer1.org3 joined channel '$CHANNEL_NAME' ===================== " echo "Installing chaincode 2.0 on peer0.org3..." installChaincode 0 3 2.0 echo -echo "========= Got Org3 halfway onto your first network ========= " +echo "========= Org3 is now halfway onto your first network ========= " echo exit 0 diff --git a/first-network/scripts/step3org3.sh b/first-network/scripts/step3org3.sh index 895a4513..9588a8b8 100755 --- a/first-network/scripts/step3org3.sh +++ b/first-network/scripts/step3org3.sh @@ -28,7 +28,6 @@ VERBOSE="$5" LANGUAGE=`echo "$LANGUAGE" | tr [:upper:] [:lower:]` COUNTER=1 MAX_RETRY=5 -ORDERER_CA=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem CC_SRC_PATH="github.com/chaincode/chaincode_example02/go/" if [ "$LANGUAGE" = "node" ]; then diff --git a/first-network/scripts/testorg3.sh b/first-network/scripts/testorg3.sh index 7c3685e8..71338775 100755 --- a/first-network/scripts/testorg3.sh +++ b/first-network/scripts/testorg3.sh @@ -32,7 +32,6 @@ VERBOSE="$5" LANGUAGE=`echo "$LANGUAGE" | tr [:upper:] [:lower:]` COUNTER=1 MAX_RETRY=5 -ORDERER_CA=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem CC_SRC_PATH="github.com/chaincode/chaincode_example02/go/" if [ "$LANGUAGE" = "node" ]; then @@ -44,8 +43,16 @@ echo "Channel name : "$CHANNEL_NAME # import functions . scripts/utils.sh +# Query chaincode on peer0.org3, check if the result is 90 +echo "Querying chaincode on peer0.org3..." chaincodeQuery 0 3 90 -chaincodeInvoke 0 3 + +# Invoke chaincode on peer0.org1, peer0.org2, and peer0.org3 +echo "Sending invoke transaction on peer0.org1 peer0.org2 peer0.org3..." +chaincodeInvoke 0 1 0 2 0 3 + +# Query on chaincode on peer0.org3, check if the result is 80 +echo "Querying chaincode on peer0.org3..." chaincodeQuery 0 3 80 echo diff --git a/first-network/scripts/upgrade_to_v11.sh b/first-network/scripts/upgrade_to_v11.sh index 54ee8905..93ab6f61 100755 --- a/first-network/scripts/upgrade_to_v11.sh +++ b/first-network/scripts/upgrade_to_v11.sh @@ -22,7 +22,6 @@ VERBOSE="$5" LANGUAGE=`echo "$LANGUAGE" | tr [:upper:] [:lower:]` COUNTER=1 MAX_RETRY=5 -ORDERER_CA=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem CC_SRC_PATH="github.com/chaincode/chaincode_example02/go/" if [ "$LANGUAGE" = "node" ]; then diff --git a/first-network/scripts/utils.sh b/first-network/scripts/utils.sh index f53b2698..a82eed8a 100755 --- a/first-network/scripts/utils.sh +++ b/first-network/scripts/utils.sh @@ -6,6 +6,10 @@ # This is a collection of bash functions used by different scripts +ORDERER_CA=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem +PEER0_ORG1_CA=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt +PEER0_ORG2_CA=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt +PEER0_ORG3_CA=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org3.example.com/peers/peer0.org3.example.com/tls/ca.crt # verify the result of the end-to-end test verifyResult () { @@ -29,7 +33,7 @@ setGlobals () { ORG=$2 if [ $ORG -eq 1 ] ; then CORE_PEER_LOCALMSPID="Org1MSP" - CORE_PEER_TLS_ROOTCERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt + CORE_PEER_TLS_ROOTCERT_FILE=$PEER0_ORG1_CA CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp if [ $PEER -eq 0 ]; then CORE_PEER_ADDRESS=peer0.org1.example.com:7051 @@ -38,7 +42,7 @@ setGlobals () { fi elif [ $ORG -eq 2 ] ; then CORE_PEER_LOCALMSPID="Org2MSP" - CORE_PEER_TLS_ROOTCERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt + CORE_PEER_TLS_ROOTCERT_FILE=$PEER0_ORG2_CA CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/users/Admin@org2.example.com/msp if [ $PEER -eq 0 ]; then CORE_PEER_ADDRESS=peer0.org2.example.com:7051 @@ -48,7 +52,7 @@ setGlobals () { elif [ $ORG -eq 3 ] ; then CORE_PEER_LOCALMSPID="Org3MSP" - CORE_PEER_TLS_ROOTCERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org3.example.com/peers/peer0.org3.example.com/tls/ca.crt + CORE_PEER_TLS_ROOTCERT_FILE=$PEER0_ORG3_CA CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org3.example.com/users/Admin@org3.example.com/msp if [ $PEER -eq 0 ]; then CORE_PEER_ADDRESS=peer0.org3.example.com:7051 @@ -83,12 +87,12 @@ updateAnchorPeers() { fi cat log.txt verifyResult $res "Anchor peer update failed" - echo "===================== Anchor peers for org \"$CORE_PEER_LOCALMSPID\" on \"$CHANNEL_NAME\" is updated successfully ===================== " + echo "===================== Anchor peers updated for org '$CORE_PEER_LOCALMSPID' on channel '$CHANNEL_NAME' ===================== " sleep $DELAY echo } -## Sometimes Join takes time hence RETRY at least for 5 times +## Sometimes Join takes time hence RETRY at least 5 times joinChannelWithRetry () { PEER=$1 ORG=$2 @@ -107,7 +111,7 @@ joinChannelWithRetry () { else COUNTER=1 fi - verifyResult $res "After $MAX_RETRY attempts, peer${PEER}.org${ORG} has failed to Join the Channel" + verifyResult $res "After $MAX_RETRY attempts, peer${PEER}.org${ORG} has failed to join channel '$CHANNEL_NAME' " } installChaincode () { @@ -120,7 +124,7 @@ installChaincode () { res=$? set +x cat log.txt - verifyResult $res "Chaincode installation on peer${PEER}.org${ORG} has Failed" + verifyResult $res "Chaincode installation on peer${PEER}.org${ORG} has failed" echo "===================== Chaincode is installed on peer${PEER}.org${ORG} ===================== " echo } @@ -131,22 +135,23 @@ instantiateChaincode () { setGlobals $PEER $ORG VERSION=${3:-1.0} - # while 'peer chaincode' command can get the orderer endpoint from the peer (if join was successful), - # lets supply it directly as we know it using the "-o" option + # while 'peer chaincode' command can get the orderer endpoint from the peer + # (if join was successful), let's supply it directly as we know it using + # the "-o" option if [ -z "$CORE_PEER_TLS_ENABLED" -o "$CORE_PEER_TLS_ENABLED" = "false" ]; then set -x - peer chaincode instantiate -o orderer.example.com:7050 -C $CHANNEL_NAME -n mycc -l ${LANGUAGE} -v ${VERSION} -c '{"Args":["init","a","100","b","200"]}' -P "OR ('Org1MSP.peer','Org2MSP.peer')" >&log.txt + peer chaincode instantiate -o orderer.example.com:7050 -C $CHANNEL_NAME -n mycc -l ${LANGUAGE} -v ${VERSION} -c '{"Args":["init","a","100","b","200"]}' -P "AND ('Org1MSP.peer','Org2MSP.peer')" >&log.txt res=$? set +x else set -x - peer chaincode instantiate -o orderer.example.com:7050 --tls $CORE_PEER_TLS_ENABLED --cafile $ORDERER_CA -C $CHANNEL_NAME -n mycc -l ${LANGUAGE} -v 1.0 -c '{"Args":["init","a","100","b","200"]}' -P "OR ('Org1MSP.peer','Org2MSP.peer')" >&log.txt + peer chaincode instantiate -o orderer.example.com:7050 --tls $CORE_PEER_TLS_ENABLED --cafile $ORDERER_CA -C $CHANNEL_NAME -n mycc -l ${LANGUAGE} -v 1.0 -c '{"Args":["init","a","100","b","200"]}' -P "AND ('Org1MSP.peer','Org2MSP.peer')" >&log.txt res=$? set +x fi cat log.txt verifyResult $res "Chaincode instantiation on peer${PEER}.org${ORG} on channel '$CHANNEL_NAME' failed" - echo "===================== Chaincode Instantiation on peer${PEER}.org${ORG} on channel '$CHANNEL_NAME' is successful ===================== " + echo "===================== Chaincode is instantiated on peer${PEER}.org${ORG} on channel '$CHANNEL_NAME' ===================== " echo } @@ -156,12 +161,12 @@ upgradeChaincode () { setGlobals $PEER $ORG set -x - peer chaincode upgrade -o orderer.example.com:7050 --tls $CORE_PEER_TLS_ENABLED --cafile $ORDERER_CA -C $CHANNEL_NAME -n mycc -v 2.0 -c '{"Args":["init","a","90","b","210"]}' -P "OR ('Org1MSP.peer','Org2MSP.peer','Org3MSP.peer')" + peer chaincode upgrade -o orderer.example.com:7050 --tls $CORE_PEER_TLS_ENABLED --cafile $ORDERER_CA -C $CHANNEL_NAME -n mycc -v 2.0 -c '{"Args":["init","a","90","b","210"]}' -P "AND ('Org1MSP.peer','Org2MSP.peer','Org3MSP.peer')" res=$? set +x cat log.txt - verifyResult $res "Chaincode upgrade on org${ORG} peer${PEER} has Failed" - echo "===================== Chaincode is upgraded on org${ORG} peer${PEER} ===================== " + verifyResult $res "Chaincode upgrade on peer${PEER}.org${ORG} has failed" + echo "===================== Chaincode is upgraded on peer${PEER}.org${ORG} on channel '$CHANNEL_NAME' ===================== " echo } @@ -186,14 +191,16 @@ chaincodeQuery () { set +x test $res -eq 0 && VALUE=$(cat log.txt | awk '/Query Result/ {print $NF}') test "$VALUE" = "$EXPECTED_RESULT" && let rc=0 - # removed the string "Query Result" from peer chaincode query command result, as a result, have to support both options until the change is merged. + # removed the string "Query Result" from peer chaincode query command + # result. as a result, have to support both options until the change + # is merged. test $rc -ne 0 && VALUE=$(cat log.txt | egrep '^[0-9]+$') test "$VALUE" = "$EXPECTED_RESULT" && let rc=0 done echo cat log.txt if test $rc -eq 0 ; then - echo "===================== Query on peer${PEER}.org${ORG} on channel '$CHANNEL_NAME' is successful ===================== " + echo "===================== Query successful on peer${PEER}.org${ORG} on channel '$CHANNEL_NAME' ===================== " else echo "!!!!!!!!!!!!!!! Query result on peer${PEER}.org${ORG} is INVALID !!!!!!!!!!!!!!!!" echo "================== ERROR !!! FAILED to execute End-2-End Scenario ==================" @@ -239,7 +246,8 @@ signConfigtxAsPeerOrg() { } # createConfigUpdate -# Takes an original and modified config, and produces the config update tx which transitions between the two +# Takes an original and modified config, and produces the config update tx +# which transitions between the two createConfigUpdate() { CHANNEL=$1 ORIGINAL=$2 @@ -256,25 +264,56 @@ createConfigUpdate() { set +x } +# parsePeerConnectionParameters $@ +# Helper function that takes the parameters from a chaincode operation +# (e.g. invoke, query, instantiate) and checks for an even number of +# peers and associated org, then sets $PEER_CONN_PARMS and $PEERS +parsePeerConnectionParameters() { + # check for uneven number of peer and org parameters + if [ $(( $# % 2 )) -ne 0 ]; then + exit 1 + fi + + PEER_CONN_PARMS="" + PEERS="" + while [ "$#" -gt 0 ]; do + PEER="peer$1.org$2" + PEERS="$PEERS $PEER" + PEER_CONN_PARMS="$PEER_CONN_PARMS --peerAddresses $PEER.example.com:7051" + if [ -z "$CORE_PEER_TLS_ENABLED" -o "$CORE_PEER_TLS_ENABLED" = "true" ]; then + TLSINFO=$(eval echo "--tlsRootCertFiles \$PEER$1_ORG$2_CA") + PEER_CONN_PARMS="$PEER_CONN_PARMS $TLSINFO" + fi + # shift by two to get the next pair of peer/org parameters + shift; shift + done + # remove leading space for output + PEERS="$(echo -e "$PEERS" | sed -e 's/^[[:space:]]*//')" +} + +# chaincodeInvoke ... +# Accepts as many peer/org pairs as desired and requests endorsement from each chaincodeInvoke () { - PEER=$1 - ORG=$2 - setGlobals $PEER $ORG - # while 'peer chaincode' command can get the orderer endpoint from the peer (if join was successful), - # lets supply it directly as we know it using the "-o" option + parsePeerConnectionParameters $@ + res=$? + verifyResult $res "Invoke transaction failed on channel '$CHANNEL_NAME' due to uneven number of peer and org parameters " + + # while 'peer chaincode' command can get the orderer endpoint from the + # peer (if join was successful), let's supply it directly as we know + # it using the "-o" option if [ -z "$CORE_PEER_TLS_ENABLED" -o "$CORE_PEER_TLS_ENABLED" = "false" ]; then set -x - peer chaincode invoke -o orderer.example.com:7050 -C $CHANNEL_NAME -n mycc -c '{"Args":["invoke","a","b","10"]}' >&log.txt + peer chaincode invoke -o orderer.example.com:7050 -C $CHANNEL_NAME -n mycc $PEER_CONN_PARMS -c '{"Args":["invoke","a","b","10"]}' >&log.txt res=$? set +x else set -x - peer chaincode invoke -o orderer.example.com:7050 --tls $CORE_PEER_TLS_ENABLED --cafile $ORDERER_CA -C $CHANNEL_NAME -n mycc -c '{"Args":["invoke","a","b","10"]}' >&log.txt + peer chaincode invoke -o orderer.example.com:7050 --tls $CORE_PEER_TLS_ENABLED --cafile $ORDERER_CA -C $CHANNEL_NAME -n mycc $PEER_CONN_PARMS -c '{"Args":["invoke","a","b","10"]}' >&log.txt res=$? set +x fi cat log.txt - verifyResult $res "Invoke execution on peer${PEER}.org${ORG} failed " - echo "===================== Invoke transaction on peer${PEER}.org${ORG} on channel '$CHANNEL_NAME' is successful ===================== " + verifyResult $res "Invoke execution on $PEERS failed " + echo "===================== Invoke transaction successful on $PEERS on channel '$CHANNEL_NAME' ===================== " echo } From 98561e09196954a9f8ef7317fba69b2ef4b4db2a Mon Sep 17 00:00:00 2001 From: Qiang Yiting Date: Wed, 18 Apr 2018 00:32:41 +0800 Subject: [PATCH 17/29] FAB-9552 Fix access of an un-declared variable Change-Id: Ia518b5733e69a999a304d251390999fa1291b4eb Signed-off-by: Qiang Yiting --- fabcar/invoke.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fabcar/invoke.js b/fabcar/invoke.js index 1c0270ac..221e2c00 100644 --- a/fabcar/invoke.js +++ b/fabcar/invoke.js @@ -148,7 +148,7 @@ Fabric_Client.newDefaultKeyValueStore({ path: store_path if (results && results[0] && results[0].status === 'SUCCESS') { console.log('Successfully sent transaction to the orderer.'); } else { - console.error('Failed to order the transaction. Error code: ' + response.status); + console.error('Failed to order the transaction. Error code: ' + results[0].status); } if(results && results[1] && results[1].event_status === 'VALID') { From fa1d8997af02861234bad1bec9640c2ad9544218 Mon Sep 17 00:00:00 2001 From: "Robert P. J. Day" Date: Fri, 4 May 2018 11:46:33 -0400 Subject: [PATCH 18/29] [FAB-9893] Add .gitreview file for quicker Gerrit setup Change-Id: I48e870e2e2b487209ba894dfd4293d3c1dbece1b Signed-off-by: Robert P. J. Day --- .gitreview | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .gitreview diff --git a/.gitreview b/.gitreview new file mode 100644 index 00000000..c1d6cb23 --- /dev/null +++ b/.gitreview @@ -0,0 +1,5 @@ +# SPDX-License-Identifier: Apache-2.0 +[gerrit] +host=gerrit.hyperledger.org +port=29418 +project=fabric-samples From ace2e5ab9165913f3a2a497bde03e55f56cc83f1 Mon Sep 17 00:00:00 2001 From: weikeng Date: Sat, 12 May 2018 08:06:56 -0700 Subject: [PATCH 19/29] [FAB-10021] Typo in balance-transfer/testAPIs.sh There is a typo for transaction in testAPIs.sh Change-Id: I0f8ca7b2a9003b5f85ba980cab5eff80853b03dc Signed-off-by: weikeng --- balance-transfer/testAPIs.sh | 2 +- balance-transfer/typescript/testAPIs.sh | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/balance-transfer/testAPIs.sh b/balance-transfer/testAPIs.sh index 57673c63..e83a672e 100755 --- a/balance-transfer/testAPIs.sh +++ b/balance-transfer/testAPIs.sh @@ -170,7 +170,7 @@ TRX_ID=$(curl -s -X POST \ "fcn":"move", "args":["a","b","10"] }') -echo "Transacton ID is $TRX_ID" +echo "Transaction ID is $TRX_ID" echo echo diff --git a/balance-transfer/typescript/testAPIs.sh b/balance-transfer/typescript/testAPIs.sh index 63430ad7..8447ad2c 100755 --- a/balance-transfer/typescript/testAPIs.sh +++ b/balance-transfer/typescript/testAPIs.sh @@ -128,7 +128,7 @@ TRX_ID=$(curl -s -X POST \ "fcn":"move", "args":["a","b","10"] }') -echo "Transacton ID is $TRX_ID" +echo "Transaction ID is $TRX_ID" echo echo From cad2b9804414213b08fd965c50fbedcff9cb3699 Mon Sep 17 00:00:00 2001 From: Yuki Kondo Date: Tue, 15 May 2018 17:37:26 +0000 Subject: [PATCH 20/29] [FAB-10073] Fix broken link in samples/fabric-ca/README This CR fixes the broken link to the document of ABAC in fabric-samples/fabric-ca/README.md. Change-Id: I2aff8a2c6b1f3e208f211f20f9237d8c3efd14d8 Signed-off-by: Yuki Kondo --- fabric-ca/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fabric-ca/README.md b/fabric-ca/README.md index 3a88c602..9c11e16f 100755 --- a/fabric-ca/README.md +++ b/fabric-ca/README.md @@ -81,7 +81,7 @@ with a value of "true". Note further that the chaincode used by this sample requires this attribute be included in the certificate of the identity that invokes its Init function. See the chaincode at *fabric-samples/chaincode/abac/abac.go*). For more information on Attribute-Based Access Control (ABAC), see -https://github.com/hyperledger/fabric/tree/release/core/chaincode/lib/cid/README.md. +https://github.com/hyperledger/fabric/blob/master/core/chaincode/lib/cid/README.md. 4. The orderer and peer containers are started. The naming of these containers is straight-forward as is their log files in the *data/logs* directory. From e2f4f20bd68ddfdb1d2d89bb079e9cfe8810fcd9 Mon Sep 17 00:00:00 2001 From: Matthew Sykes Date: Thu, 17 May 2018 08:41:05 -0400 Subject: [PATCH 21/29] [FAB-10176] Fix invalid configtx.yaml documents Change-Id: Ibf52f9380ed3b724c594b53550321a12475e9860 Signed-off-by: Matthew Sykes --- .../artifacts/channel/configtx.yaml | 132 ++++++++--------- basic-network/configtx.yaml | 133 ++++++++--------- first-network/configtx.yaml | 138 +++++++++--------- 3 files changed, 202 insertions(+), 201 deletions(-) diff --git a/balance-transfer/artifacts/channel/configtx.yaml b/balance-transfer/artifacts/channel/configtx.yaml index 4cf7ffe9..17822296 100644 --- a/balance-transfer/artifacts/channel/configtx.yaml +++ b/balance-transfer/artifacts/channel/configtx.yaml @@ -6,31 +6,48 @@ --- ################################################################################ # -# Profile +# SECTION: Orderer # -# - Different configuration profiles may be encoded here to be specified -# as parameters to the configtxgen tool +# - This section defines the values to encode into a config transaction or +# genesis block for orderer related parameters # ################################################################################ -Profiles: +Orderer: &OrdererDefaults - TwoOrgsOrdererGenesis: - Orderer: - <<: *OrdererDefaults - Organizations: - - *OrdererOrg - Consortiums: - SampleConsortium: - Organizations: - - *Org1 - - *Org2 - TwoOrgsChannel: - Consortium: SampleConsortium - Application: - <<: *ApplicationDefaults - Organizations: - - *Org1 - - *Org2 + # Orderer Type: The orderer implementation to start + # Available types are "solo" and "kafka" + OrdererType: solo + + Addresses: + - orderer.example.com:7050 + + # Batch Timeout: The amount of time to wait before creating a batch + BatchTimeout: 2s + + # Batch Size: Controls the number of messages batched into a block + BatchSize: + + # Max Message Count: The maximum number of messages to permit in a batch + MaxMessageCount: 10 + + # Absolute Max Bytes: The absolute maximum number of bytes allowed for + # the serialized messages in a batch. + AbsoluteMaxBytes: 98 MB + + # Preferred Max Bytes: The preferred maximum number of bytes allowed for + # the serialized messages in a batch. A message larger than the preferred + # max bytes will result in a batch larger than preferred max bytes. + PreferredMaxBytes: 512 KB + + Kafka: + # Brokers: A list of Kafka brokers to which the orderer connects + # NOTE: Use IP:port notation + Brokers: + - 127.0.0.1:9092 + + # Organizations is the list of orgs which are defined as participants on + # the orderer side of the network + Organizations: ################################################################################ # @@ -89,51 +106,6 @@ Organizations: - Host: peer0.org2.example.com Port: 7051 -################################################################################ -# -# SECTION: Orderer -# -# - This section defines the values to encode into a config transaction or -# genesis block for orderer related parameters -# -################################################################################ -Orderer: &OrdererDefaults - - # Orderer Type: The orderer implementation to start - # Available types are "solo" and "kafka" - OrdererType: solo - - Addresses: - - orderer.example.com:7050 - - # Batch Timeout: The amount of time to wait before creating a batch - BatchTimeout: 2s - - # Batch Size: Controls the number of messages batched into a block - BatchSize: - - # Max Message Count: The maximum number of messages to permit in a batch - MaxMessageCount: 10 - - # Absolute Max Bytes: The absolute maximum number of bytes allowed for - # the serialized messages in a batch. - AbsoluteMaxBytes: 98 MB - - # Preferred Max Bytes: The preferred maximum number of bytes allowed for - # the serialized messages in a batch. A message larger than the preferred - # max bytes will result in a batch larger than preferred max bytes. - PreferredMaxBytes: 512 KB - - Kafka: - # Brokers: A list of Kafka brokers to which the orderer connects - # NOTE: Use IP:port notation - Brokers: - - 127.0.0.1:9092 - - # Organizations is the list of orgs which are defined as participants on - # the orderer side of the network - Organizations: - ################################################################################ # # SECTION: Application @@ -147,3 +119,31 @@ Application: &ApplicationDefaults # Organizations is the list of orgs which are defined as participants on # the application side of the network Organizations: + +################################################################################ +# +# Profile +# +# - Different configuration profiles may be encoded here to be specified +# as parameters to the configtxgen tool +# +################################################################################ +Profiles: + + TwoOrgsOrdererGenesis: + Orderer: + <<: *OrdererDefaults + Organizations: + - *OrdererOrg + Consortiums: + SampleConsortium: + Organizations: + - *Org1 + - *Org2 + TwoOrgsChannel: + Consortium: SampleConsortium + Application: + <<: *ApplicationDefaults + Organizations: + - *Org1 + - *Org2 diff --git a/basic-network/configtx.yaml b/basic-network/configtx.yaml index f157db20..a4e11ea7 100644 --- a/basic-network/configtx.yaml +++ b/basic-network/configtx.yaml @@ -4,72 +4,6 @@ # --- -################################################################################ -# -# Profile -# -# - Different configuration profiles may be encoded here to be specified -# as parameters to the configtxgen tool -# -################################################################################ -Profiles: - - OneOrgOrdererGenesis: - Orderer: - <<: *OrdererDefaults - Organizations: - - *OrdererOrg - Consortiums: - SampleConsortium: - Organizations: - - *Org1 - OneOrgChannel: - Consortium: SampleConsortium - Application: - <<: *ApplicationDefaults - Organizations: - - *Org1 - -################################################################################ -# -# Section: Organizations -# -# - This section defines the different organizational identities which will -# be referenced later in the configuration. -# -################################################################################ -Organizations: - - # SampleOrg defines an MSP using the sampleconfig. It should never be used - # in production but may be used as a template for other definitions - - &OrdererOrg - # DefaultOrg defines the organization which is used in the sampleconfig - # of the fabric.git development environment - Name: OrdererOrg - - # ID to load the MSP definition as - ID: OrdererMSP - - # MSPDir is the filesystem path which contains the MSP configuration - MSPDir: crypto-config/ordererOrganizations/example.com/msp - - - &Org1 - # DefaultOrg defines the organization which is used in the sampleconfig - # of the fabric.git development environment - Name: Org1MSP - - # ID to load the MSP definition as - ID: Org1MSP - - MSPDir: crypto-config/peerOrganizations/org1.example.com/msp - - AnchorPeers: - # AnchorPeers defines the location of peers which can be used - # for cross org gossip communication. Note, this value is only - # encoded in the genesis block in the Application section context - - Host: peer0.org1.example.com - Port: 7051 - ################################################################################ # # SECTION: Orderer @@ -115,6 +49,46 @@ Orderer: &OrdererDefaults # the orderer side of the network Organizations: +################################################################################ +# +# Section: Organizations +# +# - This section defines the different organizational identities which will +# be referenced later in the configuration. +# +################################################################################ +Organizations: + + # SampleOrg defines an MSP using the sampleconfig. It should never be used + # in production but may be used as a template for other definitions + - &OrdererOrg + # DefaultOrg defines the organization which is used in the sampleconfig + # of the fabric.git development environment + Name: OrdererOrg + + # ID to load the MSP definition as + ID: OrdererMSP + + # MSPDir is the filesystem path which contains the MSP configuration + MSPDir: crypto-config/ordererOrganizations/example.com/msp + + - &Org1 + # DefaultOrg defines the organization which is used in the sampleconfig + # of the fabric.git development environment + Name: Org1MSP + + # ID to load the MSP definition as + ID: Org1MSP + + MSPDir: crypto-config/peerOrganizations/org1.example.com/msp + + AnchorPeers: + # AnchorPeers defines the location of peers which can be used + # for cross org gossip communication. Note, this value is only + # encoded in the genesis block in the Application section context + - Host: peer0.org1.example.com + Port: 7051 + ################################################################################ # # SECTION: Application @@ -128,3 +102,30 @@ Application: &ApplicationDefaults # Organizations is the list of orgs which are defined as participants on # the application side of the network Organizations: + +################################################################################ +# +# Profile +# +# - Different configuration profiles may be encoded here to be specified +# as parameters to the configtxgen tool +# +################################################################################ +Profiles: + + OneOrgOrdererGenesis: + Orderer: + <<: *OrdererDefaults + Organizations: + - *OrdererOrg + Consortiums: + SampleConsortium: + Organizations: + - *Org1 + OneOrgChannel: + Consortium: SampleConsortium + Application: + <<: *ApplicationDefaults + Organizations: + - *Org1 + diff --git a/first-network/configtx.yaml b/first-network/configtx.yaml index 31c545c3..daa59ec2 100644 --- a/first-network/configtx.yaml +++ b/first-network/configtx.yaml @@ -6,37 +6,52 @@ --- ################################################################################ # -# Profile +# SECTION: Capabilities # -# - Different configuration profiles may be encoded here to be specified -# as parameters to the configtxgen tool +# - This section defines the capabilities of fabric network. This is a new +# concept as of v1.1.0 and should not be utilized in mixed networks with +# v1.0.x peers and orderers. Capabilities define features which must be +# present in a fabric binary for that binary to safely participate in the +# fabric network. For instance, if a new MSP type is added, newer binaries +# might recognize and validate the signatures from this type, while older +# binaries without this support would be unable to validate those +# transactions. This could lead to different versions of the fabric binaries +# having different world states. Instead, defining a capability for a channel +# informs those binaries without this capability that they must cease +# processing transactions until they have been upgraded. For v1.0.x if any +# capabilities are defined (including a map with all capabilities turned off) +# then the v1.0.x peer will deliberately crash. # ################################################################################ -Profiles: +Capabilities: + # Channel capabilities apply to both the orderers and the peers and must be + # supported by both. Set the value of the capability to true to require it. + Global: &ChannelCapabilities + # V1.1 for Global is a catchall flag for behavior which has been + # determined to be desired for all orderers and peers running v1.0.x, + # but the modification of which would cause incompatibilities. Users + # should leave this flag set to true. + V1_1: true - TwoOrgsOrdererGenesis: - Capabilities: - <<: *ChannelCapabilities - Orderer: - <<: *OrdererDefaults - Organizations: - - *OrdererOrg - Capabilities: - <<: *OrdererCapabilities - Consortiums: - SampleConsortium: - Organizations: - - *Org1 - - *Org2 - TwoOrgsChannel: - Consortium: SampleConsortium - Application: - <<: *ApplicationDefaults - Organizations: - - *Org1 - - *Org2 - Capabilities: - <<: *ApplicationCapabilities + # Orderer capabilities apply only to the orderers, and may be safely + # manipulated without concern for upgrading peers. Set the value of the + # capability to true to require it. + Orderer: &OrdererCapabilities + # V1.1 for Order is a catchall flag for behavior which has been + # determined to be desired for all orderers running v1.0.x, but the + # modification of which would cause incompatibilities. Users should + # leave this flag set to true. + V1_1: true + + # Application capabilities apply only to the peer network, and may be safely + # manipulated without concern for upgrading orderers. Set the value of the + # capability to true to require it. + Application: &ApplicationCapabilities + # V1.1 for Application is a catchall flag for behavior which has been + # determined to be desired for all peers running v1.0.x, but the + # modification of which would cause incompatibilities. Users should + # leave this flag set to true. + V1_1: true ################################################################################ # @@ -156,49 +171,34 @@ Application: &ApplicationDefaults ################################################################################ # -# SECTION: Capabilities +# Profile # -# - This section defines the capabilities of fabric network. This is a new -# concept as of v1.1.0 and should not be utilized in mixed networks with -# v1.0.x peers and orderers. Capabilities define features which must be -# present in a fabric binary for that binary to safely participate in the -# fabric network. For instance, if a new MSP type is added, newer binaries -# might recognize and validate the signatures from this type, while older -# binaries without this support would be unable to validate those -# transactions. This could lead to different versions of the fabric binaries -# having different world states. Instead, defining a capability for a channel -# informs those binaries without this capability that they must cease -# processing transactions until they have been upgraded. For v1.0.x if any -# capabilities are defined (including a map with all capabilities turned off) -# then the v1.0.x peer will deliberately crash. +# - Different configuration profiles may be encoded here to be specified +# as parameters to the configtxgen tool # ################################################################################ -Capabilities: - # Channel capabilities apply to both the orderers and the peers and must be - # supported by both. Set the value of the capability to true to require it. - Global: &ChannelCapabilities - # V1.1 for Global is a catchall flag for behavior which has been - # determined to be desired for all orderers and peers running v1.0.x, - # but the modification of which would cause incompatibilities. Users - # should leave this flag set to true. - V1_1: true +Profiles: - # Orderer capabilities apply only to the orderers, and may be safely - # manipulated without concern for upgrading peers. Set the value of the - # capability to true to require it. - Orderer: &OrdererCapabilities - # V1.1 for Order is a catchall flag for behavior which has been - # determined to be desired for all orderers running v1.0.x, but the - # modification of which would cause incompatibilities. Users should - # leave this flag set to true. - V1_1: true - - # Application capabilities apply only to the peer network, and may be safely - # manipulated without concern for upgrading orderers. Set the value of the - # capability to true to require it. - Application: &ApplicationCapabilities - # V1.1 for Application is a catchall flag for behavior which has been - # determined to be desired for all peers running v1.0.x, but the - # modification of which would cause incompatibilities. Users should - # leave this flag set to true. - V1_1: true + TwoOrgsOrdererGenesis: + Capabilities: + <<: *ChannelCapabilities + Orderer: + <<: *OrdererDefaults + Organizations: + - *OrdererOrg + Capabilities: + <<: *OrdererCapabilities + Consortiums: + SampleConsortium: + Organizations: + - *Org1 + - *Org2 + TwoOrgsChannel: + Consortium: SampleConsortium + Application: + <<: *ApplicationDefaults + Organizations: + - *Org1 + - *Org2 + Capabilities: + <<: *ApplicationCapabilities From 5cf19449f1efac855f73f1a5af8977804737eeba Mon Sep 17 00:00:00 2001 From: Matthew Sykes Date: Thu, 17 May 2018 11:06:09 -0400 Subject: [PATCH 22/29] [FAB-10185] Reorder for logical consistency Change-Id: I0274250c8c0c5d1801b6db0fb7bfce3359bb1c2f Signed-off-by: Matthew Sykes --- .../artifacts/channel/configtx.yaml | 90 ++++++------- basic-network/configtx.yaml | 90 ++++++------- first-network/configtx.yaml | 126 +++++++++--------- 3 files changed, 153 insertions(+), 153 deletions(-) diff --git a/balance-transfer/artifacts/channel/configtx.yaml b/balance-transfer/artifacts/channel/configtx.yaml index 17822296..98f5cb72 100644 --- a/balance-transfer/artifacts/channel/configtx.yaml +++ b/balance-transfer/artifacts/channel/configtx.yaml @@ -4,51 +4,6 @@ # --- -################################################################################ -# -# SECTION: Orderer -# -# - This section defines the values to encode into a config transaction or -# genesis block for orderer related parameters -# -################################################################################ -Orderer: &OrdererDefaults - - # Orderer Type: The orderer implementation to start - # Available types are "solo" and "kafka" - OrdererType: solo - - Addresses: - - orderer.example.com:7050 - - # Batch Timeout: The amount of time to wait before creating a batch - BatchTimeout: 2s - - # Batch Size: Controls the number of messages batched into a block - BatchSize: - - # Max Message Count: The maximum number of messages to permit in a batch - MaxMessageCount: 10 - - # Absolute Max Bytes: The absolute maximum number of bytes allowed for - # the serialized messages in a batch. - AbsoluteMaxBytes: 98 MB - - # Preferred Max Bytes: The preferred maximum number of bytes allowed for - # the serialized messages in a batch. A message larger than the preferred - # max bytes will result in a batch larger than preferred max bytes. - PreferredMaxBytes: 512 KB - - Kafka: - # Brokers: A list of Kafka brokers to which the orderer connects - # NOTE: Use IP:port notation - Brokers: - - 127.0.0.1:9092 - - # Organizations is the list of orgs which are defined as participants on - # the orderer side of the network - Organizations: - ################################################################################ # # Section: Organizations @@ -120,6 +75,51 @@ Application: &ApplicationDefaults # the application side of the network Organizations: +################################################################################ +# +# SECTION: Orderer +# +# - This section defines the values to encode into a config transaction or +# genesis block for orderer related parameters +# +################################################################################ +Orderer: &OrdererDefaults + + # Orderer Type: The orderer implementation to start + # Available types are "solo" and "kafka" + OrdererType: solo + + Addresses: + - orderer.example.com:7050 + + # Batch Timeout: The amount of time to wait before creating a batch + BatchTimeout: 2s + + # Batch Size: Controls the number of messages batched into a block + BatchSize: + + # Max Message Count: The maximum number of messages to permit in a batch + MaxMessageCount: 10 + + # Absolute Max Bytes: The absolute maximum number of bytes allowed for + # the serialized messages in a batch. + AbsoluteMaxBytes: 98 MB + + # Preferred Max Bytes: The preferred maximum number of bytes allowed for + # the serialized messages in a batch. A message larger than the preferred + # max bytes will result in a batch larger than preferred max bytes. + PreferredMaxBytes: 512 KB + + Kafka: + # Brokers: A list of Kafka brokers to which the orderer connects + # NOTE: Use IP:port notation + Brokers: + - 127.0.0.1:9092 + + # Organizations is the list of orgs which are defined as participants on + # the orderer side of the network + Organizations: + ################################################################################ # # Profile diff --git a/basic-network/configtx.yaml b/basic-network/configtx.yaml index a4e11ea7..98828ebc 100644 --- a/basic-network/configtx.yaml +++ b/basic-network/configtx.yaml @@ -4,51 +4,6 @@ # --- -################################################################################ -# -# SECTION: Orderer -# -# - This section defines the values to encode into a config transaction or -# genesis block for orderer related parameters -# -################################################################################ -Orderer: &OrdererDefaults - - # Orderer Type: The orderer implementation to start - # Available types are "solo" and "kafka" - OrdererType: solo - - Addresses: - - orderer.example.com:7050 - - # Batch Timeout: The amount of time to wait before creating a batch - BatchTimeout: 2s - - # Batch Size: Controls the number of messages batched into a block - BatchSize: - - # Max Message Count: The maximum number of messages to permit in a batch - MaxMessageCount: 10 - - # Absolute Max Bytes: The absolute maximum number of bytes allowed for - # the serialized messages in a batch. - AbsoluteMaxBytes: 99 MB - - # Preferred Max Bytes: The preferred maximum number of bytes allowed for - # the serialized messages in a batch. A message larger than the preferred - # max bytes will result in a batch larger than preferred max bytes. - PreferredMaxBytes: 512 KB - - Kafka: - # Brokers: A list of Kafka brokers to which the orderer connects - # NOTE: Use IP:port notation - Brokers: - - 127.0.0.1:9092 - - # Organizations is the list of orgs which are defined as participants on - # the orderer side of the network - Organizations: - ################################################################################ # # Section: Organizations @@ -103,6 +58,51 @@ Application: &ApplicationDefaults # the application side of the network Organizations: +################################################################################ +# +# SECTION: Orderer +# +# - This section defines the values to encode into a config transaction or +# genesis block for orderer related parameters +# +################################################################################ +Orderer: &OrdererDefaults + + # Orderer Type: The orderer implementation to start + # Available types are "solo" and "kafka" + OrdererType: solo + + Addresses: + - orderer.example.com:7050 + + # Batch Timeout: The amount of time to wait before creating a batch + BatchTimeout: 2s + + # Batch Size: Controls the number of messages batched into a block + BatchSize: + + # Max Message Count: The maximum number of messages to permit in a batch + MaxMessageCount: 10 + + # Absolute Max Bytes: The absolute maximum number of bytes allowed for + # the serialized messages in a batch. + AbsoluteMaxBytes: 99 MB + + # Preferred Max Bytes: The preferred maximum number of bytes allowed for + # the serialized messages in a batch. A message larger than the preferred + # max bytes will result in a batch larger than preferred max bytes. + PreferredMaxBytes: 512 KB + + Kafka: + # Brokers: A list of Kafka brokers to which the orderer connects + # NOTE: Use IP:port notation + Brokers: + - 127.0.0.1:9092 + + # Organizations is the list of orgs which are defined as participants on + # the orderer side of the network + Organizations: + ################################################################################ # # Profile diff --git a/first-network/configtx.yaml b/first-network/configtx.yaml index daa59ec2..3e0deade 100644 --- a/first-network/configtx.yaml +++ b/first-network/configtx.yaml @@ -4,55 +4,6 @@ # --- -################################################################################ -# -# SECTION: Capabilities -# -# - This section defines the capabilities of fabric network. This is a new -# concept as of v1.1.0 and should not be utilized in mixed networks with -# v1.0.x peers and orderers. Capabilities define features which must be -# present in a fabric binary for that binary to safely participate in the -# fabric network. For instance, if a new MSP type is added, newer binaries -# might recognize and validate the signatures from this type, while older -# binaries without this support would be unable to validate those -# transactions. This could lead to different versions of the fabric binaries -# having different world states. Instead, defining a capability for a channel -# informs those binaries without this capability that they must cease -# processing transactions until they have been upgraded. For v1.0.x if any -# capabilities are defined (including a map with all capabilities turned off) -# then the v1.0.x peer will deliberately crash. -# -################################################################################ -Capabilities: - # Channel capabilities apply to both the orderers and the peers and must be - # supported by both. Set the value of the capability to true to require it. - Global: &ChannelCapabilities - # V1.1 for Global is a catchall flag for behavior which has been - # determined to be desired for all orderers and peers running v1.0.x, - # but the modification of which would cause incompatibilities. Users - # should leave this flag set to true. - V1_1: true - - # Orderer capabilities apply only to the orderers, and may be safely - # manipulated without concern for upgrading peers. Set the value of the - # capability to true to require it. - Orderer: &OrdererCapabilities - # V1.1 for Order is a catchall flag for behavior which has been - # determined to be desired for all orderers running v1.0.x, but the - # modification of which would cause incompatibilities. Users should - # leave this flag set to true. - V1_1: true - - # Application capabilities apply only to the peer network, and may be safely - # manipulated without concern for upgrading orderers. Set the value of the - # capability to true to require it. - Application: &ApplicationCapabilities - # V1.1 for Application is a catchall flag for behavior which has been - # determined to be desired for all peers running v1.0.x, but the - # modification of which would cause incompatibilities. Users should - # leave this flag set to true. - V1_1: true - ################################################################################ # # Section: Organizations @@ -110,6 +61,69 @@ Organizations: - Host: peer0.org2.example.com Port: 7051 +################################################################################ +# +# SECTION: Capabilities +# +# - This section defines the capabilities of fabric network. This is a new +# concept as of v1.1.0 and should not be utilized in mixed networks with +# v1.0.x peers and orderers. Capabilities define features which must be +# present in a fabric binary for that binary to safely participate in the +# fabric network. For instance, if a new MSP type is added, newer binaries +# might recognize and validate the signatures from this type, while older +# binaries without this support would be unable to validate those +# transactions. This could lead to different versions of the fabric binaries +# having different world states. Instead, defining a capability for a channel +# informs those binaries without this capability that they must cease +# processing transactions until they have been upgraded. For v1.0.x if any +# capabilities are defined (including a map with all capabilities turned off) +# then the v1.0.x peer will deliberately crash. +# +################################################################################ +Capabilities: + # Channel capabilities apply to both the orderers and the peers and must be + # supported by both. Set the value of the capability to true to require it. + Global: &ChannelCapabilities + # V1.1 for Global is a catchall flag for behavior which has been + # determined to be desired for all orderers and peers running v1.0.x, + # but the modification of which would cause incompatibilities. Users + # should leave this flag set to true. + V1_1: true + + # Orderer capabilities apply only to the orderers, and may be safely + # manipulated without concern for upgrading peers. Set the value of the + # capability to true to require it. + Orderer: &OrdererCapabilities + # V1.1 for Order is a catchall flag for behavior which has been + # determined to be desired for all orderers running v1.0.x, but the + # modification of which would cause incompatibilities. Users should + # leave this flag set to true. + V1_1: true + + # Application capabilities apply only to the peer network, and may be safely + # manipulated without concern for upgrading orderers. Set the value of the + # capability to true to require it. + Application: &ApplicationCapabilities + # V1.1 for Application is a catchall flag for behavior which has been + # determined to be desired for all peers running v1.0.x, but the + # modification of which would cause incompatibilities. Users should + # leave this flag set to true. + V1_1: true + +################################################################################ +# +# SECTION: Application +# +# - This section defines the values to encode into a config transaction or +# genesis block for application related parameters +# +################################################################################ +Application: &ApplicationDefaults + + # Organizations is the list of orgs which are defined as participants on + # the application side of the network + Organizations: + ################################################################################ # # SECTION: Orderer @@ -155,20 +169,6 @@ Orderer: &OrdererDefaults # the orderer side of the network Organizations: -################################################################################ -# -# SECTION: Application -# -# - This section defines the values to encode into a config transaction or -# genesis block for application related parameters -# -################################################################################ -Application: &ApplicationDefaults - - # Organizations is the list of orgs which are defined as participants on - # the application side of the network - Organizations: - ################################################################################ # # Profile From 3031a8c556ef4e67de2cec3f47f2d9638713bd2f Mon Sep 17 00:00:00 2001 From: David Enyeart Date: Sun, 20 May 2018 12:54:52 -0400 Subject: [PATCH 23/29] [FAB-10235] Update BYFN to use V1_2 capability Update BYFN to use V1_2 application capability. Required for private data collections. Change-Id: I56c74b9fb6cd77864b5c8d13abb066a3d729500b Signed-off-by: David Enyeart --- first-network/configtx.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/first-network/configtx.yaml b/first-network/configtx.yaml index 3e0deade..e55efb05 100644 --- a/first-network/configtx.yaml +++ b/first-network/configtx.yaml @@ -104,11 +104,11 @@ Capabilities: # manipulated without concern for upgrading orderers. Set the value of the # capability to true to require it. Application: &ApplicationCapabilities - # V1.1 for Application is a catchall flag for behavior which has been + # V1.2 for Application is a catchall flag for behavior which has been # determined to be desired for all peers running v1.0.x, but the # modification of which would cause incompatibilities. Users should # leave this flag set to true. - V1_1: true + V1_2: true ################################################################################ # From 1cd059e534aebda20d00802baaa9bb83fae05b68 Mon Sep 17 00:00:00 2001 From: Jason Yellick Date: Mon, 21 May 2018 16:46:17 -0400 Subject: [PATCH 24/29] FAB-8612 Cleanup eyfn/byfn with --remove-orphans There are currently multiple docker-compose downs going on in the first-network samples. These are in an attempt to catch different configurations of the same compose network. The flag --remove-orphans was created to allow tearing down components in a composition even when there is a mismatch in the compose definition, so this cleans the down scripts up a bit. Change-Id: Ied6a06e2ebc21053993e2a6b39b6fbd7fffdfe02 Signed-off-by: Jason Yellick --- first-network/byfn.sh | 3 +-- first-network/eyfn.sh | 7 +------ 2 files changed, 2 insertions(+), 8 deletions(-) diff --git a/first-network/byfn.sh b/first-network/byfn.sh index 4c582e4d..6cf20793 100755 --- a/first-network/byfn.sh +++ b/first-network/byfn.sh @@ -235,8 +235,7 @@ function upgradeNetwork () { # Tear down running network function networkDown () { # stop org3 containers also in addition to org1 and org2, in case we were running sample to add org3 - docker-compose -f $COMPOSE_FILE -f $COMPOSE_FILE_COUCH -f $COMPOSE_FILE_ORG3 down --volumes - docker-compose -f $COMPOSE_FILE -f $COMPOSE_FILE_ORG3 down --volumes + docker-compose -f $COMPOSE_FILE -f $COMPOSE_FILE_COUCH -f $COMPOSE_FILE_ORG3 down --volumes --remove-orphans # Don't remove the generated artifacts -- note, the ledgers are always removed if [ "$MODE" != "restart" ]; then diff --git a/first-network/eyfn.sh b/first-network/eyfn.sh index 74473888..cee408b8 100755 --- a/first-network/eyfn.sh +++ b/first-network/eyfn.sh @@ -136,8 +136,7 @@ function networkUp () { # Tear down running network function networkDown () { - docker-compose -f $COMPOSE_FILE -f $COMPOSE_FILE_ORG3 down --volumes - docker-compose -f $COMPOSE_FILE -f $COMPOSE_FILE_ORG3 -f $COMPOSE_FILE_COUCH down --volumes + docker-compose -f $COMPOSE_FILE -f $COMPOSE_FILE_ORG3 -f $COMPOSE_FILE_COUCH down --volumes --remove-orphans # Don't remove containers, images, etc if restarting if [ "$MODE" != "restart" ]; then #Cleanup the chaincode containers @@ -149,10 +148,6 @@ function networkDown () { # remove the docker-compose yaml file that was customized to the example rm -f docker-compose-e2e.yaml fi - - # For some black-magic reason the first docker-compose down does not actually cleanup the volumes - docker-compose -f $COMPOSE_FILE -f $COMPOSE_FILE_ORG3 down --volumes - docker-compose -f $COMPOSE_FILE -f $COMPOSE_FILE_ORG3 -f $COMPOSE_FILE_COUCH down --volumes } # Use the CLI container to create the configuration transaction needed to add From a603655419b36b43d7c5860c5b1172f6caf70b4f Mon Sep 17 00:00:00 2001 From: Taku Shimosawa Date: Tue, 22 May 2018 17:36:42 -0700 Subject: [PATCH 25/29] [FAB-10306] Fix config in balance-transfer This patchset removes wrong max message size configuration from network-config.yaml in the balance-transfer sample. After [FAB-9337] was merged, this configuration was activated and caused an error in running the sample. Change-Id: I209448bd7701d5843b7ac06501be6a9d16d378e1 Signed-off-by: Taku Shimosawa --- balance-transfer/artifacts/network-config-aws.yaml | 1 - balance-transfer/artifacts/network-config.yaml | 1 - 2 files changed, 2 deletions(-) diff --git a/balance-transfer/artifacts/network-config-aws.yaml b/balance-transfer/artifacts/network-config-aws.yaml index 7402a67f..d9ecd513 100644 --- a/balance-transfer/artifacts/network-config-aws.yaml +++ b/balance-transfer/artifacts/network-config-aws.yaml @@ -154,7 +154,6 @@ orderers: # they will be passed in as-is to gRPC client constructor grpcOptions: ssl-target-name-override: orderer.example.com - grpc-max-send-message-length: 15 tlsCACerts: path: artifacts/channel/crypto-config/ordererOrganizations/example.com/orderers/orderer.example.com/tls/ca.crt diff --git a/balance-transfer/artifacts/network-config.yaml b/balance-transfer/artifacts/network-config.yaml index e01768a4..f7544dd9 100644 --- a/balance-transfer/artifacts/network-config.yaml +++ b/balance-transfer/artifacts/network-config.yaml @@ -154,7 +154,6 @@ orderers: # they will be passed in as-is to gRPC client constructor grpcOptions: ssl-target-name-override: orderer.example.com - grpc-max-send-message-length: 15 tlsCACerts: path: artifacts/channel/crypto-config/ordererOrganizations/example.com/orderers/orderer.example.com/tls/ca.crt From 2f3050476966c42724632626af53fbd816882236 Mon Sep 17 00:00:00 2001 From: Yuki Kondo Date: Wed, 23 May 2018 18:47:25 +0000 Subject: [PATCH 26/29] [FAB-10340] Fix broken link in chaincode-docker-devmode This CR fixes broken links to the install manual in fabric-samples/chaincode-docker-devmode/README.rst. The style is also updated to follow the style of rst. Change-Id: I9bbb6e0b88b8aabf8e020bb81756f4619115989c Signed-off-by: Yuki Kondo --- chaincode-docker-devmode/README.rst | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/chaincode-docker-devmode/README.rst b/chaincode-docker-devmode/README.rst index 40e6a217..91bccb30 100644 --- a/chaincode-docker-devmode/README.rst +++ b/chaincode-docker-devmode/README.rst @@ -13,7 +13,7 @@ of compiling chaincode and driving calls. Install Fabric Samples ---------------------- -If you haven't already done so, please install the doc [samples](http://hyperledger-fabric.readthedocs.io/en/latest/samples.html). +If you haven't already done so, please `install samples `_. Navigate to the ``chaincode-docker-devmode`` directory of the ``fabric-samples`` clone: @@ -27,7 +27,7 @@ Download docker images We need four docker images in order for "dev mode" to run against the supplied docker compose script. If you installed the ``fabric-samples`` repo clone and -followed the instructions to [download-platform-specific-binaries](http://hyperledger-fabric.readthedocs.io/en/latest/samples.html#download-platform-specific-binaries), then +followed the instructions to `install samples, binaries and docker images `_, then you should have the necessary Docker images installed locally. .. note:: If you choose to manually pull the images then you must retag them as @@ -49,7 +49,7 @@ should see something similar to following: hyperledger/fabric-ccenv latest 82489d1c11e8 9 days ago 1.35 GB hyperledger/fabric-ccenv x86_64-1.1.0-preview 82489d1c11e8 9 days ago 1.35 GB -.. note:: If you retrieved the images through the [download-platform-specific-binaries](http://hyperledger-fabric.readthedocs.io/en/latest/samples.html#download-platform-specific-binaries), +.. note:: If you retrieved the images through the `install samples, binaries and docker images `_, then you will see additional images listed. However, we are only concerned with these four. From 3c32c524e5688114bad3a62e04a9ade2e3085723 Mon Sep 17 00:00:00 2001 From: yacovm Date: Thu, 24 May 2018 00:30:16 +0300 Subject: [PATCH 27/29] [FAB-10346] Ensure peers are in sync in eyfn This change set adds querying to peers in all orgs at the end of eyfn to ensure peers of all orgs are in sync. Which proves they all validated the transaction and there is no state fork among peers of different orgs. Change-Id: I33ed632798a6e01d182e879c66c282fc4af6dbce Signed-off-by: yacovm --- first-network/scripts/testorg3.sh | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/first-network/scripts/testorg3.sh b/first-network/scripts/testorg3.sh index 71338775..6d1930cd 100755 --- a/first-network/scripts/testorg3.sh +++ b/first-network/scripts/testorg3.sh @@ -51,10 +51,19 @@ chaincodeQuery 0 3 90 echo "Sending invoke transaction on peer0.org1 peer0.org2 peer0.org3..." chaincodeInvoke 0 1 0 2 0 3 -# Query on chaincode on peer0.org3, check if the result is 80 +# Query on chaincode on peer0.org3, peer0.org2, peer0.org1 check if the result is 80 +# We query a peer in each organization, to ensure peers from all organizations are in sync +# and there is no state fork between organizations. echo "Querying chaincode on peer0.org3..." chaincodeQuery 0 3 80 +echo "Querying chaincode on peer0.org2..." +chaincodeQuery 0 2 80 + +echo "Querying chaincode on peer0.org1..." +chaincodeQuery 0 1 80 + + echo echo "========= All GOOD, EYFN test execution completed =========== " echo From 21444abf4c36dd35f72dcba5352d01ed204babf4 Mon Sep 17 00:00:00 2001 From: Christopher Ferris Date: Tue, 22 May 2018 13:32:33 -0400 Subject: [PATCH 28/29] FAB-10297 replace fabric-preload.sh replace fabric-preload.sh w/ bootstrap.sh Change-Id: Id4b04b0835e7a03e051110aab96c62d5e6d1221c Signed-off-by: Christopher Ferris --- README.md | 24 ++++- scripts/README.md | 10 -- scripts/bootstrap.sh | 220 ++++++++++++++++++++++++++++++++++++++ scripts/fabric-preload.sh | 42 -------- 4 files changed, 242 insertions(+), 54 deletions(-) delete mode 100644 scripts/README.md create mode 100755 scripts/bootstrap.sh delete mode 100755 scripts/fabric-preload.sh diff --git a/README.md b/README.md index 5f269150..f35817e8 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,27 @@ +[//]: # (SPDX-License-Identifier: CC-BY-4.0) + ## Hyperledger Fabric Samples -Please visit the [installation instructions](http://hyperledger-fabric.readthedocs.io/en/latest/install.html). +Please visit the [installation instructions](http://hyperledger-fabric.readthedocs.io/en/latest/install.html) +to ensure you have the correct prerequisites installed. Please use the +version of the documentation that matches the version of the software you +intend to use to ensure alignment. + +## Download Binaries and Docker Images + +The [`scripts/bootstrap.sh`](https://github.com/hyperledger/fabric-samples/blob/release-1.1/scripts/bootstrap.sh) +script will preload all of the requisite docker +images for Hyperledger Fabric and tag them with the 'latest' tag. Optionally, +specify a version for fabric, fabric-ca and thirdparty images. Default versions +are 1.1.0, 1.1.0 and 0.4.7 respectively. + +```bash +./scripts/bootstrap.sh [version] [ca version] [thirdparty_version] +``` ## License -Hyperledger Project source code files are made available under the Apache License, Version 2.0 (Apache-2.0), located in the [LICENSE](LICENSE) file. Hyperledger Project documentation files are made available under the Creative Commons Attribution 4.0 International License (CC-BY-4.0), available at http://creativecommons.org/licenses/by/4.0/. +Hyperledger Project source code files are made available under the Apache +License, Version 2.0 (Apache-2.0), located in the [LICENSE](LICENSE) file. +Hyperledger Project documentation files are made available under the Creative +Commons Attribution 4.0 International License (CC-BY-4.0), available at http://creativecommons.org/licenses/by/4.0/. diff --git a/scripts/README.md b/scripts/README.md deleted file mode 100644 index 4dce8de6..00000000 --- a/scripts/README.md +++ /dev/null @@ -1,10 +0,0 @@ -## Hyperledger Fabric Samples - -fabric-preload.sh will preload all of the requisite docker images for Hyperledger Fabric and tag them -with the 'latest' tag. Optionally, specify a specific version (e.g. 1.0.1). Default version is 1.0.0. - -```bash -./fabric-preload.sh [version] -``` - -Creative Commons License
This work is licensed under a Creative Commons Attribution 4.0 International License diff --git a/scripts/bootstrap.sh b/scripts/bootstrap.sh new file mode 100755 index 00000000..37beaf4d --- /dev/null +++ b/scripts/bootstrap.sh @@ -0,0 +1,220 @@ +#!/bin/bash +# +# Copyright IBM Corp. All Rights Reserved. +# +# SPDX-License-Identifier: Apache-2.0 +# + +# if version not passed in, default to latest released version +export VERSION=1.1.0 +# if ca version not passed in, default to latest released version +export CA_VERSION=$VERSION +# current version of thirdparty images (couchdb, kafka and zookeeper) released +export THIRDPARTY_IMAGE_VERSION=0.4.7 +export ARCH=$(echo "$(uname -s|tr '[:upper:]' '[:lower:]'|sed 's/mingw64_nt.*/windows/')-$(uname -m | sed 's/x86_64/amd64/g')") +export MARCH=$(uname -m) + +# ensure we're in the fabric-samples directory +dir=`basename $PWD` +if [ "${dir}" == "scripts" ]; then + cd .. +fi + +dir=`basename $PWD` +if [ "${dir}" != "fabric-samples" ]; then + echo "You should run this script from the fabric-samples root directory." + exit 1 +fi + +printHelp() { + echo "Usage: bootstrap.sh [] [] [][-d -b]" + echo + echo "-d - bypass docker image download" + echo "-b - bypass download of platform-specific binaries" + echo + echo "e.g. bootstrap.sh 1.1.1" + echo "would download docker images and binaries for version 1.1.1" +} + +dockerFabricPull() { + local FABRIC_TAG=$1 + for IMAGES in peer orderer ccenv tools; do + echo "==> FABRIC IMAGE: $IMAGES" + echo + docker pull hyperledger/fabric-$IMAGES:$FABRIC_TAG + docker tag hyperledger/fabric-$IMAGES:$FABRIC_TAG hyperledger/fabric-$IMAGES + done +} + +dockerThirdPartyImagesPull() { + local THIRDPARTY_TAG=$1 + for IMAGES in couchdb kafka zookeeper; do + echo "==> THIRDPARTY DOCKER IMAGE: $IMAGES" + echo + docker pull hyperledger/fabric-$IMAGES:$THIRDPARTY_TAG + docker tag hyperledger/fabric-$IMAGES:$THIRDPARTY_TAG hyperledger/fabric-$IMAGES + done +} + +dockerCaPull() { + local CA_TAG=$1 + echo "==> FABRIC CA IMAGE" + echo + docker pull hyperledger/fabric-ca:$CA_TAG + docker tag hyperledger/fabric-ca:$CA_TAG hyperledger/fabric-ca +} + +# Incrementally downloads the .tar.gz file locally first, only decompressing it +# after the download is complete. This is slower than binaryDownload() but +# allows the download to be resumed. +binaryIncrementalDownload() { + local BINARY_FILE=$1 + local URL=$2 + curl -f -s -C - ${URL} -o ${BINARY_FILE} || rc=$? + # Due to limitations in the current Nexus repo: + # curl returns 33 when there's a resume attempt with no more bytes to download + # curl returns 2 after finishing a resumed download + # with -f curl returns 22 on a 404 + if [ "$rc" = 22 ]; then + # looks like the requested file doesn't actually exist so stop here + return 22 + fi + if [ -z "$rc" ] || [ $rc -eq 33 ] || [ $rc -eq 2 ]; then + # The checksum validates that RC 33 or 2 are not real failures + echo "==> File downloaded. Verifying the md5sum..." + localMd5sum=$(md5sum ${BINARY_FILE} | awk '{print $1}') + remoteMd5sum=$(curl -s ${URL}.md5) + if [ "$localMd5sum" == "$remoteMd5sum" ]; then + echo "==> Extracting ${BINARY_FILE}..." + tar xzf ./${BINARY_FILE} --overwrite + echo "==> Done." + rm -f ${BINARY_FILE} ${BINARY_FILE}.md5 + else + echo "Download failed: the local md5sum is different from the remote md5sum. Please try again." + rm -f ${BINARY_FILE} ${BINARY_FILE}.md5 + exit 1 + fi + else + echo "Failure downloading binaries (curl RC=$rc). Please try again and the download will resume from where it stopped." + exit 1 + fi +} + +# This will attempt to download the .tar.gz all at once, but will trigger the +# binaryIncrementalDownload() function upon a failure, allowing for resume +# if there are network failures. +binaryDownload() { + local BINARY_FILE=$1 + local URL=$2 + echo "===> Downloading: " ${URL} + # Check if a previous failure occurred and the file was partially downloaded + if [ -e ${BINARY_FILE} ]; then + echo "==> Partial binary file found. Resuming download..." + binaryIncrementalDownload ${BINARY_FILE} ${URL} + else + curl ${URL} | tar xz || rc=$? + if [ ! -z "$rc" ]; then + echo "==> There was an error downloading the binary file. Switching to incremental download." + echo "==> Downloading file..." + binaryIncrementalDownload ${BINARY_FILE} ${URL} + else + echo "==> Done." + fi + fi +} + +binariesInstall() { + echo "===> Downloading version ${FABRIC_TAG} platform specific fabric binaries" + binaryDownload ${BINARY_FILE} https://nexus.hyperledger.org/content/repositories/releases/org/hyperledger/fabric/hyperledger-fabric/${ARCH}-${VERSION}/${BINARY_FILE} + if [ $? -eq 22 ]; then + echo + echo "------> ${FABRIC_TAG} platform specific fabric binary is not available to download <----" + echo + fi + + echo "===> Downloading version ${CA_TAG} platform specific fabric-ca-client binary" + binaryDownload ${CA_BINARY_FILE} https://nexus.hyperledger.org/content/repositories/releases/org/hyperledger/fabric-ca/hyperledger-fabric-ca/${ARCH}-${CA_VERSION}/${CA_BINARY_FILE} + if [ $? -eq 22 ]; then + echo + echo "------> ${CA_TAG} fabric-ca-client binary is not available to download (Available from 1.1.0-rc1) <----" + echo + fi +} + +dockerInstall() { + which docker >& /dev/null + NODOCKER=$? + if [ "${NODOCKER}" == 0 ]; then + echo "===> Pulling fabric Images" + dockerFabricPull ${FABRIC_TAG} + echo "===> Pulling fabric ca Image" + dockerCaPull ${CA_TAG} + echo "===> Pulling thirdparty docker images" + dockerThirdPartyImagesPull ${THIRDPARTY_TAG} + echo + echo "===> List out hyperledger docker images" + docker images | grep hyperledger* + else + echo "=========================================================" + echo "Docker not installed, bypassing download of Fabric images" + echo "=========================================================" + fi +} + +DOCKER=true +SAMPLES=true +BINARIES=true + +# Parse commandline args pull out +# version and/or ca-version strings first +if echo $1 | grep -q '\d'; then + VERSION=$1;shift + if echo $1 | grep -q '\d'; then + CA_VERSION=$1;shift + if echo $1 | grep -q '\d'; then + THIRDPARTY_IMAGE_VERSION=$1;shift + fi + fi +fi + +# prior to 1.1.0 architecture was determined by uname -m +if [[ $VERSION =~ ^1\.[0]\.* ]]; then + export FABRIC_TAG=${MARCH}-${VERSION} + export CA_TAG=${MARCH}-${CA_VERSION} + export THIRDPARTY_TAG=${MARCH}-${THIRDPARTY_IMAGE_VERSION} +else + # starting with 1.2.0, multi-arch images will be default + : ${CA_TAG:="$CA_VERSION"} + : ${FABRIC_TAG:="$VERSION"} + : ${THIRDPARTY_TAG:="$THIRDPARTY_IMAGE_VERSION"} +fi + +BINARY_FILE=hyperledger-fabric-${ARCH}-${VERSION}.tar.gz +CA_BINARY_FILE=hyperledger-fabric-ca-${ARCH}-${CA_VERSION}.tar.gz + +# then parse opts +while getopts "h?db" opt; do + case "$opt" in + h|\?) + printHelp + exit 0 + ;; + d) DOCKER=false + ;; + b) BINARIES=false + ;; + esac +done + +if [ "$BINARIES" == "true" ]; then + echo + echo "Installing Hyperledger Fabric binaries" + echo + binariesInstall +fi +if [ "$DOCKER" == "true" ]; then + echo + echo "Installing Hyperledger Fabric docker images" + echo + dockerInstall +fi diff --git a/scripts/fabric-preload.sh b/scripts/fabric-preload.sh deleted file mode 100755 index a88963ed..00000000 --- a/scripts/fabric-preload.sh +++ /dev/null @@ -1,42 +0,0 @@ -#!/bin/bash -# -# Copyright IBM Corp. All Rights Reserved. -# -# SPDX-License-Identifier: Apache-2.0 -# - -export VERSION=${1:-1.0.0} -export ARCH=$(echo "$(uname -s|tr '[:upper:]' '[:lower:]'|sed 's/mingw64_nt.*/windows/')-$(uname -m | sed 's/x86_64/amd64/g')" | awk '{print tolower($0)}') -#Set MARCH variable i.e ppc64le,s390x,x86_64,i386 -MARCH=`uname -m` - -dockerFabricPull() { - local FABRIC_TAG=$1 - for IMAGES in peer orderer couchdb ccenv javaenv kafka zookeeper tools; do - echo "==> FABRIC IMAGE: $IMAGES" - echo - docker pull hyperledger/fabric-$IMAGES:$FABRIC_TAG - docker tag hyperledger/fabric-$IMAGES:$FABRIC_TAG hyperledger/fabric-$IMAGES - done -} - -dockerCaPull() { - local CA_TAG=$1 - echo "==> FABRIC CA IMAGE" - echo - docker pull hyperledger/fabric-ca:$CA_TAG - docker tag hyperledger/fabric-ca:$CA_TAG hyperledger/fabric-ca -} - -: ${CA_TAG:="$MARCH-$VERSION"} -: ${FABRIC_TAG:="$MARCH-$VERSION"} - -echo "===> Pulling fabric Images" -dockerFabricPull ${FABRIC_TAG} - -echo "===> Pulling fabric ca Image" -dockerCaPull ${CA_TAG} -echo -echo "===> List out hyperledger docker images" -docker images | grep hyperledger* - From 5956178406ca44800687aee2f3afbd92606ec330 Mon Sep 17 00:00:00 2001 From: David Enyeart Date: Thu, 24 May 2018 08:07:30 -0400 Subject: [PATCH 29/29] [FAB-6600] Sample chaincode for private data Marbles02 chaincode updated to utilize private data collections on all ledger APIs. To run the sample, follow the instructions in FAB-10231. An official tutorial will follow. Change-Id: Id9b3dbae8ab62afe81ee8d116b7bd4efc0213933 Signed-off-by: David Enyeart --- .../marbles02_private/collections_config.json | 16 + .../collectionMarbles/indexes/indexOwner.json | 1 + .../go/marbles_chaincode_private.go | 634 ++++++++++++++++++ 3 files changed, 651 insertions(+) create mode 100644 chaincode/marbles02_private/collections_config.json create mode 100644 chaincode/marbles02_private/go/META-INF/statedb/couchdb/collections/collectionMarbles/indexes/indexOwner.json create mode 100644 chaincode/marbles02_private/go/marbles_chaincode_private.go diff --git a/chaincode/marbles02_private/collections_config.json b/chaincode/marbles02_private/collections_config.json new file mode 100644 index 00000000..d61434a8 --- /dev/null +++ b/chaincode/marbles02_private/collections_config.json @@ -0,0 +1,16 @@ +[ + { + "name": "collectionMarbles", + "policy": "OR('Org1MSP.member', 'Org2MSP.member')", + "requiredPeerCount": 0, + "maxPeerCount": 3, + "blockToLive":1000000 +}, + { + "name": "collectionMarblePrivateDetails", + "policy": "OR('Org1MSP.member')", + "requiredPeerCount": 0, + "maxPeerCount": 3, + "blockToLive":3 + } +] diff --git a/chaincode/marbles02_private/go/META-INF/statedb/couchdb/collections/collectionMarbles/indexes/indexOwner.json b/chaincode/marbles02_private/go/META-INF/statedb/couchdb/collections/collectionMarbles/indexes/indexOwner.json new file mode 100644 index 00000000..305f0904 --- /dev/null +++ b/chaincode/marbles02_private/go/META-INF/statedb/couchdb/collections/collectionMarbles/indexes/indexOwner.json @@ -0,0 +1 @@ +{"index":{"fields":["docType","owner"]},"ddoc":"indexOwnerDoc", "name":"indexOwner","type":"json"} diff --git a/chaincode/marbles02_private/go/marbles_chaincode_private.go b/chaincode/marbles02_private/go/marbles_chaincode_private.go new file mode 100644 index 00000000..385687c0 --- /dev/null +++ b/chaincode/marbles02_private/go/marbles_chaincode_private.go @@ -0,0 +1,634 @@ +/* +Copyright IBM Corp. All Rights Reserved. + +SPDX-License-Identifier: Apache-2.0 +*/ + +// ====CHAINCODE EXECUTION SAMPLES (CLI) ================== + +// ==== Invoke marbles ==== +// peer chaincode invoke -C mychannel -n marblesp -c '{"Args":["initMarble","marble1","blue","35","tom","99"]}' +// peer chaincode invoke -C mychannel -n marblesp -c '{"Args":["initMarble","marble2","red","50","tom","102"]}' +// peer chaincode invoke -C mychannel -n marblesp -c '{"Args":["initMarble","marble3","blue","70","tom","103"]}' +// peer chaincode invoke -C mychannel -n marblesp -c '{"Args":["transferMarble","marble2","jerry"]}' +// peer chaincode invoke -C mychannel -n marblesp -c '{"Args":["delete","marble1"]}' + +// ==== Query marbles ==== +// peer chaincode query -C mychannel -n marblesp -c '{"Args":["readMarble","marble1"]}' +// peer chaincode query -C mychannel -n marblesp -c '{"Args":["readMarblePrivateDetails","marble1"]}' +// peer chaincode query -C mychannel -n marblesp -c '{"Args":["getMarblesByRange","marble1","marble3"]}' + +// Rich Query (Only supported if CouchDB is used as state database): +// peer chaincode query -C mychannel -n marblesp -c '{"Args":["queryMarblesByOwner","tom"]}' +// peer chaincode query -C mychannel -n marblesp -c '{"Args":["queryMarbles","{\"selector\":{\"owner\":\"tom\"}}"]}' + +// INDEXES TO SUPPORT COUCHDB RICH QUERIES +// +// Indexes in CouchDB are required in order to make JSON queries efficient and are required for +// any JSON query with a sort. As of Hyperledger Fabric 1.1, indexes may be packaged alongside +// chaincode in a META-INF/statedb/couchdb/indexes directory. Or for indexes on private data +// collections, in a META-INF/statedb/couchdb/collections//indexes directory. +// Each index must be defined in its own text file with extension *.json with the index +// definition formatted in JSON following the CouchDB index JSON syntax as documented at: +// http://docs.couchdb.org/en/2.1.1/api/database/find.html#db-index +// +// This marbles02_private example chaincode demonstrates a packaged index which you +// can find in META-INF/statedb/couchdb/collection/collectionMarbles/indexes/indexOwner.json. +// For deployment of chaincode to production environments, it is recommended +// to define any indexes alongside chaincode so that the chaincode and supporting indexes +// are deployed automatically as a unit, once the chaincode has been installed on a peer and +// instantiated on a channel. See Hyperledger Fabric documentation for more details. +// +// If you have access to the your peer's CouchDB state database in a development environment, +// you may want to iteratively test various indexes in support of your chaincode queries. You +// can use the CouchDB Fauxton interface or a command line curl utility to create and update +// indexes. Then once you finalize an index, include the index definition alongside your +// chaincode in the META-INF/statedb/couchdb/indexes directory or +// META-INF/statedb/couchdb/collections//indexes directory, for packaging +// and deployment to managed environments. +// +// In the examples below you can find index definitions that support marbles02_private +// chaincode queries, along with the syntax that you can use in development environments +// to create the indexes in the CouchDB Fauxton interface. +// + +//Example hostname:port configurations to access CouchDB. +// +//To access CouchDB docker container from within another docker container or from vagrant environments: +// http://couchdb:5984/ +// +//Inside couchdb docker container +// http://127.0.0.1:5984/ + +// Index for docType, owner. +// Note that docType and owner fields must be prefixed with the "data" wrapper +// +// Index definition for use with Fauxton interface +// {"index":{"fields":["data.docType","data.owner"]},"ddoc":"indexOwnerDoc", "name":"indexOwner","type":"json"} + +// Index for docType, owner, size (descending order). +// Note that docType, owner and size fields must be prefixed with the "data" wrapper +// +// Index definition for use with Fauxton interface +// {"index":{"fields":[{"data.size":"desc"},{"data.docType":"desc"},{"data.owner":"desc"}]},"ddoc":"indexSizeSortDoc", "name":"indexSizeSortDesc","type":"json"} + +// Rich Query with index design doc and index name specified (Only supported if CouchDB is used as state database): +// peer chaincode query -C mychannel -n marblesp -c '{"Args":["queryMarbles","{\"selector\":{\"docType\":\"marble\",\"owner\":\"tom\"}, \"use_index\":[\"_design/indexOwnerDoc\", \"indexOwner\"]}"]}' + +// Rich Query with index design doc specified only (Only supported if CouchDB is used as state database): +// peer chaincode query -C mychannel -n marblesp -c '{"Args":["queryMarbles","{\"selector\":{\"docType\":{\"$eq\":\"marble\"},\"owner\":{\"$eq\":\"tom\"},\"size\":{\"$gt\":0}},\"fields\":[\"docType\",\"owner\",\"size\"],\"sort\":[{\"size\":\"desc\"}],\"use_index\":\"_design/indexSizeSortDoc\"}"]}' + +package main + +import ( + "bytes" + "encoding/json" + "fmt" + "strconv" + "strings" + + "github.com/hyperledger/fabric/core/chaincode/shim" + pb "github.com/hyperledger/fabric/protos/peer" +) + +// SimpleChaincode example simple Chaincode implementation +type SimpleChaincode struct { +} + +type marble struct { + ObjectType string `json:"docType"` //docType is used to distinguish the various types of objects in state database + Name string `json:"name"` //the fieldtags are needed to keep case from bouncing around + Color string `json:"color"` + Size int `json:"size"` + Owner string `json:"owner"` +} + +type marblePrivateDetails struct { + ObjectType string `json:"docType"` //docType is used to distinguish the various types of objects in state database + Name string `json:"name"` //the fieldtags are needed to keep case from bouncing around + Price int `json:"price"` +} + +// =================================================================================== +// Main +// =================================================================================== +func main() { + err := shim.Start(new(SimpleChaincode)) + if err != nil { + fmt.Printf("Error starting Simple chaincode: %s", err) + } +} + +// Init initializes chaincode +// =========================== +func (t *SimpleChaincode) Init(stub shim.ChaincodeStubInterface) pb.Response { + return shim.Success(nil) +} + +// Invoke - Our entry point for Invocations +// ======================================== +func (t *SimpleChaincode) Invoke(stub shim.ChaincodeStubInterface) pb.Response { + function, args := stub.GetFunctionAndParameters() + fmt.Println("invoke is running " + function) + + // Handle different functions + switch function { + case "initMarble": + //create a new marble + return t.initMarble(stub, args) + case "readMarble": + //read a marble + return t.readMarble(stub, args) + case "readMarblePrivateDetails": + //read a marble private details + return t.readMarblePrivateDetails(stub, args) + case "transferMarble": + //change owner of a specific marble + return t.transferMarble(stub, args) + case "transferMarblesBasedOnColor": + //transfer all marbles of a certain color + return t.transferMarblesBasedOnColor(stub, args) + case "delete": + //delete a marble + return t.delete(stub, args) + case "queryMarblesByOwner": + //find marbles for owner X using rich query + return t.queryMarblesByOwner(stub, args) + case "queryMarbles": + //find marbles based on an ad hoc rich query + return t.queryMarbles(stub, args) + case "getMarblesByRange": + //get marbles based on range query + return t.getMarblesByRange(stub, args) + default: + //error + fmt.Println("invoke did not find func: " + function) + return shim.Error("Received unknown function invocation") + } +} + +// ============================================================ +// initMarble - create a new marble, store into chaincode state +// ============================================================ +func (t *SimpleChaincode) initMarble(stub shim.ChaincodeStubInterface, args []string) pb.Response { + var err error + + // 0-name 1-color 2-size 3-owner 4-price + // "asdf", "blue", "35", "bob", "99" + if len(args) != 5 { + return shim.Error("Incorrect number of arguments. Expecting 5") + } + + // ==== Input sanitation ==== + fmt.Println("- start init marble") + if len(args[0]) == 0 { + return shim.Error("1st argument must be a non-empty string") + } + if len(args[1]) == 0 { + return shim.Error("2nd argument must be a non-empty string") + } + if len(args[2]) == 0 { + return shim.Error("3rd argument must be a non-empty string") + } + if len(args[3]) == 0 { + return shim.Error("4th argument must be a non-empty string") + } + if len(args[4]) == 0 { + return shim.Error("5th argument must be a non-empty string") + } + marbleName := args[0] + color := strings.ToLower(args[1]) + owner := strings.ToLower(args[3]) + size, err := strconv.Atoi(args[2]) + if err != nil { + return shim.Error("3rd argument must be a numeric string") + } + price, err := strconv.Atoi(args[4]) + if err != nil { + return shim.Error("5th argument must be a numeric string") + } + + // ==== Check if marble already exists ==== + marbleAsBytes, err := stub.GetPrivateData("collectionMarbles", marbleName) + if err != nil { + return shim.Error("Failed to get marble: " + err.Error()) + } else if marbleAsBytes != nil { + fmt.Println("This marble already exists: " + marbleName) + return shim.Error("This marble already exists: " + marbleName) + } + + // ==== Create marble object and marshal to JSON ==== + objectType := "marble" + marble := &marble{objectType, marbleName, color, size, owner} + marbleJSONasBytes, err := json.Marshal(marble) + if err != nil { + return shim.Error(err.Error()) + } + //Alternatively, build the marble json string manually if you don't want to use struct marshalling + //marbleJSONasString := `{"docType":"Marble", "name": "` + marbleName + `", "color": "` + color + `", "size": ` + strconv.Itoa(size) + `, "owner": "` + owner + `"}` + //marbleJSONasBytes := []byte(str) + + // === Save marble to state === + err = stub.PutPrivateData("collectionMarbles", marbleName, marbleJSONasBytes) + if err != nil { + return shim.Error(err.Error()) + } + + // ==== Save marble private details ==== + objectType = "marblePrivateDetails" + marblePrivateDetails := &marblePrivateDetails{objectType, marbleName, price} + marblePrivateDetailsBytes, err := json.Marshal(marblePrivateDetails) + if err != nil { + return shim.Error(err.Error()) + } + err = stub.PutPrivateData("collectionMarblePrivateDetails", marbleName, marblePrivateDetailsBytes) + if err != nil { + return shim.Error(err.Error()) + } + + // ==== Index the marble to enable color-based range queries, e.g. return all blue marbles ==== + // An 'index' is a normal key/value entry in state. + // The key is a composite key, with the elements that you want to range query on listed first. + // In our case, the composite key is based on indexName~color~name. + // This will enable very efficient state range queries based on composite keys matching indexName~color~* + indexName := "color~name" + colorNameIndexKey, err := stub.CreateCompositeKey(indexName, []string{marble.Color, marble.Name}) + if err != nil { + return shim.Error(err.Error()) + } + // Save index entry to state. Only the key name is needed, no need to store a duplicate copy of the marble. + // Note - passing a 'nil' value will effectively delete the key from state, therefore we pass null character as value + value := []byte{0x00} + stub.PutPrivateData("collectionMarbles", colorNameIndexKey, value) + + // ==== Marble saved and indexed. Return success ==== + fmt.Println("- end init marble") + return shim.Success(nil) +} + +// =============================================== +// readMarble - read a marble from chaincode state +// =============================================== +func (t *SimpleChaincode) readMarble(stub shim.ChaincodeStubInterface, args []string) pb.Response { + var name, jsonResp string + var err error + + if len(args) != 1 { + return shim.Error("Incorrect number of arguments. Expecting name of the marble to query") + } + + name = args[0] + valAsbytes, err := stub.GetPrivateData("collectionMarbles", name) //get the marble from chaincode state + if err != nil { + jsonResp = "{\"Error\":\"Failed to get state for " + name + "\"}" + return shim.Error(jsonResp) + } else if valAsbytes == nil { + jsonResp = "{\"Error\":\"Marble does not exist: " + name + "\"}" + return shim.Error(jsonResp) + } + + return shim.Success(valAsbytes) +} + +// =============================================== +// readMarblereadMarblePrivateDetails - read a marble private details from chaincode state +// =============================================== +func (t *SimpleChaincode) readMarblePrivateDetails(stub shim.ChaincodeStubInterface, args []string) pb.Response { + var name, jsonResp string + var err error + + if len(args) != 1 { + return shim.Error("Incorrect number of arguments. Expecting name of the marble to query") + } + + name = args[0] + valAsbytes, err := stub.GetPrivateData("collectionMarblePrivateDetails", name) //get the marble private details from chaincode state + if err != nil { + jsonResp = "{\"Error\":\"Failed to get private details for " + name + ": " + err.Error() + "\"}" + return shim.Error(jsonResp) + } else if valAsbytes == nil { + jsonResp = "{\"Error\":\"Marble private details does not exist: " + name + "\"}" + return shim.Error(jsonResp) + } + + return shim.Success(valAsbytes) +} + +// ================================================== +// delete - remove a marble key/value pair from state +// ================================================== +func (t *SimpleChaincode) delete(stub shim.ChaincodeStubInterface, args []string) pb.Response { + var jsonResp string + var marbleJSON marble + if len(args) != 1 { + return shim.Error("Incorrect number of arguments. Expecting 1") + } + marbleName := args[0] + + // to maintain the color~name index, we need to read the marble first and get its color + valAsbytes, err := stub.GetPrivateData("collectionMarbles", marbleName) //get the marble from chaincode state + if err != nil { + jsonResp = "{\"Error\":\"Failed to get state for " + marbleName + "\"}" + return shim.Error(jsonResp) + } else if valAsbytes == nil { + jsonResp = "{\"Error\":\"Marble does not exist: " + marbleName + "\"}" + return shim.Error(jsonResp) + } + + err = json.Unmarshal([]byte(valAsbytes), &marbleJSON) + if err != nil { + jsonResp = "{\"Error\":\"Failed to decode JSON of: " + marbleName + "\"}" + return shim.Error(jsonResp) + } + + err = stub.DelPrivateData("collectionMarbles", marbleName) //remove the marble from chaincode state + if err != nil { + return shim.Error("Failed to delete state:" + err.Error()) + } + + // maintain the index + indexName := "color~name" + colorNameIndexKey, err := stub.CreateCompositeKey(indexName, []string{marbleJSON.Color, marbleJSON.Name}) + if err != nil { + return shim.Error(err.Error()) + } + + // Delete index entry to state. + err = stub.DelPrivateData("collectionMarbles", colorNameIndexKey) + if err != nil { + return shim.Error("Failed to delete state:" + err.Error()) + } + + // Delete private details of marble + err = stub.DelPrivateData("collectionMarblePrivateDetails", marbleName) + if err != nil { + return shim.Error(err.Error()) + } + + return shim.Success(nil) +} + +// =========================================================== +// transfer a marble by setting a new owner name on the marble +// =========================================================== +func (t *SimpleChaincode) transferMarble(stub shim.ChaincodeStubInterface, args []string) pb.Response { + + // 0 1 + // "name", "bob" + if len(args) < 2 { + return shim.Error("Incorrect number of arguments. Expecting 2") + } + + marbleName := args[0] + newOwner := strings.ToLower(args[1]) + fmt.Println("- start transferMarble ", marbleName, newOwner) + + marbleAsBytes, err := stub.GetPrivateData("collectionMarbles", marbleName) + if err != nil { + return shim.Error("Failed to get marble:" + err.Error()) + } else if marbleAsBytes == nil { + return shim.Error("Marble does not exist") + } + + marbleToTransfer := marble{} + err = json.Unmarshal(marbleAsBytes, &marbleToTransfer) //unmarshal it aka JSON.parse() + if err != nil { + return shim.Error(err.Error()) + } + marbleToTransfer.Owner = newOwner //change the owner + + marbleJSONasBytes, _ := json.Marshal(marbleToTransfer) + err = stub.PutPrivateData("collectionMarbles", marbleName, marbleJSONasBytes) //rewrite the marble + if err != nil { + return shim.Error(err.Error()) + } + + fmt.Println("- end transferMarble (success)") + return shim.Success(nil) +} + +// =========================================================================================== +// getMarblesByRange performs a range query based on the start and end keys provided. + +// Read-only function results are not typically submitted to ordering. If the read-only +// results are submitted to ordering, or if the query is used in an update transaction +// and submitted to ordering, then the committing peers will re-execute to guarantee that +// result sets are stable between endorsement time and commit time. The transaction is +// invalidated by the committing peers if the result set has changed between endorsement +// time and commit time. +// Therefore, range queries are a safe option for performing update transactions based on query results. +// =========================================================================================== +func (t *SimpleChaincode) getMarblesByRange(stub shim.ChaincodeStubInterface, args []string) pb.Response { + + if len(args) < 2 { + return shim.Error("Incorrect number of arguments. Expecting 2") + } + + startKey := args[0] + endKey := args[1] + + resultsIterator, err := stub.GetPrivateDataByRange("collectionMarbles", startKey, endKey) + if err != nil { + return shim.Error(err.Error()) + } + defer resultsIterator.Close() + + // buffer is a JSON array containing QueryResults + var buffer bytes.Buffer + buffer.WriteString("[") + + bArrayMemberAlreadyWritten := false + for resultsIterator.HasNext() { + queryResponse, err := resultsIterator.Next() + if err != nil { + return shim.Error(err.Error()) + } + // Add a comma before array members, suppress it for the first array member + if bArrayMemberAlreadyWritten == true { + buffer.WriteString(",") + } + buffer.WriteString("{\"Key\":") + buffer.WriteString("\"") + buffer.WriteString(queryResponse.Key) + buffer.WriteString("\"") + + buffer.WriteString(", \"Record\":") + // Record is a JSON object, so we write as-is + buffer.WriteString(string(queryResponse.Value)) + buffer.WriteString("}") + bArrayMemberAlreadyWritten = true + } + buffer.WriteString("]") + + fmt.Printf("- getMarblesByRange queryResult:\n%s\n", buffer.String()) + + return shim.Success(buffer.Bytes()) +} + +// ==== Example: GetStateByPartialCompositeKey/RangeQuery ========================================= +// transferMarblesBasedOnColor will transfer marbles of a given color to a certain new owner. +// Uses a GetStateByPartialCompositeKey (range query) against color~name 'index'. +// Committing peers will re-execute range queries to guarantee that result sets are stable +// between endorsement time and commit time. The transaction is invalidated by the +// committing peers if the result set has changed between endorsement time and commit time. +// Therefore, range queries are a safe option for performing update transactions based on query results. +// =========================================================================================== +func (t *SimpleChaincode) transferMarblesBasedOnColor(stub shim.ChaincodeStubInterface, args []string) pb.Response { + + // 0 1 + // "color", "bob" + if len(args) < 2 { + return shim.Error("Incorrect number of arguments. Expecting 2") + } + + color := args[0] + newOwner := strings.ToLower(args[1]) + fmt.Println("- start transferMarblesBasedOnColor ", color, newOwner) + + // Query the color~name index by color + // This will execute a key range query on all keys starting with 'color' + coloredMarbleResultsIterator, err := stub.GetPrivateDataByPartialCompositeKey("collectionMarbles", "color~name", []string{color}) + if err != nil { + return shim.Error(err.Error()) + } + defer coloredMarbleResultsIterator.Close() + + // Iterate through result set and for each marble found, transfer to newOwner + var i int + for i = 0; coloredMarbleResultsIterator.HasNext(); i++ { + // Note that we don't get the value (2nd return variable), we'll just get the marble name from the composite key + responseRange, err := coloredMarbleResultsIterator.Next() + if err != nil { + return shim.Error(err.Error()) + } + + // get the color and name from color~name composite key + objectType, compositeKeyParts, err := stub.SplitCompositeKey(responseRange.Key) + if err != nil { + return shim.Error(err.Error()) + } + returnedColor := compositeKeyParts[0] + returnedMarbleName := compositeKeyParts[1] + fmt.Printf("- found a marble from index:%s color:%s name:%s\n", objectType, returnedColor, returnedMarbleName) + + // Now call the transfer function for the found marble. + // Re-use the same function that is used to transfer individual marbles + response := t.transferMarble(stub, []string{returnedMarbleName, newOwner}) + // if the transfer failed break out of loop and return error + if response.Status != shim.OK { + return shim.Error("Transfer failed: " + response.Message) + } + } + + responsePayload := fmt.Sprintf("Transferred %d %s marbles to %s", i, color, newOwner) + fmt.Println("- end transferMarblesBasedOnColor: " + responsePayload) + return shim.Success([]byte(responsePayload)) +} + +// =======Rich queries ========================================================================= +// Two examples of rich queries are provided below (parameterized query and ad hoc query). +// Rich queries pass a query string to the state database. +// Rich queries are only supported by state database implementations +// that support rich query (e.g. CouchDB). +// The query string is in the syntax of the underlying state database. +// With rich queries there is no guarantee that the result set hasn't changed between +// endorsement time and commit time, aka 'phantom reads'. +// Therefore, rich queries should not be used in update transactions, unless the +// application handles the possibility of result set changes between endorsement and commit time. +// Rich queries can be used for point-in-time queries against a peer. +// ============================================================================================ + +// ===== Example: Parameterized rich query ================================================= +// queryMarblesByOwner queries for marbles based on a passed in owner. +// This is an example of a parameterized query where the query logic is baked into the chaincode, +// and accepting a single query parameter (owner). +// Only available on state databases that support rich query (e.g. CouchDB) +// ========================================================================================= +func (t *SimpleChaincode) queryMarblesByOwner(stub shim.ChaincodeStubInterface, args []string) pb.Response { + + // 0 + // "bob" + if len(args) < 1 { + return shim.Error("Incorrect number of arguments. Expecting 1") + } + + owner := strings.ToLower(args[0]) + + queryString := fmt.Sprintf("{\"selector\":{\"docType\":\"marble\",\"owner\":\"%s\"}}", owner) + + queryResults, err := getQueryResultForQueryString(stub, queryString) + if err != nil { + return shim.Error(err.Error()) + } + return shim.Success(queryResults) +} + +// ===== Example: Ad hoc rich query ======================================================== +// queryMarbles uses a query string to perform a query for marbles. +// Query string matching state database syntax is passed in and executed as is. +// Supports ad hoc queries that can be defined at runtime by the client. +// If this is not desired, follow the queryMarblesForOwner example for parameterized queries. +// Only available on state databases that support rich query (e.g. CouchDB) +// ========================================================================================= +func (t *SimpleChaincode) queryMarbles(stub shim.ChaincodeStubInterface, args []string) pb.Response { + + // 0 + // "queryString" + if len(args) < 1 { + return shim.Error("Incorrect number of arguments. Expecting 1") + } + + queryString := args[0] + + queryResults, err := getQueryResultForQueryString(stub, queryString) + if err != nil { + return shim.Error(err.Error()) + } + return shim.Success(queryResults) +} + +// ========================================================================================= +// getQueryResultForQueryString executes the passed in query string. +// Result set is built and returned as a byte array containing the JSON results. +// ========================================================================================= +func getQueryResultForQueryString(stub shim.ChaincodeStubInterface, queryString string) ([]byte, error) { + + fmt.Printf("- getQueryResultForQueryString queryString:\n%s\n", queryString) + + resultsIterator, err := stub.GetPrivateDataQueryResult("collectionMarbles", queryString) + if err != nil { + return nil, err + } + defer resultsIterator.Close() + + // buffer is a JSON array containing QueryRecords + var buffer bytes.Buffer + buffer.WriteString("[") + + bArrayMemberAlreadyWritten := false + for resultsIterator.HasNext() { + queryResponse, err := resultsIterator.Next() + if err != nil { + return nil, err + } + // Add a comma before array members, suppress it for the first array member + if bArrayMemberAlreadyWritten == true { + buffer.WriteString(",") + } + buffer.WriteString("{\"Key\":") + buffer.WriteString("\"") + buffer.WriteString(queryResponse.Key) + buffer.WriteString("\"") + + buffer.WriteString(", \"Record\":") + // Record is a JSON object, so we write as-is + buffer.WriteString(string(queryResponse.Value)) + buffer.WriteString("}") + bArrayMemberAlreadyWritten = true + } + buffer.WriteString("]") + + fmt.Printf("- getQueryResultForQueryString queryResult:\n%s\n", buffer.String()) + + return buffer.Bytes(), nil +}