chaincode useful version 1
This commit is contained in:
parent
5f8c9bbcc6
commit
7744ecbffd
|
@ -1,226 +0,0 @@
|
|||
/*
|
||||
Licensed to the Apache Software Foundation (ASF) under one
|
||||
or more contributor license agreements. See the NOTICE file
|
||||
distributed with this work for additional information
|
||||
regarding copyright ownership. The ASF licenses this file
|
||||
to you under the Apache License, Version 2.0 (the
|
||||
"License"); you may not use this file except in compliance
|
||||
with the License. You may obtain a copy of the License at
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
Unless required by applicable law or agreed to in writing,
|
||||
software distributed under the License is distributed on an
|
||||
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
KIND, either express or implied. See the License for the
|
||||
specific language governing permissions and limitations
|
||||
under the License.
|
||||
*/
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"strconv"
|
||||
|
||||
"github.com/hyperledger/fabric/core/chaincode/shim"
|
||||
)
|
||||
|
||||
// SimpleChaincode example simple Chaincode implementation
|
||||
type SimpleChaincode struct {
|
||||
}
|
||||
|
||||
func (t *SimpleChaincode) Init(stub *shim.ChaincodeStub, function string, args []string) ([]byte, error) {
|
||||
fmt.Printf("Init called, initializing chaincode")
|
||||
|
||||
var A, B string // Entities
|
||||
var Aval, Bval int // Asset holdings
|
||||
var err error
|
||||
|
||||
if len(args) != 4 {
|
||||
return nil, errors.New("Incorrect number of arguments. Expecting 4")
|
||||
}
|
||||
|
||||
// Initialize the chaincode
|
||||
A = args[0]
|
||||
Aval, err = strconv.Atoi(args[1])
|
||||
if err != nil {
|
||||
return nil, errors.New("Expecting integer value for asset holding")
|
||||
}
|
||||
B = args[2]
|
||||
Bval, err = strconv.Atoi(args[3])
|
||||
if err != nil {
|
||||
return nil, errors.New("Expecting integer value for asset holding")
|
||||
}
|
||||
fmt.Printf("Aval = %d, Bval = %d\n", Aval, Bval)
|
||||
|
||||
// Write the state to the ledger
|
||||
err = stub.PutState(A, []byte(strconv.Itoa(Aval)))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
err = stub.PutState(B, []byte(strconv.Itoa(Bval)))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
// Transaction makes payment of X units from A to B
|
||||
func (t *SimpleChaincode) invoke(stub *shim.ChaincodeStub, args []string) ([]byte, error) {
|
||||
fmt.Printf("Running invoke")
|
||||
|
||||
var A, B string // Entities
|
||||
var Aval, Bval int // Asset holdings
|
||||
var X int // Transaction value
|
||||
var err error
|
||||
|
||||
if len(args) != 3 {
|
||||
return nil, errors.New("Incorrect number of arguments. Expecting 3")
|
||||
}
|
||||
|
||||
A = args[0]
|
||||
B = args[1]
|
||||
|
||||
// Get the state from the ledger
|
||||
// TODO: will be nice to have a GetAllState call to ledger
|
||||
Avalbytes, err := stub.GetState(A)
|
||||
if err != nil {
|
||||
return nil, errors.New("Failed to get state")
|
||||
}
|
||||
if Avalbytes == nil {
|
||||
return nil, errors.New("Entity not found")
|
||||
}
|
||||
Aval, _ = strconv.Atoi(string(Avalbytes))
|
||||
|
||||
Bvalbytes, err := stub.GetState(B)
|
||||
if err != nil {
|
||||
return nil, errors.New("Failed to get state")
|
||||
}
|
||||
if Bvalbytes == nil {
|
||||
return nil, errors.New("Entity not found")
|
||||
}
|
||||
Bval, _ = strconv.Atoi(string(Bvalbytes))
|
||||
|
||||
// Perform the execution
|
||||
X, err = strconv.Atoi(args[2])
|
||||
Aval = Aval - X
|
||||
Bval = Bval + X
|
||||
fmt.Printf("Aval = %d, Bval = %d\n", Aval, Bval)
|
||||
|
||||
// Write the state back to the ledger
|
||||
err = stub.PutState(A, []byte(strconv.Itoa(Aval)))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
err = stub.PutState(B, []byte(strconv.Itoa(Bval)))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
// Deletes an entity from state
|
||||
func (t *SimpleChaincode) delete(stub *shim.ChaincodeStub, args []string) ([]byte, error) {
|
||||
fmt.Printf("Running delete")
|
||||
|
||||
if len(args) != 1 {
|
||||
return nil, errors.New("Incorrect number of arguments. Expecting 3")
|
||||
}
|
||||
|
||||
A := args[0]
|
||||
|
||||
// Delete the key from the state in ledger
|
||||
err := stub.DelState(A)
|
||||
if err != nil {
|
||||
return nil, errors.New("Failed to delete state")
|
||||
}
|
||||
|
||||
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.ChaincodeStub, function string, args []string) ([]byte, error) {
|
||||
fmt.Printf("Invoke called, determining function")
|
||||
|
||||
// Handle different functions
|
||||
if function == "invoke" {
|
||||
// Transaction makes payment of X units from A to B
|
||||
fmt.Printf("Function is invoke")
|
||||
return t.invoke(stub, args)
|
||||
} else if function == "init" {
|
||||
fmt.Printf("Function is init")
|
||||
return t.Init(stub, function, args)
|
||||
} else if function == "delete" {
|
||||
// Deletes an entity from its state
|
||||
fmt.Printf("Function is delete")
|
||||
return t.delete(stub, args)
|
||||
}
|
||||
|
||||
return nil, errors.New("Received unknown function invocation")
|
||||
}
|
||||
|
||||
func (t* SimpleChaincode) Run(stub *shim.ChaincodeStub, function string, args []string) ([]byte, error) {
|
||||
fmt.Printf("Run called, passing through to Invoke (same function)")
|
||||
|
||||
// Handle different functions
|
||||
if function == "invoke" {
|
||||
// Transaction makes payment of X units from A to B
|
||||
fmt.Printf("Function is invoke")
|
||||
return t.invoke(stub, args)
|
||||
} else if function == "init" {
|
||||
fmt.Printf("Function is init")
|
||||
return t.Init(stub, function, args)
|
||||
} else if function == "delete" {
|
||||
// Deletes an entity from its state
|
||||
fmt.Printf("Function is delete")
|
||||
return t.delete(stub, args)
|
||||
}
|
||||
|
||||
return nil, errors.New("Received unknown function invocation")
|
||||
}
|
||||
|
||||
// Query callback representing the query of a chaincode
|
||||
func (t *SimpleChaincode) Query(stub *shim.ChaincodeStub, function string, args []string) ([]byte, error) {
|
||||
fmt.Printf("Query called, determining function")
|
||||
|
||||
if function != "query" {
|
||||
fmt.Printf("Function is query")
|
||||
return nil, errors.New("Invalid query function name. Expecting \"query\"")
|
||||
}
|
||||
var A string // Entities
|
||||
var err error
|
||||
|
||||
if len(args) != 1 {
|
||||
return nil, errors.New("Incorrect number of arguments. Expecting name of the person to query")
|
||||
}
|
||||
|
||||
A = args[0]
|
||||
|
||||
// Get the state from the ledger
|
||||
Avalbytes, err := stub.GetState(A)
|
||||
if err != nil {
|
||||
jsonResp := "{\"Error\":\"Failed to get state for " + A + "\"}"
|
||||
return nil, errors.New(jsonResp)
|
||||
}
|
||||
|
||||
if Avalbytes == nil {
|
||||
jsonResp := "{\"Error\":\"Nil amount for " + A + "\"}"
|
||||
return nil, errors.New(jsonResp)
|
||||
}
|
||||
|
||||
jsonResp := "{\"Name\":\"" + A + "\",\"Amount\":\"" + string(Avalbytes) + "\"}"
|
||||
fmt.Printf("Query Response:%s\n", jsonResp)
|
||||
return Avalbytes, nil
|
||||
}
|
||||
|
||||
func main() {
|
||||
err := shim.Start(new(SimpleChaincode))
|
||||
if err != nil {
|
||||
fmt.Printf("Error starting Simple chaincode: %s", err)
|
||||
}
|
||||
}
|
781
monnethic.go
Normal file
781
monnethic.go
Normal file
|
@ -0,0 +1,781 @@
|
|||
/*
|
||||
Copyright IBM Corp. 2016 All Rights Reserved.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package main
|
||||
|
||||
//WARNING - this chaincode's ID is hard-coded in chaincode_example04 to illustrate one way of
|
||||
//calling chaincode from a chaincode. If this example is modified, chaincode_example04.go has
|
||||
//to be modified as well with the new ID of chaincode_example02.
|
||||
//chaincode_example05 show's how chaincode ID can be passed in as a parameter instead of
|
||||
//hard-coding.
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/hyperledger/fabric/core/chaincode/shim"
|
||||
pb "github.com/hyperledger/fabric/protos/peer"
|
||||
)
|
||||
|
||||
|
||||
// SimpleChaincode example simple Chaincode implementation
|
||||
type SimpleChaincode struct {
|
||||
}
|
||||
|
||||
type owner struct {
|
||||
ObjectType string `json:"docType"`
|
||||
UserId string `json:"userId"`
|
||||
UserName string `json:"userName"`
|
||||
UserFirstName string `json:"userFirstName"`
|
||||
// Mail string `json:"userMail"`
|
||||
UserPhone string `json:"userPhone"`
|
||||
// Address string `json:"userAddress"`
|
||||
// PostalCode string `json:"userPostalCode"`
|
||||
// City int `json:"userCity"`
|
||||
UserAssociation string `json:"userAssociation"`
|
||||
UserAuthorized bool `json:"userAuthorized"`
|
||||
}
|
||||
|
||||
type wallet struct {
|
||||
ObjectType string `json:"docType"` //docType is used to distinguish the various type$
|
||||
Id string `json:"id"` //the fieldtags are needed to keep case from bounci$
|
||||
WalletType string `json:"walletType"`
|
||||
Sold int `json:"sold"`
|
||||
Owner string `json:"owner"`
|
||||
}
|
||||
|
||||
|
||||
func (t *SimpleChaincode) Init(stub shim.ChaincodeStubInterface) pb.Response {
|
||||
fmt.Println("ex02 Init")
|
||||
_, args := stub.GetFunctionAndParameters()
|
||||
var A string // Entities
|
||||
var Aval int // Asset holdings
|
||||
var err error
|
||||
|
||||
if len(args) != 2 {
|
||||
return shim.Error("Incorrect number of arguments. Expecting 2")
|
||||
}
|
||||
|
||||
// Initialize the chaincode
|
||||
A = args[0]
|
||||
Aval, err = strconv.Atoi(args[1])
|
||||
if err != nil {
|
||||
return shim.Error("Expecting integer value for asset holding")
|
||||
}
|
||||
fmt.Printf("Aval = %d\n", Aval)
|
||||
|
||||
// Write the state to the ledger
|
||||
err = stub.PutState(A, []byte(strconv.Itoa(Aval)))
|
||||
if err != nil {
|
||||
return shim.Error(err.Error())
|
||||
}
|
||||
|
||||
return shim.Success(nil)
|
||||
}
|
||||
|
||||
|
||||
func (t *SimpleChaincode) Invoke(stub shim.ChaincodeStubInterface) pb.Response {
|
||||
fmt.Println("ex02 Invoke")
|
||||
function, args := stub.GetFunctionAndParameters()
|
||||
if function == "invoke" {
|
||||
// Make payment of X units from A to B
|
||||
return t.invoke(stub, args)
|
||||
} else if function == "delete" {
|
||||
// Deletes an entity from its state
|
||||
return t.delete(stub, args)
|
||||
} else if function == "query" {
|
||||
// the old "Query" is now implemtned in invoke
|
||||
return t.query(stub, args)
|
||||
} else if function == "register" {
|
||||
// register a new user into the ledger
|
||||
return t.register(stub, args)
|
||||
} else if function == "registerUser" {
|
||||
// initiate a new account
|
||||
return t.registerUser(stub, args)
|
||||
} else if function == "readUser" {
|
||||
// query a specific user from the ledger
|
||||
return t.readUser(stub, args)
|
||||
} else if function == "deleteUser" {
|
||||
// delete a specific user from the ledger
|
||||
return t.deleteUser(stub, args)
|
||||
} else if function == "initWallet" {
|
||||
// initiate a new wallet
|
||||
return t.initWallet(stub, args)
|
||||
} else if function == "readWallet" {
|
||||
// query a specific wallet from the ledger
|
||||
return t.readWallet(stub, args)
|
||||
} else if function == "deleteWallet" {
|
||||
// delete a specific wallet from the ledger
|
||||
return t.deleteWallet(stub, args)
|
||||
} else if function == "transferWallet" {
|
||||
// change the owner of a specific wallet
|
||||
return t.transferWallet(stub, args)
|
||||
} else if function == "setSoldOnWallet" {
|
||||
// set a new sold to a wallet
|
||||
return t.setSoldOnWallet(stub, args)
|
||||
} else if function == "transaction" {
|
||||
// make a transaction of X units from a wallet to an other
|
||||
return t.transaction(stub, args)
|
||||
}
|
||||
|
||||
return shim.Error("Invalid invoke function name. Expecting \"invoke\" \"delete\" \"query\" \"register\"")
|
||||
}
|
||||
|
||||
|
||||
// Transaction makes payment of X units from A to B
|
||||
func (t *SimpleChaincode) invoke(stub shim.ChaincodeStubInterface, args []string) pb.Response {
|
||||
var A, B string // Entities
|
||||
var Aval, Bval int // Asset holdings
|
||||
var X int // Transaction value
|
||||
var err error
|
||||
|
||||
if len(args) != 3 {
|
||||
return shim.Error("Incorrect number of arguments. Expecting 3")
|
||||
}
|
||||
|
||||
A = args[0]
|
||||
B = args[1]
|
||||
|
||||
// Get the state from the ledger
|
||||
// TODO: will be nice to have a GetAllState call to ledger
|
||||
Avalbytes, err := stub.GetState(A)
|
||||
if err != nil {
|
||||
return shim.Error("Failed to get state")
|
||||
}
|
||||
if Avalbytes == nil {
|
||||
return shim.Error("Entity not found")
|
||||
}
|
||||
Aval, _ = strconv.Atoi(string(Avalbytes))
|
||||
|
||||
Bvalbytes, err := stub.GetState(B)
|
||||
if err != nil {
|
||||
return shim.Error("Failed to get state")
|
||||
}
|
||||
if Bvalbytes == nil {
|
||||
return shim.Error("Entity not found")
|
||||
}
|
||||
Bval, _ = strconv.Atoi(string(Bvalbytes))
|
||||
|
||||
// Perform the execution
|
||||
X, err = strconv.Atoi(args[2])
|
||||
if err != nil {
|
||||
return shim.Error("Invalid transaction amount, expecting a integer value")
|
||||
}
|
||||
Aval = Aval - X
|
||||
Bval = Bval + X
|
||||
fmt.Printf("Aval = %d, Bval = %d\n", Aval, Bval)
|
||||
|
||||
// Write the state back to the ledger
|
||||
err = stub.PutState(A, []byte(strconv.Itoa(Aval)))
|
||||
if err != nil {
|
||||
return shim.Error(err.Error())
|
||||
}
|
||||
|
||||
err = stub.PutState(B, []byte(strconv.Itoa(Bval)))
|
||||
if err != nil {
|
||||
return shim.Error(err.Error())
|
||||
}
|
||||
|
||||
return shim.Success(nil)
|
||||
}
|
||||
|
||||
|
||||
// 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)
|
||||
}
|
||||
|
||||
|
||||
// query callback representing the query of a chaincode
|
||||
func (t *SimpleChaincode) query(stub shim.ChaincodeStubInterface, args []string) pb.Response {
|
||||
var A string // Entities
|
||||
var err error
|
||||
|
||||
if len(args) != 1 {
|
||||
return shim.Error("Incorrect number of arguments. Expecting name of the person to query")
|
||||
}
|
||||
|
||||
A = args[0]
|
||||
|
||||
// Get the state from the ledger
|
||||
Avalbytes, err := stub.GetState(A)
|
||||
if err != nil {
|
||||
jsonResp := "{\"Error\":\"Failed to get state for " + A + "\"}"
|
||||
return shim.Error(jsonResp)
|
||||
}
|
||||
|
||||
if Avalbytes == nil {
|
||||
jsonResp := "{\"Error\":\"Nil amount for " + A + "\"}"
|
||||
return shim.Error(jsonResp)
|
||||
}
|
||||
|
||||
jsonResp := "{\"Name\":\"" + A + "\",\"Amount\":\"" + string(Avalbytes) + "\"}"
|
||||
fmt.Printf("Query Response:%s\n", jsonResp)
|
||||
return shim.Success(Avalbytes)
|
||||
}
|
||||
|
||||
|
||||
func (t *SimpleChaincode) register(stub shim.ChaincodeStubInterface, args []string) pb.Response {
|
||||
var A string // Entities
|
||||
var Aval int // Asset holdings
|
||||
var err error
|
||||
|
||||
if len(args) != 2 {
|
||||
return shim.Error("Incorrect number of arguments. Expecting 2")
|
||||
}
|
||||
|
||||
// Initialize the chaincode
|
||||
A = args[0]
|
||||
Aval, err = strconv.Atoi(args[1])
|
||||
if err != nil {
|
||||
return shim.Error("Expecting integer value for asset holding")
|
||||
}
|
||||
fmt.Printf("Aval = %d\n", Aval)
|
||||
|
||||
// Write the state to the ledger
|
||||
err = stub.PutState(A, []byte(strconv.Itoa(Aval)))
|
||||
if err != nil {
|
||||
return shim.Error(err.Error())
|
||||
}
|
||||
return shim.Success(nil)
|
||||
}
|
||||
|
||||
|
||||
func (t *SimpleChaincode) registerUser(stub shim.ChaincodeStubInterface, args []string) pb.Response {
|
||||
var err error
|
||||
|
||||
if len(args) != 5 {
|
||||
return shim.Error("Incorrect number of arguments. Expecting 6")
|
||||
}
|
||||
|
||||
// ==== Input sanitation ====
|
||||
fmt.Println("- start init user")
|
||||
if len(args[0]) <= 0 {
|
||||
return shim.Error("1st argument must be a non-empty string")
|
||||
}
|
||||
if len(args[1]) <= 0 {
|
||||
return shim.Error("2nd argument must be a non-empty string")
|
||||
}
|
||||
if len(args[2]) <= 0 {
|
||||
return shim.Error("3rd argument must be a non-empty string")
|
||||
}
|
||||
if len(args[3]) <= 0 {
|
||||
return shim.Error("4th argument must be a non-empty string")
|
||||
}
|
||||
if len(args[4]) <= 0 {
|
||||
return shim.Error("5th argument must be a non-empty string")
|
||||
}
|
||||
//if len(args[5]) <= 0 {
|
||||
// return shim.Error("6th argument must be a non-empty string")
|
||||
//}
|
||||
|
||||
|
||||
userId := args[0]
|
||||
userName := strings.ToLower(args[1])
|
||||
userFirstName := strings.ToLower(args[2])
|
||||
userPhone := strings.ToLower(args[3])
|
||||
userAssociation := strings.ToLower(args[4])
|
||||
userAuthorized := false
|
||||
|
||||
if err != nil {
|
||||
return shim.Error("3rd argument must be a numeric string")
|
||||
}
|
||||
|
||||
// ==== Check if user already exists ====
|
||||
ownerAsBytes, err := stub.GetState(userId)
|
||||
if err != nil {
|
||||
return shim.Error("Failed to get user: " + err.Error())
|
||||
} else if ownerAsBytes != nil {
|
||||
fmt.Println("This user already exists: " + userId)
|
||||
return shim.Error("This user already exists: " + userId)
|
||||
}
|
||||
|
||||
// ==== Create wallet object and marshal to JSON ====
|
||||
objectType := "owner"
|
||||
owner := &owner{objectType, userId, userName, userFirstName, userPhone, userAssociation, userAuthorized}
|
||||
ownerJSONasBytes, err := json.Marshal(owner)
|
||||
if err != nil {
|
||||
return shim.Error(err.Error())
|
||||
}
|
||||
//Alternatively, build the marble json string manually if you don't want to us$
|
||||
//walletJSONasString := `{"docType":"Wallet", "id": "` + "walletType + `", "s$
|
||||
//walletJSONasBytes := []byte(str)
|
||||
|
||||
// === Save user to state ===
|
||||
err = stub.PutState(userId, ownerJSONasBytes)
|
||||
if err != nil {
|
||||
return shim.Error(err.Error())
|
||||
}
|
||||
|
||||
// ==== Index the wallet to enable type-based range queries, e.g. return all $
|
||||
// An 'index' is a normal key/value entry in state.
|
||||
// The key is a composite key, with the elements that you want to range query$
|
||||
// In our case, the composite key is based on indexName~typeWallet~id.
|
||||
// This will enable very efficient state range queries based on composite key$
|
||||
indexName := "userAssociation~userId"
|
||||
ownerAssociationIdIndexKey, err := stub.CreateCompositeKey(indexName, []string{owner.UserAssociation, owner.UserId})
|
||||
if err != nil {
|
||||
return shim.Error(err.Error())
|
||||
}
|
||||
// Save index entry to state. Only the key name is needed, no need to store a$
|
||||
// Note - passing a 'nil' value will effectively delete the key from state, t$
|
||||
value := []byte{0x00}
|
||||
stub.PutState(ownerAssociationIdIndexKey, value)
|
||||
|
||||
// ==== User saved and indexed. Return success ====
|
||||
fmt.Println("- end init user")
|
||||
return shim.Success(nil)
|
||||
}
|
||||
|
||||
|
||||
//===============================================
|
||||
// readUser - read a user from chaincode state
|
||||
//===============================================
|
||||
func (t *SimpleChaincode) readUser(stub shim.ChaincodeStubInterface, args []string) pb.Response {
|
||||
var userId, jsonResp string
|
||||
var err error
|
||||
|
||||
if len(args) != 1 {
|
||||
return shim.Error("Incorrect number of arguments. Expecting name of the user to query")
|
||||
}
|
||||
|
||||
userId = args[0]
|
||||
valAsbytes, err := stub.GetState(userId) //get the wallet from chaincode state
|
||||
if err != nil {
|
||||
jsonResp = "{\"Error\":\"Failed to get state for " + userId + "\"}"
|
||||
return shim.Error(jsonResp)
|
||||
} else if valAsbytes == nil {
|
||||
jsonResp = "{\"Error\":\"Wallet does not exist: " + userId + "\"}"
|
||||
return shim.Error(jsonResp)
|
||||
}
|
||||
|
||||
return shim.Success(valAsbytes)
|
||||
}
|
||||
|
||||
|
||||
// ==================================================
|
||||
// delete - remove a wallet key/value pair from state
|
||||
// ==================================================
|
||||
func (t *SimpleChaincode) deleteUser(stub shim.ChaincodeStubInterface, args []string) pb.Response {
|
||||
var jsonResp string
|
||||
var ownerJSON owner
|
||||
if len(args) != 1 {
|
||||
return shim.Error("Incorrect number of arguments. Expecting 1")
|
||||
}
|
||||
userId := args[0]
|
||||
|
||||
// to maintain the color~name index, we need to read the marble first and get its color
|
||||
valAsbytes, err := stub.GetState(userId) //get the marble from chaincode state
|
||||
if err != nil {
|
||||
jsonResp = "{\"Error\":\"Failed to get state for " + userId + "\"}"
|
||||
return shim.Error(jsonResp)
|
||||
} else if valAsbytes == nil {
|
||||
jsonResp = "{\"Error\":\"User does not exist: " + userId + "\"}"
|
||||
return shim.Error(jsonResp)
|
||||
}
|
||||
|
||||
err = json.Unmarshal([]byte(valAsbytes), &ownerJSON)
|
||||
|
||||
if err != nil {
|
||||
jsonResp = "{\"Error\":\"Failed to get state for " + userId + "\"}"
|
||||
return shim.Error(jsonResp)
|
||||
} else if valAsbytes == nil {
|
||||
jsonResp = "{\"Error\":\"User does not exist: " + userId + "\"}"
|
||||
return shim.Error(jsonResp)
|
||||
}
|
||||
|
||||
err = json.Unmarshal([]byte(valAsbytes), &ownerJSON)
|
||||
if err != nil {
|
||||
jsonResp = "{\"Error\":\"Failed to decode JSON of: " + userId + "\"}"
|
||||
return shim.Error(jsonResp)
|
||||
}
|
||||
|
||||
err = stub.DelState(userId) //remove the owner from chaincode state
|
||||
if err != nil {
|
||||
return shim.Error("Failed to delete state:" + err.Error())
|
||||
}
|
||||
|
||||
// maintain the index
|
||||
indexName := "userAssociation~userId"
|
||||
ownerAssociationIdIndexKey, err := stub.CreateCompositeKey(indexName, []string{ownerJSON.UserAssociation, ownerJSON.UserId})
|
||||
if err != nil {
|
||||
return shim.Error(err.Error())
|
||||
}
|
||||
|
||||
// Delete index entry to state.
|
||||
err = stub.DelState(ownerAssociationIdIndexKey)
|
||||
if err != nil {
|
||||
return shim.Error("Failed to delete state:" + err.Error())
|
||||
}
|
||||
return shim.Success(nil)
|
||||
}
|
||||
|
||||
|
||||
func (t *SimpleChaincode) initWallet(stub shim.ChaincodeStubInterface, args []string) pb.Response {
|
||||
var err error
|
||||
|
||||
if len(args) != 3 {
|
||||
return shim.Error("Incorrect number of arguments. Expecting 4")
|
||||
}
|
||||
|
||||
// ==== Input sanitation ====
|
||||
fmt.Println("- start init wallet")
|
||||
if len(args[0]) <= 0 {
|
||||
return shim.Error("1st argument must be a non-empty string")
|
||||
}
|
||||
if len(args[1]) <= 0 {
|
||||
return shim.Error("2nd argument must be a non-empty string")
|
||||
}
|
||||
if len(args[2]) <= 0 {
|
||||
return shim.Error("3rd argument must be a non-empty string")
|
||||
}
|
||||
//if len(args[3]) <= 0 {
|
||||
// return shim.Error("4th argument must be a non-empty string")
|
||||
//}
|
||||
//if len(args[4]) <= 0 {
|
||||
// return shim.Error("4th argument must be a non-empty string")
|
||||
//}
|
||||
|
||||
walletId := args[0]
|
||||
walletType := strings.ToLower(args[1])
|
||||
owner := strings.ToLower(args[2])
|
||||
sold := 0
|
||||
//authorized_by_association := args[4]
|
||||
|
||||
if err != nil {
|
||||
return shim.Error("3rd argument must be a numeric string")
|
||||
}
|
||||
|
||||
//if owner.UserAssociation != authorized_by_association {
|
||||
// return shim.Error("The association '" + authorized_by_association + "'cannot authorize creation for '" + owner.UserId + "'.")
|
||||
//}
|
||||
|
||||
// ==== Check if user already exists ====
|
||||
ownerAsBytes, err := stub.GetState(owner)
|
||||
if err != nil {
|
||||
return shim.Error("Failed to get owner: " + err.Error())
|
||||
} else if ownerAsBytes == nil {
|
||||
fmt.Println("This user doesn't exists: " + owner)
|
||||
return shim.Error("This user doesn't exists: " + owner)
|
||||
}
|
||||
|
||||
// ==== Check if wallet already exists ====
|
||||
walletAsBytes, err := stub.GetState(walletId)
|
||||
if err != nil {
|
||||
return shim.Error("Failed to get wallet: " + err.Error())
|
||||
} else if walletAsBytes != nil {
|
||||
fmt.Println("This wallet already exists: " + walletId)
|
||||
return shim.Error("This wallet already exists: " + walletId)
|
||||
}
|
||||
|
||||
// ==== Create wallet object and marshal to JSON ====
|
||||
objectType := "wallet"
|
||||
wallet := &wallet{objectType, walletId, walletType, sold, owner}
|
||||
walletJSONasBytes, err := json.Marshal(wallet)
|
||||
if err != nil {
|
||||
return shim.Error(err.Error())
|
||||
}
|
||||
|
||||
//Alternatively, build the marble json string manually if you don't want to use struct marshalling
|
||||
//walletJSONasString := `{"docType":"Wallet", "id": "` + "walletType + `", "sold": `, strconv.Itoa(size) , `"owner": "` + owner + `"}`
|
||||
//walletJSONasBytes := []byte(str)
|
||||
|
||||
// === Save wallet to state ===
|
||||
err = stub.PutState(walletId, walletJSONasBytes)
|
||||
if err != nil {
|
||||
return shim.Error(err.Error())
|
||||
}
|
||||
|
||||
// ==== Index the wallet to enable type-based range queries, e.g. return all clients wallets ====
|
||||
// An 'index' is a normal key/value entry in state.
|
||||
// The key is a composite key, with the elements that you want to range query on listed first.
|
||||
// In our case, the composite key is based on indexName~typeWallet~id.
|
||||
// This will enable very efficient state range queries based on composite keys matching indexName~type~*
|
||||
indexName := "typeWallet~id"
|
||||
walletTypeNameIndexKey, err := stub.CreateCompositeKey(indexName, []string{wallet.WalletType, wallet.Id})
|
||||
if err != nil {
|
||||
return shim.Error(err.Error())
|
||||
}
|
||||
|
||||
// Save index entry to state. Only the key name is needed, no need to store a duplicate copy of the marble.
|
||||
// Note - passing a 'nil' value will effectively delete the key from state, therefore we pass null character as value
|
||||
value := []byte{0x00}
|
||||
stub.PutState(walletTypeNameIndexKey, value)
|
||||
|
||||
// ==== Wallet saved and indexed. Return success ====
|
||||
fmt.Println("- end init wallet")
|
||||
return shim.Success(nil)
|
||||
}
|
||||
|
||||
|
||||
// ===============================================
|
||||
// readWallet - read a wallet from chaincode state
|
||||
// ===============================================
|
||||
func (t *SimpleChaincode) readWallet(stub shim.ChaincodeStubInterface, args []string) pb.Response {
|
||||
var id, jsonResp string
|
||||
var err error
|
||||
|
||||
if len(args) != 1 {
|
||||
return shim.Error("Incorrect number of arguments. Expecting name of the wallet to query")
|
||||
}
|
||||
|
||||
id = args[0]
|
||||
valAsbytes, err := stub.GetState(id) //get the wallet from chaincode state
|
||||
if err != nil {
|
||||
jsonResp = "{\"Error\":\"Failed to get state for " + id + "\"}"
|
||||
return shim.Error(jsonResp)
|
||||
} else if valAsbytes == nil {
|
||||
jsonResp = "{\"Error\":\"Wallet does not exist: " + id + "\"}"
|
||||
return shim.Error(jsonResp)
|
||||
}
|
||||
|
||||
return shim.Success(valAsbytes)
|
||||
}
|
||||
|
||||
// ==================================================
|
||||
// delete - remove a wallet key/value pair from state
|
||||
// ==================================================
|
||||
func (t *SimpleChaincode) deleteWallet(stub shim.ChaincodeStubInterface, args []string) pb.Response {
|
||||
var jsonResp string
|
||||
var walletJSON wallet
|
||||
if len(args) != 1 {
|
||||
return shim.Error("Incorrect number of arguments. Expecting 1")
|
||||
}
|
||||
Id := args[0]
|
||||
|
||||
// to maintain the color~name index, we need to read the marble first and get its color
|
||||
valAsbytes, err := stub.GetState(Id) //get the marble from chaincode state
|
||||
if err != nil {
|
||||
jsonResp = "{\"Error\":\"Failed to get state for " + Id + "\"}"
|
||||
return shim.Error(jsonResp)
|
||||
} else if valAsbytes == nil {
|
||||
jsonResp = "{\"Error\":\"Wallet does not exist: " + Id + "\"}"
|
||||
return shim.Error(jsonResp)
|
||||
}
|
||||
|
||||
err = json.Unmarshal([]byte(valAsbytes), &walletJSON)
|
||||
|
||||
if err != nil {
|
||||
jsonResp = "{\"Error\":\"Failed to get state for " + Id + "\"}"
|
||||
return shim.Error(jsonResp)
|
||||
} else if valAsbytes == nil {
|
||||
jsonResp = "{\"Error\":\"Wallet does not exist: " + Id + "\"}"
|
||||
return shim.Error(jsonResp)
|
||||
}
|
||||
|
||||
err = json.Unmarshal([]byte(valAsbytes), &walletJSON)
|
||||
if err != nil {
|
||||
jsonResp = "{\"Error\":\"Failed to decode JSON of: " + Id + "\"}"
|
||||
return shim.Error(jsonResp)
|
||||
}
|
||||
|
||||
err = stub.DelState(Id) //remove the wallet from chaincode state
|
||||
if err != nil {
|
||||
return shim.Error("Failed to delete state:" + err.Error())
|
||||
}
|
||||
|
||||
// maintain the index
|
||||
indexName := "typeWallet~id"
|
||||
walletTypeNameIndexKey, err := stub.CreateCompositeKey(indexName, []string{walletJSON.WalletType, walletJSON.Id})
|
||||
if err != nil {
|
||||
return shim.Error(err.Error())
|
||||
}
|
||||
|
||||
// Delete index entry to state.
|
||||
err = stub.DelState(walletTypeNameIndexKey)
|
||||
if err != nil {
|
||||
return shim.Error("Failed to delete state:" + err.Error())
|
||||
}
|
||||
return shim.Success(nil)
|
||||
}
|
||||
|
||||
|
||||
// ===========================================================
|
||||
// transfer a wallet by setting a new owner name on the wallet
|
||||
// ===========================================================
|
||||
func (t *SimpleChaincode) transferWallet(stub shim.ChaincodeStubInterface, args []string) pb.Response {
|
||||
|
||||
// 0 1
|
||||
// "name", "bob"
|
||||
if len(args) < 2 {
|
||||
return shim.Error("Incorrect number of arguments. Expecting 2")
|
||||
}
|
||||
|
||||
walletId := args[0]
|
||||
newOwner := strings.ToLower(args[1])
|
||||
fmt.Println("- start transferWallet ", walletId, newOwner)
|
||||
|
||||
// ==== Check if user already exists ====
|
||||
ownerAsBytes, err := stub.GetState(newOwner)
|
||||
if err != nil {
|
||||
return shim.Error("Failed to get user: " + err.Error())
|
||||
} else if ownerAsBytes == nil {
|
||||
fmt.Println("This user doesn't exists: " + newOwner)
|
||||
return shim.Error("This user doesn't exists: " + newOwner)
|
||||
}
|
||||
|
||||
|
||||
walletAsBytes, err := stub.GetState(walletId)
|
||||
|
||||
if err != nil {
|
||||
return shim.Error("Failed to get wallet:" + err.Error())
|
||||
} else if walletAsBytes == nil {
|
||||
return shim.Error("wallet does not exist")
|
||||
}
|
||||
|
||||
walletToTransfer := wallet{}
|
||||
err = json.Unmarshal(walletAsBytes, &walletToTransfer) //unmarshal it aka JSON
|
||||
if err != nil {
|
||||
return shim.Error(err.Error())
|
||||
}
|
||||
walletToTransfer.Owner = newOwner //change the owner
|
||||
|
||||
walletJSONasBytes, _ := json.Marshal(walletToTransfer)
|
||||
err = stub.PutState(walletId, walletJSONasBytes) //rewrite the wallet
|
||||
if err != nil {
|
||||
return shim.Error(err.Error())
|
||||
}
|
||||
|
||||
fmt.Println("- end transferWallet (success)")
|
||||
return shim.Success(nil)
|
||||
}
|
||||
|
||||
|
||||
// ===========================================================
|
||||
// set a sold of a wallet by setting a new owner name on the wallet
|
||||
// ===========================================================
|
||||
func (t *SimpleChaincode) setSoldOnWallet(stub shim.ChaincodeStubInterface, args []string) pb.Response {
|
||||
|
||||
// 0 1
|
||||
// "name", "bob"
|
||||
if len(args) < 2 {
|
||||
return shim.Error("Incorrect number of arguments. Expecting 2")
|
||||
}
|
||||
|
||||
walletId := args[0]
|
||||
newSold, err := strconv.Atoi(args[1])
|
||||
fmt.Println("- start setSoldOnWallet ", walletId, newSold)
|
||||
|
||||
// ==== Check if wallet already exists ====
|
||||
walletAsBytes, err := stub.GetState(walletId)
|
||||
if err != nil {
|
||||
return shim.Error("Failed to get wallet: " + err.Error())
|
||||
} else if walletAsBytes == nil {
|
||||
fmt.Println("This wallet doesn't exists: " + walletId)
|
||||
return shim.Error("This wallet doesn't exists: " + walletId)
|
||||
}
|
||||
|
||||
walletToSet := wallet{}
|
||||
err = json.Unmarshal(walletAsBytes, &walletToSet) //unmarshal it aka JSON
|
||||
if err != nil {
|
||||
return shim.Error(err.Error())
|
||||
}
|
||||
walletToSet.Sold = newSold //change the sold
|
||||
|
||||
walletJSONasBytes, _ := json.Marshal(walletToSet)
|
||||
err = stub.PutState(walletId, walletJSONasBytes) //rewrite the wallet
|
||||
if err != nil {
|
||||
return shim.Error(err.Error())
|
||||
}
|
||||
fmt.Println("- end setSoldOnWallet (success)")
|
||||
return shim.Success(nil)
|
||||
}
|
||||
|
||||
|
||||
// Transaction makes payment of X units from A to B
|
||||
func (t *SimpleChaincode) transaction(stub shim.ChaincodeStubInterface, args []string) pb.Response {
|
||||
|
||||
if len(args) != 3 {
|
||||
return shim.Error("Incorrect number of arguments. Expecting 3")
|
||||
}
|
||||
|
||||
walletId := args[0]
|
||||
walletTargetId := args[1]
|
||||
transactionValue, err := strconv.Atoi(args[2])
|
||||
|
||||
fmt.Println("- start transaction ", walletId, transactionValue)
|
||||
|
||||
// ==== Check if wallet already exists ====
|
||||
walletAsBytes, err := stub.GetState(walletId)
|
||||
if err != nil {
|
||||
return shim.Error("Failed to get wallet: " + err.Error())
|
||||
} else if walletAsBytes == nil {
|
||||
fmt.Println("This wallet doesn't exists: " + walletId)
|
||||
return shim.Error("This wallet doesn't exists: " + walletId)
|
||||
}
|
||||
|
||||
// ==== Check if wallet already exists ====
|
||||
walletTargetAsBytes, err := stub.GetState(walletTargetId)
|
||||
if err != nil {
|
||||
return shim.Error("Failed to get wallet: " + err.Error())
|
||||
} else if walletTargetAsBytes == nil {
|
||||
fmt.Println("This wallet doesn't exists: " + walletTargetId)
|
||||
return shim.Error("This wallet doesn't exists: " + walletTargetId)
|
||||
}
|
||||
|
||||
walletSoldToSet := wallet{}
|
||||
err = json.Unmarshal(walletAsBytes, &walletSoldToSet) //unmarshal it aka JSON
|
||||
if err != nil {
|
||||
return shim.Error(err.Error())
|
||||
}
|
||||
|
||||
walletSoldToSet.Sold = walletSoldToSet.Sold - transactionValue //change the sold
|
||||
|
||||
walletJSONasBytes, _ := json.Marshal(walletSoldToSet)
|
||||
err = stub.PutState(walletId, walletJSONasBytes) //rewrite the wallet
|
||||
if err != nil {
|
||||
return shim.Error(err.Error())
|
||||
}
|
||||
|
||||
walletTargetSoldToSet := wallet{}
|
||||
err = json.Unmarshal(walletTargetAsBytes, &walletTargetSoldToSet) //unmarshal it aka JSON
|
||||
if err != nil {
|
||||
return shim.Error(err.Error())
|
||||
}
|
||||
|
||||
walletTargetSoldToSet.Sold = walletTargetSoldToSet.Sold + transactionValue
|
||||
|
||||
walletTargetJSONasBytes, _ := json.Marshal(walletTargetSoldToSet)
|
||||
err = stub.PutState(walletTargetId, walletTargetJSONasBytes) //rewrite the wallet
|
||||
if err != nil {
|
||||
return shim.Error(err.Error())
|
||||
}
|
||||
|
||||
fmt.Println("- end setSoldOnWallet (success)")
|
||||
return shim.Success(nil)
|
||||
}
|
||||
|
||||
|
||||
func main() {
|
||||
err := shim.Start(new(SimpleChaincode))
|
||||
if err != nil {
|
||||
fmt.Printf("Error starting Simple chaincode: %s", err)
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue