項目總要求
創(chuàng)建三個角色生產(chǎn)者,分銷商,零售商,并分別通過三個角色對產(chǎn)品的生產(chǎn),分銷,零售上鏈,并且能夠分別查出上鏈的全信息。包括每次交易的時間戳,每次交易的交易名稱,每次交易的交易地址,每次交易的食品質(zhì)量,食品的名稱,當前交易的名稱,當前交易的地址,當前交易的食品質(zhì)量,當前交易的狀態(tài)等等
運行環(huán)境:remix(0.8.13版本)
Roles.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.13;
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;
}
/**這個函數(shù)用于向特定角色添加成員。它接受一個 Role 結構體和一個地址作為參數(shù)。在函數(shù)內(nèi)部,
它首先調(diào)用 has 函數(shù)檢查地址是否已經(jīng)具有該角色,
如果沒有,則將地址添加到映射中,并將其值設置為 true,表示該地址擁有該角色。
*/
//刪除角色
function remove(Role storage role,address amount) internal {
require(has(role, amount));
role.bearer[amount] = false;
}
/**
這個函數(shù)用于從特定角色中移除成員。它接受一個 Role 結構體和一個地址作為參數(shù)。
在函數(shù)內(nèi)部,它首先調(diào)用 has 函數(shù)檢查地址是否具有該角色,
如果是,則將地址從映射中移除,并將其值設置為 false,表示該地址不再擁有該角色。
*/
}
Producer.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.13;
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);
}
/**
這個函數(shù)用于將調(diào)用者從生產(chǎn)商角色中移除。
任何人都可以調(diào)用此函數(shù)來將自己從生產(chǎn)商角色中移除。它調(diào)用了 _removeProducer 函數(shù)來執(zhí)行實際的移除操作。
*/
function removeProducer() public {
_removeProducer(msg.sender);
}
}
Distributor.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.13;
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);
}
}
Retailer.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.13;
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);
}
}
FoodInfoItem.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.13;
contract FoodInfoItem{
uint256[] _timestamp; //時間戳
string[] _traceName; //交易名稱
address[] _traceAddress; //交易地址
uint8[] _traceQuality; //交易食品名稱
string _name; //食品名稱
string _currentName; //當前交易名稱
address _currentAddress; //當前交易地址
uint8 _currentQuality; //當前交易質(zhì)量 0 優(yōu)質(zhì) 1 合格 2 不合格
uint8 _status; //當前交易狀態(tài) 0 生產(chǎn) 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);
}
//返回新增食品的信息農(nóng)場
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
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.13;
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(producer) Distributor(distributor) Retailer(retailer){
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();
}
//農(nóng)場溯源
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;
}
}
編譯部署最終結果
?文章來源:http://www.zghlxwxcb.cn/news/detail-739081.html
有不懂的可以直接評論區(qū)留言,必回文章來源地址http://www.zghlxwxcb.cn/news/detail-739081.html
到了這里,關于solidity智能合約實例開發(fā)(2)(解釋+注釋)——食品溯源的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關文章,希望大家以后多多支持TOY模板網(wǎng)!