zoukankan      html  css  js  c++  java
  • 使用GO开发ChainCode

    本来不会GO,最近突击学了些GO的基础,就开始搞chaincode了。

    首先给大家推荐一个非常好的Hyperldeger Fabric项目 marble:https://github.com/ibm-blockchain/marbles/

    这次的项目,有很多地方借鉴了这个marble。

    GO的包的引入

    package main

    import (
    //"bytes"
    "encoding/json"
    "fmt"
    "strconv"
    //"strings"
    "github.com/hyperledger/fabric/core/chaincode/shim"
    pb "github.com/hyperledger/fabric/protos/peer"
    "time"
    )

    这些是经常用的包

    Main

    main是入口

    // SimpleChaincode example simple Chaincode implementation
    type SimpleChaincode struct {
    }

    // ===================================================================================
    // Main
    // ===================================================================================
    func main() {
    err := shim.Start(new(SimpleChaincode))
    if err != nil {
    fmt.Printf("Error starting Simple chaincode: %s", err)
    }
    }

    Init

    chaincode 包含一个Init和一个Invoke函数。

    Init是初始化的地方,还需要注意以后版本升级时能够通用

    // Init initializes chaincode
    // ===========================
    func (t *SimpleChaincode) Init(stub shim.ChaincodeStubInterface) pb.Response {
    return shim.Success(nil)
    }

    Invoke

    所有的调用都进入到这里,然后分发出去。

    // Invoke - Our entry point 
    // ========================================
    func (t *SimpleChaincode) Invoke(stub shim.ChaincodeStubInterface) pb.Response {
    function, args := stub.GetFunctionAndParameters()
    fmt.Println("invoke is running " + function)

    // Handle different functions
    if function == "initProvider" { // create Provider
    return t.initProvider(stub, args)
    } else if function == "initBeneficiary" { // create beneficiary
    return t.initBeneficiary(stub, args)

    fmt.Println("invoke did not find func: " + function) //error
    return shim.Error("Received unknown function ")
    }

    数据定义

    强烈建议,每个数据都增加一个额外的ObjectType字段,以便更好的查询(rich query)

    ObjectType总是被保存为数据名称(Provider)

    如果是复杂字段,则需要将首字母大写,不然序列化的时候回丢失(好像是被认为private)

    type Provider struct {
    ObjectType string `json:"ObjectType"` //docType is used to distinguish the various types of objects in state database
    Name string `json:"Name"`
    Id string `json:"Id"`
    Eligibility bool `json:"Eligibility"`
    }

     关键语法

    //序列化


    providerJSONasBytes, err := json.Marshal(provider)

    // 指定Id,保存

    err = stub.PutState(id, providerJSONasBytes)

    //根据Id查询

    providerAsBytes, err := stub.GetState(id)

    //反序列化

    err = json.Unmarshal(providerAsBytes, &provider) //unmarshal it aka JSON.parse()

    Selector查询

    queryString := fmt.Sprintf("{"selector":{"ObjectType":"ServiceTransaction","ServiceCode":"%s","RideId":"%s"}}", "T01", ride.Id)

    resultsIterator, err := stub.GetQueryResult(queryString)

    // loop all results
    for resultsIterator.HasNext() {
    queryResponse, err := resultsIterator.Next()

     由于一些原因不能上传代码。如果有需要,请留下联系方式。

  • 相关阅读:
    POJ 2942 圆桌骑士 (点双学习笔记)
    洛谷P3563 POI Polarization
    通过集群的方式解决基于MQTT协议的RabbitMQ消息收发
    在WebAPI中调用其他WebAPI
    将WebAPI发布到本地服务器与远程服务器
    利用RabbitMQ、MySQL实现超大用户级别的消息在/离线收发
    C#程序调用cmd.exe执行命令
    C#调用python
    Trixbox下SIP TRUNK的基本设定
    连接两台asterisk服务器
  • 原文地址:https://www.cnblogs.com/13579net/p/9024246.html
Copyright © 2011-2022 走看看