/* Copyright 33.cn Corp. 2017 All Rights Reserved. Chaincode for Meidi Corp. Chang history: 2017/4/12 Building successfully. 2017/4/11 init version. */ package main import ( "encoding/json" "errors" "fmt" "strconv" "time" "github.com/hyperledger/fabric/core/chaincode/shim" pb "github.com/hyperledger/fabric/protos/peer" ) var transactionNo int = 0 // SimpleChaincode example simple Chaincode implementation type SimpleChaincode struct { } type Bill struct { BillId string Maker string Acceptor string Receiver string //Receiver name IssueDate int64 ExpireDate int64 RecBank string //Name of receiver's Bank Amount int //Amount of money Type int //0:taels 1:Business Form int //0:paper 1:electronic Status int //0: 1: 2: 3: 4: 5: } // Record all operation include the create/change or the bill type Transaction struct { BillId string Operation string BillStatus int Time int64 ID int } func (t *SimpleChaincode) Init(stub shim.ChaincodeStubInterface) pb.Response { fmt.Println("Chaicode_Meidi Init") // Write the state to the ledger err := stub.PutState("MeiDiFabric", []byte("This is the block chain for MeiDiBill system...")) if err != nil { return shim.Error(err.Error()) } return shim.Success(nil) } func (t *SimpleChaincode) Invoke(stub shim.ChaincodeStubInterface) pb.Response { fmt.Println("ChainCode_Meidi Invoke") function, args := stub.GetFunctionAndParameters() if function == "createBill" { // Create the Bill return t.createBill(stub, args) } else if function == "changeBillStatus" { // Change the status of Bill return t.changeBillStatus(stub, args) } else if function == "queryBill" { //Query the Bill info from fabric return t.queryBill(stub, args) } else if function == "queryTransaction" { //Query the Bill info from fabric return t.queryTransaction(stub, args) } return shim.Error("Invalid invoke function name. Expecting \"createBill\" \"changeBillStaus\" \"queryBill\" \"queryTransaction\"") } // Deletes an entity from state func (t *SimpleChaincode) delete(stub shim.ChaincodeStubInterface, args []string) pb.Response { if len(args) != 1 { return shim.Error("Incorrect number of arguments. Expecting 1") } A := args[0] // Delete the key from the state in ledger err := stub.DelState(A) if err != nil { return shim.Error("Failed to delete state") } return shim.Success(nil) } func (t *SimpleChaincode) createBill(stub shim.ChaincodeStubInterface, args []string) pb.Response { if len(args) != 11 { return shim.Error("createBill(): Incorrect number of arguments. Expecting 11") } var bill Bill var t_issue time.Time var t_expire time.Time var err error var amount int var billtype int var form int var status int var billBytes []byte layout := "2006-01-02 15:04:05" t_issue, err = time.Parse(layout, args[4]) if err != nil { jsonResp := "{\"Error\":\"Failed to pharse the time, plese follow the fomat as" + layout + "\"}" return shim.Error(jsonResp) } t_expire, err = time.Parse(layout, args[5]) if err != nil { jsonResp := "{\"Error\":\"Failed to pharse the time, plese follow the fomat " + layout + "\"}" return shim.Error(jsonResp) } amount, err = strconv.Atoi(args[7]) if err != nil { return shim.Error("Expecting integer value for asset holding") } billtype, err = strconv.Atoi(args[8]) if err != nil { return shim.Error("Expecting integer value for asset holding") } form, err = strconv.Atoi(args[9]) if err != nil { return shim.Error("Expecting integer value for asset holding") } status, err = strconv.Atoi(args[10]) if err != nil { return shim.Error("Expecting integer value for asset holding") } bill = Bill{BillId:args[0], Maker: args[1], Acceptor: args[2], Receiver: args[3], IssueDate: t_issue.Unix(), ExpireDate: t_expire.Unix(), RecBank: args[6], Amount: amount, Type: billtype, Form: form, Status: status} err = writeBill(stub, bill) if err != nil { return shim.Error("createBill(): Fail to write the bill" + err.Error()) } billBytes, err = json.Marshal(&bill) if err != nil { return shim.Error("createBill():" + err.Error()) } //Any operation of Bill will treat as transaction. transaction := Transaction{BillId: args[0], Operation: "Create", BillStatus: status, Time: time.Now().Unix(), ID: transactionNo } err = writeTransaction(stub, transaction) if err != nil { return shim.Error("createBill(): Fail to write the transaction" + err.Error()) } transactionNo += 1 return shim.Success(billBytes) } // Change the Bill status func (t *SimpleChaincode) changeBillStatus(stub shim.ChaincodeStubInterface, args []string) pb.Response { if len(args) != 2 { return shim.Error("changeBillStatus(): Incorrect number of arguments. Expecting 2") } var bill Bill status, err := strconv.Atoi(args[1]) if err != nil { return shim.Error("changeBillStatus(): status want Integer number") } bill,_,err = getBillById(stub, args[0]) if err != nil { return shim.Error("changeBillStatus(): Fail to get Bill" + err.Error()) } bill.Status = status err = writeBill(stub, bill) if err != nil { shim.Error("changeBillStatus():fail to write Bill" + err.Error()) } transaction := Transaction{BillId: args[0], Operation: "changeStatus", BillStatus: status, Time: time.Now().Unix(), ID: transactionNo } err = writeTransaction(stub, transaction) if err != nil { return shim.Error("changeBillStatus(): Fail to write the transaction" + err.Error()) } transactionNo += 1 return shim.Success(nil) } // Query Bill info func (t *SimpleChaincode) queryBill(stub shim.ChaincodeStubInterface, args []string) pb.Response { if len(args) != 1 { return shim.Error("queryBill(): Incorrect number of arguments. Expecting 1") } _,billBytes,err := getBillById(stub,args[0]) if err != nil { shim.Error("queryBill(): Fail to get Bill" + err.Error()) } return shim.Success(billBytes) } // Query Transaction info func (t *SimpleChaincode) queryTransaction(stub shim.ChaincodeStubInterface, args []string) pb.Response { if len(args) != 1 { return shim.Error("queryTransaction(): Incorrect number of arguments. Expecting 1") } _,transBytes,err := getTransactionById(stub,args[0]) if err != nil { return shim.Error("queryBill(): Fail to get Bill" + err.Error()) } return shim.Success(transBytes) } // Write Bill info into the fabric func writeBill(stub shim.ChaincodeStubInterface, bill Bill) error { billBytes, err := json.Marshal(&bill) if err != nil { return errors.New("writeBill():" + err.Error()) } err = stub.PutState("bill"+bill.BillId, billBytes) if err != nil { return errors.New("writeBill(): PutState Error" + err.Error()) } return nil } //Write the transaction info into the Fabric func writeTransaction(stub shim.ChaincodeStubInterface, transaction Transaction) error { var tsId string tsBytes, err := json.Marshal(&transaction) if err != nil { return errors.New("writeTransaction():" + err.Error()) } tsId = strconv.Itoa(transaction.ID) if err != nil { return errors.New("writeTransaction(): want Integer number") } err = stub.PutState("transaction"+tsId, tsBytes) if err != nil { return errors.New("writeTransaction(): PutState Error" + err.Error()) } return nil } func getBillById(stub shim.ChaincodeStubInterface, id string) (Bill, []byte, error) { var bill Bill billBytes, err := stub.GetState("bill" + id) if err != nil { fmt.Println("Error retrieving cpBytes") } err = json.Unmarshal(billBytes, &bill) if err != nil { fmt.Println("Error unmarshalling Bill") } return bill, billBytes, nil } func getTransactionById(stub shim.ChaincodeStubInterface, id string) (Transaction, []byte, error) { var transaction Transaction transBytes, err := stub.GetState("transaction" + id) if err != nil { fmt.Println("Error retrieving transBytes") } err = json.Unmarshal(transBytes, &transaction) if err != nil { fmt.Println("Error unmarshalling transaction") } return transaction, transBytes, nil } func main() { err := shim.Start(new(SimpleChaincode)) if err != nil { fmt.Printf("Error starting Simple chaincode: %s", err) } }