链码:使用 Go 或 node.js 开发,运行在 Docker 容器中的 peer 上,实现了一个规定的接口,使用 Java 等其他语言调用,链码通常处理有网络成员同意的业务逻辑,因此他可能被认为是一种“智能合约”,由链码创建的状态只做用于该链码,不能由另一个链码直接访问,在同一个网络中给定适当的权限,链码可能会调用另一个链码来访问其状态。

两个角色:
1、链码开发者:链码开发者 Chaincode for Developers
2、链码操作者:链码部署和调用者 Chaincode for Operators

下面通过开发者的角度探索链码
Chaincode Shim API

1、每一个链码程序必须实现 Chaincode interface

链码编写示例:
1、首先写包名和导入库

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 {
}

2、然后是初始化方法

// Init is called during chaincode instantiation to initialize any data.
func (t *SimpleAsset) Init(stub shim.ChaincodeStubInterface) peer.Response {

}

初始化方法中,编写初始化代码,这个例子是检查参数数量,API:ChaincodeStubInterface.GetStringArgs

// Init is called during chaincode instantiation to initialize any
// data. Note that chaincode upgrade also calls this function to reset
// or to migrate data, so be careful to avoid a scenario where you
// inadvertently clobber your ledger's data!
func (t *SimpleAsset) Init(stub shim.ChaincodeStubInterface) peer.Response {
  // Get the args from the transaction proposal
  args := stub.GetStringArgs()
  if len(args) != 2 {
    return shim.Error("Incorrect arguments. Expecting a key and a value")
  }
}

将传递进来的参数写入,然后返回初始化成功,内容放入到 Init 方法中

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)

3、Invoking the Chaincode,编写调用方法

// Invoke is called per transaction on the chaincode. Each transaction is
// either a 'get' or a 'set' on the asset created by Init function. The 'set'
// method may create a new asset by specifying a new key-value pair.
func (t *SimpleAsset) Invoke(stub shim.ChaincodeStubInterface) peer.Response {

}

使用 ChaincodeStubInterface 获取调用参数

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))

4、编写在 Invoke 中调用的方法

// 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
}
  • Fabric
    8 引用
  • 区块链

    区块链就是一条信息多方确认并存储于多个地方。 学习区块链,拥抱未来吧!

    63 引用 • 8 回帖 • 1 关注
  • 智能合约

    智能合约(英语:Smart contract )是一种旨在以信息化方式传播、验证或执行合同的计算机协议。

    20 引用 • 9 回帖
感谢    赞同    分享    收藏    关注    反对    举报    ...