食品溯源合约 -- 智能合约实例

这篇具有很好参考价值的文章主要介绍了食品溯源合约 -- 智能合约实例。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

食品溯源合约 -- 智能合约实例,区块链开发,智能合约,区块链

前提

Roles: 实现对用户地址的角色权限管控,添加、删除角色。

Producer: 生产商角色管控。

...

FoodInfoItem: 食品信息管控。生产商、中间商、超市添加食品信息。

Trace:食品溯源合约,主要负责对以上几个合约的统筹协

Roles

// SPDX-License-Identifier: MIT
pragma solidity >=0.4 <=0.9;

//角色库(管理所有角色地址)
// 1. 实现增加角色地址
// 2. 移除角色地址
// 3. 判断角色地址是否被授权
library Roles{
    struct Role{
        mapping (address =>bool) bearer;
    }
    // 在 Solidity 中,映射(mapping)不能在函数内部声明为局部变量,
    // 也不能在当前版本(0.8.0)中作为库(library)的成员变量。
   

    // 假如role 显示声明storage,那么算是合约中的状态变量,而且不能是memory
    function add(Role storage role,address account) internal {   
        require(!has(role,account),"Roles:account already has role");
        role.bearer[account] = true;
    }

    function remove(Role storage role,address account) internal {
        require(!has(role,account),"Roles:account has no role ");
        role.bearer[account] = false;
    }

    function has(Role storage role,address account) internal  view returns(bool){
        require(account != address(0),"Roles: account cannot be zero address");
        return role.bearer[account];
    }

}

Producer

PS:这下面这三个都是代表角色,代码几乎一样的,看会这个,其他都会。

// SPDX-License-Identifier: MIT
pragma solidity >=0.4 <=0.9;
import "./Roles.sol";
/**
*@title Producer
*@dev 
*/
contract Producer {
    using Roles for Roles.Role;

    event ProducerAdded(address indexed account);
    event ProducerRemoved(address indexed account);

    Roles.Role private _producers; // 使用这个相当于使用库

    constructor(address producer){ // 初始化给账户添加权限
        _addProducer(producer);
    }

    // 关于下面这几个函数为什么要拆分?提高代码可读性。


    modifier onlyProducer(){
        require(
            isProducer(msg.sender),
            "Producer:caller has no Producer role"
        );
        _;
    }

     // 用户是否拥有权限
      function isProducer(address account) public view returns (bool) {
        return _producers.has(account);
    }

    function addProducer(address account) public onlyProducer {
        _addProducer(account); // 不是很理解,为什么设置只有生产者角色才能为地址添加生产者角色权限
    }

    function removeRroducer(address account) public  {
        _removeProducer(account);
    }


     function _addProducer(address account) internal {
        _producers.add(account); 
        // 我们看向Roles的add()其实还有一个参数,但是我们 using for 了那个参数就相当于 _producers本身
        emit ProducerAdded(account);
    }

    function _removeProducer(address account) internal {
        _producers.remove(account);
        emit ProducerRemoved(account);
    }
    
}

Retailer

// SPDX-License-Identifier: MIT
pragma solidity >=0.4 <=0.9;
import "./Roles.sol";

// 超市
contract Retailer {
     using Roles for Roles.Role;

    event RetailerAdded(address indexed account);
    event RetailerRemoved(address indexed account);

    Roles.Role private _retailers; // 使用这个相当于使用库

    constructor(address retailer){ // 初始化给账户添加权限
        _addRetailer(retailer);
    }

    // 关于下面这几个函数为什么要拆分?提高代码可读性。


    modifier onlyRetailer(){
        require(
            isRetailer(msg.sender),
            "Retailer:caller has no Retailer role"
        );
        _;
    }

     // 用户是否拥有权限
      function isRetailer(address account) public view returns (bool) {
        return _retailers.has(account);
    }

    function addRetailer(address account) public onlyRetailer {
        _addRetailer(account); 
    }

    function removeRroducer(address account) public  {
        _removeRetailer(account);
    }


     function _addRetailer(address account) internal {
        _retailers.add(account); 
        // 我们看向Roles的add()其实还有一个参数,但是我们 using for 了那个参数就相当于 _Retailers本身
        emit RetailerAdded(account);
    }

    function _removeRetailer(address account) internal {
        _retailers.remove(account);
        emit RetailerRemoved(account);
    }
    
}

Distributor

// SPDX-License-Identifier: MIT
pragma solidity >=0.4 <=0.9;
import "./Roles.sol";
// 中间商
contract Distributor {
     using Roles for Roles.Role;

    event DistributorAdded(address indexed account);
    event DistributorRemoved(address indexed account);

    Roles.Role private _distributors; // 使用这个相当于使用库

    constructor(address distributor){ // 初始化给账户添加权限
        _addDistributor(distributor);
    }

    // 关于下面这几个函数为什么要拆分?提高代码可读性。


    modifier onlyDistributor(){
        require(
            isDistributor(msg.sender),
            "Distributor:caller has no Distributor role"
        );
        _;
    }

     // 用户是否拥有权限
      function isDistributor(address account) public view returns (bool) {
        return _distributors.has(account);
    }

    function addDistributor(address account) public onlyDistributor {
        _addDistributor(account); 
    }

    function removeRroducer(address account) public  {
        _removeDistributor(account);
    }


     function _addDistributor(address account) internal {
        _distributors.add(account); 
        // 我们看向Roles的add()其实还有一个参数,但是我们 using for 了那个参数就相当于 _Distributors本身
        emit DistributorAdded(account);
    }

    function _removeDistributor(address account) internal {
        _distributors.remove(account);
        emit DistributorRemoved(account);
    }
    
}

FoodInfoItem

// SPDX-License-Identifier: MIT
pragma solidity >=0.4 <=0.9;
pragma experimental ABIEncoderV2;

//食品信息管理合约
// 1.	保存食品基本信息:时间戳(流转过程中),用户名(流转过程中),用户地址信息(流转过程中),食品质量(流转过程中),食物名称,当前用户名称,质量,状态.
// 2.	对食品基本信息进行初始化
// 3.	实现两个方法:中间商添加食品信息;超市添加食品信息
// 4.	实现显示食品信息的方法

contract FoodInfoItem {
    uint[] _timestamp;     //保存食品流转过程中各个阶段的时间戳
    string[] _traceName;    //保存食品流转过程各个阶段的用户名
    address[] _traceAddress; //保存食品流转过程各个阶段的用户地址信息(和用户一一对应)
    uint8[] _traceQuality;  //保存食品流转过程中各个阶段的质量
    string _name;  //食品名称
    string _currentTraceName;  //当前用户名称
    uint8 _quality; //质量(0=优质 1=合格 2=不合格)
    uint8 _status; //状态(0:生产 1:分销 2:出售)
    address  _owner;

   // 初始化食品,创建者是生产商
    constructor(string memory name,string memory traceName,uint8 quality,address producer) public  {
        _name = name;
        _currentTraceName = traceName;
        _quality = quality;
        _owner = producer;
        _status = 0;
        // 不多说,看上面状态变量都能明白
        _timestamp.push(block.timestamp); 
        _traceName.push(traceName);
        _traceAddress.push(producer);
        _traceQuality.push(quality);
    }

   // 中间商添加食品信息
    function addTraceInfoByDistributor(
        string memory traceName,
        uint8 quality,
        address distributor
    ) public returns(bool){
        require(_status == 0, "FoddIndo: caller must be distributor");
        _currentTraceName = traceName;
        _quality = quality;
        _status = 1;

        _timestamp.push(block.timestamp); 
        _traceName.push(traceName);
        _traceAddress.push(distributor);
        _traceQuality.push(quality);

        return true;
    }


    // 超市添加食品信息
    function addTraceInfoByRetailer(
        string memory traceName,
        uint8 quality,
        address retailer
    )public returns(bool){
        require(_status == 1, "FoddIndo: caller must be retailer");
        _currentTraceName = traceName;
        _quality = quality;
        _status = 2;

        _timestamp.push(block.timestamp); 
        _traceName.push(traceName);
        _traceAddress.push(retailer);
        _traceQuality.push(quality);
        return true;
    }

    // 拿到食品流转的全部信息
    function getTraceInfo() public view  returns(uint[] memory,string[] memory,address[] memory,uint8[] memory){
        return (
            _timestamp,
            _traceName,
            _traceAddress,
            _traceQuality
        );
    }

    // 拿到生产商一开始添加食品信息
    function getFood() public view returns(uint,string memory,address,uint8,string memory){
        return (
            _timestamp[0],
            _traceName[0],
            _traceAddress[0],
            _traceQuality[0],
            _name
        );
    }

}


Trace

// SPDX-License-Identifier: MIT
pragma solidity >=0.4.22 <0.9.0;
pragma experimental ABIEncoderV2; // 开启实验性功能,包括对map,数组的编码和解码等
import "./FoodInfoItem.sol";
import "./Distributor.sol";
import "./Producer.sol";
import "./Retailer.sol";

//食品溯源合约(负责具体食品溯源信息的生成)
//  1.实现生产食品的方法(新建食品信息)
//  2.实现食品分销过程中增加溯源信息的接口
//  3.实现食品出售过程中增加溯源信息的接口
//  4.实现获取食品溯源信息接口

contract Trace is Distributor,Producer,Retailer {
    mapping(uint256 => address) foods; //食品溯源id到 -> 具体食品溯源合约的映射表
    uint[] foodList; // 食品溯源id数组

    //构造函数初始化,一起把父类角色初始化
    constructor(
        address producer,
        address distributor,
        address retailer
    )    Producer(producer) Distributor(distributor) Retailer(retailer) {}

    // 生产商调用,调用添加食品信息
    function newFood(
        string memory name,
        uint256 traceNumber, // 溯源id
        string memory traceName,
        uint8 quality
    ) public onlyProducer returns (address) {
        require(foods[traceNumber] == address(0), "Trace:traceNumber already exist"); // 检测溯源id对应食品合约是否已经存在,已存在id不能用。
        FoodInfoItem food = new FoodInfoItem( // 初始化食品合约
            name,
            traceName,
            quality,
            msg.sender
        );
        foods[traceNumber] = address(food); // 往映射表添加地址
        foodList.push(traceNumber); // 往食品溯源数组添加溯源id
        return address(food);
    }

   // 中间商调用,添加食品信息
    function addTraceInfoByDistributor(
        uint256 traceNumber,
        string memory traceName,
        uint8 quality
    ) public onlyDistributor returns (bool) {
        require(foods[traceNumber] != address(0), "Trace:traceNumber does not exist"); // id 对应食品合约没存在,代表没食品
        return
            FoodInfoItem(foods[traceNumber]).addTraceInfoByDistributor(traceName,quality,msg.sender); // 调用对应的食品合约方法
    }

   // 超市调用,添加食品信息
    function addTraceInfoByRetailer(
        uint256 traceNumber,
        string memory traceName,
        uint8 quality
    ) public onlyRetailer returns (bool) {
        require(foods[traceNumber] != address(0), "Trace:traceNumber does not exist");
        return
            FoodInfoItem(foods[traceNumber]).addTraceInfoByRetailer(traceName,quality,msg.sender);
    }

    // 拿到所有食品信息
    function getTraceInfo(
        uint256 traceNumber
    ) public view returns (uint[] memory,string[] memory,address[] memory,uint8[] memory) {
        require(foods[traceNumber] != address(0), "Trace:traceNumber does not exist");
        return FoodInfoItem(foods[traceNumber]).getTraceInfo();
    }

    //拿到单条食品信息
    function getFood(
        uint256 traceNumber
    ) public view returns (uint,string memory,address,uint8,string memory) {
        require(foods[traceNumber] != address(0), "Trace:traceNumber does not exist");
        return FoodInfoItem(foods[traceNumber]).getFood();
    }

    // 拿到全部食品的溯源id数组
    function getAllFood() public view returns (uint[] memory) {
        return foodList;
    }

}

核心流程演示

1.创建Trace合约,赋予三个地址生产商、中间商、超市权限。

食品溯源合约 -- 智能合约实例,区块链开发,智能合约,区块链

2.利用上述producer地址,调用newFood接口

食品溯源合约 -- 智能合约实例,区块链开发,智能合约,区块链

结果成功,我就不演示了。

3.利用上述distributor地址,调用addTraceInfoByDistributor接口

食品溯源合约 -- 智能合约实例,区块链开发,智能合约,区块链

4.利用上述retailer地址,调用addTraceInfoByRetailer接口

食品溯源合约 -- 智能合约实例,区块链开发,智能合约,区块链文章来源地址https://www.toymoban.com/news/detail-640978.html

到了这里,关于食品溯源合约 -- 智能合约实例的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

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

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

相关文章

  • 8. Fabric2.2 区块链农产品溯源系统 - 智能合约设计

    根据上小节的需求分析与方案设计来进行智能合约的设计。 智能合约设计最核心的是存储字段的设计、也就是索引设计,Fabric 常见的时间状态存储引擎是LevelDB 或 CouchDB,这两个数据库是KV存储,KV存储不像SQL类型存储,一张表创建多个字段,多个字段索引可以进行各种复查询

    2023年04月08日
    浏览(43)
  • 区块链溯源:如何提高食品溯源效率

    食品溯源是指从消费者购买的食品追溯到其生产、加工、销售等各个环节的过程。食品溯源对于保障食品安全和质量非常重要,因为它可以帮助我们快速找出潜在的食品安全事件的原因,从而采取相应的措施。 然而,传统的食品溯源方法存在许多问题。首先,数据收集和存储

    2024年04月14日
    浏览(53)
  • 区块链食品安全(区块链食品安全溯源系统痛点)

    区块链在未来,会如何影响普通人的吃穿住行要回答这个问题我们需要好好的开一下脑洞我们先简单说下 区块链技术的特点:数据安全性高,应用区块链技术的数据几乎不可能被篡改。数据被记录后不可更改。数据可以有高度的透明性,人人都可以看到。分布式节点,数据不

    2024年01月22日
    浏览(41)
  • 智能合约在区块链溯源技术中的应用及未来发展:提升企业运营效率

    作者:禅与计算机程序设计艺术 引言 随着互联网、物联网、区块链等技术的快速发展,企业运营效率也逐渐有了很大的提高。特别是在区块链技术的作用下,企业运营效率得到了很大的提升。智能合约是区块链技术的一种重要应用,可以帮助企业实现数据的透明化、安全性

    2024年02月16日
    浏览(49)
  • 区块链食品溯源案例实现(二)

    引言         随着前端界面的完成,我们接下来需要编写后端代码来与区块链网络进行交互。后端将负责处理前端发送的请求,调用智能合约的方法获取食品溯源信息,并将结果返回给前端。 通过前后端的整合,我们可以构建一个食品溯源系统,为用户提供便捷、安全的

    2024年04月08日
    浏览(46)
  • 区块链食品溯源案例实现(一)

    引言:         食品安全问题一直是社会关注的热点,而食品溯源作为解决食品安全问题的重要手段,其重要性不言而喻。传统的 食品溯源系统 往往存在数据易被篡改、信息不透明等问题,而区块链技术的引入,为食品溯源带来了革命性的变革。 目录 引言: 区块链食品

    2024年04月27日
    浏览(38)
  • 区块链部署和运维---食品溯源

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

    2024年02月04日
    浏览(43)
  • beego框架编写食品溯源区块链后端

    安装go-sdk 将webase的sdk证书文件复制到自己的项目 修改config.toml使sdk是本项目下 修改配置文件app.conf 地址私钥根据自己的webase修改 新建conf.go获取配置文件信息 将go-sdk下config.go和config_pem.go复制到项目目录conf目录下 将合约编译成go文件 编写TraceService 与合约进行交互 编写foodI

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

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

    2023年04月12日
    浏览(45)
  • Fisco-Bcos智能合约开发案例----商品溯源

    1个商品种类----》n个商品,同时还可以创建多个商品种类(工厂合约的作用) 1.部署工厂合约 2.创建商品种类 3. 创建对应的商品 4.查询商品种类 5. 查询商品状态 0–生产者,1—运输者,2—超市售卖者,3—消费者 6. 查询商品溯源信息 7.改变商品状态 8.查询商品溯源

    2024年02月11日
    浏览(47)

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

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

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

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

二维码1

领取红包

二维码2

领红包