fabric链码
链码是什么
链码是一个程序,可以使用 Go 、node.js 、 或者 Java 来实现预定义的接口。链码运行在一个和背书节点进程相 隔离的安全的容器中。通过应用程序提交交易来初始化链码和管理账本状态。
一个链码一般用来处理由网络中成员一致认可的商业逻辑,所以可以认为它就是一个“智能合约”。 链码创建的状态仅限于该链码范围内,其他链码不能直接访问。但是在同一个网络中,通过合理 的授权,链码可以让其他链码访问的它状态数据。
下面以go语言进行实验:
引入链码必要的依赖
package main
import (
"fmt"
"github.com/hyperledger/fabric/core/chaincode/shim"
"github.com/hyperledger/fabric/protos/peer"
)
// SimpleAsset implements a simple chaincode to manage an asset
type SimpleAsset struct {
}
初始化链码
func (t *SimpleAsset) Init(stub shim.ChaincodeStubInterface) peer.Response {
// 从提案中获取传入的参数
args := stub.GetStringArgs()
if len(args) != 2 {
return shim.Error("Incorrect arguments. Expecting a key and a value")
}
// 将kv更新到世界状态
err := stub.PutState(args[0], []byte(args[1]))
if err != nil {
return shim.Error(fmt.Sprintf("Failed to create asset: %s", args[0]))
}
return shim.Success(nil)
}
调用链码
func (t *SimpleAsset) Invoke(stub shim.ChaincodeStubInterface) peer.Response {
// Invoke 函数的参数是将要调用的链码应用程序的函数名。
fn, args := stub.GetFunctionAndParameters()
var result string
var err error
if fn == "set" {
result, err = set(stub, args)
} else {
result, err = get(stub, args)
}
if err != nil {
return shim.Error(err.Error())
}
// Return the result as success payload
return shim.Success([]byte(result))
}
实现链码应用程序
// Set stores the asset (both key and value) on the ledger. If the key exists,
// it will override the value with the new one
func set(stub shim.ChaincodeStubInterface, args []string) (string, error) {
if len(args) != 2 {
return "", fmt.Errorf("Incorrect arguments. Expecting a key and a value")
}
err := stub.PutState(args[0], []byte(args[1]))
if err != nil {
return "", fmt.Errorf("Failed to set asset: %s", args[0])
}
return args[1], nil
}
// Get returns the value of the specified asset key
func get(stub shim.ChaincodeStubInterface, args []string) (string, error) {
if len(args) != 1 {
return "", fmt.Errorf("Incorrect arguments. Expecting a key")
}
value, err := stub.GetState(args[0])
if err != nil {
return "", fmt.Errorf("Failed to get asset: %s with error: %s", args[0], err)
}
if value == nil {
return "", fmt.Errorf("Asset not found: %s", args[0])
}
return string(value), nil
}