Food traceability smart contract development (full version)

Author: Key

Operating environment: FISCO BCOS alliance chain middleware-WeBASE-Front

Roles.sol

pragma solidity^0.4.25;

library Roles{
    
    
    struct Role{
    
    
        mapping(address=>bool) bearer;
    }
    //判定地址存在否
    function has(Role storage role,address amount)internal view returns(bool){
    
    
        require(amount!=address(0));
        return role.bearer[amount];
    }
    //添加角色
    function add(Role storage role,address amount)internal{
    
    
        require(!has(role,amount));
        role.bearer[amount] = true;
    }
    //删除角色
    function remove(Role storage role,address amount)internal{
    
    
        require(has(role,amount));
        role.bearer[amount] = false;
    }
}

Producer.sol

pragma solidity^0.4.25;
import "Roles.sol";
contract Producer{
    
    
    using Roles for Roles.Role;
    Roles.Role private _producer;
    
    event producerAdded(address amount);
    event producerRemoved(address amount);
    
    constructor(address producer)public{
    
    
        _addProducer(producer);
    }
    
    function _addProducer(address amount)internal{
    
    
        _producer.add(amount);
        emit producerAdded(amount);
    }
    
    function _removeProducer(address amount)internal{
    
    
        _producer.remove(amount);
        emit producerAdded(amount);
    }
    
    function isProducer(address amount)public view returns(bool){
    
    
        return _producer.has(amount);
    }
    modifier onlyProducer(){
    
    
        require(isProducer(msg.sender));
        _;
    }
    function addProducer(address amount)public onlyProducer{
    
    
        _addProducer(amount);
    }
    
    function removeProducer()public{
    
    
        _removeProducer(msg.sender);
    }
}

Distributor.sol

pragma solidity^0.4.25;
import "Roles.sol";
contract Distributor{
    
    
    using Roles for Roles.Role;
    Roles.Role private _distributor;
    
    event distributorAdded(address amount);
    event distributorRemoved(address amount);
    
    constructor(address distributor)public{
    
    
        _addDistributor(distributor);
    }
    
    function _addDistributor(address amount)internal{
    
    
        _distributor.add(amount);
        emit distributorAdded(amount);
    }
    
    function _removeDistributor(address amount)internal{
    
    
        _distributor.remove(amount);
        emit distributorAdded(amount);
    }
    
    function isDistributor(address amount)public view returns(bool){
    
    
        return _distributor.has(amount);
    }
    modifier onlyDistributor(){
    
    
        require(isDistributor(msg.sender));
        _;
    }
    function addDistributor(address amount)public onlyDistributor{
    
    
        _addDistributor(amount);
    }
    
    function removeDistributor() public{
    
    
        _removeDistributor(msg.sender);
    }
}

Retailer.sol

pragma solidity^0.4.25;
import "Roles.sol";
contract Retailer{
    
    
    using Roles for Roles.Role;
    Roles.Role private _retailer;
    
    event retailerAdded(address amount);
    event retailerRemoved(address amount);
    
    constructor(address distributor)public{
    
    
        _addRetailer(distributor);
    }
    
    function _addRetailer(address amount)internal{
    
    
        _retailer.add(amount);
        emit retailerAdded(amount);
    }
    
    function _removeRetailer(address amount)internal{
    
    
        _retailer.remove(amount);
        emit retailerAdded(amount);
    }
    
    function isRetailer(address amount)public view returns(bool){
    
    
        return _retailer.has(amount);
    }
    modifier onlyRetailer(){
    
    
        require(isRetailer(msg.sender));
        _;
    }
    function addRetailer(address amount)public onlyRetailer{
    
    
        _addRetailer(amount);
    }
    
    function removeRetailer()public{
    
    
        _removeRetailer(msg.sender);
    }
}

FoodInfoItem.sol

pragma solidity^0.4.25;
contract FoodInfoItem{
    
    
    uint256[] _timestamp;  //时间戳
    string[] _traceName;   //交易名称
    address[] _traceAddress; //交易地址
    uint8[] _traceQuality;   //交易食品质量
    string _name;           //食品名称
    string _currentName;    //当前交易名称
    address _currentAddress; //当前交易地址
    uint8 _currentQuality;   //当前交易质量 0 优质 1 合格 2 不合格
    uint8 _status;          //当前交易状态 0生产 1 分销 2销售
    address owner;
    
    constructor(string name,string traceName,address traceAddress,uint8 quality)public{
    
    
        _timestamp.push(now);
        _traceName.push(traceName);
        _traceAddress.push(traceAddress);
        _traceQuality.push(quality);
        _name = name;
        _currentName = traceName;
        _currentAddress = traceAddress;
        _currentQuality = quality;
        _status = 0;
        owner = msg.sender;
    }
    function addFoodByDistributor(string traceName,address traceAddress,uint8 quality)public returns(bool){
    
    
        require(_status == 0,"this is not already exit");
        _timestamp.push(now);
        _traceName.push(traceName);
        _traceAddress.push(traceAddress);
        _traceQuality.push(quality);
        _currentName = traceName;
        _currentAddress = traceAddress;
        _currentQuality = quality;
        _status = 1;
        return true;
    }
    
    function addFoodByRetailer(string traceName,address traceAddress,uint8 quality)public returns(bool){
    
    
        require(_status == 1,"this is not already exit");
        _timestamp.push(now);
        _traceName.push(traceName);
        _traceAddress.push(traceAddress);
        _traceQuality.push(quality);
        _currentName = traceName;
        _currentAddress = traceAddress;
        _currentQuality = quality;
        _status = 2;
        return true;
    }
    
    function getFoodInfo()public view returns(uint256,string,string,uint8,address,uint8){
    
    
        return(_timestamp[0],_name,_currentName,_currentQuality,_traceAddress[0],_status);
    }
    
    function getFoodInfoByNew()public view returns(uint256,string,string,address,uint8){
    
    
        return(_timestamp[0],_name,_traceName[0],_traceAddress[0],_traceQuality[0]);
    }
    
    function getDFoodInfoByDistributor()public view returns(uint256,string,string,string,address,uint8){
    
    
        return(_timestamp[0],_name,_traceName[0],_traceName[1],_traceAddress[1],_traceQuality[1]);
    }
    
    function getFoodInfoByRetailer()public view returns(uint256,string,string,string,string,address,uint8){
    
    
        return(_timestamp[0],_name,_traceName[0],_traceName[1],_traceName[2],_traceAddress[2],_traceQuality[2]);
    }
        
    function getFoodInfoByRoles()public view returns(uint256[],address[],uint8[]){
    
    
        return(_timestamp,_traceAddress,_traceQuality);
    }
    
    function getFoodInfoByAll()public view returns(string,uint256,string,uint8,uint256,string,uint8,uint256,string,uint8){
    
    
        return(_name,_timestamp[0],_traceName[0],_traceQuality[0],_timestamp[1],_traceName[1],_traceQuality[1],_timestamp[2],_traceName[2],_traceQuality[2]);
    }
}

Trace.sol

pragma solidity^0.4.25;
//pragma experimental ABIEncoderV2; //返回结构体类型
import "./Roles.sol";
import "./Producer.sol";
import "./Distributor.sol";
import "./Retailer.sol";
import "./FoodInfoItem.sol";

contract Trace is Producer,Distributor,Retailer{
    
    
    mapping(uint256=>address) foods;   //溯源码映射食品合约地址
    uint256[] foodList; 
    address owner; //合约的部署者,管理员
    
    //初始化三个角色,农场,分销商,超市
    constructor(address producer,address distributor,address retailer)public Producer(producer) Distributor(distributor) Retailer(retailer){
    
    
        owner = msg.sender;
    }
    //农村食品上链
    function newFood(uint256 traceNumber,string name,string traceName,uint8 quality)public onlyProducer returns(address){
    
    
        require(foods[traceNumber]==address(0));
        FoodInfoItem food = new FoodInfoItem(name,traceName,msg.sender,quality);
        foods[traceNumber] = food;
        foodList.push(traceNumber);
        return food;
    }
    //分销商食品上链
    function addFoodByDistributor(uint256 traceNumber,string traceName,uint8 quality)public onlyDistributor returns(bool){
    
    
        require(foods[traceNumber]!=address(0));
        return FoodInfoItem(foods[traceNumber]).addFoodByDistributor(traceName,msg.sender,quality);
    }
    //超市食品上链
    function addFoodByRetailer(uint256 traceNumber,string traceName,uint8 quality)public onlyRetailer returns(bool){
    
    
        require(foods[traceNumber]!=address(0));
        return FoodInfoItem(foods[traceNumber]).addFoodByRetailer(traceName,msg.sender,quality);
    }
    //当前食品溯源
    function getFoodInfo(uint256 traceNumber)public view returns(uint256,string,string,uint8,address,uint8){
    
    
        return FoodInfoItem(foods[traceNumber]).getFoodInfo();
    }
    //农场溯源
    function getFoodInfoByNew(uint256 traceNumber)public view returns(uint256,string,string,address,uint8){
    
    
        return FoodInfoItem(foods[traceNumber]).getFoodInfoByNew();
    }
    //分销商溯源
    function getDFoodInfoByDistributor(uint256 traceNumber)public view returns(uint256,string,string,string,address,uint8){
    
    
        return FoodInfoItem(foods[traceNumber]).getDFoodInfoByDistributor();
    }
    //超市溯源
    function getFoodInfoByRetailer(uint256 traceNumber)public view returns(uint256,string,string,string,string,address,uint8){
    
    
        return FoodInfoItem(foods[traceNumber]).getFoodInfoByRetailer();
    }
    //三个阶段溯源
    function getFoodInfoByRoles(uint256 traceNumber)public view returns(uint256[],address[],uint8[]){
    
    
        return FoodInfoItem(foods[traceNumber]).getFoodInfoByRoles();
    }
    //消费者整体溯源
    function getFoodInfoByAll(uint256 traceNumber)public view returns(string,uint256,string,uint8,uint256,string,uint8,uint256,string,uint8){
    
    
        return FoodInfoItem(foods[traceNumber]).getFoodInfoByAll();
    }
    //获取所有食品
    function getFoodList()public view returns(uint256[]){
    
    
        require(msg.sender == owner,'you are not owner');
        return foodList;
    }
}

Final rendering:

Insert picture description here
Insert picture description here
Insert picture description here

Guess you like

Origin blog.csdn.net/weixin_43402353/article/details/109409249