// Query callback representing the query of a chaincode // Supported functions are the following: // "query(asset)": returns the owner of the asset. // Anyone can invoke this function. func (t *AssetManagementChaincode) Query(stub shim.ChaincodeStubInterface) ([]byte, error) { function, args := stub.GetFunctionAndParameters() myLogger.Debugf("Query [%s]", function) if function != "query" { return nil, errors.New("Invalid query function name. Expecting 'query' but found '" + function + "'") } var err error if len(args) != 1 { myLogger.Debug("Incorrect number of arguments. Expecting name of an asset to query") return nil, errors.New("Incorrect number of arguments. Expecting name of an asset to query") } // Who is the owner of the asset? asset := args[0] myLogger.Debugf("Arg [%s]", string(asset)) var columns []shim.Column col1 := shim.Column{Value: &shim.Column_String_{String_: asset}} columns = append(columns, col1) row, err := stub.GetRow("AssetsOwnership", columns) if err != nil { myLogger.Debugf("Failed retriving asset [%s]: [%s]", string(asset), err) return nil, fmt.Errorf("Failed retriving asset [%s]: [%s]", string(asset), err) } myLogger.Debugf("Query done [% x]", row.Columns[1].GetBytes()) return row.Columns[1].GetBytes(), nil }
func (t *AssetManagementChaincode) query(stub shim.ChaincodeStubInterface, args []string) ([]byte, error) { var err error if len(args) != 1 { return nil, errors.New("Incorrect number of arguments. Expecting name of an asset to query") } // Who is the owner of the asset? asset := args[0] fmt.Printf("ASSET: %v", string(asset)) var columns []shim.Column col1 := shim.Column{Value: &shim.Column_String_{String_: asset}} columns = append(columns, col1) row, err := stub.GetRow("AssetsOwnership", columns) if err != nil { jsonResp := "{\"Error\":\"Failed retrieving asset " + asset + ". Error " + err.Error() + ". \"}" return nil, errors.New(jsonResp) } if len(row.Columns) == 0 { jsonResp := "{\"Error\":\"Failed retrieving owner for " + asset + ". \"}" return nil, errors.New(jsonResp) } jsonResp := "{\"Owner\":\"" + string(row.Columns[1].GetBytes()) + "\"}" fmt.Printf("Query Response:%s\n", jsonResp) return row.Columns[1].GetBytes(), nil }
// queryTable returns the record row matching a correponding account ID on the chaincode state table // stub: chaincodestub // accountID: account ID func (t *depositoryHandler) queryTable(stub shim.ChaincodeStubInterface, accountID string) (shim.Row, error) { var columns []shim.Column col1 := shim.Column{Value: &shim.Column_String_{String_: accountID}} columns = append(columns, col1) return stub.GetRow(tableColumn, columns) }
func (t *RBACChaincode) hasInvokerRole(stub shim.ChaincodeStubInterface, role string) (bool, []byte, error) { // In order to enforce access control, we require that the // metadata contains the following items: // 1. a certificate Cert // 2. a signature Sigma under the signing key corresponding // to the verification key inside Cert of : // (a) Cert; // (b) The payload of the transaction (namely, function name and args) and // (c) the transaction binding. // Verify Sigma=Sign(certificate.sk, Cert||tx.Payload||tx.Binding) against Cert.vk // Unmarshall metadata metadata, err := stub.GetCallerMetadata() rbacMetadata := new(RBACMetadata) _, err = asn1.Unmarshal(metadata, rbacMetadata) if err != nil { return false, nil, fmt.Errorf("Failed unmarshalling metadata [%s]", err) } // Verify signature payload, err := stub.GetPayload() if err != nil { return false, nil, errors.New("Failed getting payload") } binding, err := stub.GetBinding() if err != nil { return false, nil, errors.New("Failed getting binding") } myLogger.Debug("passed certificate [% x]", rbacMetadata.Cert) myLogger.Debug("passed sigma [% x]", rbacMetadata.Sigma) myLogger.Debug("passed payload [% x]", payload) myLogger.Debug("passed binding [% x]", binding) ok, err := stub.VerifySignature( rbacMetadata.Cert, rbacMetadata.Sigma, append(rbacMetadata.Cert, append(payload, binding...)...), ) if err != nil { return false, nil, fmt.Errorf("Failed verifying signature [%s]", err) } if !ok { return false, nil, fmt.Errorf("Signature is not valid!") } myLogger.Debug("Signature verified. Check for role...") myLogger.Debug("ID [% x]", rbacMetadata.Cert) // Check role var columns []shim.Column idCol := shim.Column{Value: &shim.Column_Bytes{Bytes: rbacMetadata.Cert}} columns = append(columns, idCol) row, err := stub.GetRow("RBAC", columns) if err != nil { return false, nil, fmt.Errorf("Failed retrieveing RBAC row [%s]", err) } if len(row.GetColumns()) == 0 { return false, nil, fmt.Errorf("Failed retrieveing RBAC row [%s]", err) } myLogger.Debug("#Columns: [%d]", len(row.Columns)) roles := row.Columns[1].GetString_() result := strings.Split(roles, " ") for i := range result { if result[i] == role { myLogger.Debug("Role found.") return true, rbacMetadata.Cert, nil } } myLogger.Debug("Role not found.") return false, nil, nil }
func (t *RBACChaincode) addRole(stub shim.ChaincodeStubInterface, args []string) ([]byte, error) { if len(args) != 2 { return nil, errors.New("Incorrect number of arguments. Expecting 2") } id, err := base64.StdEncoding.DecodeString(args[0]) if err != nil { return nil, fmt.Errorf("Failed decoding tcert: %s", err) } //id := []byte(args[0]) role := args[1] myLogger.Debug("Add role [% x][%s]", id, role) // Verify that the invoker has the 'admin' role ok, _, err := t.hasInvokerRole(stub, "admin") if err != nil { return nil, fmt.Errorf("Failed checking role [%s]", err) } if !ok { return nil, errors.New("The invoker does not have the required roles.") } // Add role to id myLogger.Debug("Permission granted to the invoker") // Retrieve id's row var columns []shim.Column idCol := shim.Column{Value: &shim.Column_Bytes{Bytes: id}} columns = append(columns, idCol) row, err := stub.GetRow("RBAC", columns) if err != nil { return nil, fmt.Errorf("Failed retriving associated row [%s]", err) } if len(row.Columns) == 0 { // Insert row ok, err = stub.InsertRow("RBAC", shim.Row{ Columns: []*shim.Column{ &shim.Column{Value: &shim.Column_Bytes{Bytes: id}}, &shim.Column{Value: &shim.Column_String_{String_: role}}, }, }) if err != nil { return nil, fmt.Errorf("Failed inserting row [%s]", err) } if !ok { return nil, errors.New("Failed inserting row.") } } else { // Update row ok, err = stub.ReplaceRow("RBAC", shim.Row{ Columns: []*shim.Column{ &shim.Column{Value: &shim.Column_Bytes{Bytes: id}}, &shim.Column{Value: &shim.Column_String_{String_: row.Columns[1].GetString_() + " " + role}}, }, }) if err != nil { return nil, fmt.Errorf("Failed replacing row [%s]", err) } if !ok { return nil, errors.New("Failed replacing row.") } } return nil, err }
func (t *AssetManagementChaincode) transfer(stub shim.ChaincodeStubInterface, args []string) ([]byte, error) { myLogger.Debug("Transfer...") if len(args) != 2 { return nil, errors.New("Incorrect number of arguments. Expecting 2") } asset := args[0] newOwner, err := base64.StdEncoding.DecodeString(args[1]) if err != nil { return nil, fmt.Errorf("Failed decoding owner") } // Verify the identity of the caller // Only the owner can transfer one of his assets var columns []shim.Column col1 := shim.Column{Value: &shim.Column_String_{String_: asset}} columns = append(columns, col1) row, err := stub.GetRow("AssetsOwnership", columns) if err != nil { return nil, fmt.Errorf("Failed retrieving asset [%s]: [%s]", asset, err) } prvOwner := row.Columns[1].GetBytes() myLogger.Debugf("Previous owener of [%s] is [% x]", asset, prvOwner) if len(prvOwner) == 0 { return nil, fmt.Errorf("Invalid previous owner. Nil") } // Verify ownership ok, err := t.isCaller(stub, prvOwner) if err != nil { return nil, errors.New("Failed checking asset owner identity") } if !ok { return nil, errors.New("The caller is not the owner of the asset") } // At this point, the proof of ownership is valid, then register transfer err = stub.DeleteRow( "AssetsOwnership", []shim.Column{shim.Column{Value: &shim.Column_String_{String_: asset}}}, ) if err != nil { return nil, errors.New("Failed deliting row.") } _, err = stub.InsertRow( "AssetsOwnership", shim.Row{ Columns: []*shim.Column{ &shim.Column{Value: &shim.Column_String_{String_: asset}}, &shim.Column{Value: &shim.Column_Bytes{Bytes: newOwner}}, }, }) if err != nil { return nil, errors.New("Failed inserting row.") } myLogger.Debug("New owner of [%s] is [% x]", asset, newOwner) myLogger.Debug("Transfer...done") return nil, nil }
func (t *AssetManagementChaincode) transfer(stub shim.ChaincodeStubInterface, args []string) ([]byte, error) { if len(args) != 2 { return nil, errors.New("Incorrect number of arguments. Expecting 2") } asset := args[0] newOwner, err := base64.StdEncoding.DecodeString(args[1]) if err != nil { fmt.Printf("Error decoding [%v] \n", err) return nil, errors.New("Failed decoding owner") } // Verify the identity of the caller // Only the owner can transfer one of his assets var columns []shim.Column col1 := shim.Column{Value: &shim.Column_String_{String_: asset}} columns = append(columns, col1) row, err := stub.GetRow("AssetsOwnership", columns) if err != nil { return nil, fmt.Errorf("Failed retrieving asset [%s]: [%s]", asset, err) } prvOwner := row.Columns[1].GetBytes() myLogger.Debugf("Previous owener of [%s] is [% x]", asset, prvOwner) if len(prvOwner) == 0 { return nil, fmt.Errorf("Invalid previous owner. Nil") } // Verify ownership callerAccount, err := stub.ReadCertAttribute("account") if err != nil { return nil, fmt.Errorf("Failed fetching caller account. Error was [%v]", err) } if bytes.Compare(prvOwner, callerAccount) != 0 { return nil, fmt.Errorf("Failed verifying caller ownership.") } newOwnerAccount, err := attr.GetValueFrom("account", newOwner) if err != nil { return nil, fmt.Errorf("Failed fetching new owner account. Error was [%v]", err) } // At this point, the proof of ownership is valid, then register transfer err = stub.DeleteRow( "AssetsOwnership", []shim.Column{shim.Column{Value: &shim.Column_String_{String_: asset}}}, ) if err != nil { return nil, errors.New("Failed deliting row.") } _, err = stub.InsertRow( "AssetsOwnership", shim.Row{ Columns: []*shim.Column{ &shim.Column{Value: &shim.Column_String_{String_: asset}}, &shim.Column{Value: &shim.Column_Bytes{Bytes: newOwnerAccount}}, }, }) if err != nil { return nil, errors.New("Failed inserting row.") } return nil, nil }
// Query callback representing the query of a chaincode func (t *SimpleChaincode) Query(stub shim.ChaincodeStubInterface, function string, args []string) ([]byte, error) { switch function { case "getRowTableOne": if len(args) < 1 { return nil, errors.New("getRowTableOne failed. Must include 1 key value") } col1Val := args[0] var columns []shim.Column col1 := shim.Column{Value: &shim.Column_String_{String_: col1Val}} columns = append(columns, col1) row, err := stub.GetRow("tableOne", columns) if err != nil { return nil, fmt.Errorf("getRowTableOne operation failed. %s", err) } rowString := fmt.Sprintf("%s", row) return []byte(rowString), nil case "getRowTableTwo": if len(args) < 3 { return nil, errors.New("getRowTableTwo failed. Must include 3 key values") } col1Val := args[0] col2Int, err := strconv.ParseInt(args[1], 10, 32) if err != nil { return nil, errors.New("getRowTableTwo failed. arg[1] must be convertable to int32") } col2Val := int32(col2Int) col3Val := args[2] var columns []shim.Column col1 := shim.Column{Value: &shim.Column_String_{String_: col1Val}} col2 := shim.Column{Value: &shim.Column_Int32{Int32: col2Val}} col3 := shim.Column{Value: &shim.Column_String_{String_: col3Val}} columns = append(columns, col1) columns = append(columns, col2) columns = append(columns, col3) row, err := stub.GetRow("tableTwo", columns) if err != nil { return nil, fmt.Errorf("getRowTableTwo operation failed. %s", err) } rowString := fmt.Sprintf("%s", row) return []byte(rowString), nil case "getRowTableThree": if len(args) < 1 { return nil, errors.New("getRowTableThree failed. Must include 1 key value") } col1Val := args[0] var columns []shim.Column col1 := shim.Column{Value: &shim.Column_String_{String_: col1Val}} columns = append(columns, col1) row, err := stub.GetRow("tableThree", columns) if err != nil { return nil, fmt.Errorf("getRowTableThree operation failed. %s", err) } rowString := fmt.Sprintf("%s", row) return []byte(rowString), nil case "getRowsTableTwo": if len(args) < 1 { return nil, errors.New("getRowsTableTwo failed. Must include at least key values") } var columns []shim.Column col1Val := args[0] col1 := shim.Column{Value: &shim.Column_String_{String_: col1Val}} columns = append(columns, col1) if len(args) > 1 { col2Int, err := strconv.ParseInt(args[1], 10, 32) if err != nil { return nil, errors.New("getRowsTableTwo failed. arg[1] must be convertable to int32") } col2Val := int32(col2Int) col2 := shim.Column{Value: &shim.Column_Int32{Int32: col2Val}} columns = append(columns, col2) } rowChannel, err := stub.GetRows("tableTwo", columns) if err != nil { return nil, fmt.Errorf("getRowsTableTwo operation failed. %s", err) } var rows []shim.Row for { select { case row, ok := <-rowChannel: if !ok { rowChannel = nil } else { rows = append(rows, row) } } if rowChannel == nil { break } } jsonRows, err := json.Marshal(rows) if err != nil { return nil, fmt.Errorf("getRowsTableTwo operation failed. Error marshaling JSON: %s", err) } return jsonRows, nil case "getRowTableFour": if len(args) < 1 { return nil, errors.New("getRowTableFour failed. Must include 1 key") } col1Val := args[0] var columns []shim.Column col1 := shim.Column{Value: &shim.Column_String_{String_: col1Val}} columns = append(columns, col1) row, err := stub.GetRow("tableFour", columns) if err != nil { return nil, fmt.Errorf("getRowTableFour operation failed. %s", err) } rowString := fmt.Sprintf("%s", row) return []byte(rowString), nil case "getRowsTableFour": if len(args) < 1 { return nil, errors.New("getRowsTableFour failed. Must include 1 key value") } var columns []shim.Column col1Val := args[0] col1 := shim.Column{Value: &shim.Column_String_{String_: col1Val}} columns = append(columns, col1) rowChannel, err := stub.GetRows("tableFour", columns) if err != nil { return nil, fmt.Errorf("getRowsTableFour operation failed. %s", err) } var rows []shim.Row for { select { case row, ok := <-rowChannel: if !ok { rowChannel = nil } else { rows = append(rows, row) } } if rowChannel == nil { break } } jsonRows, err := json.Marshal(rows) if err != nil { return nil, fmt.Errorf("getRowsTableFour operation failed. Error marshaling JSON: %s", err) } return jsonRows, nil default: return nil, errors.New("Unsupported operation") } }