/* SPDX-License-Identifier: Apache-2.0 */ package auction import ( "encoding/json" "fmt" "github.com/hyperledger/fabric-chaincode-go/shim" "github.com/hyperledger/fabric-contract-api-go/contractapi" ) // QueryAuction allows all members of the channel to read a public auction func (s *SmartContract) QueryAuction(ctx contractapi.TransactionContextInterface, auctionID string) (*Auction, error) { auctionJSON, err := ctx.GetStub().GetState(auctionID) if err != nil { return nil, fmt.Errorf("failed to get auction object %v: %v", auctionID, err) } if auctionJSON == nil { return nil, fmt.Errorf("auction does not exist") } var auction *Auction err = json.Unmarshal(auctionJSON, &auction) if err != nil { return nil, err } return auction, nil } // QueryBid allows the submitter of the bid to read their bid from public state func (s *SmartContract) QueryBid(ctx contractapi.TransactionContextInterface, auctionID string, txID string) (*FullBid, error) { err := verifyClientOrgMatchesPeerOrg(ctx) if err != nil { return nil, fmt.Errorf("failed to get implicit collection name: %v", err) } clientID, err := s.GetSubmittingClientIdentity(ctx) if err != nil { return nil, fmt.Errorf("failed to get client identity %v", err) } collection, err := getCollectionName(ctx) if err != nil { return nil, fmt.Errorf("failed to get implicit collection name: %v", err) } bidKey, err := ctx.GetStub().CreateCompositeKey(bidKeyType, []string{auctionID, txID}) if err != nil { return nil, fmt.Errorf("failed to create composite key: %v", err) } bidJSON, err := ctx.GetStub().GetPrivateData(collection, bidKey) if err != nil { return nil, fmt.Errorf("failed to get bid %v: %v", bidKey, err) } if bidJSON == nil { return nil, fmt.Errorf("bid %v does not exist", bidKey) } var bid *FullBid err = json.Unmarshal(bidJSON, &bid) if err != nil { return nil, err } // check that the client querying the bid is the bid owner if bid.Bidder != clientID { return nil, fmt.Errorf("Permission denied, client id %v is not the owner of the bid", clientID) } return bid, nil } // 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() if err != nil { return fmt.Errorf("failed getting the peer's MSPID: %v", err) } var error error error = nil for bidKey, privateBid := range bidders { if _, bidInAuction := revealedBidders[bidKey]; bidInAuction { //bid is already revealed, no action to take } else { collection := "_implicit_org_" + privateBid.Org if privateBid.Org == peerMSPID { bidJSON, err := ctx.GetStub().GetPrivateData(collection, bidKey) if err != nil { return fmt.Errorf("failed to get bid %v: %v", bidKey, err) } if bidJSON == nil { return fmt.Errorf("bid %v does not exist", bidKey) } var bid *FullBid err = json.Unmarshal(bidJSON, &bid) if err != nil { return err } if bid.Price > auctionPrice { error = fmt.Errorf("Cannot close auction, bidder has a higher price: %v", err) } } else { Hash, err := ctx.GetStub().GetPrivateDataHash(collection, bidKey) if err != nil { return fmt.Errorf("failed to read bid hash from collection: %v", err) } if Hash == nil { return fmt.Errorf("bid hash does not exist: %s", bidKey) } } } } return error }