Hyperledger Fabric2.2.X基于fabric-contract-api-go编写go链码 教程(一)开始


前言

本文来自`fabric-contract-api-go`api手册,基于Hyperledger Fabric2.2.2开发

提示:以下是本篇文章正文内容,下面案例可供参考

声明合约

The first thing we will do here is declare a contract for use in our chaincode.
所有合约第一件事就是继承或者实现接口
implement the contractapi.ContractInterface
embed the contractapi.Contract struct within your own contract

package main
import (
    "errors"
    "fmt"
    "github.com/hyperledger/fabric-contract-api-go/contractapi"
)
// SimpleContract contract for handling writing and reading from the world state
type SimpleContract struct {
    contractapi.Contract
}

编写合约

规则

参数类型说明

交易合约的第一个参数必须type *contractapi.TransactionContextor contractapi.TransactionContextInterface

返回值个数与说明

编写

Create

当交易时需要提供交易上下文,但是我们采用contractapi.TransactionContext提供的默认事务上下文,因为它提供了与世界状态进行交互的所有必要功能。也可以使用contractapi.TransactionContextInterface

// 写入数据样例函数,其中ctx.GetStub().就相当于stub.更进一层的封装
// Create adds a new key with value to the world state
func (sc *SimpleContract) Create(ctx contractapi.TransactionContextInterface, 
key string, value string) error {
    existing, err := ctx.GetStub().GetState(key)
    if err != nil {
        return errors.New("Unable to interact with world state")
    }
    if existing != nil {
        return fmt.Errorf("Cannot create world state pair with key %s. Already 
exists", key)
    }
    err = ctx.GetStub().PutState(key, []byte(value))
    if err != nil {
        return errors.New("Unable to interact with world state")
    }
    return nil
}

update

// 与create区别在于existng == nil
// Update changes the value with key in the world state
func (sc *SimpleContract) Update(ctx contractapi.TransactionContextInterface, 
key string, value string) error {
    existing, err := ctx.GetStub().GetState(key)
    if err != nil {
        return errors.New("Unable to interact with world state") 
 }
    if existing == nil {
        return fmt.Errorf("Cannot update world state pair with key %s. Does not 
exist", key)
    }
    err = ctx.GetStub().PutState(key, []byte(value))
    if err != nil {
        return errors.New("Unable to interact with world state")
    }
    return nil
}

read

// Read returns the value at key in the world state
func (sc *SimpleContract) Read(ctx contractapi.TransactionContextInterface, key 
string) (string, error) {
    existing, err := ctx.GetStub().GetState(key)
    if err != nil {
        return "", errors.New("Unable to interact with world state")
    }
    if existing == nil {
        return "", fmt.Errorf("Cannot read world state pair with key %s. Does 
not exist", key)
    }
    return string(existing), nil
}

在链码中使用合约

package main

import (
    "errors"
    "fmt"

    "github.com/hyperledger/fabric-contract-api-go/contractapi"
)

// SimpleContract contract for handling writing and reading from the world state
type SimpleContract struct {
    contractapi.Contract
}

// Create adds a new key with value to the world state
func (sc *SimpleContract) Create(ctx contractapi.TransactionContextInterface, key string, value string) error {
    existing, err := ctx.GetStub().GetState(key)

    if err != nil {
        return errors.New("Unable to interact with world state")
    }

    if existing != nil {
        return fmt.Errorf("Cannot create world state pair with key %s. Already exists", key)
    }

    err = ctx.GetStub().PutState(key, []byte(value))

    if err != nil {
        return errors.New("Unable to interact with world state")
    }

    return nil
}

// Update changes the value with key in the world state
func (sc *SimpleContract) Update(ctx contractapi.TransactionContextInterface, key string, value string) error {
    existing, err := ctx.GetStub().GetState(key)

    if err != nil {
        return errors.New("Unable to interact with world state")
    }

    if existing == nil {
        return fmt.Errorf("Cannot update world state pair with key %s. Does not exist", key)
    }

    err = ctx.GetStub().PutState(key, []byte(value))

    if err != nil {
        return errors.New("Unable to interact with world state")
    }

    return nil
}

// Read returns the value at key in the world state
func (sc *SimpleContract) Read(ctx contractapi.TransactionContextInterface, key string) (string, error) {
    existing, err := ctx.GetStub().GetState(key)

    if err != nil {
        return "", errors.New("Unable to interact with world state")
    }

    if existing == nil {
        return "", fmt.Errorf("Cannot read world state pair with key %s. Does not exist", key)
    }

    return string(existing), nil
}
package main

import (
    "github.com/hyperledger/fabric-contract-api-go/contractapi"
)

func main() {
}

链码必须满足shim.Chaincode接口, 要有两个函数 InitInvoke 。但幸运的是,您不需要编写这些代码,因为contractapi提供了一种根据一个或多个合同生成链码的方法。要创建一个链码,请在main函数中添加以下内容:

simpleContract := new(SimpleContract)
cc, err := contractapi.NewChaincode(simpleContract)
if err != nil {
    panic(err.Error())
}
//start以方便合约能够调用
if err := cc.Start(); err != nil {
    panic(err.Error())
}
package main

import (
    "github.com/hyperledger/fabric-contract-api-go/contractapi"
)

func main() {
    simpleContract := new(SimpleContract)

    cc, err := contractapi.NewChaincode(simpleContract)

    if err != nil {
        panic(err.Error())
    }

    if err := cc.Start(); err != nil {
        panic(err.Error())
    }
}

调用合约

peer chaincode instantiate -n mycc -v 0 -c '{"Args":[]}' -C myc
peer chaincode invoke -n mycc -c '{"Args":["Create", "KEY_1", "VALUE_1"]}' -C myc
peer chaincode invoke -n mycc -c '{"Args":["Update", "KEY_1", "VALUE_2"]}' -C myc
peer chaincode query -n mycc -c '{"Args":["Read", "KEY_1"]}' -C myc

参考文献:官方api教程

  • 2
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值