2024-09-13
区块链学习笔记
00
请注意,本文编写于 219 天前,最后修改于 213 天前,其中某些信息可能已经过时。

目录

GZ036 区块链技术应用赛项赛题第1套(模块二)
模块二 食品溯源智能合约部分
练习代码
Roles.sol
Producer.sol
Retailer.sol
Distributor.sol
FoodInfoItem.sol
Trace.sol
完整代码
Roles.sol
Producer.sol
Retailer.sol
Distributor.sol
FoodInfoItem.sol
Trace.sol
下载

GZ036 区块链技术应用赛项赛题第1套(模块二)

模块二 食品溯源智能合约部分

相关信息

相关信息 学习记录

image.png

练习代码

Roles.sol
js
pragma solidity ^0.4.25; //请在本文件实现 Roles 库,定义一个结构体 Role,结构体内只有一个映射元素,用来存储某地址是否在该映射中,给地址进行授权 //库中定义三个方法,第一个方法在映射中添加地址,第二个方法在映射中删除地址,第三个方法判断某给定地址是否在授权映射中 //上述三个方法都是内部方法, 需在方法开始进行错误处理,参数都为 Role storage role 和 address account library Roles { }
Producer.sol
js
pragma solidity ^0.4.25; /* 请在本文件中实现生产者Producer合约 1. 请引入 Role 库 2.定义两个事件:添加生产者和删除生产者事件,参数为添加或删除的地址,都为该事件的索引 3.定义一个私有的 Role 类型的结构体用来存储生产者地址以及其是否授权的信息 4.创建一个修饰符,该修饰符的作用是判断当前合约调用者是否被授权,若未授权,则报错 5.创建给某生产者地址授权的方法(增加生产者地址至映射中),并触发事件 6.创建给某生产者地址移除授权的方法,并触发事件 7.在最开始创建一个构造函数,构造函数中调用给某生产者地址授权的方法 */ import "./Roles.sol"; contract Producer { }
Retailer.sol
js
pragma solidity ^0.4.25; /* 请在本文件中实现超市Retailer合约 参考生产者合约要求 */ import "./Roles.sol"; contract Retailer { }
Distributor.sol
js
pragma solidity ^0.4.25; /* 请在本文件中实现中间商Distributor合约 参考生产者合约要求 */ import "./Roles.sol"; contract Distributor { }
FoodInfoItem.sol
js
pragma solidity >=0.4.22 <0.5.0; pragma experimental ABIEncoderV2; /* 请在本文件实现食品信息管理合约 1.定义食品信息变量,包括: a.uint[] 保存食品流转过程中各个阶段的时间戳 b.string[] 保存食品流转过程各个阶段的用户名 c.address[] 保存食品流转过程各个阶段的用户地址信息(和用户一一对应) d.uint8[] 保存食品流转过程中各个阶段的质量 e.食物名称 f.当前用户名称 g.质量(0=优质 1=合格 2=不合格) h.状态(0:生产 1:分销 2:出售) i._owner 食物创建人 2. 在构造函数中对上述变量进行初始化 a.存入当前时间 b.状态为生产 c._owner 为当前合约调用者 d.其他信息作为参数传入 3.实现中间商添加食品信息方法: a.首先进行错误处理,需要食品状态信息为生产,_owner为当前合约调用者,否则报错 b.更新食品信息:存入当前时间,状态为分销 c.其他信息作为参数传入 4.实现超市添加食品信息方法,参考上一步 5.实现返回食品溯源信息方法,返回信息有食品流转过程中的:时间戳,用户名称,用户地址信息,质量 6.实现返回食品信息方法,返回信息有:时间戳,用户名,食品名称,当前用户名,用户地址,食品质量 */ 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 name, string traceName, uint8 quality, address producer) public { _timestamp.push(now); _traceName.push(traceName); _traceAddress.push(producer); _traceQuality.push(quality); _name = name; _currentTraceName = traceName; _quality = quality; _status = 0; _owner = msg.sender; } function addTraceInfoByDistributor( string traceName, address distributor, uint8 quality) public returns(bool) { //补充代码 } function addTraceInfoByRetailer( string traceName, address retailer, uint8 quality) public returns(bool) { //补充代码 } function getTraceInfo() public constant returns(uint[], string[], address[], uint8[]) { //补充代码 } function getFood() public constant returns(uint, string, string, string, address, uint8) { //补充代码 } }
Trace.sol
js
pragma solidity >=0.4.22 <0.7.0; pragma experimental ABIEncoderV2; import "./FoodInfoItem.sol"; import "./Distributor.sol"; import "./Producer.sol"; import "./Retailer.sol"; /* 请在本文件中按照提示实现对应的方法 */ //食品工厂合约,负责具体食品溯源信息的生成 contract Trace is Producer, Distrisbutor, Retailer{ //创建映射foods,存储食品溯源 id 到具体食品溯源合约地址的映射表 //创建一个数组存储食品列表foodList //补充代码 //构造函数 constructor(address producer, address distributor, address retailer) public Producer(producer) Distributor(distributor) Retailer(retailer){ } /*生成食品溯源信息接口: 1.只有Producer能调用 2.首先进行错误处理,在 foods 映射中不存在当前食物,否则报错 3.对FoodInfoItem合约进行初始化,传入参数name, traceName, quality, msg.sender 4.将初始化后的合约地址传入 foods 映射 5.在foodList数组中存入新食物的traceNumber */ function newFood(string name, uint256 traceNumber, string traceName, uint8 quality) public onlyProducer returns(address) { require(foods[traceNumber] == address(0), "traceNumber already exist"); FoodInfoItem food = new FoodInfoItem(name, traceName, quality, msg.sender); //补充代码 return food; } /*食品分销过程中增加溯源信息的接口 1.只有Distributor能调用 2.首先进行错误处理,在 foods 映射中存在当前食物,否则报错 3.调用 FoodInfoItem 合约中的中间商添加食品信息方法 */ function addTraceInfoByDistributor(uint256 traceNumber, string traceName, uint8 quality) public onlyDistributor returns(bool) { require(foods[traceNumber] != address(0), "traceNumber does not exist"); return FoodInfoItem(foods[traceNumber]).addTraceInfoByDistributor( traceName, msg.sender, quality); } /*食品出售过程中增加溯源信息的接口 1.只有Retailer能调用 2.首先进行错误处理,在 foods 映射中存在当前食物,否则报错 3.调用 FoodInfoItem 合约中的超市添加食品信息方法 */ function addTraceInfoByRetailer(uint256 traceNumber, string traceName, uint8 quality) public onlyRetailer returns(bool) { //补充代码 } /*获取食品溯源信息接口 1.首先进行错误处理,在 foods 映射中存在当前食物,否则报错 2.调用FoodInfoItem合约中的获取食品溯源信息方法 string[] 保存食品流转过程中各个阶段的相关信息 address[] 保存食品流转过程各个阶段的用户地址信息(和用户一一对应) uint8[] 保存食品流转过程中各个阶段的状态变化 */ function getTraceInfo(uint256 traceNumber) public constant returns(uint[], string[], address[], uint8[]) { //补充代码 } /*获取食品信息接口 1.首先进行错误处理,在 foods 映射中存在当前食物,否则报错 2.调用FoodInfoItem合约中的获取食品信息方法 */ function getFood(uint256 traceNumber) public constant returns(uint, string, string, string, address, uint8) { //补充代码 } /*获取所有食品信息列表接口 返回foodList */ function getAllFood() public constant returns (uint[]) { return foodList; } }

完整代码

Roles.sol
js
// SPDX-License-Identifier: MIT 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; } /**这个函数用于向特定角色添加成员。它接受一个 Role 结构体和一个地址作为参数。在函数内部, 它首先调用 has 函数检查地址是否已经具有该角色, 如果没有,则将地址添加到映射中,并将其值设置为 true,表示该地址拥有该角色。 */ //删除角色 function remove(Role storage role,address amount) internal { require(has(role, amount)); role.bearer[amount] = false; } /** 这个函数用于从特定角色中移除成员。它接受一个 Role 结构体和一个地址作为参数。 在函数内部,它首先调用 has 函数检查地址是否具有该角色, 如果是,则将地址从映射中移除,并将其值设置为 false,表示该地址不再拥有该角色。 */ }
Producer.sol
js
// SPDX-License-Identifier: MIT pragma solidity ^0.4.25; import "./Roles.sol"; contract Producer{ using Roles for Roles.Role; Roles.Role private _produce; event producerAdded(address amount); event producerRemoved(address amount); constructor(address produce) public { _addProducer(produce); } function _addProducer(address amount) internal { _produce.add(amount); emit producerAdded(amount); } function _removeProducer(address amount) internal { _produce.remove(amount); emit producerRemoved(amount); } function isProducer(address amount ) public view returns (bool){ return _produce.has(amount); } modifier onlyProducer(){ require(isProducer(msg.sender),"you are not deployer"); _; } function addProducer(address amount) public onlyProducer{ _addProducer(amount); } /** 这个函数用于将调用者从生产商角色中移除。 任何人都可以调用此函数来将自己从生产商角色中移除。它调用了 _removeProducer 函数来执行实际的移除操作。 */ function removeProducer() public { _removeProducer(msg.sender); } }
Retailer.sol
js
// SPDX-License-Identifier: MIT 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 Retailer) { _addRetalier(Retailer); } function _addRetalier(address amount) internal { _retailer.add(amount); emit retailerAdded(amount); } function _removeRetailer(address amount) internal { _retailer.remove(amount); emit retailerRemoved(amount); } function isRetailer(address amount) public view returns (bool){ return _retailer.has(amount); } modifier onlyRetailer() { require(isRetailer(msg.sender),"you are not deployer"); _; } function addRetailer(address amount) public { _addRetalier(amount); } function removeRetailer() public { _removeRetailer(msg.sender); } }
Distributor.sol
js
// SPDX-License-Identifier: MIT 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){ _addDistributor(distributor); } function _addDistributor(address amount) internal { _distributor.add(amount); emit distributorAdded(amount); } function _removeDistributor(address amount) internal { _distributor.remove(amount); emit distributorRemoved(amount); } function isDistributor(address amount) public view returns (bool){ return _distributor.has(amount); } modifier onlyDistributor(){ require(isDistributor(msg.sender),"you are not deployer"); _; } function addDistributor(address amount) public onlyDistributor{ _addDistributor(amount); } function removeDistributor() public { _removeDistributor(msg.sender); } }
FoodInfoItem.sol
js
// SPDX-License-Identifier: MIT 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 memory name, string memory traceName, address traceAddress,uint8 quality) public { _timestamp.push(block.timestamp); _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 memory traceName, address traceAddress,uint8 quality) public returns(bool) { require(_status == 0 ,"this is not status 0"); _timestamp.push(block.timestamp); _traceName.push(traceName); _traceAddress.push(traceAddress); _traceQuality.push(quality); _currentName = traceName; _currentAddress = traceAddress; _currentQuality = quality; _status = 1; return true; } function addFoodByRetailer(string memory traceName, address traceAddress,uint8 quality) public returns(bool){ require(_status == 1 ,"this is not status 0"); _timestamp.push(block.timestamp); _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 memory,string memory,uint8,address,uint8){ return (block.timestamp,_name,_currentName,_currentQuality,_currentAddress,_status); } //返回新增食品的信息农场 function getFoodInfoNew() public view returns (uint256,string memory,string memory,address,uint8){ return (block.timestamp,_name,_traceName[0],_traceAddress[0],_traceQuality[0]); } //返回通过分销商的信息 function getFoodInfoByDistributor() public view returns (uint256,string memory,string memory,string memory,address,uint8){ return (block.timestamp,_name,_traceName[0],_traceName[1],_traceAddress[1], _traceQuality[1]); } //返回通过零售商的信息 function getFoodInfoByRetailer() public view returns (uint256,string memory, string memory,string memory,string memory, address,uint8){ return (_timestamp[0],_name,_traceName[0],_traceName[1],_traceName[2],_traceAddress[2],_traceQuality[2]); } function getFoodInfoByRoles() public view returns (uint256,address[] memory,uint8[] memory){ return (_timestamp[0],_traceAddress,_traceQuality); } function getFoodInfoByAll() public view returns (string memory,uint256,string memory,uint8,uint256,string memory,uint8,uint256,string memory,uint8){ return (_name,_timestamp[0],_traceName[0],_traceQuality[0],_timestamp[1],_traceName[1],_traceQuality[1],_timestamp[2],_traceName[2],_traceQuality[2]); } }
Trace.sol
js
// SPDX-License-Identifier: MIT pragma solidity ^0.4.25; 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 public owner; constructor(address producer,address distributor,address retailer) public Producer(address(0x64fa644d2a694681bd6addd6c5e36cccd8dcdde3)) Distributor(address(0x64fa644d2a694681bd6addd6c5e36cccd8dcdde3)) Retailer(address(0x64fa644d2a694681bd6addd6c5e36cccd8dcdde3)){ owner = msg.sender; } function newFood(uint256 traceNumber,string memory name,string memory traceName, uint8 quality) public onlyProducer returns (FoodInfoItem){ require(foods[traceNumber]==address(0),"address is not exist"); FoodInfoItem food = new FoodInfoItem(name,traceName,msg.sender,quality); foods[traceNumber] = address(food); foodlist.push(traceNumber); return food; } function addFoodByDistributor(uint256 traceNumber,string memory traceName,uint8 quality) public onlyDistributor returns (bool){ require(foods[traceNumber] != address(0),"address is 0"); return FoodInfoItem(foods[traceNumber]).addFoodByDistributor(traceName,msg.sender, quality); } function addFoodByRetailer(uint256 traceNumber, string memory traceName, uint8 quality) public onlyRetailer returns (bool){ require(foods[traceNumber] != address(0),"address is 0"); return FoodInfoItem(foods[traceNumber]).addFoodByRetailer(traceName, msg.sender, quality); } //当前食品溯源 function getFoodInfo(uint256 traceNumber) public view returns (uint256,string memory,string memory,uint8,address,uint8){ return FoodInfoItem(foods[traceNumber]).getFoodInfo(); } //农场溯源 function getFoodInfoByNew(uint256 traceNumber) public view returns (uint256,string memory,string memory,address,uint8) { return FoodInfoItem(foods[traceNumber]).getFoodInfoNew(); } //分销商溯源 function getFoodInfoByDistributor(uint256 traceNumber) public view returns (uint256,string memory,string memory,string memory,address,uint8) { return FoodInfoItem(foods[traceNumber]).getFoodInfoByDistributor(); } //零售商溯源 function getFoodInfoRetailer(uint256 traceNumber) public view returns (uint256,string memory, string memory,string memory,string memory, address,uint8) { return FoodInfoItem(foods[traceNumber]).getFoodInfoByRetailer(); } //三个阶段溯源 function getFoodInfoByRoles(uint256 traceNumber) public view returns (uint256,address[] memory,uint8[] memory){ return FoodInfoItem(foods[traceNumber]).getFoodInfoByRoles(); } //消费者整体溯源 function getFoodInfoByAll(uint256 traceNumber) public view returns (string memory,uint256,string memory,uint8,uint256,string memory,uint8,uint256,string memory,uint8) { return FoodInfoItem(foods[traceNumber]).getFoodInfoByAll(); } //获取所有商品 function getAllFood() public view returns (uint256[] memory){ require(msg.sender == owner,"you are not deployer"); return foodlist; } }

至此所有演示全部结束。

下载

原题下载:GZ036 区块链技术应用赛项赛题第1套
合约下载:食品溯源合约

本文作者:苏皓明

本文链接:

版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!