栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Go语言

fabric链码编写(一):常用接口(以fabcar.go为例)

Go语言 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

fabric链码编写(一):常用接口(以fabcar.go为例)

fabric链码编写思路和常见的API整理:

type SmartContract struct {
	contractapi.Contract
}

contractapi.Contract :关于资产调用的常用接口,很多官方链码都使用了,自己编写链码的时候可以不用,后面的都换成Stub()方法即可

首先需要init方法进行初始化:

func (s *SmartContract) InitLedger(ctx contractapi.TransactionContextInterface) error {
...
}
err = ctx.GetStub().PutState(plan.ID, planJSON)

上面的ctx.GetStub() 相当于 Stub()

PutState() :存入数据库的API

GetState() :读取数据

GetStateByRange: 给定起始和终点,根据这个范围来查询信息

查询之后返回迭代器,GetStateByRange里的hasnext()和next()进行循环,实现功能

链码可以定义各种函数方法与结构体绑定,实现增删改查 不同的功能

下面以官方示例的fabcar.go为例,熟悉链码编写的思路:

package main  //包名一定要是main

import (
	"encoding/json"
	"fmt"
	"strconv"
	"github.com/hyperledger/fabric-contract-api-go/contractapi"  //引入常用接口
)

// SmartContract provides functions for managing a car
// 需要定义一个链码总体的结构体,这个结构体定义了关于资产调用的常用接口
type SmartContract struct {
	contractapi.Contract
}

// Car describes basic details of what makes up a car
//定义car结构体,声明其中的字段(对应car的各种属性)
type Car struct {
	Make   string `json:"make"`
	Model  string `json:"model"`
	Colour string `json:"colour"`
	Owner  string `json:"owner"`
}

// QueryResult structure used for handling result of query
type QueryResult struct {
	Key    string `json:"Key"`
	Record *Car
}

// InitLedger adds a base set of cars to the ledger
// 首先需要init方法进行初始化
func (s *SmartContract) InitLedger(ctx contractapi.TransactionContextInterface) error {
	cars := []Car{
		Car{Make: "Toyota", Model: "Prius", Colour: "blue", Owner: "Tomoko"},
		Car{Make: "Ford", Model: "Mustang", Colour: "red", Owner: "Brad"},
		Car{Make: "Hyundai", Model: "Tucson", Colour: "green", Owner: "Jin Soo"},
		Car{Make: "Volkswagen", Model: "Passat", Colour: "yellow", Owner: "Max"},
		Car{Make: "Tesla", Model: "S", Colour: "black", Owner: "Adriana"},
		Car{Make: "Peugeot", Model: "205", Colour: "purple", Owner: "Michel"},
		Car{Make: "Chery", Model: "S22L", Colour: "white", Owner: "Aarav"},
		Car{Make: "Fiat", Model: "Punto", Colour: "violet", Owner: "Pari"},
		Car{Make: "Tata", Model: "Nano", Colour: "indigo", Owner: "Valeria"},
		Car{Make: "Holden", Model: "Barina", Colour: "brown", Owner: "Shotaro"},
	}

	for i, car := range cars {
		carAsBytes, _ := json.Marshal(car)
		//ctx.GetStub() 相当于 Stub()
		//PutState() : 存入数据库的API
		err := ctx.GetStub().PutState("CAR"+strconv.Itoa(i), carAsBytes)

		if err != nil {
			return fmt.Errorf("Failed to put to world state. %s", err.Error())
		}
	}

	return nil
}

//下面定义各种方法与结构体绑定,实现不同的功能
// 第一个函数方法:createcar() 实现功能:向数据库增加车辆信息
// CreateCar adds a new car to the world state with given details
func (s *SmartContract) CreateCar(ctx contractapi.TransactionContextInterface, carNumber string, make string, model string, colour string, owner string) error {
	car := Car{
		Make:   make,
		Model:  model,
		Colour: colour,
		Owner:  owner,
	}

	carAsBytes, _ := json.Marshal(car)
        //序列化后,存入数据库,使用putstate
	return ctx.GetStub().PutState(carNumber, carAsBytes)
}

//第二个函数方法:querycar() 实现功能:查询车辆信息
// QueryCar returns the car stored in the world state with given id
func (s *SmartContract) QueryCar(ctx contractapi.TransactionContextInterface, carNumber string) (*Car, error) {
	carAsBytes, err := ctx.GetStub().GetState(carNumber)
       //使用getstate获取车辆信息
	if err != nil {
		return nil, fmt.Errorf("Failed to read from world state. %s", err.Error())
	}

	if carAsBytes == nil {
		return nil, fmt.Errorf("%s does not exist", carNumber)
	}

	car := new(Car)
	_ = json.Unmarshal(carAsBytes, car)
     //反序列化后读出数据
	return car, nil
}

//第三个函数方法: queryallcars() 实现功能:查询所有车辆信息
// QueryAllCars returns all cars found in world state
func (s *SmartContract) QueryAllCars(ctx contractapi.TransactionContextInterface) ([]QueryResult, error) {
	startKey := ""
	endKey := ""
        //GetStateByRange: 给定起始和终点,根据这个范围来查询信息
	resultsIterator, err := ctx.GetStub().GetStateByRange(startKey, endKey)

	if err != nil {
		return nil, err
	}
	defer resultsIterator.Close()
        //定义了查询结果的切片
	results := []QueryResult{}
        //查询之后返回迭代器,GetStateByRange里的hasnext()和next()进行循环,实现功能
	for resultsIterator.HasNext() {
		queryResponse, err := resultsIterator.Next()

		if err != nil {
			return nil, err
		}

		car := new(Car)
		_ = json.Unmarshal(queryResponse.Value, car)

		queryResult := QueryResult{Key: queryResponse.Key, Record: car}
		results = append(results, queryResult)
	}

	return results, nil
}

//第四个函数方法:ChangeCarOwner() 实现功能:改变车辆拥有者的信息
// ChangeCarOwner updates the owner field of car with given id in world state
func (s *SmartContract) ChangeCarOwner(ctx contractapi.TransactionContextInterface, carNumber string, newOwner string) error {
	car, err := s.QueryCar(ctx, carNumber)
      //先查询车辆
	if err != nil {
		return err
	}
       //更改拥有者
	car.Owner = newOwner

	carAsBytes, _ := json.Marshal(car)
       //序列化后放入数据库
	return ctx.GetStub().PutState(carNumber, carAsBytes)
}

func main() {

	chaincode, err := contractapi.NewChaincode(new(SmartContract))

	if err != nil {
		fmt.Printf("Error create fabcar chaincode: %s", err.Error())
		return
	}

	if err := chaincode.Start(); err != nil {
		fmt.Printf("Error starting fabcar chaincode: %s", err.Error())
	}
}

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/905978.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号