beego框架编写食品溯源区块链后端

这篇具有很好参考价值的文章主要介绍了beego框架编写食品溯源区块链后端。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

区块链食品溯源项目

创建项目

bee new trace

安装go-sdk

go get github.com/FISCO-BCOS/go-sdk
  • 将webase的sdk证书文件复制到自己的项目

  • 修改config.toml使sdk是本项目下

修改配置文件app.conf

appname = trace
httpport = 8080
runmode = dev
autorender = false
copyrequestbody = true
EnableDocs = true
contractAddress=0xc5a3d4384897acb9ce3e9096644c35aa903d1687
distributorAddress=0x1cb30f505b9e338bb48f9cec3ceadd1d2d4da565
distributorPK=5eff4114710e69a7677a39145b71ab4b763c126aa118defd2f0316a604e9495cad29c3854604e3b7721588b4778d047e2deb9911a48ae04125e22fdce8eda292
producerAddress=0x1cb30f505b9e338bb48f9cec3ceadd1d2d4da565
producerPK=e885dc09e398461121608831780410fb2e6c782d2afc95e324057dec60e07f34d8bde9f6cdc63dd79591988165b63b9ebb96e0ddbc823fe80c6570bcee5c97fd
retailerAddress=0x746afad125d42011b289ef421e8703e0dd867b60
retailerPK=47f39c99583acea98ab31b5b38f13bd0c05726e9304cf5e803bc4cf82910c1ddb80b7941bb9bad4db450e2d761045161ea67b8cb74a66f738004d5927c3a1f70

地址私钥根据自己的webase修改

新建conf.go获取配置文件信息

package conf
​
import (
    "fmt"
​
    "github.com/astaxie/beego"
)
​
var (
    ContractAddress    string
    DistributorAddress string
    DistributorPK      string
    ProducerAddress    string
    ProducerPK         string
    RetailerAddress    string
    RetailerPK         string
)
​
func init() {
    err := beego.LoadAppConfig("ini","conf/app.conf")
    if err != nil{
        fmt.Println(err)
        return
    }
    ContractAddress, _ =beego.AppConfig.String("contractAddress")
    DistributorAddress,_ = beego.AppConfig.String("distributorAddress")
    DistributorPK,_ = beego.AppConfig.String("distributorPK")
    ProducerAddress,_ = beego.AppConfig.String("producerAddress")
    ProducerPK,_ = beego.AppConfig.String("producerPK")
    RetailerAddress,_ = beego.AppConfig.String("retailerAddress")
    RetailerPK,_ = beego.AppConfig.String("retailerPK")
}

将go-sdk下config.go和config_pem.go复制到项目目录conf目录下

编写Service层

将合约编译成go文件

abigen -abi abi/FoodInfo.abi -bin bin/FoodInfo.bin -pkg main -type FoodInfo -out FoodInfo.go
​
abigen -abi abi/Role.abi -bin bin/Role.bin -pkg main -type Role -out Role.go
​
abigen -abi abi/RoleController.abi -bin bin/RoleController.bin -pkg main -type RoleController -out RoleController.go
​
abigen -abi abi/Trace.abi -bin bin/Trace.bin -pkg main -type Trace -out Trace.go

编写TraceService

与合约进行交互

package service
​
import (
    "log"
​
    "github.com/FISCO-BCOS/go-sdk/abi/bind"
    "github.com/FISCO-BCOS/go-sdk/client"
    conf2 "github.com/FISCO-BCOS/go-sdk/conf"
    "github.com/ethereum/go-ethereum/common"
​
    //"github.com/FISCO-BCOS/go-sdk/client"
    "trace/conf"
)
​
var Tracecli TraceSession
​
func init() {
    configs, err := conf.ParseConfigFile("config.toml")
    if err != nil {
        log.Fatal(err)
    }
    client, err := client.Dial((*conf2.Config)(&configs[0]))
    if(err != nil) {
        log.Fatal(err)
    }
    address := conf.ContractAddress
    ContractAddress := common.HexToAddress(address)
    instance, err := NewTrace(ContractAddress,client)
    if err != nil{
        log.Fatal(err)
    }
    Tracecli = TraceSession{Contract: instance, CallOpts: *client.GetCallOpts(),TransactOpts: *client.GetTransactOpts()}
}
​
func LoadUser(user string) {
    fromAddress := ""
    privateKey := ""
    switch user {
    case "producer":
        fromAddress = conf.ProducerAddress
        privateKey = conf.ProducerPK
    case "distributor":
        fromAddress = conf.DistributorAddress
        privateKey = conf.DistributorPK
    case "retailer":
        fromAddress = conf.RetailerAddress
        privateKey = conf.RetailerPK
    default:
        return
    }
    ket,_ := crpto.HexToECDSA(privateKey)
    auth := bind.NewKeyedTransactor(key)
    auth.From = common.HexToAddress(fromAddress)
    files, _ := conf.ParseConfigFile("config.toml")
    client,_ := client.Dial((*conf2.Config)(&files[0]))
    instance,_ := TraceSession{Contract: instance,CallOpts: *client.GetCallOpts(), TransactOpts: *auth}
}

编写foodInfoService

package service
​
import (
    "fmt"
    "strconv"
)
​
type FoodInfoService struct{}
​
func (fs *FoodInfoService) Trace(traceNumber string) interface{} {
    trace := get_trace(traceNumber)
    return trace
}
func (fs *FoodInfoService) Get_food(traceNumber string) map[string]interface{} {
    response := make(map[string]interface{})
    name, current, quality, _, err := Tracecli.GetTraceinfoByTraceNumber(traceNumber)
    byTraceNumber, i, i2, _, err := Tracecli.GetTraceDetailByTraceNumber(traceNumber)
    if err != nil {
        fmt.Println(err)
    }
    response["timestamp"] = byTraceNumber[len(byTraceNumber)-1]
    response["produce"] = i[0]
    response["name"] = name
    response["current"] = current
    response["address"] = i2[0]
    response["quality"] = quality
    return response
}
func (fs *FoodInfoService) GetFoodList() []int {
    food, _ := Tracecli.GetAllFood()
    intSlice := make([]int, len(food))
    for i, v := range food {
        intSlice[i] = int(v.Int64())
    }
    return intSlice
}
​
func get_trace(traceNumber string) []interface{} {
    _, s, _, _, err := Tracecli.GetTraceinfoByTraceNumber(traceNumber)
    var responses []interface{}
    byTraceNumber, i, i2, i3, err := Tracecli.GetTraceDetailByTraceNumber(traceNumber)
    if err != nil {
        fmt.Println(err)
    }
    for index := 0; index < len(byTraceNumber); index++ {
        if index == 0 {
            response := make(map[string]interface{})
            response["traceNumber"] = traceNumber
            response["name"] = s
            response["produce_time"] = byTraceNumber[0]
            response["timestamp"] = byTraceNumber[index]
            response["from"] = i[index]
            response["quality"] = i3[index]
            response["from_address"] = i2[index]
            i4 := append(responses, response)
            responses = i4
        } else {
            response := make(map[string]interface{})
            response["traceNumber"] = traceNumber
            response["name"] = s
            response["produce_time"] = byTraceNumber[0]
            response["timestamp"] = byTraceNumber[index]
            response["from"] = i[index-1]
            response["to"] = i[index]
            response["quality"] = i3[index]
            response["from_address"] = i2[index-1]
            i4 := append(responses, response)
            responses = i4
        }
    }
    return responses
}
​
func (fs *FoodInfoService) GetTrace(traceNumber string) []interface{} {
    _, s, _, _, err := Tracecli.GetTraceinfoByTraceNumber(traceNumber)
    var responses []interface{}
    byTraceNumber, i, i2, i3, err := Tracecli.GetTraceDetailByTraceNumber(traceNumber)
    if err != nil {
        fmt.Println(err)
    }
    for index := 0; index < len(byTraceNumber); index++ {
        if index == 0 {
            response := make(map[string]interface{})
            response["traceNumber"] = traceNumber
            response["name"] = s
            response["produce_time"] = byTraceNumber[0]
            response["timestamp"] = byTraceNumber[index]
            response["from"] = i[index]
            response["quality"] = i3[index]
            response["from_address"] = i2[index]
            i4 := append(responses, response)
            responses = i4
        } else {
            response := make(map[string]interface{})
            response["traceNumber"] = traceNumber
            response["name"] = s
            response["produce_time"] = byTraceNumber[0]
            response["timestamp"] = byTraceNumber[index]
            response["from"] = i[index-1]
            response["quality"] = i3[index]
            response["from_address"] = i2[index-1]
            i4 := append(responses, response)
            responses = i4
        }
    }
    return responses
}
func (f FoodInfoService) Producing() []interface{} {
    var resList []interface{}
    numList := f.GetFoodList()
    for index := 0; index < len(numList); index++ {
        trace := f.GetTrace(strconv.Itoa(numList[index]))
        if len(trace) == 1 {
            i := append(resList, trace[0])
            resList = i
        }
    }
    fmt.Println("Producing: ", resList)
    return resList
}
func (f FoodInfoService) Distributing() []interface{} {
    numList := f.GetFoodList()
    var resList []interface{}
    for index := 0; index < len(numList); index++ {
        trace := f.GetTrace(strconv.Itoa(numList[index]))
        if len(trace) == 2 {
            i := append(resList, trace[1])
            resList = i
        }
    }
    return resList
}
func (f FoodInfoService) Retailing() []interface{} {
    numList := f.GetFoodList()
    var resList []interface{}
    for index := 0; index < len(numList); index++ {
        trace := f.GetTrace(strconv.Itoa(numList[index]))
        if len(trace) == 3 {
            i := append(resList, trace[2])
            resList = i
        }
    }
    return resList
}
​

编写食物数据模型Food

food.go

package models
​
import "math/big"
​
// Food 表示食物的数据模型
type Food struct {
    Name        string   `json:"name"`        // 食物名称
    TraceNumber *big.Int `json:"TraceNumber"` // 追溯编号,使用 *big.Int 类型以支持大整数
    TraceName   string   `json:"TraceName"`   // 追溯名称
    Quality     uint8    `json:"Quality"`     // 食物质量,使用 uint8 表示无符号 8 位整数
}
​

在utils下统一请求数据格式

response.go
package utils
​
import (
    "encoding/json"
    "fmt"
)
​
// returnDataStruct 定义了用于返回 JSON 数据的结构体
type returnDataStruct struct {
    Ret  int         `json:"ret"`  // 返回状态码
    Msg  string      `json:"msg"`  // 返回消息
    Data interface{} `json:"data"` // 返回数据,使用空接口表示可以包含任何类型的数据
}
​
// Send_json 用于构建并返回标准的 JSON 响应
func Send_json(ret int, msg string, data interface{}) []byte {
    // 构建 returnDataStruct 结构体实例
    retu, err := json.Marshal(returnDataStruct{
        Ret:  ret,
        Msg:  msg,
        Data: data,
    })
    if err != nil {
        fmt.Println("error:", err)
    }
    return retu
}
​
// Send_custom_json 用于构建并返回标准的 json响应
func Send_custom_json(ret int, data_key string, data interface{}) []byte {
    response := make(map[string]interface{})
    response["ret"] = ret
    response[data_key] = data
    retu, err := json.Marshal(response)
    if err != nil {
        fmt.Println(err)
    }
    return retu
}
​

编写给用户返回的数据格式

User.go
package controllers
​
import (
    "trace/conf"
    "trace/utils"
​
    "github.com/beego/beego/v2/server/web"
)
​
type User struct {
    web.Controller
}
​
func (u User) Userinfof() {
    userName := u.GetString("userName")
    var jsons []byte
    switch userName {
    case "produce":
        jsons = utils.Send_custom_json(200, "address", conf.ProducerAddress)
    case "distributor":
        jsons = utils.Send_custom_json(200, "address", conf.DistributorAddress)
    case "retailer":
        jsons = utils.Send_custom_json(200, "address", conf.RetailerAddress)
    default:
        jsons = utils.Send_custom_json(200, "error", "user not found")
    }
    u.Ctx.ResponseWriter.Write(jsons)
}
​
注册路由
web.Router("/userinfo", &controllers.User{}, "*:Userinfof")

编写处理与食物追溯相关请求

Trace.go

package controllers
​
import "github.com/beego/beego/v2/server/web"
​
type Trace struct {
    web.Controller
}
​
​
newfood处理创建新食物的请求
func (t Trace) newFood() {
    t.newFood()
}
​
处理创建新食物的具体逻辑
func (t *Trace) newfood() {
    // 初始化 Food 结构体
    var food models.Food
    // 获取请求体数据
    data := t.Ctx.Input.RequestBody
    // 调用 paramjson 函数解析 JSON 数据
    success, parsedFood := paramjson(data, &food)
    if !success {
        // 如果解析失败,返回错误响应
        t.Ctx.ResponseWriter.Write(utils.Send_json(0, "传入参数不正确", parsedFood))
        return
    }
    // 调用 LoadUser 函数加载用户
    service.LoadUser("producer")
    // 调用 Tracecli.NewFood 函数创建新食物
    _, receipt, err := service.Tracecli.NewFood(parsedFood.Name, parsedFood.TraceNumber, parsedFood.TraceName, strconv.Itoa(int(parsedFood.Quality)))
    if err != nil {
        // 如果创建失败,返回错误响应
        t.Ctx.ResponseWriter.Write(utils.Send_json(0, "trace already exist", err))
        return
    }
    // 返回成功响应
    t.Ctx.ResponseWriter.Write(utils.Send_json(1, "ok", receipt))
}
编写解析json数据具体逻辑
func paramjson(data []byte, food *models.Food) (bool, models.Food) {
    // 如果输入数据为 nil,则返回解析失败的结果
    if data == nil {
        return false, models.Food{}
    }
    // 尝试解析 JSON 数据并填充到 models.Food 结构体中
    if err := json.Unmarshal(data, &food); err != nil {
        // 解析失败,则返回解析失败的结果
        return false, models.Food{}
    } else {
        // 解析成功,则返回解析后的 models.Food 结构体
        return true, *food
    }
}
​
配置路由
web.Router("/produce", &controllers.Trace{}, "POST:NewFood")

Adddistribution 处理食物分销的请求

func (t Trace) Adddistribution() {
    t.adddistribution()
}
adddistribution 处理食物分销的具体逻辑
func (t Trace) adddistribution() {
    var food models.Food
    data := t.Ctx.Input.RequestBody
    paramjson(data, &food)
    b, i := paramjson(data, &food)
    if !b {
        t.Ctx.ResponseWriter.Write(utils.Send_json(0, "传入参数不正确", i))
    }
    service.LoadUser("distributor")
    _, receipt, err := service.Tracecli.AddTraceInfoByDistributor(food.TraceNumber, food.TraceName, new(big.Int).SetUint64(uint64(food.Quality)))
    if err != nil {
        t.Ctx.ResponseWriter.Write(utils.Send_json(0, "error", err))
    }
    t.Ctx.ResponseWriter.Write(utils.Send_json(1, "ok", receipt))
}
配置路由
web.Router("/distributor", &controllers.Trace{}, "POST:Adddistribution")

Addretail 处理食物零售的请求

func (t Trace) Addretail() {
    t.Addretail()
}
addretail 处理食物零售的具体逻辑
func (t Trace) addretail() {
    var food models.Food
    data := t.Ctx.Input.RequestBody
    paramjson(data, &food)
    b, i := paramjson(data, &food)
    if !b {
        t.Ctx.ResponseWriter.Write(utils.Send_json(0, "传入参数不正确", i))
    }
    service.LoadUser("retailer")
    _, receipt, err := service.Tracecli.AddTraceInfoByRetailer(food.TraceNumber, food.TraceName, new(big.Int).SetUint64(uint64(food.Quality)))
    if err != nil {
        t.Ctx.ResponseWriter.Write(utils.Send_json(0, "error", err))
​
    }
    t.Ctx.ResponseWriter.Write(utils.Send_json(1, "ok", receipt))
}
配置路由
web.Router("/addretail", &controllers.Trace{}, "POST:Addretail")

编写GetfoodInfo 控制器

处理食品信息的请求

type GetfoodInfo struct {
    web.Controller
}
​

Trace 获取某个食品的溯源信息

func (g GetfoodInfo) Trace() {
    // 检索追溯号和 FoodInfoService 实例
    tn, fs := g.getTraceNumberAndService()
​
    // 在 FoodInfoService 上调用 Get_food 方法,并以 JSON 格式响应结果
    g.Ctx.Output.JSON(fs.Get_food(tn), false, false)
}

getTraceNumberAndService 是一个辅助方法,用于检索追溯号和 FoodInfoService

编写getTraceNumberAndService方法
func (g GetfoodInfo) getTraceNumberAndService() (string, *service.FoodInfoService) {
    // 从请求参数中检索追溯号
    tn := g.GetString("traceNumber")
​
    // 将追溯号转换为整数
    atoi, _ := strconv.Atoi(tn)
​
    // 检查追溯号是否小于 0 或为空;如果是,则以错误响应
    if atoi < 0 || tn == "" {
        g.Ctx.ResponseWriter.Write(utils.Send_custom_json(0, "error", "invalid parameter"))
    }
​
    // 创建 FoodInfoService 的新实例
    fs := &service.FoodInfoService{}
​
    // 返回追溯号和 FoodInfoService 实例
    return tn, fs
}
配置路由
web.Router("/trace", &controllers.GetfoodInfo{}, "*:Trace")

获取某个食品当前信息

func (g GetfoodInfo) GetFood() {
    tn, fs := g.getTraceNumberAndService()
    g.Ctx.Output.JSON(fs.Get_food(tn), false, false)
}
​
配置路由
web.Router("/food", &controllers.GetfoodInfo{}, "*:GetFood")

获取某个生产商的食物信息

func (g GetfoodInfo) Producing() {
    fs := g.getFoodInfoService()
    g.Ctx.Output.JSON(fs.Producing(), false, false)
}

getFoodInfoService 是用于获取 FoodInfoService 实例的方法

func (g GetfoodInfo) getFoodInfoService() *service.FoodInfoService {
    // 创建并返回 FoodInfoService 的新实例
    fs := &service.FoodInfoService{}
    return fs
}
配置路由
web.Router("/producing", &controllers.GetfoodInfo{}, "GET:Producing")

获取位于中间商的食物信息

func (g GetfoodInfo) Distributing() {
    fs := g.getFoodInfoService()
    g.Ctx.Output.JSON(fs.Distributing(), false, false)
}
配置路由
web.Router("/distributing", &controllers.GetfoodInfo{}, "GET:Distributing")

获取超市的食物信息

func (g GetfoodInfo) Retailing() {
    fs := g.getFoodInfoService()
    g.Ctx.Output.JSON(fs.Retailing(), false, false)
}
​
配置路由
web.Router("/retailing", &controllers.GetfoodInfo{}, "GET:Retailing")

INITROLE 函数用于初始化角色设置

INITROLE

// INITROLE 函数用于初始化角色设置
func INITROLE() {
    // 从配置中获取分发者的地址和私钥
    fromAddress := conf.DistributorAddress
    privateKey := conf.DistributorPK
​
    // 将私钥解析为 ECDSA 密钥
    key, err := crypto.HexToECDSA(privateKey)
    if err != nil {
        fmt.Println("error private:", err)
        return
    }
​
    // 创建一个新的 KeyedTransactor,将密钥和地址设置为授权信息
    auth := bind.NewKeyedTransactor(key)
    auth.From = common.HexToAddress(fromAddress)
​
    // 从配置文件中解析 FISCO-BCOS 客户端的配置
    files, _ := conf.ParseConfigFile("config.toml")
    client, _ := client.Dial((*conf2.Config)(&files[0]))
​
    // 部署 Service 合约并获取合约实例
    _, _, instance, _ := service.DeployService(client.GetTransactOpts(), client)
    session := service.ServiceSession{Contract: instance, CallOpts: *client.GetCallOpts(), TransactOpts: *client.GetTransactOpts()}
​
    // 将分发者地址转换为 common.Address 类型
    address := common.HexToAddress(conf.DistributorAddress)
​
    // 设置 Distributor 角色
    _, _, err = session.SetDRRole(address.String())
    if err != nil {
        fmt.Println(err)
    }
​
    // 将生产者地址转换为 common.Address 类型
    address1 := common.HexToAddress(conf.ProducerAddress)
​
    // 设置 Producer 角色
    _, _, err = session.ResetPRRole(address1.String())
    if err != nil {
        fmt.Println(err)
    }
​
    // 将零售商地址转换为 common.Address 类型
    address2 := common.HexToAddress(conf.RetailerAddress)
​
    // 设置 Retailer 角色
    _, _, err = session.ResetRRRole(address2.String())
    if err != nil {
        fmt.Println(err)
    }
​
    // 部署 Role 合约并获取合约实例
    _, _, instance1, err := Role.DeployService(client.GetTransactOpts(), client)
    if err != nil {
        fmt.Println(err)
    }
​
    session1 := Role.ServiceSession{Contract: instance1, CallOpts: *client.GetCallOpts(), TransactOpts: *client.GetTransactOpts()}
​
    // 判断所有角色是否设置成功
    err1 := session1.OnlyDRRole(address)
    err2 := session1.OnlyPRRole(address1)
    err3 := session1.OnlyPRRole(address2)
​
    if err1 != nil || err2 != nil || err3 != nil {
        fmt.Println(err1)
        fmt.Println(err2)
        fmt.Println(err3)
    }
}
​

main函数初始化文章来源地址https://www.toymoban.com/news/detail-778285.html

func main() {
    // 初始化角色
    INITROLE()
​
    // 设置 Beego 路由不区分大小写
    beego.BConfig.RouterCaseSensitive = false
​
    // 运行 Beego 应用
    beego.Run()
}

到了这里,关于beego框架编写食品溯源区块链后端的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 区块链部署和运维---食品溯源

    一.应用背景:     基于FISCO BCOS部署去中心化的食品溯源系统,部署方式为基于容器技术Docker,部署内容包括系统前端、后端、数据库,并在最后进行验证。具体工作内容如下:     1. 以容器的方式部署Mysql以及Redis数据库     2. 配置Dockerfile,生成系统后端的镜像    

    2024年02月04日
    浏览(42)
  • 区块链技术在食品溯源中的应用

    1.1食品溯源的研究意义         近年来,食品安全问题频发引起了 社会大众的广泛关注 。 在 当今 食品贸易 的大背景 下,生产商和消费者 之间 存在 着 严重的 信息不对称现象 : 生产商的有意误导、 消费者的认知缺乏,使得消费者在 选择 食品时无法做出 确切 的选择

    2023年04月12日
    浏览(45)
  • 区块链溯源:信任的力量——如何看待区块链技术在食品安全、药品监管等领域的应用?

    作者:禅与计算机程序设计艺术 随着互联网技术的飞速发展,以及对现实世界中物流、信息传递、货币流通等方面需求的不断提升,越来越多的人开始利用区块链技术进行各种各样的商业活动,特别是在金融、保险、贸易、医疗、物流、电子政务等领域。而现代社会的复杂性

    2024年02月14日
    浏览(47)
  • 基于区块链溯源系统后端开发

    已经完成了育种组织、养殖户组织、政府职能、普通用户的链码编写及后端接口编写,前三个组织均可添加数据及查询数据,且支持富查询,同时还可进行登录注册操作,普通用户则只可以进行查询溯源操作。总的Api路由组如下图: 但仍旧存在问题,当开启7个区块链节点容

    2024年02月02日
    浏览(31)
  • go1.20环境安装以及beego框架配置

    打开网址下载安装包 选择对应安装包来下载安装(个人是windows,下载的1.20.3版本) 默认情况下会安装在C盘,但是我安装在了D盘目录 根据安装提示一步步next,直至完成  go get 在1.18版本之后就弃掉了,换成了install 配置自己的work目录,假如是GOPATH=**/WORKS/ beego和bee的安装配置

    2023年04月24日
    浏览(41)
  • Go开发使用bee工具生成beego框架工程代码、运行web项目以及beego中内置模板函数列表

        GO开发中使用bee工具生成beego框架工程代码,在这之前假定你已经成功安装好了Beego环境搭建和bee工具,Windows下Beego环境搭建和bee工具的安装使用_bee命令 windows-CSDN博客 然后在命令行或者在git bash中进入到GOPATH的src目录,执行bee new 工程名称,来生成一个beego框架工程目录:

    2024年04月29日
    浏览(39)
  • 42. 【农产品溯源项目前后端Demo】后端-区块链连接服务

    本节介绍后端代码是如何与区块链网络连接的。 1.在后端代码里fabric包 负责与区块链网络连接,并发送交易。 2.fabric.Const文件 定义 区块链网络拓扑结构,请查看注释。

    2023年04月08日
    浏览(46)
  • 37. 使用Fabric-Go-SDK 访问农产品溯源区块链集群

    上面章节讲过农产品溯源应用,包括集群搭建、智能合约编写,本节基于18.1 多peer、多orderer集群,使用fabric-go-sdk进行调用,这里需要读者重新复习一下农产品溯源的网络模型、智能合约。 配置/etc/hosts文件 前面xxx是服务器地址,如果是本地127.0.0.1 创建go工程,工程中新建

    2024年02月11日
    浏览(43)
  • 食品溯源合约 -- 智能合约实例

    Roles: 实现对用户地址的角色权限管控,添加、删除角色。 Producer: 生产商角色管控。 ... FoodInfoItem: 食品信息管控。生产商、中间商、超市添加食品信息。 Trace:食品溯源合约,主要负责对以上几个合约的统筹协 PS:这下面这三个都是代表角色,代码几乎一样的,看会这个,其他都

    2024年02月13日
    浏览(41)
  • 【Solidity】智能合约案例——①食品溯源合约

    目录 一、合约源码分析: 二、合约整体流程:       1.部署合约       2.管理角色       3.食品信息管理       4.食品溯源管理         Producer.sol:生产者角色的管理合约,功能为:添加新的生产者地址、移除生产者地址、判断角色地址是否被授权         Di

    2024年02月08日
    浏览(53)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包