Netkiller Blockchain 手札
作者正在找工作,联系方式 13113668890
Mr. Neo Chan, 陈景峯(BG7NYT)
中国广东省深圳市望海路半岛城邦三期
518067
+86 13113668890<netkiller@msn.com>
文档始创于2018-02-10
版权 © 2018 Netkiller(Neo Chan). All rights reserved.
版权声明
转载请与作者联系,转载时请务必标明文章原始出处和作者信息及本声明。
|
|
|
|
2.10.6. 资产上链的 Hyperledger Fabic 链码
我们希望资产上链适用于任何领域,后面也方便将业务拓展。所以我实现了一个万能合约。以不变应万变。
package main import ( "fmt" "github.com/hyperledger/fabric/core/chaincode/shim" pb "github.com/hyperledger/fabric/protos/peer" ) type SmartContract struct {} func (s *SmartContract) Init(stub shim.ChaincodeStubInterface) pb.Response { return shim.Success(nil) } func (s *SmartContract) Query(stub shim.ChaincodeStubInterface) pb.Response { return shim.Success(nil) } func (s *SmartContract) Invoke(stub shim.ChaincodeStubInterface) pb.Response { // Retrieve the requested Smart Contract function and arguments function, args := stub.GetFunctionAndParameters() // Route to the appropriate handler function to interact with the ledger appropriately if function == "create" { return s.create(stub, args) } else if function == "find" { return s.find(stub, args) } else if function == "update" { return s.update(stub, args) } else if function == "delete" { return s.delete(stub, args) } return shim.Error("Invalid Smart Contract function name.") } func (s *SmartContract) create(stub shim.ChaincodeStubInterface, args []string) pb.Response { if len(args) != 2 { return shim.Error("Incorrect number of arguments. Expecting 2") } _key := args[0] _data := args[1] if(_data == ""){ return shim.Error("Incorrect string of data") } existAsBytes,err := stub.GetState(_key) if string(existAsBytes) != "" { fmt.Println("Failed to create account, Duplicate key.") return shim.Error("Failed to create account, Duplicate key.") } err = stub.PutState(_key, []byte(_data)) if err != nil { return shim.Error(err.Error()) } fmt.Printf("create %s %s \n", _key, string(_data)) return shim.Success(nil) } func (s *SmartContract) find(stub shim.ChaincodeStubInterface, args []string) pb.Response { if len(args) != 1 { return shim.Error("Incorrect number of arguments. Expecting 1") } _key := args[0] _data, err := stub.GetState(_key) if err != nil { return shim.Error(err.Error()) } if string(_data) == "" { return shim.Error("The key isn't exist.") }else{ fmt.Printf("query %s %s \n", _key, string(_data)) } return shim.Success(_data) } func (s *SmartContract) update(stub shim.ChaincodeStubInterface, args []string) pb.Response { if len(args) != 2 { return shim.Error("Incorrect number of arguments. Expecting 2") } _key := args[0] _data := args[1] if(_data == ""){ return shim.Error("Incorrect string of data") } err := stub.PutState(_key, []byte(_data)) if err != nil { return shim.Error(err.Error()) }else{ fmt.Printf("update %s %s \n", _key, string(_data)) } return shim.Success(nil) } // Deletes an entity from state func (t *SmartContract) delete(stub shim.ChaincodeStubInterface, args []string) pb.Response { if len(args) != 1 { return shim.Error("Incorrect number of arguments. Expecting 1") } _key := args[0] // Delete the key from the state in ledger err := stub.DelState(_key) if err != nil { return shim.Error("Failed to delete state") } return shim.Success(nil) } func main() { err := shim.Start(new(SmartContract)) if err != nil { fmt.Printf("Error creating new Smart Contract: %s", err) } }
链码有四个函数,分别是创建,查找,更新,删除。
if function == "create" { return s.create(stub, args) // 创建 } else if function == "find" { return s.find(stub, args) // 查找 } else if function == "update" { return s.update(stub, args) // 更新 } else if function == "delete" { return s.delete(stub, args) // 删除 }
上链使用 create 方法,函数有两个参数,一个是 key, 另一个是数据。
key 使用 UUID 存储再数据库和链上,同时 UUID 对应通证的
data 是序列化 byte 数据。例如可以使用 json, hession, msgpack 等序列化后的数据。
err = stub.PutState(_key, []byte(_data))
这个链码考虑到前期产品上市,不确定性因素很多,需要更新和删除等等。后期我们可以在数据中设置一个 status 变量,当 status = false 就不在允许数据的删除和更新。