mirror of
https://github.com/hyperledger/fabric-samples.git
synced 2026-06-17 15:35:09 +00:00
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:
parent
822c4c4c25
commit
7b1168cd9d
13 changed files with 146 additions and 276 deletions
|
|
@ -82,7 +82,7 @@ After the transaction is complete, the `createAuction.js` application will query
|
|||
*** Result: Auction: {
|
||||
"objectType": "auction",
|
||||
"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": [
|
||||
"Org1MSP"
|
||||
],
|
||||
|
|
@ -93,16 +93,7 @@ After the transaction is complete, the `createAuction.js` application will query
|
|||
"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:
|
||||
|
||||
```
|
||||
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
|
||||
```
|
||||
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.
|
||||
|
||||
## Bid on the auction
|
||||
|
||||
|
|
@ -121,7 +112,7 @@ The application will query the bid after it is created:
|
|||
"objectType": "bid",
|
||||
"price": 800,
|
||||
"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:
|
||||
```
|
||||
*** 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:
|
||||
```
|
||||
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.
|
||||
|
||||
|
|
@ -148,14 +139,14 @@ The hash of bid will be added to the list private bids in that have been submitt
|
|||
*** Result: Auction: {
|
||||
"objectType": "auction",
|
||||
"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": [
|
||||
"Org1MSP"
|
||||
],
|
||||
"privateBids": {
|
||||
"\u0000bid\u0000PaintingAuction\u00008ef83011a5fb791f75ed008337839426f6b87981519e5d58ef5ada39c3044edd\u0000": {
|
||||
"\u0000bid\u0000PaintingAuction\u00005c049b0b4552d34c88e0f8fb5abca31fa04472b7e1336a16650ac8cfb0b16472\u0000": {
|
||||
"org": "Org1MSP",
|
||||
"hash": "5cb50a17b5a21c02fc01306e3e9b54f4db67e9a440552ce898bbd7daa62dce0f"
|
||||
"hash": "0b8bbdb96b1d252e71ac1ed71df3580f7a0e31a743a4a09bbf5196dffef426b2"
|
||||
}
|
||||
},
|
||||
"revealedBids": {},
|
||||
|
|
@ -174,7 +165,7 @@ node bid.js org1 bidder2 PaintingAuction 500
|
|||
|
||||
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:
|
||||
|
|
@ -191,7 +182,7 @@ node bid.js org2 bidder3 PaintingAuction 700
|
|||
|
||||
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:
|
||||
|
|
@ -204,23 +195,23 @@ Because bidder3 belongs to Org2, submitting the bid will add Org2 to the list of
|
|||
*** Result: Auction: {
|
||||
"objectType": "auction",
|
||||
"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": [
|
||||
"Org1MSP",
|
||||
"Org2MSP"
|
||||
],
|
||||
"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",
|
||||
"hash": "40107eab7a99dfc2f25d02b8ab840f12fd802a9f86d8d42b78d7b4409b2c15bd"
|
||||
},
|
||||
"\u0000bid\u0000PaintingAuction\u00008ef83011a5fb791f75ed008337839426f6b87981519e5d58ef5ada39c3044edd\u0000": {
|
||||
"org": "Org1MSP",
|
||||
"hash": "5cb50a17b5a21c02fc01306e3e9b54f4db67e9a440552ce898bbd7daa62dce0f"
|
||||
},
|
||||
"\u0000bid\u0000PaintingAuction\u0000915a908c8f2c368f4a3aedd73176656af81ddfab000b11629503403f3d97b185\u0000": {
|
||||
"org": "Org1MSP",
|
||||
"hash": "a458df18b12dffe4ae6d56a270134c2d55bd53fface034bd24381d0073d46a45"
|
||||
"hash": "14d47d17acceceb483e87c14a4349844874fce549d71c6a23457d953ed8ffbd3"
|
||||
}
|
||||
},
|
||||
"revealedBids": {},
|
||||
|
|
@ -241,7 +232,7 @@ node bid.js org2 bidder4 PaintingAuction 900
|
|||
|
||||
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:
|
||||
|
|
@ -276,35 +267,35 @@ The full bid details, including the price, are now visible:
|
|||
*** Result: Auction: {
|
||||
"objectType": "auction",
|
||||
"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": [
|
||||
"Org1MSP",
|
||||
"Org2MSP"
|
||||
],
|
||||
"privateBids": {
|
||||
"\u0000bid\u0000PaintingAuction\u000049466271ae879bd009e75a60730a12bfa986e75f263202ab81ccd3deec544a35\u0000": {
|
||||
"\u0000bid\u0000PaintingAuction\u000019a7a0dd2c5456a3f79c2f9ccb09dddd0f1c9ece514dfea7cbea06e7cbc79855\u0000": {
|
||||
"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",
|
||||
"hash": "40107eab7a99dfc2f25d02b8ab840f12fd802a9f86d8d42b78d7b4409b2c15bd"
|
||||
},
|
||||
"\u0000bid\u0000PaintingAuction\u00008ef83011a5fb791f75ed008337839426f6b87981519e5d58ef5ada39c3044edd\u0000": {
|
||||
"org": "Org1MSP",
|
||||
"hash": "5cb50a17b5a21c02fc01306e3e9b54f4db67e9a440552ce898bbd7daa62dce0f"
|
||||
},
|
||||
"\u0000bid\u0000PaintingAuction\u0000915a908c8f2c368f4a3aedd73176656af81ddfab000b11629503403f3d97b185\u0000": {
|
||||
"org": "Org1MSP",
|
||||
"hash": "a458df18b12dffe4ae6d56a270134c2d55bd53fface034bd24381d0073d46a45"
|
||||
"hash": "14d47d17acceceb483e87c14a4349844874fce549d71c6a23457d953ed8ffbd3"
|
||||
}
|
||||
},
|
||||
"revealedBids": {
|
||||
"\u0000bid\u0000PaintingAuction\u00008ef83011a5fb791f75ed008337839426f6b87981519e5d58ef5ada39c3044edd\u0000": {
|
||||
"\u0000bid\u0000PaintingAuction\u00005c049b0b4552d34c88e0f8fb5abca31fa04472b7e1336a16650ac8cfb0b16472\u0000": {
|
||||
"objectType": "bid",
|
||||
"price": 800,
|
||||
"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": "",
|
||||
|
|
@ -328,8 +319,11 @@ The output should look something like the following:
|
|||
|
||||
```
|
||||
--> 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
|
||||
******** 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.501Z - error: [DiscoveryHandler]: compareProposalResponseResults[undefined] - read/writes result sets do not match index=1
|
||||
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.
|
||||
|
|
@ -353,50 +347,50 @@ The transaction was successfully endorsed by both Org1 and Org2, who both calcul
|
|||
*** Result: Auction: {
|
||||
"objectType": "auction",
|
||||
"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": [
|
||||
"Org1MSP",
|
||||
"Org2MSP"
|
||||
],
|
||||
"privateBids": {
|
||||
"\u0000bid\u0000PaintingAuction\u000049466271ae879bd009e75a60730a12bfa986e75f263202ab81ccd3deec544a35\u0000": {
|
||||
"\u0000bid\u0000PaintingAuction\u000019a7a0dd2c5456a3f79c2f9ccb09dddd0f1c9ece514dfea7cbea06e7cbc79855\u0000": {
|
||||
"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",
|
||||
"hash": "40107eab7a99dfc2f25d02b8ab840f12fd802a9f86d8d42b78d7b4409b2c15bd"
|
||||
},
|
||||
"\u0000bid\u0000PaintingAuction\u00008ef83011a5fb791f75ed008337839426f6b87981519e5d58ef5ada39c3044edd\u0000": {
|
||||
"org": "Org1MSP",
|
||||
"hash": "5cb50a17b5a21c02fc01306e3e9b54f4db67e9a440552ce898bbd7daa62dce0f"
|
||||
},
|
||||
"\u0000bid\u0000PaintingAuction\u0000915a908c8f2c368f4a3aedd73176656af81ddfab000b11629503403f3d97b185\u0000": {
|
||||
"org": "Org1MSP",
|
||||
"hash": "a458df18b12dffe4ae6d56a270134c2d55bd53fface034bd24381d0073d46a45"
|
||||
"hash": "14d47d17acceceb483e87c14a4349844874fce549d71c6a23457d953ed8ffbd3"
|
||||
}
|
||||
},
|
||||
"revealedBids": {
|
||||
"\u0000bid\u0000PaintingAuction\u000049466271ae879bd009e75a60730a12bfa986e75f263202ab81ccd3deec544a35\u0000": {
|
||||
"\u0000bid\u0000PaintingAuction\u000019a7a0dd2c5456a3f79c2f9ccb09dddd0f1c9ece514dfea7cbea06e7cbc79855\u0000": {
|
||||
"objectType": "bid",
|
||||
"price": 900,
|
||||
"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": {
|
||||
"objectType": "bid",
|
||||
"price": 700,
|
||||
"org": "Org2MSP",
|
||||
"bidder": "eDUwOTo6Q049YmlkZGVyMyxPVT1jbGllbnQrT1U9b3JnMitPVT1kZXBhcnRtZW50MTo6Q049Y2Eub3JnMi5leGFtcGxlLmNvbSxPPW9yZzIuZXhhbXBsZS5jb20sTD1IdXJzbGV5LFNUPUhhbXBzaGlyZSxDPVVL"
|
||||
},
|
||||
"\u0000bid\u0000PaintingAuction\u00008ef83011a5fb791f75ed008337839426f6b87981519e5d58ef5ada39c3044edd\u0000": {
|
||||
"\u0000bid\u0000PaintingAuction\u00005c049b0b4552d34c88e0f8fb5abca31fa04472b7e1336a16650ac8cfb0b16472\u0000": {
|
||||
"objectType": "bid",
|
||||
"price": 800,
|
||||
"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,
|
||||
"status": "ended"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,21 +8,11 @@
|
|||
|
||||
const { Gateway, Wallets } = require('fabric-network');
|
||||
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 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) {
|
||||
try {
|
||||
|
||||
|
|
@ -36,7 +26,7 @@ async function bid(ccp,wallet,user,orgMSP,auctionID,price) {
|
|||
const contract = network.getContract(myChaincodeName);
|
||||
|
||||
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());
|
||||
|
||||
let bidData = { objectType: 'bid', price: parseInt(price), org: orgMSP, bidder: bidder.toString()};
|
||||
|
|
@ -78,7 +68,7 @@ async function main() {
|
|||
process.exit(1);
|
||||
}
|
||||
|
||||
const org = process.argv[2]
|
||||
const org = process.argv[2];
|
||||
const user = process.argv[3];
|
||||
const auctionID = process.argv[4];
|
||||
const price = process.argv[5];
|
||||
|
|
@ -108,5 +98,4 @@ async function main() {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
main();
|
||||
|
|
|
|||
|
|
@ -8,21 +8,11 @@
|
|||
|
||||
const { Gateway, Wallets } = require('fabric-network');
|
||||
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 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) {
|
||||
try {
|
||||
|
||||
|
|
@ -36,9 +26,7 @@ async function closeAuction(ccp,wallet,user,auctionID) {
|
|||
const contract = network.getContract(myChaincodeName);
|
||||
|
||||
// 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);
|
||||
//console.log('*** Result: Bid: ' + prettyJSONString(auctionString.toString()));
|
||||
var auctionJSON = JSON.parse(auctionString);
|
||||
|
||||
let statefulTxn = contract.createTransaction('CloseAuction');
|
||||
|
|
@ -73,7 +61,7 @@ async function main() {
|
|||
process.exit(1);
|
||||
}
|
||||
|
||||
const org = process.argv[2]
|
||||
const org = process.argv[2];
|
||||
const user = process.argv[3];
|
||||
const auctionID = process.argv[4];
|
||||
|
||||
|
|
|
|||
|
|
@ -8,21 +8,11 @@
|
|||
|
||||
const { Gateway, Wallets } = require('fabric-network');
|
||||
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 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) {
|
||||
try {
|
||||
|
||||
|
|
@ -60,7 +50,7 @@ async function main() {
|
|||
process.exit(1);
|
||||
}
|
||||
|
||||
const org = process.argv[2]
|
||||
const org = process.argv[2];
|
||||
const user = process.argv[3];
|
||||
const auctionID = process.argv[4];
|
||||
const item = process.argv[5];
|
||||
|
|
|
|||
|
|
@ -8,21 +8,11 @@
|
|||
|
||||
const { Gateway, Wallets } = require('fabric-network');
|
||||
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 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) {
|
||||
try {
|
||||
|
||||
|
|
@ -36,9 +26,7 @@ async function endAuction(ccp,wallet,user,auctionID) {
|
|||
const contract = network.getContract(myChaincodeName);
|
||||
|
||||
// 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);
|
||||
//console.log('*** Result: Bid: ' + prettyJSONString(auctionString.toString()));
|
||||
var auctionJSON = JSON.parse(auctionString);
|
||||
|
||||
let statefulTxn = contract.createTransaction('EndAuction');
|
||||
|
|
@ -73,7 +61,7 @@ async function main() {
|
|||
process.exit(1);
|
||||
}
|
||||
|
||||
const org = process.argv[2]
|
||||
const org = process.argv[2];
|
||||
const user = process.argv[3];
|
||||
const auctionID = process.argv[4];
|
||||
|
||||
|
|
|
|||
|
|
@ -15,15 +15,6 @@ const { buildCCPOrg1, buildCCPOrg2, buildWallet } = require('../../test-applicat
|
|||
const mspOrg1 = 'Org1MSP';
|
||||
const mspOrg2 = 'Org2MSP';
|
||||
|
||||
function prettyJSONString(inputString) {
|
||||
if (inputString) {
|
||||
return JSON.stringify(JSON.parse(inputString), null, 2);
|
||||
}
|
||||
else {
|
||||
return inputString;
|
||||
}
|
||||
}
|
||||
|
||||
async function connectToOrg1CA() {
|
||||
console.log('\n--> Enrolling the Org1 CA admin');
|
||||
const ccpOrg1 = buildCCPOrg1();
|
||||
|
|
|
|||
|
|
@ -8,21 +8,11 @@
|
|||
|
||||
const { Gateway, Wallets } = require('fabric-network');
|
||||
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 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) {
|
||||
try {
|
||||
|
||||
|
|
@ -54,7 +44,7 @@ async function main() {
|
|||
process.exit(1);
|
||||
}
|
||||
|
||||
const org = process.argv[2]
|
||||
const org = process.argv[2];
|
||||
const user = process.argv[3];
|
||||
const auctionID = process.argv[4];
|
||||
|
||||
|
|
|
|||
|
|
@ -8,21 +8,11 @@
|
|||
|
||||
const { Gateway, Wallets } = require('fabric-network');
|
||||
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 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) {
|
||||
try {
|
||||
|
||||
|
|
@ -54,7 +44,7 @@ async function main() {
|
|||
process.exit(1);
|
||||
}
|
||||
|
||||
const org = process.argv[2]
|
||||
const org = process.argv[2];
|
||||
const user = process.argv[3];
|
||||
const auctionID = process.argv[4];
|
||||
const bidID = process.argv[5];
|
||||
|
|
|
|||
|
|
@ -15,15 +15,6 @@ const { buildCCPOrg1, buildCCPOrg2, buildWallet } = require('../../test-applicat
|
|||
const mspOrg1 = 'Org1MSP';
|
||||
const mspOrg2 = 'Org2MSP';
|
||||
|
||||
function prettyJSONString(inputString) {
|
||||
if (inputString) {
|
||||
return JSON.stringify(JSON.parse(inputString), null, 2);
|
||||
}
|
||||
else {
|
||||
return inputString;
|
||||
}
|
||||
}
|
||||
|
||||
async function connectToOrg1CA(UserID) {
|
||||
console.log('\n--> Register and enrolling new user');
|
||||
const ccpOrg1 = buildCCPOrg1();
|
||||
|
|
|
|||
|
|
@ -8,21 +8,11 @@
|
|||
|
||||
const { Gateway, Wallets } = require('fabric-network');
|
||||
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 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) {
|
||||
try {
|
||||
|
||||
|
|
@ -81,7 +71,7 @@ async function main() {
|
|||
process.exit(1);
|
||||
}
|
||||
|
||||
const org = process.argv[2]
|
||||
const org = process.argv[2];
|
||||
const user = process.argv[3];
|
||||
const auctionID = process.argv[4];
|
||||
const bidID = process.argv[5];
|
||||
|
|
|
|||
|
|
@ -51,7 +51,7 @@ const bidKeyType = "bid"
|
|||
func (s *SmartContract) CreateAuction(ctx contractapi.TransactionContextInterface, auctionID string, itemsold string) error {
|
||||
|
||||
// get ID of submitting client
|
||||
clientID, err := ctx.GetClientIdentity().GetID()
|
||||
clientID, err := s.GetSubmittingClientIdentity(ctx)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to get client identity %v", err)
|
||||
}
|
||||
|
|
@ -78,13 +78,13 @@ func (s *SmartContract) CreateAuction(ctx contractapi.TransactionContextInterfac
|
|||
Status: "open",
|
||||
}
|
||||
|
||||
auctionBytes, err := json.Marshal(auction)
|
||||
auctionJSON, err := json.Marshal(auction)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// put auction into state
|
||||
err = ctx.GetStub().PutState(auctionID, auctionBytes)
|
||||
err = ctx.GetStub().PutState(auctionID, auctionJSON)
|
||||
if err != nil {
|
||||
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)
|
||||
}
|
||||
|
||||
// get the auction from state
|
||||
auctionBytes, err := ctx.GetStub().GetState(auctionID)
|
||||
var auctionJSON Auction
|
||||
|
||||
if auctionBytes == nil {
|
||||
return fmt.Errorf("Auction not found: %v", auctionID)
|
||||
}
|
||||
err = json.Unmarshal(auctionBytes, &auctionJSON)
|
||||
// get the auction from public state
|
||||
auction, err := s.QueryAuction(ctx,auctionID)
|
||||
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
|
||||
Status := auctionJSON.Status
|
||||
Status := auction.Status
|
||||
if Status != "open" {
|
||||
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 = auctionJSON.PrivateBids
|
||||
bidders = auction.PrivateBids
|
||||
bidders[bidKey] = NewHash
|
||||
auctionJSON.PrivateBids = bidders
|
||||
auction.PrivateBids = bidders
|
||||
|
||||
// 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)) {
|
||||
newOrgs := append(Orgs, clientOrgID)
|
||||
auctionJSON.Orgs = newOrgs
|
||||
auction.Orgs = newOrgs
|
||||
|
||||
err = addAssetStateBasedEndorsement(ctx, auctionID, clientOrgID)
|
||||
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 {
|
||||
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
|
||||
auctionBytes, err := ctx.GetStub().GetState(auctionID)
|
||||
auction, err := s.QueryAuction(ctx,auctionID)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to get auction %v: %v", auctionID, 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)
|
||||
return fmt.Errorf("failed to get auction from public state %v", err)
|
||||
}
|
||||
|
||||
// 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
|
||||
// bid to an open auction
|
||||
Status := auctionJSON.Status
|
||||
Status := auction.Status
|
||||
if Status != "closed" {
|
||||
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
|
||||
// was added to the auction
|
||||
|
||||
bidders := auctionJSON.PrivateBids
|
||||
bidders := auction.PrivateBids
|
||||
privateBidHashString := bidders[bidKey].Hash
|
||||
|
||||
onChainBidHashString := fmt.Sprintf("%x", bidHash)
|
||||
|
|
@ -335,7 +320,7 @@ func (s *SmartContract) RevealBid(ctx contractapi.TransactionContextInterface, a
|
|||
}
|
||||
|
||||
// Get ID of submitting client identity
|
||||
clientID, err := ctx.GetClientIdentity().GetID()
|
||||
clientID, err := s.GetSubmittingClientIdentity(ctx)
|
||||
if err != nil {
|
||||
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 = auctionJSON.RevealedBids
|
||||
revealedBids = auction.RevealedBids
|
||||
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
|
||||
err = ctx.GetStub().PutState(auctionID, newAuctionBytes)
|
||||
err = ctx.GetStub().PutState(auctionID, newAuctionJSON)
|
||||
if err != nil {
|
||||
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
|
||||
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 {
|
||||
return fmt.Errorf("failed to get auction %v: %v", auctionID, 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)
|
||||
return fmt.Errorf("failed to get auction from public state %v", err)
|
||||
}
|
||||
|
||||
// the auction can only be closed by the seller
|
||||
|
||||
// get ID of submitting client
|
||||
clientID, err := ctx.GetClientIdentity().GetID()
|
||||
clientID, err := s.GetSubmittingClientIdentity(ctx)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to get client identity %v", err)
|
||||
}
|
||||
|
||||
Seller := auctionJSON.Seller
|
||||
Seller := auction.Seller
|
||||
if Seller != clientID {
|
||||
return fmt.Errorf("auction can only be closed by seller: %v", err)
|
||||
}
|
||||
|
||||
Status := auctionJSON.Status
|
||||
Status := auction.Status
|
||||
if Status != "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 {
|
||||
return fmt.Errorf("failed to close auction: %v", err)
|
||||
}
|
||||
|
|
@ -422,66 +398,57 @@ func (s *SmartContract) CloseAuction(ctx contractapi.TransactionContextInterface
|
|||
// of the auction
|
||||
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 {
|
||||
return fmt.Errorf("failed to get auction %v: %v", auctionID, 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)
|
||||
return fmt.Errorf("failed to get auction from public state %v", err)
|
||||
}
|
||||
|
||||
// Check that the auction is being ended by the seller
|
||||
|
||||
// get ID of submitting client
|
||||
clientID, err := ctx.GetClientIdentity().GetID()
|
||||
clientID, err := s.GetSubmittingClientIdentity(ctx)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to get client identity %v", err)
|
||||
}
|
||||
|
||||
Seller := auctionJSON.Seller
|
||||
Seller := auction.Seller
|
||||
if Seller != clientID {
|
||||
return fmt.Errorf("auction can only be ended by seller: %v", err)
|
||||
}
|
||||
|
||||
Status := auctionJSON.Status
|
||||
Status := auction.Status
|
||||
if Status != "closed" {
|
||||
return fmt.Errorf("Can only end a closed auction")
|
||||
}
|
||||
|
||||
// get the list of revealed bids
|
||||
revealedBidMap := auctionJSON.RevealedBids
|
||||
if len(auctionJSON.RevealedBids) == 0 {
|
||||
revealedBidMap := auction.RevealedBids
|
||||
if len(auction.RevealedBids) == 0 {
|
||||
return fmt.Errorf("No bids have been revealed, cannot end auction: %v", err)
|
||||
}
|
||||
|
||||
// determine the highest bid
|
||||
for _, bid := range revealedBidMap {
|
||||
if bid.Price > auctionJSON.Price {
|
||||
auctionJSON.Winner = bid.Bidder
|
||||
auctionJSON.Price = bid.Price
|
||||
if bid.Price > auction.Price {
|
||||
auction.Winner = bid.Bidder
|
||||
auction.Price = bid.Price
|
||||
}
|
||||
}
|
||||
|
||||
// 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 {
|
||||
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 {
|
||||
return fmt.Errorf("failed to close auction: %v", err)
|
||||
return fmt.Errorf("failed to end auction: %v", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -40,7 +40,7 @@ func (s *SmartContract) QueryBid(ctx contractapi.TransactionContextInterface, au
|
|||
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 {
|
||||
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
|
||||
}
|
||||
|
||||
// GetID is an internal helper function to allow users to get their identity
|
||||
func (s *SmartContract) GetID(ctx contractapi.TransactionContextInterface) (string, 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 {
|
||||
// checkForHigherBid is an internal function that is used to determine if a winning bid has yet to be revealed
|
||||
func checkForHigherBid(ctx contractapi.TransactionContextInterface, auctionPrice int, revealedBidders map[string]FullBid, bidders map[string]BidHash) error {
|
||||
|
||||
// Get MSP ID of peer org
|
||||
peerMSPID, err := shim.GetMSPID()
|
||||
|
|
|
|||
|
|
@ -6,12 +6,26 @@ package auction
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
"encoding/base64"
|
||||
|
||||
"github.com/hyperledger/fabric-chaincode-go/pkg/statebased"
|
||||
"github.com/hyperledger/fabric-chaincode-go/shim"
|
||||
"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
|
||||
func setAssetStateBasedEndorsement(ctx contractapi.TransactionContextInterface, auctionID string, orgToEndorse string) error {
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue