func (t *AssetManagementChaincode) assign(stub shim.ChaincodeStubInterface, args []string) ([]byte, error) { fmt.Println("Assigning Asset...") if len(args) != 2 { return nil, errors.New("Incorrect number of arguments. Expecting 2") } asset := args[0] owner, err := base64.StdEncoding.DecodeString(args[1]) if err != nil { fmt.Printf("Error decoding [%v] \n", err) return nil, errors.New("Failed decodinf owner") } // Recover the role that is allowed to make assignments assignerRole, err := stub.GetState("assignerRole") if err != nil { fmt.Printf("Error getting role [%v] \n", err) return nil, errors.New("Failed fetching assigner role") } callerRole, err := stub.ReadCertAttribute("role") if err != nil { fmt.Printf("Error reading attribute 'role' [%v] \n", err) return nil, fmt.Errorf("Failed fetching caller role. Error was [%v]", err) } caller := string(callerRole[:]) assigner := string(assignerRole[:]) if caller != assigner { fmt.Printf("Caller is not assigner - caller %v assigner %v\n", caller, assigner) return nil, fmt.Errorf("The caller does not have the rights to invoke assign. Expected role [%v], caller role [%v]", assigner, caller) } account, err := attr.GetValueFrom("account", owner) if err != nil { fmt.Printf("Error reading account [%v] \n", err) return nil, fmt.Errorf("Failed fetching recipient account. Error was [%v]", err) } // Register assignment myLogger.Debugf("New owner of [%s] is [% x]", asset, owner) ok, err := stub.InsertRow("AssetsOwnership", shim.Row{ Columns: []*shim.Column{ &shim.Column{Value: &shim.Column_String_{String_: asset}}, &shim.Column{Value: &shim.Column_Bytes{Bytes: account}}}, }) if !ok && err == nil { fmt.Println("Error inserting row") return nil, errors.New("Asset was already assigned.") } return nil, err }
// Init method will be called during deployment func (t *RBACChaincode) Init(stub shim.ChaincodeStubInterface) ([]byte, error) { function, args := stub.GetFunctionAndParameters() // Init the crypto layer if err := crypto.Init(); err != nil { panic(fmt.Errorf("Failed initializing the crypto layer [%s]", err)) } myLogger.Info("Init") // if len(args) != 0 { // return nil, errors.New("Incorrect number of arguments. Expecting 0") // } myLogger.Debug("Creating RBAC Table...") // Create RBAC table err := stub.CreateTable("RBAC", []*shim.ColumnDefinition{ &shim.ColumnDefinition{Name: "ID", Type: shim.ColumnDefinition_BYTES, Key: true}, &shim.ColumnDefinition{Name: "Roles", Type: shim.ColumnDefinition_STRING, Key: false}, }) if err != nil { return nil, errors.New("Failed creating RBAC table.") } myLogger.Debug("Assign 'admin' role...") // Give to the deployer the role 'admin' deployer, err := stub.GetCallerMetadata() if err != nil { return nil, errors.New("Failed getting metadata.") } if len(deployer) == 0 { return nil, errors.New("Invalid admin certificate. Empty.") } myLogger.Debug("Add admin [% x][%s]", deployer, "admin") ok, err := stub.InsertRow("RBAC", shim.Row{ Columns: []*shim.Column{ &shim.Column{Value: &shim.Column_Bytes{Bytes: deployer}}, &shim.Column{Value: &shim.Column_String_{String_: "admin"}}, }, }) if !ok && err == nil { return nil, fmt.Errorf("Failed initiliazing RBAC entries.") } if err != nil { return nil, fmt.Errorf("Failed initiliazing RBAC entries [%s]", err) } myLogger.Debug("Done.") return nil, nil }
func (t *AssetManagementChaincode) assign(stub shim.ChaincodeStubInterface, args []string) ([]byte, error) { myLogger.Debug("Assign...") if len(args) != 2 { return nil, errors.New("Incorrect number of arguments. Expecting 2") } asset := args[0] owner, err := base64.StdEncoding.DecodeString(args[1]) if err != nil { return nil, errors.New("Failed decodinf owner") } // Verify the identity of the caller // Only an administrator can invoker assign adminCertificate, err := stub.GetState("admin") if err != nil { return nil, errors.New("Failed fetching admin identity") } ok, err := t.isCaller(stub, adminCertificate) if err != nil { return nil, errors.New("Failed checking admin identity") } if !ok { return nil, errors.New("The caller is not an administrator") } // Register assignment myLogger.Debugf("New owner of [%s] is [% x]", asset, owner) ok, err = stub.InsertRow("AssetsOwnership", shim.Row{ Columns: []*shim.Column{ &shim.Column{Value: &shim.Column_String_{String_: asset}}, &shim.Column{Value: &shim.Column_Bytes{Bytes: owner}}}, }) if !ok && err == nil { return nil, errors.New("Asset was already assigned.") } myLogger.Debug("Assign...done!") return nil, err }
// assign allocates assets to account IDs in the chaincode state for each of the // account ID passed in. // accountID: account ID to be allocated with requested amount // contactInfo: contact information of the owner of the account ID passed in // amount: amount to be allocated to this account ID func (t *depositoryHandler) assign(stub shim.ChaincodeStubInterface, accountID string, contactInfo string, amount uint64) error { myLogger.Debugf("insert accountID= %v", accountID) //insert a new row for this account ID that includes contact information and balance ok, err := stub.InsertRow(tableColumn, shim.Row{ Columns: []*shim.Column{ &shim.Column{Value: &shim.Column_String_{String_: accountID}}, &shim.Column{Value: &shim.Column_String_{String_: contactInfo}}, &shim.Column{Value: &shim.Column_Uint64{Uint64: amount}}}, }) // you can only assign balances to new account IDs if !ok && err == nil { myLogger.Errorf("system error %v", err) return errors.New("Asset was already assigned.") } return 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 }
// Invoke callback representing the invocation of a chaincode // This chaincode will manage two accounts A and B and will transfer X units from A to B upon invoke func (t *SimpleChaincode) Invoke(stub shim.ChaincodeStubInterface, function string, args []string) ([]byte, error) { switch function { case "insertRowTableOne": if len(args) < 3 { return nil, errors.New("insertTableOne failed. Must include 3 column values") } col1Val := args[0] col2Int, err := strconv.ParseInt(args[1], 10, 32) if err != nil { return nil, errors.New("insertTableOne failed. arg[1] must be convertable to int32") } col2Val := int32(col2Int) col3Int, err := strconv.ParseInt(args[2], 10, 32) if err != nil { return nil, errors.New("insertTableOne failed. arg[2] must be convertable to int32") } col3Val := int32(col3Int) 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_Int32{Int32: col3Val}} columns = append(columns, &col1) columns = append(columns, &col2) columns = append(columns, &col3) row := shim.Row{Columns: columns} ok, err := stub.InsertRow("tableOne", row) if err != nil { return nil, fmt.Errorf("insertTableOne operation failed. %s", err) } if !ok { return nil, errors.New("insertTableOne operation failed. Row with given key already exists") } case "insertRowTableTwo": if len(args) < 4 { return nil, errors.New("insertRowTableTwo failed. Must include 4 column values") } col1Val := args[0] col2Int, err := strconv.ParseInt(args[1], 10, 32) if err != nil { return nil, errors.New("insertRowTableTwo failed. arg[1] must be convertable to int32") } col2Val := int32(col2Int) col3Int, err := strconv.ParseInt(args[2], 10, 32) if err != nil { return nil, errors.New("insertRowTableTwo failed. arg[2] must be convertable to int32") } col3Val := int32(col3Int) col4Val := args[3] 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_Int32{Int32: col3Val}} col4 := shim.Column{Value: &shim.Column_String_{String_: col4Val}} columns = append(columns, &col1) columns = append(columns, &col2) columns = append(columns, &col3) columns = append(columns, &col4) row := shim.Row{Columns: columns} ok, err := stub.InsertRow("tableTwo", row) if err != nil { return nil, fmt.Errorf("insertRowTableTwo operation failed. %s", err) } if !ok { return nil, errors.New("insertRowTableTwo operation failed. Row with given key already exists") } case "insertRowTableThree": if len(args) < 7 { return nil, errors.New("insertRowTableThree failed. Must include 7 column values") } col1Val := args[0] col2Int, err := strconv.ParseInt(args[1], 10, 32) if err != nil { return nil, errors.New("insertRowTableThree failed. arg[1] must be convertable to int32") } col2Val := int32(col2Int) col3Val, err := strconv.ParseInt(args[2], 10, 64) if err != nil { return nil, errors.New("insertRowTableThree failed. arg[2] must be convertable to int64") } col4Uint, err := strconv.ParseUint(args[3], 10, 32) if err != nil { return nil, errors.New("insertRowTableThree failed. arg[3] must be convertable to uint32") } col4Val := uint32(col4Uint) col5Val, err := strconv.ParseUint(args[4], 10, 64) if err != nil { return nil, errors.New("insertRowTableThree failed. arg[4] must be convertable to uint64") } col6Val := []byte(args[5]) col7Val, err := strconv.ParseBool(args[6]) if err != nil { return nil, errors.New("insertRowTableThree failed. arg[6] must be convertable to bool") } 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_Int64{Int64: col3Val}} col4 := shim.Column{Value: &shim.Column_Uint32{Uint32: col4Val}} col5 := shim.Column{Value: &shim.Column_Uint64{Uint64: col5Val}} col6 := shim.Column{Value: &shim.Column_Bytes{Bytes: col6Val}} col7 := shim.Column{Value: &shim.Column_Bool{Bool: col7Val}} columns = append(columns, &col1) columns = append(columns, &col2) columns = append(columns, &col3) columns = append(columns, &col4) columns = append(columns, &col5) columns = append(columns, &col6) columns = append(columns, &col7) row := shim.Row{Columns: columns} ok, err := stub.InsertRow("tableThree", row) if err != nil { return nil, fmt.Errorf("insertRowTableThree operation failed. %s", err) } if !ok { return nil, errors.New("insertRowTableThree operation failed. Row with given key already exists") } case "insertRowTableFour": if len(args) < 1 { return nil, errors.New("insertRowTableFour failed. Must include 1 column value1") } col1Val := args[0] var columns []*shim.Column col1 := shim.Column{Value: &shim.Column_String_{String_: col1Val}} columns = append(columns, &col1) row := shim.Row{Columns: columns} ok, err := stub.InsertRow("tableFour", row) if err != nil { return nil, fmt.Errorf("insertRowTableFour operation failed. %s", err) } if !ok { return nil, errors.New("insertRowTableFour operation failed. Row with given key already exists") } case "deleteRowTableOne": if len(args) < 1 { return nil, errors.New("deleteRowTableOne 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) err := stub.DeleteRow("tableOne", columns) if err != nil { return nil, fmt.Errorf("deleteRowTableOne operation failed. %s", err) } case "replaceRowTableOne": if len(args) < 3 { return nil, errors.New("replaceRowTableOne failed. Must include 3 column values") } col1Val := args[0] col2Int, err := strconv.ParseInt(args[1], 10, 32) if err != nil { return nil, errors.New("replaceRowTableOne failed. arg[1] must be convertable to int32") } col2Val := int32(col2Int) col3Int, err := strconv.ParseInt(args[2], 10, 32) if err != nil { return nil, errors.New("replaceRowTableOne failed. arg[2] must be convertable to int32") } col3Val := int32(col3Int) 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_Int32{Int32: col3Val}} columns = append(columns, &col1) columns = append(columns, &col2) columns = append(columns, &col3) row := shim.Row{Columns: columns} ok, err := stub.ReplaceRow("tableOne", row) if err != nil { return nil, fmt.Errorf("replaceRowTableOne operation failed. %s", err) } if !ok { return nil, errors.New("replaceRowTableOne operation failed. Row with given key does not exist") } case "deleteAndRecreateTableOne": err := stub.DeleteTable("tableOne") if err != nil { return nil, fmt.Errorf("deleteAndRecreateTableOne operation failed. Error deleting table. %s", err) } err = createTableOne(stub) if err != nil { return nil, fmt.Errorf("deleteAndRecreateTableOne operation failed. Error creating table. %s", err) } return nil, nil default: return nil, errors.New("Unsupported operation") } return nil, nil }