溯源项目(全套源码)

基于以太坊的产品溯源方案

溯源,指的是往上游寻找发源的地方,比喻向上寻求历史根源。

这里有一个对商品的溯源需求,实现溯源方案有很多技术方案,无非是db+前端、或者是db+中间件+前端;db也是有很多选择,mysql、sqlserver、oracle、mongodb、redis等等不列举了;中间件也是可选择java、php、c/c++等等;前端就更加多了什么vue、h5、ios、android等等。我这里选择不用中间件,直接db+前端,db使用以太坊、前端使用h5。

补充说明下中间件可以带来很多好处,但这里我为了让这个流程简单清晰就没有使用。

现实现一套产品溯源系统,db使用以太坊、前端使用h5。如下

角色如下(角色功能如其名):

<option>消费者</option>
<option>商店</option>
<option>批发商</option>
<option>生产商</option>
<option>监管部门</option>

合约如下:

pragma solidity ^0.4.18;
contract ProductSystem{
    struct Product{//产品生产信息
        string name; //产品名称
        uint num;//库存量
        string key;//批号
        uint date;//生产时间
        address producer;//生产厂商
    }
    mapping(uint=>Product) public product;  //产品数组

    struct Warehouse{//仓库
        string name;//产品名称
        string key;//批号
        uint num;//库存量
        uint price;//价格
    }

    struct Message{//流通信息
        address seller;//卖方
        address buyer;//买方
        uint time;//交易日期
        uint num;//数量
        string key;//批号
    }
    struct Role{//角色
        string name;//名称
        uint typ;//角色类型
        uint flag;//可操作标记(0不可操作;1可以操作)
        uint ware_key;
        uint mess_key;
        mapping(uint=>Warehouse) ware;//仓库数据
        mapping(uint=>Message) mess;//购买记录
    }
    struct Role_address{//昵称与地址的映射
        string name;
        address add;
    }

    struct Report{//举报信息
        address people;//举报人
        string key;//产品批号
    }

    uint product_key;//批号的基准值
    uint report_key;//举报信息的基准值
    uint public name_address_key;//账户的基准值
    mapping(address=>Role) public role;
    mapping(uint=>Report) public report;
    mapping(uint=>Role_address) public role_address;
    event enroll_key(bool key);
    event product_production_key(bool key);
    event transaction_key(bool key);
    event reporting_key(bool key);
    event process_account_key(bool key);
    event huifu_account_key(bool key);


    function Productsystem()public{//初始化
        product_key=0;
        report_key=0;
        name_address_key=0;
    }

    function name_address(string _name)constant returns(address){
        uint i;
        for(i=0;i<name_address_key;i++){
            if(compare(_name,role_address[i].name)){
                return role_address[i].add;
            }
        }
        return;
    }

    function enroll(string _name,uint _type)public returns(bool)//注册角色
    {
        uint i;
        if(role[msg.sender].flag==1){
            emit enroll_key(false);
            return false;
        }
        for(i=0;i<name_address_key;i++){
            if(compare(_name,role_address[i].name)){
                emit enroll_key(false);
                return false;
            }
        }
        role_address[name_address_key].name=_name;
        role_address[name_address_key].add=msg.sender;
        name_address_key++;
        role[msg.sender].name=_name;
        role[msg.sender].typ=_type;
        role[msg.sender].flag=1;
        role[msg.sender].ware_key=0;
        role[msg.sender].mess_key=0;
        emit enroll_key(true);
        return true;
    }

    /*function product_inquire(uint i)constant public returns(string){
        string memory results;
        results="name:";
        results=strConcat(results,product[i].name);
        return results;
    }*/

    function product_production(string _name,uint _num,string _key,address _producer)public returns(bool){//生产产品
        uint w_key;
        if(role[_producer].typ!=0||role[_producer].flag!=1){
            emit product_production_key(false);
            return false;
        }
        if(_producer!=msg.sender){
            emit product_production_key(false);
            return false;
        }
        uint i;
        for(i=0;i<product_key;i++){
            if(compare(_key,product[i].key)){
                emit product_production_key(false);
                return false;
            }
        }
        product[product_key].name=_name;
        product[product_key].num=_num;
        product[product_key].key=_key;
        product[product_key].date=block.timestamp;
        product[product_key].producer=_producer;
        w_key=role[_producer].ware_key;
        product_key=product_key+1;
        role[_producer].ware[w_key].name=_name;
        role[_producer].ware[w_key].key=_key;
        role[_producer].ware[w_key].num=_num;
        role[_producer].ware[w_key].price=0;
        role[_producer].ware_key++;
        emit product_production_key(true);
        return true;
    }

    //function product_management_add(address account,Warehouse _ware)public{
    //    role[account].ware.push(_ware);
    //}

    function compare(string _a,string _b)returns(bool){//判断字符串是否相等
        bytes memory a = bytes(_a);
        bytes memory b = bytes(_b);
        if (a.length != b.length)
            return false;
        // @todo unroll this loop
        for (uint i = 0; i < a.length; i ++)
            if (a[i] != b[i])
                return false;
        return true;
    }

    function product_management_inquire(address account,string _name)constant public returns (uint){//监管者查询仓库中某产品的数量
        uint sum=0;
        uint i;
        if(role[msg.sender].typ!=4)
            return;
        for(i=0;i<role[account].ware_key;i++){
            if(compare(_name,role[account].ware[i].name)){
                sum+=role[account].ware[i].num;
            }
        }
        return sum;
    }

    function inquire_product(string _name)constant public returns (uint){//查询本人仓库中某产品的数量
        uint sum=0;
        uint i;
        for(i=0;i<role[msg.sender].ware_key;i++){
            if(compare(_name,role[msg.sender].ware[i].name)){
                sum+=role[msg.sender].ware[i].num;
            }
        }
        return sum;
    }

    function transaction(address _from,address to,string _name,string _key,uint _price)public returns(bool){//产品交易函数
        uint i;
        uint j;
        uint w_key;
        uint m_key;
        if(role[_from].typ==4||role[to].typ==4||role[to].typ==0){
            emit transaction_key(false);
            return false;
        }
        if(_from!=msg.sender){
            emit transaction_key(false);
            return false;
        }
        if(role[_from].flag==0){
            emit transaction_key(false);
            return false;
        }
        for(i=0;i<role[_from].ware_key;i++){
            if(compare(_key,role[_from].ware[i].key)){
                if(!compare(role[_from].ware[i].name,_name)){
                    emit transaction_key(false);
                    return false;
                }
                w_key=role[to].ware_key;//将交易产品的信息写入买方的仓库
                role[to].ware[w_key].name=_name;
                role[to].ware[w_key].key=_key;
                role[to].ware[w_key].price=_price;
                role[to].ware[w_key].num=role[_from].ware[i].num;
                for(j=i;j<role[_from].ware_key-1;j++){//从卖方仓库中删除交易产品的信息
                    role[_from].ware[j].name=role[_from].ware[j+1].name;
                    role[_from].ware[j].key= role[_from].ware[j+1].key;
                    role[_from].ware[j].num=role[_from].ware[j+1].num;
                    role[_from].ware[j].price=role[_from].ware[j+1].price;
                }
                role[to].ware_key++;
                role[_from].ware_key--;

                m_key=role[to].mess_key;//交易信息写入买方的交易信息数组
                role[to].mess[m_key].seller=_from;
                role[to].mess[m_key].buyer=to;
                role[to].mess[m_key].time=block.timestamp;
                role[to].mess[m_key].num=role[to].ware[w_key].num;
                role[to].mess[m_key].key=_key;
                role[to].mess_key++;
                emit transaction_key(true);
                return true;
            }
        }
        emit transaction_key(false);
        return false;
    }

    function strConcat(string _a, string _b) returns (string){//字符串拼接
        bytes memory _ba = bytes(_a);
        bytes memory _bb = bytes(_b);
        string memory ret = new string(_ba.length + _bb.length);
        bytes memory bret = bytes(ret);
        uint k = 0;
        for (uint i = 0; i < _ba.length; i++)bret[k++] = _ba[i];
        for (i = 0; i < _bb.length; i++) bret[k++] = _bb[i];
        return string(ret);
    }

    function inquire(address account,string _key)constant public returns (string){//查询产品交易信息链
        uint i;
        string memory results;
        results="";
        if(role[account].flag==0){
            return;
        }
        if(0==role[account].typ){
            results=role[account].name;
            return results;
        }
        for(i=0;i<role[account].mess_key;i++){
            if(compare(_key,role[account].mess[i].key)){
                results=inquire(role[account].mess[i].seller,_key);
                break;
            }
        }
        if(i==role[account].mess_key){
            return "errer!!!";
        }
        results=strConcat("<=",results);
        results=strConcat(role[account].name,results);
        return results;
    }

    function reporting(address _account,string _key)public returns(bool){//消费者提交举报信息
        if(_account!=msg.sender){
            emit reporting_key(false);
            return false;
        }
        else
        {
            report[report_key].people=_account;
            report[report_key].key=_key;
            report_key++;
        }
        emit reporting_key(true);
        return true;
    }

    function buyer_inquire_mess(uint _int)constant public returns(address,address,uint,uint,string){//返回消费记录
        /*uint i;
        string memory results;
        for(i=0;i<role[_account].mess_key;i++){
            results=strConcat(results,"seller:");
            results=strConcat(results,role[role[_account].mess[i].seller].name);
            results=strConcat(results,"   ");
            results=strConcat(results,"buyer:");
            results=strConcat(results,role[role[_account].mess[i].buyer].name);
            results=strConcat(results,"   ");
            results=strConcat(results,"key:");
            results=strConcat(results,role[_account].mess[i].key);
            results=strConcat(results,"\n ");
        }*/
        if(_int<role[msg.sender].mess_key)
            return (role[msg.sender].mess[_int].seller,role[msg.sender].mess[_int].buyer,role[msg.sender].mess[_int].time,role[msg.sender].mess[_int].num,role[msg.sender].mess[_int].key);
        else
            return;
    }

    function buyer_inquire_ware(uint _int)constant public returns(string,string,uint,uint){//返回仓库信息
        /*uint i;
        string memory results;
        for(i=0;i<role[_account].ware_key;i++){
            results=strConcat(results,"name:");
            results=strConcat(results,role[_account].ware[i].name);
            results=strConcat(results,"   ");
            results=strConcat(results,"key:");
            results=strConcat(results,role[_account].ware[i].key);
            results=strConcat(results,"\n ");
        }*/
        if(_int<role[msg.sender].ware_key)
            return (role[msg.sender].ware[_int].name,role[msg.sender].ware[_int].key,role[msg.sender].ware[_int].num,role[msg.sender].ware[_int].price);
        else
            return;
    }

    function process_report(address _account)constant public returns(string){//处理举报信息
        uint i;
        uint j;
        string memory results;
        if(role[msg.sender].typ!=4)
            return;
        for(i=report_key-1;i>=0;i--){
            if(_account==report[i].people){
                results=inquire(report[i].people,report[i].key);
                for(j=i;j<report_key-1;j++){
                    report[j].people=report[j+1].people;
                    report[j].key=report[j+1].key;
                }
                report_key--;
                break;
            }
        }
        return results;
    }

    function process_account(address _account)public returns(bool){//处理违规账户
        if(role[msg.sender].typ!=4){
            emit process_account_key(false);
            return false;
        }
        role[_account].flag=0;
        emit process_account_key(true);
        return true;
    }

    function huifu_account(address _account)public returns(bool){//恢复违规账户
        if(role[msg.sender].typ!=4){
            emit huifu_account_key(false);
            return false;
        }
        role[_account].flag=1;
        emit huifu_account_key(true);
        return true;
    }
}

搭建本地以太坊开发环境,弄一个私链,不清楚搭建看这个网址

1.启动本地环境

Geth输入命令

geth -targetgaslimit 4294967295 -rpc -rpcaddr “127.0.0.1” -rpcport “8101” -port “30301” -rpcapi “eth,web3,personal” -networkid 123 -identity 123 -nodiscover -maxpeers 5 -datadir “/root/ethereum/chain2” -unlock 0 -rpccorsdomain “*” -mine console

其中,datadir表示数据存储位置,123表示识别ID,要保持和其他节点一致,port表示使用的和别的节点连接的端口,rpc表示与外界进行交互,其中暴露的端口rpcport默认为8545也可以修改为自己的8101,rpcdomain表示允许进行访问的网站域名集,*表示所有网站都可以访问,否则会出现无法进行跨域访问的报错,console表示控制台打开。

  1. 创建账户并解锁账户,挖矿,使账户具有一定的余额

    > eth.accounts
    ["0x4aeb1e38b0821c26d6d834e4e7680301bbbba7f1", "0x2a35fc2bb657e247b10cff2a009b0912d4f9eace", "0x1340037bcc54787b2b629189b4eff3eded6741c5", "0x63cbdd13bf223ce6ce675457155c2198b377b05f", "0x424a7972e9fa609c0834c23e7dfd83a68de8531b", "0x79143c7d4af835e9836276ff8788614865811b04"]
    > 
    > eth.getBalance(eth.accounts[0])
    1.36757044740584e+23
    

personal.newcount(“password”);//创建新账户

personal.unlockAccount(eth.account[0]);//解锁账户

miner.start()//开始挖矿

3.发布合约,修改连接文件

使用loadScript(“001.js”);将合约发布,将合约地址复制。

打开项目中的连接文件conect.js,将地址替换为新的合约地址。

INFO [03-30|17:58:14] Regenerated local transaction journal    transactions=0 accounts=0
INFO [03-30|18:12:50] Submitted contract creation              fullhash=0xdec1c60c8361169a2db4cec9ee9cd8e891e3ea142857ae517b3066fe5f35d7c7 contract=0x4dfA7D24F4913Fbb6869ed2180200e767328573B
INFO [03-30|18:14:03] Updated mining threads                   threads=0
INFO [03-30|18:14:03] Transaction pool price threshold updated price=18000000000
INFO [03-30|18:14:03] Starting mining operation 
INFO [03-30|18:14:03] Commit new mining work                   number=28153 txs=1 uncles=0 elapsed=2.477ms

前端管理界面就不上代码了,源码见下。

源码地址

本地调试可使用webstorm打开工程或者直接文件夹中找到index.html,双击index.html在浏览器中打开,修改相关配置:

conect.js 文件

if (typeof web3 !== 'undefined')  
   web3 = new Web3(web3.currentProvider);  
else   
    web3 = new Web3(new Web3.providers.HttpProvider("http://localhost:8101"));//此处为geth填写的rpcport
     
if(!web3.isConnected()) 
       console.log("UnConected")
else 
   console.log("Conected")

deployeAddr="0xA975A87c72A2E4141E85365AFf0424b7da45Ae3A";           //此处为合约发布后的地址

index.js 文件

if (typeof web3 !== 'undefined')  
   web3 = new Web3(web3.currentProvider);  
else
{  
    web3 = new Web3(new Web3.providers.HttpProvider("http://localhost:8101"));
 } 

打开index.html愉快的工作了!在这里插入图片描述个人信息界面在这里插入图片描述

  • 10
    点赞
  • 85
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
【资源说明】 基于区块链技术JavaScript+Vue的食品安全溯源平台源码+项目部署运行说明.zip基于区块链技术JavaScript+Vue的食品安全溯源平台源码+项目部署运行说明.zip基于区块链技术JavaScript+Vue的食品安全溯源平台源码+项目部署运行说明.zip基于区块链技术JavaScript+Vue的食品安全溯源平台源码+项目部署运行说明.zip基于区块链技术JavaScript+Vue的食品安全溯源平台源码+项目部署运行说明.zip基于区块链技术JavaScript+Vue的食品安全溯源平台源码+项目部署运行说明.zip 基于区块链技术JavaScript+Vue的食品安全溯源平台源码+项目部署运行说明.zip - 项目代码 ```bash csdn下载项目源码并解压 cd jeecg-boot/ant-design-jeecg-vue ``` - 安装依赖 ``` yarn install ``` - 开发模式运行 ``` yarn run serve ``` - 编译项目 ``` yarn run build ``` - Lints and fixes files ``` yarn run lint ``` 【备注】 1、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用! 2、本项目适合计算机相关专业(如计科、人工智能、通信工程、自动化、电子信息等)的在校学生、老师或者企业员工下载使用,也适合小白学习进阶,当然也可作为毕设项目、课程设计、作业、项目初期立项演示等。 3、如果基础还行,也可在此代码基础上进行修改,以实现其他功能,也可直接用于毕设、课设、作业等。 欢迎下载,沟通交流,互相学习,共同进步!

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值