Auction sample clean up (#408)

Signed-off-by: Nikhil Gupta <ngupta@symbridge.com>

Co-authored-by: Nikhil Gupta <nikhilgupta@macbook-air.lan>
This commit is contained in:
nikhil550 2021-02-01 04:19:45 -05:00 committed by GitHub
parent 822c4c4c25
commit 7b1168cd9d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
13 changed files with 146 additions and 276 deletions

View file

@ -82,7 +82,7 @@ After the transaction is complete, the `createAuction.js` application will query
*** Result: Auction: { *** Result: Auction: {
"objectType": "auction", "objectType": "auction",
"item": "painting", "item": "painting",
"seller": "eDUwOTo6Q049c2VsbGVyLE9VPWNsaWVudCtPVT1vcmcxK09VPWRlcGFydG1lbnQxOjpDTj1jYS5vcmcxLmV4YW1wbGUuY29tLE89b3JnMS5leGFtcGxlLmNvbSxMPUR1cmhhbSxTVD1Ob3J0aCBDYXJvbGluYSxDPVVT", "seller": "x509::CN=seller,OU=client+OU=org1+OU=department1::CN=ca.org1.example.com,O=org1.example.com,L=Durham,ST=North Carolina,C=US",
"organizations": [ "organizations": [
"Org1MSP" "Org1MSP"
], ],
@ -93,16 +93,7 @@ After the transaction is complete, the `createAuction.js` application will query
"status": "open" "status": "open"
} }
``` ```
The smart contract uses the `GetClientIdentity().GetID()` API to read identity that creates the auction and defines that identity as the auction `"seller"`. You can see the seller information by decoding the `"seller"` string out of base64 format: The smart contract uses the `GetClientIdentity().GetID()` API to read the identity that creates the auction and defines that identity as the auction `"seller"`. The seller is identified by the name and issuer of the seller's certificate.
```
echo eDUwOTo6Q049c2VsbGVyLE9VPWNsaWVudCtPVT1vcmcxK09VPWRlcGFydG1lbnQxOjpDTj1jYS5vcmcxLmV4YW1wbGUuY29tLE89b3JnMS5leGFtcGxlLmNvbSxMPUR1cmhhbSxTVD1Ob3J0aCBDYXJvbGluYSxDPVVT | base64 --decode
```
The result is the name and issuer of the seller's certificate:
```
x509::CN=org1admin,OU=admin,O=Hyperledger,ST=North Carolina,C=US::CN=ca.org1.example.com,O=org1.example.com,L=Durham,ST=North Carolina,C=USn
```
## Bid on the auction ## Bid on the auction
@ -121,7 +112,7 @@ The application will query the bid after it is created:
"objectType": "bid", "objectType": "bid",
"price": 800, "price": 800,
"org": "Org1MSP", "org": "Org1MSP",
"bidder": "eDUwOTo6Q049YmlkZGVyMSxPVT1jbGllbnQrT1U9b3JnMStPVT1kZXBhcnRtZW50MTo6Q049Y2Eub3JnMS5leGFtcGxlLmNvbSxPPW9yZzEuZXhhbXBsZS5jb20sTD1EdXJoYW0sU1Q9Tm9ydGggQ2Fyb2xpbmEsQz1VUw==" "bidder": "x509::CN=bidder1,OU=client+OU=org1+OU=department1::CN=ca.org1.example.com,O=org1.example.com,L=Durham,ST=North Carolina,C=US"
} }
``` ```
@ -129,12 +120,12 @@ The bid is stored in the Org1 implicit data collection. The `"bidder"` parameter
The `bid.js` application also prints the bidID: The `bid.js` application also prints the bidID:
``` ```
*** Result ***SAVE THIS VALUE*** BidID: 8ef83011a5fb791f75ed008337839426f6b87981519e5d58ef5ada39c3044edd *** Result ***SAVE THIS VALUE*** BidID: 67d85ef08e32de20994c816362d0952fe5c2ae3f2d1083600c3ac61f65a89f60
``` ```
The BidID acts as the unique identifier for the bid. This ID allows you to query the bid using the `queryBid.js` program and add the bid to the auction. Save the bidID returned by the application as an environment variable in your terminal: The BidID acts as the unique identifier for the bid. This ID allows you to query the bid using the `queryBid.js` program and add the bid to the auction. Save the bidID returned by the application as an environment variable in your terminal:
``` ```
export BIDDER1_BID_ID=8ef83011a5fb791f75ed008337839426f6b87981519e5d58ef5ada39c3044edd export BIDDER1_BID_ID=67d85ef08e32de20994c816362d0952fe5c2ae3f2d1083600c3ac61f65a89f60
``` ```
This value will be different for each transaction, so you will need to use the value returned in your terminal. This value will be different for each transaction, so you will need to use the value returned in your terminal.
@ -148,14 +139,14 @@ The hash of bid will be added to the list private bids in that have been submitt
*** Result: Auction: { *** Result: Auction: {
"objectType": "auction", "objectType": "auction",
"item": "painting", "item": "painting",
"seller": "eDUwOTo6Q049c2VsbGVyLE9VPWNsaWVudCtPVT1vcmcxK09VPWRlcGFydG1lbnQxOjpDTj1jYS5vcmcxLmV4YW1wbGUuY29tLE89b3JnMS5leGFtcGxlLmNvbSxMPUR1cmhhbSxTVD1Ob3J0aCBDYXJvbGluYSxDPVVT", "seller": "x509::CN=seller,OU=client+OU=org1+OU=department1::CN=ca.org1.example.com,O=org1.example.com,L=Durham,ST=North Carolina,C=US",
"organizations": [ "organizations": [
"Org1MSP" "Org1MSP"
], ],
"privateBids": { "privateBids": {
"\u0000bid\u0000PaintingAuction\u00008ef83011a5fb791f75ed008337839426f6b87981519e5d58ef5ada39c3044edd\u0000": { "\u0000bid\u0000PaintingAuction\u00005c049b0b4552d34c88e0f8fb5abca31fa04472b7e1336a16650ac8cfb0b16472\u0000": {
"org": "Org1MSP", "org": "Org1MSP",
"hash": "5cb50a17b5a21c02fc01306e3e9b54f4db67e9a440552ce898bbd7daa62dce0f" "hash": "0b8bbdb96b1d252e71ac1ed71df3580f7a0e31a743a4a09bbf5196dffef426b2"
} }
}, },
"revealedBids": {}, "revealedBids": {},
@ -174,7 +165,7 @@ node bid.js org1 bidder2 PaintingAuction 500
Save the Bid ID returned by the application: Save the Bid ID returned by the application:
``` ```
export BIDDER2_BID_ID=915a908c8f2c368f4a3aedd73176656af81ddfab000b11629503403f3d97b185 export BIDDER2_BID_ID=0fa8b3b15923966f205a1f5ebd163d2707d069ffa055105114fc654d225f511d
``` ```
Submit bidder2's bid to the auction: Submit bidder2's bid to the auction:
@ -191,7 +182,7 @@ node bid.js org2 bidder3 PaintingAuction 700
Save the Bid ID returned by the application: Save the Bid ID returned by the application:
``` ```
export BIDDER3_BID_ID=5e4e637c68833b178739575f6fe09820b019551a8cfbb43a4d172e0aa864dfad export BIDDER3_BID_ID=cda8bb2849fc0553efb036c56ea86d82791a695b5641941dac797dc6e2d75768
``` ```
Add bidder3's bid to the auction: Add bidder3's bid to the auction:
@ -204,23 +195,23 @@ Because bidder3 belongs to Org2, submitting the bid will add Org2 to the list of
*** Result: Auction: { *** Result: Auction: {
"objectType": "auction", "objectType": "auction",
"item": "painting", "item": "painting",
"seller": "eDUwOTo6Q049c2VsbGVyLE9VPWNsaWVudCtPVT1vcmcxK09VPWRlcGFydG1lbnQxOjpDTj1jYS5vcmcxLmV4YW1wbGUuY29tLE89b3JnMS5leGFtcGxlLmNvbSxMPUR1cmhhbSxTVD1Ob3J0aCBDYXJvbGluYSxDPVVT", "seller": "x509::CN=seller,OU=client+OU=org1+OU=department1::CN=ca.org1.example.com,O=org1.example.com,L=Durham,ST=North Carolina,C=US",
"organizations": [ "organizations": [
"Org1MSP", "Org1MSP",
"Org2MSP" "Org2MSP"
], ],
"privateBids": { "privateBids": {
"\u0000bid\u0000PaintingAuction\u00005e4e637c68833b178739575f6fe09820b019551a8cfbb43a4d172e0aa864dfad\u0000": { "\u0000bid\u0000PaintingAuction\u00001b9dc0006fef10413df5cca927cabdf73ab854fe92b7a7b2eebfa00961fdac67\u0000": {
"org": "Org1MSP",
"hash": "15cd9a3e12825017f3e758499ac6138ebbe1adec4c49cc6ea6a0973fc6514666"
},
"\u0000bid\u0000PaintingAuction\u00005c049b0b4552d34c88e0f8fb5abca31fa04472b7e1336a16650ac8cfb0b16472\u0000": {
"org": "Org1MSP",
"hash": "0b8bbdb96b1d252e71ac1ed71df3580f7a0e31a743a4a09bbf5196dffef426b2"
},
"\u0000bid\u0000PaintingAuction\u00005ee4fa53b54ea0821e57a6884a1ada5eb04f136ee222e92d7399bcdf47556ea1\u0000": {
"org": "Org2MSP", "org": "Org2MSP",
"hash": "40107eab7a99dfc2f25d02b8ab840f12fd802a9f86d8d42b78d7b4409b2c15bd" "hash": "14d47d17acceceb483e87c14a4349844874fce549d71c6a23457d953ed8ffbd3"
},
"\u0000bid\u0000PaintingAuction\u00008ef83011a5fb791f75ed008337839426f6b87981519e5d58ef5ada39c3044edd\u0000": {
"org": "Org1MSP",
"hash": "5cb50a17b5a21c02fc01306e3e9b54f4db67e9a440552ce898bbd7daa62dce0f"
},
"\u0000bid\u0000PaintingAuction\u0000915a908c8f2c368f4a3aedd73176656af81ddfab000b11629503403f3d97b185\u0000": {
"org": "Org1MSP",
"hash": "a458df18b12dffe4ae6d56a270134c2d55bd53fface034bd24381d0073d46a45"
} }
}, },
"revealedBids": {}, "revealedBids": {},
@ -241,7 +232,7 @@ node bid.js org2 bidder4 PaintingAuction 900
Save the Bid ID returned by the application: Save the Bid ID returned by the application:
``` ```
export BIDDER4_BID_ID=49466271ae879bd009e75a60730a12bfa986e75f263202ab81ccd3deec544a35 export BIDDER4_BID_ID=83861eb17715ff537a1e73cd2d08509dc7199572806a5368706516759af1a257
``` ```
Add bidder4's bid to the auction: Add bidder4's bid to the auction:
@ -276,35 +267,35 @@ The full bid details, including the price, are now visible:
*** Result: Auction: { *** Result: Auction: {
"objectType": "auction", "objectType": "auction",
"item": "painting", "item": "painting",
"seller": "eDUwOTo6Q049c2VsbGVyLE9VPWNsaWVudCtPVT1vcmcxK09VPWRlcGFydG1lbnQxOjpDTj1jYS5vcmcxLmV4YW1wbGUuY29tLE89b3JnMS5leGFtcGxlLmNvbSxMPUR1cmhhbSxTVD1Ob3J0aCBDYXJvbGluYSxDPVVT", "seller": "x509::CN=seller,OU=client+OU=org1+OU=department1::CN=ca.org1.example.com,O=org1.example.com,L=Durham,ST=North Carolina,C=US",
"organizations": [ "organizations": [
"Org1MSP", "Org1MSP",
"Org2MSP" "Org2MSP"
], ],
"privateBids": { "privateBids": {
"\u0000bid\u0000PaintingAuction\u000049466271ae879bd009e75a60730a12bfa986e75f263202ab81ccd3deec544a35\u0000": { "\u0000bid\u0000PaintingAuction\u000019a7a0dd2c5456a3f79c2f9ccb09dddd0f1c9ece514dfea7cbea06e7cbc79855\u0000": {
"org": "Org2MSP", "org": "Org2MSP",
"hash": "b8eaeb4422b93abdfe4ccb6aa11b745b3d1cb072a99bd3eb3618f081fb1b1f89" "hash": "08db66c6cc226577a3153dadeb0b77d3834162fcf5f008b344058a1bc5c1b3a4"
}, },
"\u0000bid\u0000PaintingAuction\u00005e4e637c68833b178739575f6fe09820b019551a8cfbb43a4d172e0aa864dfad\u0000": { "\u0000bid\u0000PaintingAuction\u00001b9dc0006fef10413df5cca927cabdf73ab854fe92b7a7b2eebfa00961fdac67\u0000": {
"org": "Org1MSP",
"hash": "15cd9a3e12825017f3e758499ac6138ebbe1adec4c49cc6ea6a0973fc6514666"
},
"\u0000bid\u0000PaintingAuction\u00005c049b0b4552d34c88e0f8fb5abca31fa04472b7e1336a16650ac8cfb0b16472\u0000": {
"org": "Org1MSP",
"hash": "0b8bbdb96b1d252e71ac1ed71df3580f7a0e31a743a4a09bbf5196dffef426b2"
},
"\u0000bid\u0000PaintingAuction\u00005ee4fa53b54ea0821e57a6884a1ada5eb04f136ee222e92d7399bcdf47556ea1\u0000": {
"org": "Org2MSP", "org": "Org2MSP",
"hash": "40107eab7a99dfc2f25d02b8ab840f12fd802a9f86d8d42b78d7b4409b2c15bd" "hash": "14d47d17acceceb483e87c14a4349844874fce549d71c6a23457d953ed8ffbd3"
},
"\u0000bid\u0000PaintingAuction\u00008ef83011a5fb791f75ed008337839426f6b87981519e5d58ef5ada39c3044edd\u0000": {
"org": "Org1MSP",
"hash": "5cb50a17b5a21c02fc01306e3e9b54f4db67e9a440552ce898bbd7daa62dce0f"
},
"\u0000bid\u0000PaintingAuction\u0000915a908c8f2c368f4a3aedd73176656af81ddfab000b11629503403f3d97b185\u0000": {
"org": "Org1MSP",
"hash": "a458df18b12dffe4ae6d56a270134c2d55bd53fface034bd24381d0073d46a45"
} }
}, },
"revealedBids": { "revealedBids": {
"\u0000bid\u0000PaintingAuction\u00008ef83011a5fb791f75ed008337839426f6b87981519e5d58ef5ada39c3044edd\u0000": { "\u0000bid\u0000PaintingAuction\u00005c049b0b4552d34c88e0f8fb5abca31fa04472b7e1336a16650ac8cfb0b16472\u0000": {
"objectType": "bid", "objectType": "bid",
"price": 800, "price": 800,
"org": "Org1MSP", "org": "Org1MSP",
"bidder": "eDUwOTo6Q049YmlkZGVyMSxPVT1jbGllbnQrT1U9b3JnMStPVT1kZXBhcnRtZW50MTo6Q049Y2Eub3JnMS5leGFtcGxlLmNvbSxPPW9yZzEuZXhhbXBsZS5jb20sTD1EdXJoYW0sU1Q9Tm9ydGggQ2Fyb2xpbmEsQz1VUw==" "bidder": "x509::CN=bidder1,OU=client+OU=org1+OU=department1::CN=ca.org1.example.com,O=org1.example.com,L=Durham,ST=North Carolina,C=US"
} }
}, },
"winner": "", "winner": "",
@ -328,8 +319,11 @@ The output should look something like the following:
``` ```
--> Submit the transaction to end the auction --> Submit the transaction to end the auction
2020-11-06T13:16:11.591Z - warn: [TransactionEventHandler]: strategyFail: commit failure for transaction "99feade5b7ec223839200867b57d18971c3e9f923efc95aaeec720727f927366": TransactionError: Commit of transaction 99feade5b7ec223839200867b57d18971c3e9f923efc95aaeec720727f927366 failed on peer peer0.org1.example.com:7051 with status ENDORSEMENT_POLICY_FAILURE 2021-01-28T16:47:27.501Z - error: [DiscoveryHandler]: compareProposalResponseResults[undefined] - read/writes result sets do not match index=1
******** FAILED to submit bid: TransactionError: Commit of transaction 99feade5b7ec223839200867b57d18971c3e9f923efc95aaeec720727f927366 failed on peer peer0.org1.example.com:7051 with status ENDORSEMENT_POLICY_FAILURE 2021-01-28T16:47:27.503Z - error: [Transaction]: Error: No valid responses from any peers. Errors:
peer=undefined, status=grpc, message=Peer endorsements do not match
******** FAILED to submit bid: Error: No valid responses from any peers. Errors:
peer=undefined, status=grpc, message=Peer endorsements do not match
``` ```
Instead of ending the auction, the transaction results in an endorsement policy failure. The end of the auction needs to be endorsed by Org2. Before endorsing the transaction, the Org2 peer queries its private data collection for any winning bids that have not yet been revealed. Because Bidder4 created a bid that is above the winning price, the Org2 peer refuses to endorse the transaction that would end the auction. Instead of ending the auction, the transaction results in an endorsement policy failure. The end of the auction needs to be endorsed by Org2. Before endorsing the transaction, the Org2 peer queries its private data collection for any winning bids that have not yet been revealed. Because Bidder4 created a bid that is above the winning price, the Org2 peer refuses to endorse the transaction that would end the auction.
@ -353,50 +347,50 @@ The transaction was successfully endorsed by both Org1 and Org2, who both calcul
*** Result: Auction: { *** Result: Auction: {
"objectType": "auction", "objectType": "auction",
"item": "painting", "item": "painting",
"seller": "eDUwOTo6Q049c2VsbGVyLE9VPWNsaWVudCtPVT1vcmcxK09VPWRlcGFydG1lbnQxOjpDTj1jYS5vcmcxLmV4YW1wbGUuY29tLE89b3JnMS5leGFtcGxlLmNvbSxMPUR1cmhhbSxTVD1Ob3J0aCBDYXJvbGluYSxDPVVT", "seller": "x509::CN=seller,OU=client+OU=org1+OU=department1::CN=ca.org1.example.com,O=org1.example.com,L=Durham,ST=North Carolina,C=US",
"organizations": [ "organizations": [
"Org1MSP", "Org1MSP",
"Org2MSP" "Org2MSP"
], ],
"privateBids": { "privateBids": {
"\u0000bid\u0000PaintingAuction\u000049466271ae879bd009e75a60730a12bfa986e75f263202ab81ccd3deec544a35\u0000": { "\u0000bid\u0000PaintingAuction\u000019a7a0dd2c5456a3f79c2f9ccb09dddd0f1c9ece514dfea7cbea06e7cbc79855\u0000": {
"org": "Org2MSP", "org": "Org2MSP",
"hash": "b8eaeb4422b93abdfe4ccb6aa11b745b3d1cb072a99bd3eb3618f081fb1b1f89" "hash": "08db66c6cc226577a3153dadeb0b77d3834162fcf5f008b344058a1bc5c1b3a4"
}, },
"\u0000bid\u0000PaintingAuction\u00005e4e637c68833b178739575f6fe09820b019551a8cfbb43a4d172e0aa864dfad\u0000": { "\u0000bid\u0000PaintingAuction\u00001b9dc0006fef10413df5cca927cabdf73ab854fe92b7a7b2eebfa00961fdac67\u0000": {
"org": "Org1MSP",
"hash": "15cd9a3e12825017f3e758499ac6138ebbe1adec4c49cc6ea6a0973fc6514666"
},
"\u0000bid\u0000PaintingAuction\u00005c049b0b4552d34c88e0f8fb5abca31fa04472b7e1336a16650ac8cfb0b16472\u0000": {
"org": "Org1MSP",
"hash": "0b8bbdb96b1d252e71ac1ed71df3580f7a0e31a743a4a09bbf5196dffef426b2"
},
"\u0000bid\u0000PaintingAuction\u00005ee4fa53b54ea0821e57a6884a1ada5eb04f136ee222e92d7399bcdf47556ea1\u0000": {
"org": "Org2MSP", "org": "Org2MSP",
"hash": "40107eab7a99dfc2f25d02b8ab840f12fd802a9f86d8d42b78d7b4409b2c15bd" "hash": "14d47d17acceceb483e87c14a4349844874fce549d71c6a23457d953ed8ffbd3"
},
"\u0000bid\u0000PaintingAuction\u00008ef83011a5fb791f75ed008337839426f6b87981519e5d58ef5ada39c3044edd\u0000": {
"org": "Org1MSP",
"hash": "5cb50a17b5a21c02fc01306e3e9b54f4db67e9a440552ce898bbd7daa62dce0f"
},
"\u0000bid\u0000PaintingAuction\u0000915a908c8f2c368f4a3aedd73176656af81ddfab000b11629503403f3d97b185\u0000": {
"org": "Org1MSP",
"hash": "a458df18b12dffe4ae6d56a270134c2d55bd53fface034bd24381d0073d46a45"
} }
}, },
"revealedBids": { "revealedBids": {
"\u0000bid\u0000PaintingAuction\u000049466271ae879bd009e75a60730a12bfa986e75f263202ab81ccd3deec544a35\u0000": { "\u0000bid\u0000PaintingAuction\u000019a7a0dd2c5456a3f79c2f9ccb09dddd0f1c9ece514dfea7cbea06e7cbc79855\u0000": {
"objectType": "bid", "objectType": "bid",
"price": 900, "price": 900,
"org": "Org2MSP", "org": "Org2MSP",
"bidder": "eDUwOTo6Q049YmlkZGVyNCxPVT1jbGllbnQrT1U9b3JnMitPVT1kZXBhcnRtZW50MTo6Q049Y2Eub3JnMi5leGFtcGxlLmNvbSxPPW9yZzIuZXhhbXBsZS5jb20sTD1IdXJzbGV5LFNUPUhhbXBzaGlyZSxDPVVL" "bidder": "x509::CN=bidder4,OU=client+OU=org2+OU=department1::CN=ca.org2.example.com,O=org2.example.com,L=Hursley,ST=Hampshire,C=UK"
}, },
"\u0000bid\u0000PaintingAuction\u00005e4e637c68833b178739575f6fe09820b019551a8cfbb43a4d172e0aa864dfad\u0000": { "\u0000bid\u0000PaintingAuction\u00005c049b0b4552d34c88e0f8fb5abca31fa04472b7e1336a16650ac8cfb0b16472\u0000": {
"objectType": "bid",
"price": 700,
"org": "Org2MSP",
"bidder": "eDUwOTo6Q049YmlkZGVyMyxPVT1jbGllbnQrT1U9b3JnMitPVT1kZXBhcnRtZW50MTo6Q049Y2Eub3JnMi5leGFtcGxlLmNvbSxPPW9yZzIuZXhhbXBsZS5jb20sTD1IdXJzbGV5LFNUPUhhbXBzaGlyZSxDPVVL"
},
"\u0000bid\u0000PaintingAuction\u00008ef83011a5fb791f75ed008337839426f6b87981519e5d58ef5ada39c3044edd\u0000": {
"objectType": "bid", "objectType": "bid",
"price": 800, "price": 800,
"org": "Org1MSP", "org": "Org1MSP",
"bidder": "eDUwOTo6Q049YmlkZGVyMSxPVT1jbGllbnQrT1U9b3JnMStPVT1kZXBhcnRtZW50MTo6Q049Y2Eub3JnMS5leGFtcGxlLmNvbSxPPW9yZzEuZXhhbXBsZS5jb20sTD1EdXJoYW0sU1Q9Tm9ydGggQ2Fyb2xpbmEsQz1VUw==" "bidder": "x509::CN=bidder1,OU=client+OU=org1+OU=department1::CN=ca.org1.example.com,O=org1.example.com,L=Durham,ST=North Carolina,C=US"
},
"\u0000bid\u0000PaintingAuction\u00005ee4fa53b54ea0821e57a6884a1ada5eb04f136ee222e92d7399bcdf47556ea1\u0000": {
"objectType": "bid",
"price": 700,
"org": "Org2MSP",
"bidder": "x509::CN=bidder3,OU=client+OU=org2+OU=department1::CN=ca.org2.example.com,O=org2.example.com,L=Hursley,ST=Hampshire,C=UK"
} }
}, },
"winner": "eDUwOTo6Q049YmlkZGVyNCxPVT1jbGllbnQrT1U9b3JnMitPVT1kZXBhcnRtZW50MTo6Q049Y2Eub3JnMi5leGFtcGxlLmNvbSxPPW9yZzIuZXhhbXBsZS5jb20sTD1IdXJzbGV5LFNUPUhhbXBzaGlyZSxDPVVL", "winner": "x509::CN=bidder4,OU=client+OU=org2+OU=department1::CN=ca.org2.example.com,O=org2.example.com,L=Hursley,ST=Hampshire,C=UK",
"price": 900, "price": 900,
"status": "ended" "status": "ended"
} }

View file

@ -8,21 +8,11 @@
const { Gateway, Wallets } = require('fabric-network'); const { Gateway, Wallets } = require('fabric-network');
const path = require('path'); const path = require('path');
const { buildCCPOrg1, buildCCPOrg2, buildWallet } = require('../../test-application/javascript/AppUtil.js'); const { buildCCPOrg1, buildCCPOrg2, buildWallet, prettyJSONString} = require('../../test-application/javascript/AppUtil.js');
const myChannel = 'mychannel'; const myChannel = 'mychannel';
const myChaincodeName = 'auction'; const myChaincodeName = 'auction';
function prettyJSONString(inputString) {
if (inputString) {
return JSON.stringify(JSON.parse(inputString), null, 2);
}
else {
return inputString;
}
}
async function bid(ccp,wallet,user,orgMSP,auctionID,price) { async function bid(ccp,wallet,user,orgMSP,auctionID,price) {
try { try {
@ -36,7 +26,7 @@ async function bid(ccp,wallet,user,orgMSP,auctionID,price) {
const contract = network.getContract(myChaincodeName); const contract = network.getContract(myChaincodeName);
console.log('\n--> Evaluate Transaction: get your client ID'); console.log('\n--> Evaluate Transaction: get your client ID');
let bidder = await contract.evaluateTransaction('GetID'); let bidder = await contract.evaluateTransaction('GetSubmittingClientIdentity');
console.log('*** Result: Bidder ID is ' + bidder.toString()); console.log('*** Result: Bidder ID is ' + bidder.toString());
let bidData = { objectType: 'bid', price: parseInt(price), org: orgMSP, bidder: bidder.toString()}; let bidData = { objectType: 'bid', price: parseInt(price), org: orgMSP, bidder: bidder.toString()};
@ -78,7 +68,7 @@ async function main() {
process.exit(1); process.exit(1);
} }
const org = process.argv[2] const org = process.argv[2];
const user = process.argv[3]; const user = process.argv[3];
const auctionID = process.argv[4]; const auctionID = process.argv[4];
const price = process.argv[5]; const price = process.argv[5];
@ -108,5 +98,4 @@ async function main() {
} }
} }
main(); main();

View file

@ -8,21 +8,11 @@
const { Gateway, Wallets } = require('fabric-network'); const { Gateway, Wallets } = require('fabric-network');
const path = require('path'); const path = require('path');
const { buildCCPOrg1, buildCCPOrg2, buildWallet } = require('../../test-application/javascript/AppUtil.js'); const { buildCCPOrg1, buildCCPOrg2, buildWallet, prettyJSONString} = require('../../test-application/javascript/AppUtil.js');
const myChannel = 'mychannel'; const myChannel = 'mychannel';
const myChaincodeName = 'auction'; const myChaincodeName = 'auction';
function prettyJSONString(inputString) {
if (inputString) {
return JSON.stringify(JSON.parse(inputString), null, 2);
}
else {
return inputString;
}
}
async function closeAuction(ccp,wallet,user,auctionID) { async function closeAuction(ccp,wallet,user,auctionID) {
try { try {
@ -36,9 +26,7 @@ async function closeAuction(ccp,wallet,user,auctionID) {
const contract = network.getContract(myChaincodeName); const contract = network.getContract(myChaincodeName);
// Query the auction to get the list of endorsing orgs. // Query the auction to get the list of endorsing orgs.
//console.log('\n--> Evaluate Transaction: query the auction you want to close');
let auctionString = await contract.evaluateTransaction('QueryAuction',auctionID); let auctionString = await contract.evaluateTransaction('QueryAuction',auctionID);
//console.log('*** Result: Bid: ' + prettyJSONString(auctionString.toString()));
var auctionJSON = JSON.parse(auctionString); var auctionJSON = JSON.parse(auctionString);
let statefulTxn = contract.createTransaction('CloseAuction'); let statefulTxn = contract.createTransaction('CloseAuction');
@ -73,7 +61,7 @@ async function main() {
process.exit(1); process.exit(1);
} }
const org = process.argv[2] const org = process.argv[2];
const user = process.argv[3]; const user = process.argv[3];
const auctionID = process.argv[4]; const auctionID = process.argv[4];

View file

@ -8,21 +8,11 @@
const { Gateway, Wallets } = require('fabric-network'); const { Gateway, Wallets } = require('fabric-network');
const path = require('path'); const path = require('path');
const { buildCCPOrg1, buildCCPOrg2, buildWallet } = require('../../test-application/javascript/AppUtil.js'); const { buildCCPOrg1, buildCCPOrg2, buildWallet, prettyJSONString} = require('../../test-application/javascript/AppUtil.js');
const myChannel = 'mychannel'; const myChannel = 'mychannel';
const myChaincodeName = 'auction'; const myChaincodeName = 'auction';
function prettyJSONString(inputString) {
if (inputString) {
return JSON.stringify(JSON.parse(inputString), null, 2);
}
else {
return inputString;
}
}
async function createAuction(ccp,wallet,user,auctionID,item) { async function createAuction(ccp,wallet,user,auctionID,item) {
try { try {
@ -60,7 +50,7 @@ async function main() {
process.exit(1); process.exit(1);
} }
const org = process.argv[2] const org = process.argv[2];
const user = process.argv[3]; const user = process.argv[3];
const auctionID = process.argv[4]; const auctionID = process.argv[4];
const item = process.argv[5]; const item = process.argv[5];

View file

@ -8,21 +8,11 @@
const { Gateway, Wallets } = require('fabric-network'); const { Gateway, Wallets } = require('fabric-network');
const path = require('path'); const path = require('path');
const { buildCCPOrg1, buildCCPOrg2, buildWallet } = require('../../test-application/javascript/AppUtil.js'); const { buildCCPOrg1, buildCCPOrg2, buildWallet, prettyJSONString} = require('../../test-application/javascript/AppUtil.js');
const myChannel = 'mychannel'; const myChannel = 'mychannel';
const myChaincodeName = 'auction'; const myChaincodeName = 'auction';
function prettyJSONString(inputString) {
if (inputString) {
return JSON.stringify(JSON.parse(inputString), null, 2);
}
else {
return inputString;
}
}
async function endAuction(ccp,wallet,user,auctionID) { async function endAuction(ccp,wallet,user,auctionID) {
try { try {
@ -36,9 +26,7 @@ async function endAuction(ccp,wallet,user,auctionID) {
const contract = network.getContract(myChaincodeName); const contract = network.getContract(myChaincodeName);
// Query the auction to get the list of endorsing orgs. // Query the auction to get the list of endorsing orgs.
//console.log('\n--> Evaluate Transaction: query the auction you want to end');
let auctionString = await contract.evaluateTransaction('QueryAuction',auctionID); let auctionString = await contract.evaluateTransaction('QueryAuction',auctionID);
//console.log('*** Result: Bid: ' + prettyJSONString(auctionString.toString()));
var auctionJSON = JSON.parse(auctionString); var auctionJSON = JSON.parse(auctionString);
let statefulTxn = contract.createTransaction('EndAuction'); let statefulTxn = contract.createTransaction('EndAuction');
@ -73,7 +61,7 @@ async function main() {
process.exit(1); process.exit(1);
} }
const org = process.argv[2] const org = process.argv[2];
const user = process.argv[3]; const user = process.argv[3];
const auctionID = process.argv[4]; const auctionID = process.argv[4];

View file

@ -15,15 +15,6 @@ const { buildCCPOrg1, buildCCPOrg2, buildWallet } = require('../../test-applicat
const mspOrg1 = 'Org1MSP'; const mspOrg1 = 'Org1MSP';
const mspOrg2 = 'Org2MSP'; const mspOrg2 = 'Org2MSP';
function prettyJSONString(inputString) {
if (inputString) {
return JSON.stringify(JSON.parse(inputString), null, 2);
}
else {
return inputString;
}
}
async function connectToOrg1CA() { async function connectToOrg1CA() {
console.log('\n--> Enrolling the Org1 CA admin'); console.log('\n--> Enrolling the Org1 CA admin');
const ccpOrg1 = buildCCPOrg1(); const ccpOrg1 = buildCCPOrg1();

View file

@ -8,21 +8,11 @@
const { Gateway, Wallets } = require('fabric-network'); const { Gateway, Wallets } = require('fabric-network');
const path = require('path'); const path = require('path');
const { buildCCPOrg1, buildCCPOrg2, buildWallet } = require('../../test-application/javascript/AppUtil.js'); const { buildCCPOrg1, buildCCPOrg2, buildWallet, prettyJSONString} = require('../../test-application/javascript/AppUtil.js');
const myChannel = 'mychannel'; const myChannel = 'mychannel';
const myChaincodeName = 'auction'; const myChaincodeName = 'auction';
function prettyJSONString(inputString) {
if (inputString) {
return JSON.stringify(JSON.parse(inputString), null, 2);
}
else {
return inputString;
}
}
async function queryAuction(ccp,wallet,user,auctionID) { async function queryAuction(ccp,wallet,user,auctionID) {
try { try {
@ -54,7 +44,7 @@ async function main() {
process.exit(1); process.exit(1);
} }
const org = process.argv[2] const org = process.argv[2];
const user = process.argv[3]; const user = process.argv[3];
const auctionID = process.argv[4]; const auctionID = process.argv[4];

View file

@ -8,21 +8,11 @@
const { Gateway, Wallets } = require('fabric-network'); const { Gateway, Wallets } = require('fabric-network');
const path = require('path'); const path = require('path');
const { buildCCPOrg1, buildCCPOrg2, buildWallet } = require('../../test-application/javascript/AppUtil.js'); const { buildCCPOrg1, buildCCPOrg2, buildWallet, prettyJSONString} = require('../../test-application/javascript/AppUtil.js');
const myChannel = 'mychannel'; const myChannel = 'mychannel';
const myChaincodeName = 'auction'; const myChaincodeName = 'auction';
function prettyJSONString(inputString) {
if (inputString) {
return JSON.stringify(JSON.parse(inputString), null, 2);
}
else {
return inputString;
}
}
async function queryBid(ccp,wallet,user,auctionID,bidID) { async function queryBid(ccp,wallet,user,auctionID,bidID) {
try { try {
@ -54,7 +44,7 @@ async function main() {
process.exit(1); process.exit(1);
} }
const org = process.argv[2] const org = process.argv[2];
const user = process.argv[3]; const user = process.argv[3];
const auctionID = process.argv[4]; const auctionID = process.argv[4];
const bidID = process.argv[5]; const bidID = process.argv[5];

View file

@ -15,15 +15,6 @@ const { buildCCPOrg1, buildCCPOrg2, buildWallet } = require('../../test-applicat
const mspOrg1 = 'Org1MSP'; const mspOrg1 = 'Org1MSP';
const mspOrg2 = 'Org2MSP'; const mspOrg2 = 'Org2MSP';
function prettyJSONString(inputString) {
if (inputString) {
return JSON.stringify(JSON.parse(inputString), null, 2);
}
else {
return inputString;
}
}
async function connectToOrg1CA(UserID) { async function connectToOrg1CA(UserID) {
console.log('\n--> Register and enrolling new user'); console.log('\n--> Register and enrolling new user');
const ccpOrg1 = buildCCPOrg1(); const ccpOrg1 = buildCCPOrg1();

View file

@ -8,21 +8,11 @@
const { Gateway, Wallets } = require('fabric-network'); const { Gateway, Wallets } = require('fabric-network');
const path = require('path'); const path = require('path');
const { buildCCPOrg1, buildCCPOrg2, buildWallet } = require('../../test-application/javascript/AppUtil.js'); const { buildCCPOrg1, buildCCPOrg2, buildWallet, prettyJSONString} = require('../../test-application/javascript/AppUtil.js');
const myChannel = 'mychannel'; const myChannel = 'mychannel';
const myChaincodeName = 'auction'; const myChaincodeName = 'auction';
function prettyJSONString(inputString) {
if (inputString) {
return JSON.stringify(JSON.parse(inputString), null, 2);
}
else {
return inputString;
}
}
async function addBid(ccp,wallet,user,auctionID,bidID) { async function addBid(ccp,wallet,user,auctionID,bidID) {
try { try {
@ -81,7 +71,7 @@ async function main() {
process.exit(1); process.exit(1);
} }
const org = process.argv[2] const org = process.argv[2];
const user = process.argv[3]; const user = process.argv[3];
const auctionID = process.argv[4]; const auctionID = process.argv[4];
const bidID = process.argv[5]; const bidID = process.argv[5];

View file

@ -51,7 +51,7 @@ const bidKeyType = "bid"
func (s *SmartContract) CreateAuction(ctx contractapi.TransactionContextInterface, auctionID string, itemsold string) error { func (s *SmartContract) CreateAuction(ctx contractapi.TransactionContextInterface, auctionID string, itemsold string) error {
// get ID of submitting client // get ID of submitting client
clientID, err := ctx.GetClientIdentity().GetID() clientID, err := s.GetSubmittingClientIdentity(ctx)
if err != nil { if err != nil {
return fmt.Errorf("failed to get client identity %v", err) return fmt.Errorf("failed to get client identity %v", err)
} }
@ -78,13 +78,13 @@ func (s *SmartContract) CreateAuction(ctx contractapi.TransactionContextInterfac
Status: "open", Status: "open",
} }
auctionBytes, err := json.Marshal(auction) auctionJSON, err := json.Marshal(auction)
if err != nil { if err != nil {
return err return err
} }
// put auction into state // put auction into state
err = ctx.GetStub().PutState(auctionID, auctionBytes) err = ctx.GetStub().PutState(auctionID, auctionJSON)
if err != nil { if err != nil {
return fmt.Errorf("failed to put auction in public data: %v", err) return fmt.Errorf("failed to put auction in public data: %v", err)
} }
@ -156,20 +156,14 @@ func (s *SmartContract) SubmitBid(ctx contractapi.TransactionContextInterface, a
return fmt.Errorf("failed to get client MSP ID: %v", err) return fmt.Errorf("failed to get client MSP ID: %v", err)
} }
// get the auction from state // get the auction from public state
auctionBytes, err := ctx.GetStub().GetState(auctionID) auction, err := s.QueryAuction(ctx,auctionID)
var auctionJSON Auction
if auctionBytes == nil {
return fmt.Errorf("Auction not found: %v", auctionID)
}
err = json.Unmarshal(auctionBytes, &auctionJSON)
if err != nil { if err != nil {
return fmt.Errorf("failed to create auction object JSON: %v", err) return fmt.Errorf("failed to get auction from public state %v", err)
} }
// the auction needs to be open for users to add their bid // the auction needs to be open for users to add their bid
Status := auctionJSON.Status Status := auction.Status
if Status != "open" { if Status != "open" {
return fmt.Errorf("cannot join closed or ended auction") return fmt.Errorf("cannot join closed or ended auction")
} }
@ -202,15 +196,15 @@ func (s *SmartContract) SubmitBid(ctx contractapi.TransactionContextInterface, a
} }
bidders := make(map[string]BidHash) bidders := make(map[string]BidHash)
bidders = auctionJSON.PrivateBids bidders = auction.PrivateBids
bidders[bidKey] = NewHash bidders[bidKey] = NewHash
auctionJSON.PrivateBids = bidders auction.PrivateBids = bidders
// Add the bidding organization to the list of participating organizations if it is not already // Add the bidding organization to the list of participating organizations if it is not already
Orgs := auctionJSON.Orgs Orgs := auction.Orgs
if !(contains(Orgs, clientOrgID)) { if !(contains(Orgs, clientOrgID)) {
newOrgs := append(Orgs, clientOrgID) newOrgs := append(Orgs, clientOrgID)
auctionJSON.Orgs = newOrgs auction.Orgs = newOrgs
err = addAssetStateBasedEndorsement(ctx, auctionID, clientOrgID) err = addAssetStateBasedEndorsement(ctx, auctionID, clientOrgID)
if err != nil { if err != nil {
@ -218,9 +212,9 @@ func (s *SmartContract) SubmitBid(ctx contractapi.TransactionContextInterface, a
} }
} }
newAuctionBytes, _ := json.Marshal(auctionJSON) newAuctionJSON, _ := json.Marshal(auction)
err = ctx.GetStub().PutState(auctionID, newAuctionBytes) err = ctx.GetStub().PutState(auctionID, newAuctionJSON)
if err != nil { if err != nil {
return fmt.Errorf("failed to update auction: %v", err) return fmt.Errorf("failed to update auction: %v", err)
} }
@ -264,25 +258,16 @@ func (s *SmartContract) RevealBid(ctx contractapi.TransactionContextInterface, a
} }
// get auction from public state // get auction from public state
auctionBytes, err := ctx.GetStub().GetState(auctionID) auction, err := s.QueryAuction(ctx,auctionID)
if err != nil { if err != nil {
return fmt.Errorf("failed to get auction %v: %v", auctionID, err) return fmt.Errorf("failed to get auction from public state %v", err)
}
if auctionBytes == nil {
return fmt.Errorf("Auction interest object %v not found", auctionID)
}
var auctionJSON Auction
err = json.Unmarshal(auctionBytes, &auctionJSON)
if err != nil {
return fmt.Errorf("failed to create auction object JSON: %v", err)
} }
// Complete a series of three checks before we add the bid to the auction // Complete a series of three checks before we add the bid to the auction
// check 1: check that the auction is closed. We cannot reveal a // check 1: check that the auction is closed. We cannot reveal a
// bid to an open auction // bid to an open auction
Status := auctionJSON.Status Status := auction.Status
if Status != "closed" { if Status != "closed" {
return fmt.Errorf("cannot reveal bid for open or ended auction") return fmt.Errorf("cannot reveal bid for open or ended auction")
} }
@ -308,7 +293,7 @@ func (s *SmartContract) RevealBid(ctx contractapi.TransactionContextInterface, a
// added earlier. This ensures that the bid has not changed since it // added earlier. This ensures that the bid has not changed since it
// was added to the auction // was added to the auction
bidders := auctionJSON.PrivateBids bidders := auction.PrivateBids
privateBidHashString := bidders[bidKey].Hash privateBidHashString := bidders[bidKey].Hash
onChainBidHashString := fmt.Sprintf("%x", bidHash) onChainBidHashString := fmt.Sprintf("%x", bidHash)
@ -335,7 +320,7 @@ func (s *SmartContract) RevealBid(ctx contractapi.TransactionContextInterface, a
} }
// Get ID of submitting client identity // Get ID of submitting client identity
clientID, err := ctx.GetClientIdentity().GetID() clientID, err := s.GetSubmittingClientIdentity(ctx)
if err != nil { if err != nil {
return fmt.Errorf("failed to get client identity %v", err) return fmt.Errorf("failed to get client identity %v", err)
} }
@ -354,14 +339,14 @@ func (s *SmartContract) RevealBid(ctx contractapi.TransactionContextInterface, a
} }
revealedBids := make(map[string]FullBid) revealedBids := make(map[string]FullBid)
revealedBids = auctionJSON.RevealedBids revealedBids = auction.RevealedBids
revealedBids[bidKey] = NewBid revealedBids[bidKey] = NewBid
auctionJSON.RevealedBids = revealedBids auction.RevealedBids = revealedBids
newAuctionBytes, _ := json.Marshal(auctionJSON) newAuctionJSON, _ := json.Marshal(auction)
// put auction with bid added back into state // put auction with bid added back into state
err = ctx.GetStub().PutState(auctionID, newAuctionBytes) err = ctx.GetStub().PutState(auctionID, newAuctionJSON)
if err != nil { if err != nil {
return fmt.Errorf("failed to update auction: %v", err) return fmt.Errorf("failed to update auction: %v", err)
} }
@ -373,44 +358,35 @@ func (s *SmartContract) RevealBid(ctx contractapi.TransactionContextInterface, a
// bids from being added to the auction, and allows users to reveal their bid // bids from being added to the auction, and allows users to reveal their bid
func (s *SmartContract) CloseAuction(ctx contractapi.TransactionContextInterface, auctionID string) error { func (s *SmartContract) CloseAuction(ctx contractapi.TransactionContextInterface, auctionID string) error {
auctionBytes, err := ctx.GetStub().GetState(auctionID) // get auction from public state
auction, err := s.QueryAuction(ctx,auctionID)
if err != nil { if err != nil {
return fmt.Errorf("failed to get auction %v: %v", auctionID, err) return fmt.Errorf("failed to get auction from public state %v", err)
}
if auctionBytes == nil {
return fmt.Errorf("Auction interest object %v not found", auctionID)
}
var auctionJSON Auction
err = json.Unmarshal(auctionBytes, &auctionJSON)
if err != nil {
return fmt.Errorf("failed to create auction object JSON: %v", err)
} }
// the auction can only be closed by the seller // the auction can only be closed by the seller
// get ID of submitting client // get ID of submitting client
clientID, err := ctx.GetClientIdentity().GetID() clientID, err := s.GetSubmittingClientIdentity(ctx)
if err != nil { if err != nil {
return fmt.Errorf("failed to get client identity %v", err) return fmt.Errorf("failed to get client identity %v", err)
} }
Seller := auctionJSON.Seller Seller := auction.Seller
if Seller != clientID { if Seller != clientID {
return fmt.Errorf("auction can only be closed by seller: %v", err) return fmt.Errorf("auction can only be closed by seller: %v", err)
} }
Status := auctionJSON.Status Status := auction.Status
if Status != "open" { if Status != "open" {
return fmt.Errorf("cannot close auction that is not open") return fmt.Errorf("cannot close auction that is not open")
} }
auctionJSON.Status = string("closed") auction.Status = string("closed")
closedAuction, _ := json.Marshal(auctionJSON) closedAuctionJSON, _ := json.Marshal(auction)
err = ctx.GetStub().PutState(auctionID, closedAuction) err = ctx.GetStub().PutState(auctionID, closedAuctionJSON)
if err != nil { if err != nil {
return fmt.Errorf("failed to close auction: %v", err) return fmt.Errorf("failed to close auction: %v", err)
} }
@ -422,66 +398,57 @@ func (s *SmartContract) CloseAuction(ctx contractapi.TransactionContextInterface
// of the auction // of the auction
func (s *SmartContract) EndAuction(ctx contractapi.TransactionContextInterface, auctionID string) error { func (s *SmartContract) EndAuction(ctx contractapi.TransactionContextInterface, auctionID string) error {
auctionBytes, err := ctx.GetStub().GetState(auctionID) // get auction from public state
auction, err := s.QueryAuction(ctx,auctionID)
if err != nil { if err != nil {
return fmt.Errorf("failed to get auction %v: %v", auctionID, err) return fmt.Errorf("failed to get auction from public state %v", err)
}
if auctionBytes == nil {
return fmt.Errorf("Auction interest object %v not found", auctionID)
}
var auctionJSON Auction
err = json.Unmarshal(auctionBytes, &auctionJSON)
if err != nil {
return fmt.Errorf("failed to create auction object JSON: %v", err)
} }
// Check that the auction is being ended by the seller // Check that the auction is being ended by the seller
// get ID of submitting client // get ID of submitting client
clientID, err := ctx.GetClientIdentity().GetID() clientID, err := s.GetSubmittingClientIdentity(ctx)
if err != nil { if err != nil {
return fmt.Errorf("failed to get client identity %v", err) return fmt.Errorf("failed to get client identity %v", err)
} }
Seller := auctionJSON.Seller Seller := auction.Seller
if Seller != clientID { if Seller != clientID {
return fmt.Errorf("auction can only be ended by seller: %v", err) return fmt.Errorf("auction can only be ended by seller: %v", err)
} }
Status := auctionJSON.Status Status := auction.Status
if Status != "closed" { if Status != "closed" {
return fmt.Errorf("Can only end a closed auction") return fmt.Errorf("Can only end a closed auction")
} }
// get the list of revealed bids // get the list of revealed bids
revealedBidMap := auctionJSON.RevealedBids revealedBidMap := auction.RevealedBids
if len(auctionJSON.RevealedBids) == 0 { if len(auction.RevealedBids) == 0 {
return fmt.Errorf("No bids have been revealed, cannot end auction: %v", err) return fmt.Errorf("No bids have been revealed, cannot end auction: %v", err)
} }
// determine the highest bid // determine the highest bid
for _, bid := range revealedBidMap { for _, bid := range revealedBidMap {
if bid.Price > auctionJSON.Price { if bid.Price > auction.Price {
auctionJSON.Winner = bid.Bidder auction.Winner = bid.Bidder
auctionJSON.Price = bid.Price auction.Price = bid.Price
} }
} }
// check if there is a winning bid that has yet to be revealed // check if there is a winning bid that has yet to be revealed
err = queryAllBids(ctx, auctionJSON.Price, auctionJSON.RevealedBids, auctionJSON.PrivateBids) err = checkForHigherBid(ctx, auction.Price, auction.RevealedBids, auction.PrivateBids)
if err != nil { if err != nil {
return fmt.Errorf("Cannot close auction: %v", err) return fmt.Errorf("Cannot end auction: %v", err)
} }
auctionJSON.Status = string("ended") auction.Status = string("ended")
closedAuction, _ := json.Marshal(auctionJSON) endedAuctionJSON, _ := json.Marshal(auction)
err = ctx.GetStub().PutState(auctionID, closedAuction) err = ctx.GetStub().PutState(auctionID, endedAuctionJSON)
if err != nil { if err != nil {
return fmt.Errorf("failed to close auction: %v", err) return fmt.Errorf("failed to end auction: %v", err)
} }
return nil return nil
} }

View file

@ -40,7 +40,7 @@ func (s *SmartContract) QueryBid(ctx contractapi.TransactionContextInterface, au
return nil, fmt.Errorf("failed to get implicit collection name: %v", err) return nil, fmt.Errorf("failed to get implicit collection name: %v", err)
} }
clientID, err := ctx.GetClientIdentity().GetID() clientID, err := s.GetSubmittingClientIdentity(ctx)
if err != nil { if err != nil {
return nil, fmt.Errorf("failed to get client identity %v", err) return nil, fmt.Errorf("failed to get client identity %v", err)
} }
@ -77,20 +77,8 @@ func (s *SmartContract) QueryBid(ctx contractapi.TransactionContextInterface, au
return bid, nil return bid, nil
} }
// GetID is an internal helper function to allow users to get their identity // checkForHigherBid is an internal function that is used to determine if a winning bid has yet to be revealed
func (s *SmartContract) GetID(ctx contractapi.TransactionContextInterface) (string, error) { func checkForHigherBid(ctx contractapi.TransactionContextInterface, auctionPrice int, revealedBidders map[string]FullBid, bidders map[string]BidHash) error {
// Get the MSP ID of submitting client identity
clientID, err := ctx.GetClientIdentity().GetID()
if err != nil {
return "", fmt.Errorf("failed to get verified MSPID: %v", err)
}
return clientID, nil
}
// queryAllBids is an internal function that is used to determine if a winning bid has yet to be revealed
func queryAllBids(ctx contractapi.TransactionContextInterface, auctionPrice int, revealedBidders map[string]FullBid, bidders map[string]BidHash) error {
// Get MSP ID of peer org // Get MSP ID of peer org
peerMSPID, err := shim.GetMSPID() peerMSPID, err := shim.GetMSPID()

View file

@ -6,12 +6,26 @@ package auction
import ( import (
"fmt" "fmt"
"encoding/base64"
"github.com/hyperledger/fabric-chaincode-go/pkg/statebased" "github.com/hyperledger/fabric-chaincode-go/pkg/statebased"
"github.com/hyperledger/fabric-chaincode-go/shim" "github.com/hyperledger/fabric-chaincode-go/shim"
"github.com/hyperledger/fabric-contract-api-go/contractapi" "github.com/hyperledger/fabric-contract-api-go/contractapi"
) )
func (s *SmartContract) GetSubmittingClientIdentity(ctx contractapi.TransactionContextInterface) (string, error) {
b64ID, err := ctx.GetClientIdentity().GetID()
if err != nil {
return "", fmt.Errorf("Failed to read clientID: %v", err)
}
decodeID, err := base64.StdEncoding.DecodeString(b64ID)
if err != nil {
return "", fmt.Errorf("failed to base64 decode clientID: %v", err)
}
return string(decodeID), nil
}
// setAssetStateBasedEndorsement sets the endorsement policy of a new auction // setAssetStateBasedEndorsement sets the endorsement policy of a new auction
func setAssetStateBasedEndorsement(ctx contractapi.TransactionContextInterface, auctionID string, orgToEndorse string) error { func setAssetStateBasedEndorsement(ctx contractapi.TransactionContextInterface, auctionID string, orgToEndorse string) error {