Traceability商品溯源合约案例分析
一、合约场景分析
产品溯源是将当前先进的物联网技术、自动控制技术、自动识别技术、互联网技术结合利用,通过专业的机器设备对单件产品赋予唯一的一维码或者二维码作为防伪身份证,实现“一物一码”,然后可对产品的生产、仓储、分销、物流运输、市场稽查、销售终端等各个环节采集数据并追踪,构成产品的生产、仓储、销售、流通和服务的一个全生命周期管理
源码贡献者:
github:dalaocu
源码分析者:
github:Blockchain_Key
源码链接:
https://github.com/WeBankBlockchain/SmartDev-Contract/tree/master/contracts/business_template/traceability
二、基础合约介绍
1. 产品基础合约
Goods.sol
:
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;
}
}
2.产品封装合约
Traceability.sol
:
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) public returns(Goods){
require(!_goods[goodsId].valid, "is really exists");
_goods[goodsId].valid = true;
Goods traceGoods = new Goods(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;
}
}
3.功能说明
本合约支持产品操作。包含产品的创建,获取,以及状态跟踪:
4.接口说明
提供了两个合约:Goods基合约,Traceability应用合约。
Goods合约:
- 部署创建合约:传入参数goodsId,类型uint64
getStatus()public view returns(int16)
: 获取当前产品的状态changeStatus(int16 goodsStatus, string memory remark)
: 改变当前状态。goodsStatus是改变状态的值,remark是作为当前状态的标记getTraceInfo()public view returns(TraceData[] memory _data)
:获取整个流程的状态以及详细信息(产品,状态,时间戳,状态标记)
5.使用说明
(1)Goods合约使用说明
- 部署创建合约
- 获取当前产品的状态
- 改变当前产品状态。
- 获取当前产品整个流程信息
(2)Traceability合约使用说明
- Traceability作为封装Goods的基合约,进一步抽象合约
- 由于没有对外bytes32数据接口,不支持单独使用
一、业务工厂合约介绍
TraceabilityFactory
:
pragma solidity ^0.4.25;
import "./Traceability.sol";
contract TraceabilityFactory{
struct GoodsTrace{
Traceability trace;
bool valid;
}
mapping(bytes32=>GoodsTrace) private _goodsCategory;
event newTraceEvent(bytes32 goodsGroup);
//Create traceability commodity category
function createTraceability(bytes32 goodsGroup)public returns(Traceability) {
require(!_goodsCategory[goodsGroup].valid,"The trademark already exists" );
Traceability category = new Traceability(goodsGroup);
_goodsCategory[goodsGroup].valid = true;
_goodsCategory[goodsGroup].trace = category;
emit newTraceEvent(goodsGroup);
return category;
}
function getTraceability(bytes32 goodsGroup)private view returns(Traceability) {
require(_goodsCategory[goodsGroup].valid,"The trademark has not exists" );
return _goodsCategory[goodsGroup].trace;
}
//Create traceability products
function createTraceGoods(bytes32 goodsGroup, uint64 goodsId)public returns(Goods) {
Traceability category = getTraceability(goodsGroup);
return category.createGoods(goodsId);
}
//Change product status
function changeTraceGoods(bytes32 goodsGroup, uint64 goodsId, int16 goodsStatus, string memory remark)public{
Traceability category = getTraceability(goodsGroup);
category.changeGoodsStatus(goodsId, goodsStatus, remark);
}
//Query the current status of goods
function getStatus(bytes32 goodsGroup, uint64 goodsId)public view returns(int16){
Traceability category = getTraceability(goodsGroup);
return category.getStatus(goodsId);
}
//The whole process of querying goods
function getTraceInfo(bytes32 goodsGroup, uint64 goodsId)public view returns(Goods){
Traceability category = getTraceability(goodsGroup);
return category.getGoods(goodsId);
}
function getGoodsGroup(string memory name) public pure returns (bytes32) {
return keccak256(abi.encode(name));
}
}
1.功能说明
本合约支持产品操作。包含产品类hash的创建,产品溯源创建,产品示例的创建,改变状态追踪,获取当前状态,获取溯源产品地址
2.接口说明
TraceabilityFactory合约:
function getGoodsGroup(string memory name) public pure returns (bytes32)
:根据产品名创建产品组hash值,返回bytes32类型的goodsGroupcreateTraceability(bytes32 goodsGroup)public returns(Traceability)
:根据所属产品组的goodsGroup,创建并初始化溯源合约,返回Traceability合约createTraceGoods(bytes32 goodsGroup, uint64 goodsId)public returns(Goods)
:根据所属产品组的goodsGroup,以及当前产品ID,创建并初始化本产品,返回产品地址getStatus(bytes32 goodsGroup, uint64 goodsId)public view returns(int16)
:根据所属产品组的goodsGroup,以及当前产品ID,获取当前产品的状态getTraceInfo(bytes32 goodsGroup, uint64 goodsId)public view returns(Goods)
:根据所属产品组的goodsGroup,以及当前产品ID,获取当前产品的地址changeTraceGoods(bytes32 goodsGroup, uint64 goodsId, int16 goodsStatus, string memory remark)
:根据所属产品组的goodsGroup,以及当前产品ID,更改产品的状态,和当前标志getStatus(bytes32 goodsGroup, uint64 goodsId)public view returns(int16)
:再次查看当前状态
3.使用说明
-
产品类hash的创建
-
产品溯源创建
-
产品示例的创建
-
获取当前状态
-
改变状态追踪
-
查看改变后的状态
-
获取溯源产品地址
-
拿到产品地址,返回Goods合约,查看溯源全流程