最近学习webase-front的使用,基于springboot与vue写了一个简单的溯源管理平台。
合约基于官网提供的溯源合约Traceability,下面写了详细的注释
Goods合约
pragma solidity ^0.4.25;
pragma experimental ABIEncoderV2;
contract Goods{
struct TraceData{//操作人地址
address addr;//Operator address//商品状态
int16 status;//goods status//操作时间
uint timestamp;//Operator time//数据摘要
string remark;//Digested Data}//商品编号
uint64 _goodsId;//当前商品状态
int16 _status;//current status//存储追溯数据的数组TraceData[] _traceData;//定义状态改变事件
event newStatus( address addr, int16 status, uint timestamp, string remark);//构造函数,默认调用此方法为增加商品constructor(uint64 goodsId)public{
_goodsId = goodsId;
_traceData.push(TraceData({addr:tx.origin, status:0, timestamp:now, remark:"create"}));
emit newStatus(tx.origin,0, now,"create");}//改变商品状态
function changeStatus(int16 goodsStatus, string memory remark)public{
_status = goodsStatus;
_traceData.push(TraceData({addr:tx.origin, status:goodsStatus, timestamp:now, remark:remark}));
emit newStatus(tx.origin, goodsStatus, now, remark);}//获取商品状态
function getStatus()public view returns(int16){return _status;}//获取商品追溯信息
function getTraceInfo()public view returns(TraceData[] memory _data){return _traceData;}}
Traceability合约
pragma solidity ^0.4.25;import"./Goods.sol";
contract Traceability{
struct GoodsData{Goods traceGoods;
bool valid;}
bytes32 _category;mapping(uint64=>GoodsData)private _goods;constructor(bytes32 goodsTp)public{
_category = goodsTp;}
event newGoodsEvent(uint64 goodsId);
function createGoods(uint64 goodsId)publicreturns(Goods){require(!_goods[goodsId].valid,"is really exists");
_goods[goodsId].valid =true;Goods traceGoods =newGoods(goodsId);
emit newGoodsEvent(goodsId);
_goods[goodsId].traceGoods = traceGoods;return traceGoods;}
function changeGoodsStatus(uint64 goodsId, int16 goodsStatus, string memory remark)public{require(_goods[goodsId].valid,"not exists");
_goods[goodsId].traceGoods.changeStatus(goodsStatus, remark);}
function getStatus(uint64 goodsId)public view returns(int16){require(_goods[goodsId].valid,"not exists");return _goods[goodsId].traceGoods.getStatus();}
function getGoods(uint64 goodsId)public view returns(Goods){require(_goods[goodsId].valid,"not exists");return _goods[goodsId].traceGoods;}}
TraceabilityFactory合约
pragma solidity ^0.4.25;
pragma experimental ABIEncoderV2;import"./Traceability.sol";//本合约支持产品操作。包含产品类hash的创建,产品溯源创建,产品示例的创建,改变状态追踪,获取当前状态,获取溯源产品地址
contract TraceabilityFactory{
struct GoodsTrace{Traceability trace;
bool valid;}// 声明映射,将货物类别与GoodsTrace结构体对应mapping(bytes32=>GoodsTrace)private _goodsCategory;//用于通知新的溯源商品类别已创建
event newTraceEvent(bytes32 goodsGroup);//Create traceability commodity category
function createTraceability(bytes32 goodsGroup)publicreturns(Traceability){// 判断货物类别是否已经存在require(!_goodsCategory[goodsGroup].valid,"The trademark already exists");// 创建Traceability合约实例Traceability category =newTraceability(goodsGroup);// 将货物类别标记为已验证
_goodsCategory[goodsGroup].valid =true;// 将Traceability合约实例与货物类别进行对应
_goodsCategory[goodsGroup].trace = category;// 触发newTraceEvent事件,通知新的溯源商品类别已创建
emit newTraceEvent(goodsGroup);// 返回Traceability合约实例return category;}// 根据所属产品组的goodsGroup,创建并初始化溯源合约,返回Traceability合约
function getTraceability(bytes32 goodsGroup)private view returns(Traceability){// 判断货物类别是否存在require(_goodsCategory[goodsGroup].valid,"The trademark has not exists");// 返回Traceability合约实例return _goodsCategory[goodsGroup].trace;}// 根据所属产品组的goodsGroup,以及当前产品ID,创建并初始化本产品,返回产品地址
function createTraceGoods(bytes32 goodsGroup, uint64 goodsId)publicreturns(Goods){// 获取对应货物类别的Traceability合约实例Traceability category =getTraceability(goodsGroup);// 调用Traceability合约中的createGoods函数创建溯源商品return category.createGoods(goodsId);}//根据所属产品组的goodsGroup,以及当前产品ID,更改产品的状态,和当前标志
function changeTraceGoods(bytes32 goodsGroup, uint64 goodsId, int16 goodsStatus, string memory remark)public{// 获取对应货物类别的Traceability合约实例Traceability category =getTraceability(goodsGroup);// 调用Traceability合约中的changeGoodsStatus函数更改商品状态
category.changeGoodsStatus(goodsId, goodsStatus, remark);}//根据所属产品组的goodsGroup,以及当前产品ID,获取当前产品的状态
function getStatus(bytes32 goodsGroup, uint64 goodsId)public view returns(int16){// 获取对应货物类别的Traceability合约实例Traceability category =getTraceability(goodsGroup);// 调用Traceability合约中的getStatus函数查询商品当前状态return category.getStatus(goodsId);}// 根据所属产品组的goodsGroup,以及当前产品ID,获取当前产品的地址
function getTraceInfo(bytes32 goodsGroup, uint64 goodsId)public view returns(Goods){// 获取对应货物类别的Traceability合约实例Traceability category =getTraceability(goodsGroup);// 调用Traceability合约中的getGoods函数查询商品的整个溯源过程return category.getGoods(goodsId);}//根据产品名创建产品组hash值,返回bytes32类型的goodsGroup
function getGoodsGroup(string memory name)public pure returns (bytes32){returnkeccak256(abi.encode(name));}}
这里展示一下页面的流程
新建一个商品类别,这里设置为苹果
创建类别成功的提示,这里我们已经创建的一个苹果的类别
页面的逻辑我设置成了创建类别会自动选择这个类别,所以我们创建成功后的当前类别就是苹果,我们输入1创建这个类别的id为1的商品。
在更新商品状态中,创建完id为1的商品也会自动选择到这个商品(ID:1)来,这里的1为status(状态,0为创建中,1为运输中,2为销售中),这里的话看合约规定或者按你自己想要的来改了,运输中就是remarks(备注)。
更新状态成功的提示
现在我们查询一下商品信息,查看ID为1的商品信息。可以看到已经成功记录我们的溯源信息。
这是很简单的示例,适合初学者。不过第一次弄可能确实有些困难,后端代码和前端代码太长了这里我就不放出来了,有需要的小伙伴可以私信我加我qq或者到我的咸鱼:夏沫mds,我也可以帮忙解答哦。
版权归原作者 夏沫mds 所有, 如有侵权,请联系我们删除。