相关信息
相关信息 学习记录
jspragma solidity ^0.4.25;
//请在本文件实现 Roles 库,定义一个结构体 Role,结构体内只有一个映射元素,用来存储某地址是否在该映射中,给地址进行授权
//库中定义三个方法,第一个方法在映射中添加地址,第二个方法在映射中删除地址,第三个方法判断某给定地址是否在授权映射中
//上述三个方法都是内部方法, 需在方法开始进行错误处理,参数都为 Role storage role 和 address account
library Roles {
}
jspragma solidity ^0.4.25;
/*
请在本文件中实现生产者Producer合约
1. 请引入 Role 库
2.定义两个事件:添加生产者和删除生产者事件,参数为添加或删除的地址,都为该事件的索引
3.定义一个私有的 Role 类型的结构体用来存储生产者地址以及其是否授权的信息
4.创建一个修饰符,该修饰符的作用是判断当前合约调用者是否被授权,若未授权,则报错
5.创建给某生产者地址授权的方法(增加生产者地址至映射中),并触发事件
6.创建给某生产者地址移除授权的方法,并触发事件
7.在最开始创建一个构造函数,构造函数中调用给某生产者地址授权的方法
*/
import "./Roles.sol";
contract Producer {
}
jspragma solidity ^0.4.25;
/*
请在本文件中实现超市Retailer合约
参考生产者合约要求
*/
import "./Roles.sol";
contract Retailer {
}
jspragma solidity ^0.4.25;
/*
请在本文件中实现中间商Distributor合约
参考生产者合约要求
*/
import "./Roles.sol";
contract Distributor {
}
jspragma 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) {
//补充代码
}
}
jspragma 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;
}
}
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,表示该地址不再拥有该角色。
*/
}
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);
}
}
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);
}
}
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);
}
}
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]);
}
}
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 许可协议。转载请注明出处!