From be7a67d7d9ea00c5cedc847537241edb39cfb4f7 Mon Sep 17 00:00:00 2001 From: KOSASIH Date: Wed, 14 Aug 2024 09:25:24 +0700 Subject: [PATCH] Update supply_chain_finance.go --- .../supply_chain_finance.go | 120 ++++++++++++------ 1 file changed, 83 insertions(+), 37 deletions(-) diff --git a/features/blockchain-based-upply-chain-finance/supply_chain_finance.go b/features/blockchain-based-upply-chain-finance/supply_chain_finance.go index cc2c3d4fb..71192a6b2 100644 --- a/features/blockchain-based-upply-chain-finance/supply_chain_finance.go +++ b/features/blockchain-based-upply-chain-finance/supply_chain_finance.go @@ -1,52 +1,98 @@ package main import ( + "encoding/json" "fmt" + "log" + "math/big" + "strings" + "time" + "github.com/hyperledger/fabric-chaincode-go/shim" "github.com/hyperledger/fabric-chaincode-go/stub" + "github.com/hyperledger/fabric-contract-api-go/contractapi" ) +// SupplyChainFinance is the main struct for the supply chain finance smart contract type SupplyChainFinance struct { + contractapi.Contract +} + +// Trade represents a trade in the supply chain +type Trade struct { + ID string `json:"id"` + Buyer string `json:"buyer"` + Seller string `json:"seller"` + Product string `json:"product"` + Quantity int `json:"quantity"` + Price *big.Rat `json:"price"` + Status string `json:"status"` + Timestamp int64 `json:"timestamp"` + Hash string `json:"hash"` + Signatures []string `json:"signatures"` } +// Ledger represents the ledger of trades +type Ledger struct { + Trades []Trade `json:"trades"` +} + +// Init initializes the supply chain finance smart contract func (s *SupplyChainFinance) Init(stub shim.ChaincodeStubInterface) []byte { - fmt.Println("Initializing Supply Chain Finance Chaincode") + log.Println("Initializing supply chain finance smart contract") return nil } +// Invoke handles incoming requests to the supply chain finance smart contract func (s *SupplyChainFinance) Invoke(stub shim.ChaincodeStubInterface) ([]byte, error) { - fmt.Println("Received invoke request") - - // Get the function and args from the stub - funcName, args := stub.GetFunctionAndParameters() - - // Handle different functions - switch funcName { + log.Println("Received invoke request") + function, args := stub.GetFunctionAndParameters() + switch function { case "createTrade": return s.createTrade(stub, args) case "updateTrade": return s.updateTrade(stub, args) case "getTrade": return s.getTrade(stub, args) + case "getAllTrades": + return s.getAllTrades(stub, args) + case "getTradeHistory": + return s.getTradeHistory(stub, args) + case "verifyTrade": + return s.verifyTrade(stub, args) default: - return nil, errors.New("Invalid function name") + return nil, fmt.Errorf("Invalid function name: %s", function) } } +// createTrade creates a new trade in the supply chain func (s *SupplyChainFinance) createTrade(stub shim.ChaincodeStubInterface, args []string) ([]byte, error) { - // Create a new trade object + log.Println("Creating new trade") + if len(args) != 6 { + return nil, fmt.Errorf("Invalid number of arguments. Expecting 6, got %d", len(args)) + } + trade := Trade{ ID: args[0], Buyer: args[1], Seller: args[2], Product: args[3], - Quantity: args[4], - Price: args[5], + Quantity: parseInt(args[4]), + Price: new(big.Rat).SetString(args[5]), Status: "pending", + Timestamp: time.Now().Unix(), + Hash: calculateHash(trade), + Signatures: []string{}, } - // Put the trade object into the ledger - err := stub.PutState(trade.ID, trade) + ledger, err := s.getLedger(stub) + if err != nil { + return nil, err + } + + ledger.Trades = append(ledger.Trades, trade) + + err = stub.PutState("ledger", ledger) if err != nil { return nil, err } @@ -54,41 +100,41 @@ func (s *SupplyChainFinance) createTrade(stub shim.ChaincodeStubInterface, args return []byte("Trade created successfully"), nil } +// updateTrade updates an existing trade in the supply chain func (s *SupplyChainFinance) updateTrade(stub shim.ChaincodeStubInterface, args []string) ([]byte, error) { - // Get the trade object from the ledger - trade, err := s.getTrade(stub, args[0]) - if err != nil { - return nil, err + log.Println("Updating trade") + if len(args) != 2 { + return nil, fmt.Errorf("Invalid number of arguments. Expecting 2, got %d", len(args)) } - // Update the trade object - trade.Status = args[1] + tradeID := args[0] + status := args[1] - // Put the updated trade object into the ledger - err = stub.PutState(trade.ID, trade) + ledger, err := s.getLedger(stub) if err != nil { return nil, err } - return []byte("Trade updated successfully"), nil -} + for i, trade := range ledger.Trades { + if trade.ID == tradeID { + trade.Status = status + trade.Timestamp = time.Now().Unix() + trade.Hash = calculateHash(trade) + ledger.Trades[i] = trade + break + } + } -func (s *SupplyChainFinance) getTrade(stub shim.ChaincodeStubInterface, tradeID string) ([]byte, error) { - // Get the trade object from the ledger - trade, err := stub.GetState(tradeID) + err = stub.PutState("ledger", ledger) if err != nil { return nil, err } - return trade, nil + return []byte("Trade updated successfully"), nil } -type Trade struct { - ID string `json:"id"` - Buyer string `json:"buyer"` - Seller string `json:"seller"` - Product string `json:"product"` - Quantity string `json:"quantity"` - Price string `json:"price"` - Status string `json:"status"` -} +// getTrade retrieves a trade from the supply chain +func (s *SupplyChainFinance) getTrade(stub shim.ChaincodeStubInterface, args []string) ([]byte, error) { + log.Println("Retrieving trade") + if len(args) != 1 { + return nil, fmt.Errorf("Invalid number of arguments. Expecting 1, got %d", len(args