前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >以太坊·食品溯源案例

以太坊·食品溯源案例

原创
作者头像
netkiller old
修改2018-02-28 21:22:02
2.1K0
修改2018-02-28 21:22:02
举报
文章被收录于专栏:Netkiller

本文节选自电子书《Netkiller Blockchain 手札》

Netkiller Blockchain 手札

本文作者最近在找工作,有意向致电 13113668890

Mr. Neo Chan, 陈景峯(BG7NYT)

中国广东省深圳市龙华新区民治街道溪山美地 518131

+86 13113668890 <netkiller@msn.com>

文档始创于2018-02-10

版权 © 2018 Netkiller(Neo Chan). All rights reserved.

版权声明

转载请与作者联系,转载时请务必标明文章原始出处和作者信息及本声明。

http://www.netkiller.cn

http://netkiller.github.io

http://netkiller.sourceforge.net

微信订阅号 netkiller-ebook (微信扫描二维码)

QQ:13721218 请注明“读者”

QQ群:128659835 请注明“读者”

内容摘要

这一部关于区块链开发及运维的电子书。

为什么会写区块链电子书?因为2018年是区块链年。

这本电子书是否会出版(纸质图书)? 不会,因为互联网技术更迭太快,纸质书籍的内容无法实时更新,一本书动辄百元,很快就成为垃圾,你会发现目前市面的上区块链书籍至少是一年前写的,内容已经过时,很多例子无法正确运行。所以我不会出版,电子书的内容会追逐技术发展,及时跟进软件版本的升级,做到内容最新,至少是主流。

这本电子书与其他区块链书籍有什么不同?市面上大部分区块链书籍都是用2/3去讲区块链原理,只要不到 1/3 的干货,干货不够理论来凑,通篇将理论或是大谈特谈区块链行业,这些内容更多是头脑风暴,展望区块链,均无法落地实施。本书与那些书籍完全不同,不讲理论和原理,面向应用落地,注重例子,均是干货。

电子书更新频率?每天都会有新内容加入,更新频率最迟不会超过一周,更新内容请关注 https://github.com/netkiller/netkiller.github.io/commits/master

本文采用碎片化写作,原文会不定期更新,请尽量阅读原文。

http://www.netkiller.cn/blockchain/index.html

您的打赏是我的写作动力:http://www.netkiller.cn/blockchain/donations.html

-----------------------------------

食品溯源案例

背景

需求是通过区块链跟踪产品,实现产品产地,生产,流通等环节溯源。

需求归纳,需要实现下面几点:

产品具备通用的属性,例如名称,价格,重量,颜色,体积等等

生产销售链条跟踪

涉及环节,农产品的供应链是一个非常复杂的过程,涉及多方,农业局、卫生局、药监局、工商局、环保局等多个部门交织其中。

合约设计

我们设计一个简单的合约

代码语言:js
复制
pragma solidity ^0.4.20;

contract Trace {

    enum State { Origin, Factory, QA, Shipping, Received, Pending }
    
    string name;
    uint price;
    uint weight;
    bool lock = false;    //合约锁
    bool close = false;    //合约状态
    uint number = 1;
    uint attr_number = 1;
    
    mapping (address  => string) guestbook; //客户留言本    

    struct Attribute {
        address owner;    // 供应商
        string name;        // 属性的名字
        string date;        // 生产日期
        string desc;        // 描述信息
        
    }
    mapping (uint  => Attribute) attribute;

    struct Logistics {
        address owner;    // 中转站
        string date;    // 转运日期
        State status;   // 状态
        string message; // 留言信息
    }
    mapping (uint  => Logistics) stations;
    
    function Trace(string _name, uint _price, uint _weight) public {
        name = _name;
        price = _price;
        weight = _weight;
    }
    // 名称
    function getName() public view returns(string){
        return name;
    }
    // 价格
    function getPrice() public view returns(uint){
        return price;
    }
    // 重量
    function getWeight() public view returns(uint){
        return weight;
    }
    
     // 增加商品属性
    function putAttribute(address _owner,string _name, string _date, string _desc ) public{
        if(lock == false){
                Attribute memory item = Attribute(_owner, _name,_date,_desc);
                attribute[attr_number] = item;
                attr_number = attr_number + 1;
        }
    }

    // 获得属性
    function getAttribute(uint _attr_number) public view returns(address, string, string, string) {
        require(_attr_number < attr_number);
        Attribute memory item = attribute[_attr_number];
        
        return (item.owner, item.name, item.date, item.desc);
    }
    
    // 增加物流中转信息
    function putLogistics(address _owner,string _date, State _status, string _message ) public{
        if(close == false){
            Logistics memory node = Logistics(_owner,_date,_status,_message);
            stations[number] = node;
            number = number + 1;
            lock = true;
        }
        if (_status == State.Received) {
            close = true;
        }
    }

    // 获得中转信息
    function getLogistics(uint _number) public view returns(address, string, State, string) {
        require(_number < number);

        Logistics memory node = stations[_number];
        
        return (node.owner, node.date, node.status, node.message);
    }
    
    // 或者转中站数量
    function getLogisticsCount() public view returns(uint){
        return number;
    }
    
    // 客户留言
        function addGuestbook(address _owner, string message) public{
        guestbook[_owner] = message;
    }
}

怎样使用这个合约呢?

合约部署,需要输入三个参数,分别是名称,价格和装量

代码语言:js
复制
Trace(string _name, uint _price, uint _weight)     

应用场景一

调用合约案例一,这是没有经过深加工的原产品案例。例如 Trace("山羊肉", 25, 50)

代码语言:js
复制
var contract;
Trace.deployed().then(function(instance){contract=instance;});
contract.getName();
contract.putAttribute("0x627306090abab3a6e1400e9345bc60c78a8bef57","颜色", "", "黑色")
contract.putAttribute("0x627306090abab3a6e1400e9345bc60c78a8bef57","产地", "", "内蒙古")
contract.putAttribute("0x627306090abab3a6e1400e9345bc60c78a8bef57","出生", "2017-01-12", "XXX牧场")
contract.putAttribute("0x627306090abab3a6e1400e9345bc60c78a8bef57","宰杀", "2018-02-12", "XXX宰杀")

contract.putLogistics("0x627306090abab3a6e1400e9345bc60c78a8bef57","2018-02-20",0,"XXX牧场");
contract.putLogistics("0x627306090abab3a6e1400e9345bc60c78a8bef57","2018-02-20",1,"XXX屠宰公司");
contract.putLogistics("0xc5fdf4076b8f3a5357c5e395ab970b5b54098fef","2018-02-22",2,"XXX检验检疫");
contract.putLogistics("0xf17f52151ebef6c7334fad080c5704d77216b732","2018-02-21",3,"XXX一级经销商");
contract.putLogistics("0x821aea9a577a9b44299b9c15c88cf3087f3b5544","2018-02-23",3,"XXX二级经销商");
contract.putLogistics("0x821aea9a577a9b44299b9c15c88cf3087f3b5544","2018-02-24",3,"XXX批发中心");
contract.putLogistics("0x821aea9a577a9b44299b9c15c88cf3087f3b5544","2018-02-25",3,"XXX超市");
contract.putLogistics("0x0d1d4e623d10f9fba5db95830f7d3839406c6af2","2018-02-26",4,"用户包裹收到");

contract.getNode(); // 获得物流经过的转运站数量        
应用场景二

调用合约案例二,经过深加工的原产品案例。

例如 Trace("牦牛肉干", 80, 500)

代码语言:js
复制
var contract;
Trace.deployed().then(function(instance){contract=instance;});
contract.getName();
contract.putAttribute("0x627306090abab3a6e1400e9345bc60c78a8bef57","调和油", "2016-10-10", "银龙鱼牌")
contract.putAttribute("0x627306090abab3a6e1400e9345bc60c78a8bef57","辣椒粉", "2016-10-30", "西藏XXX公司生产")
contract.putAttribute("0x627306090abab3a6e1400e9345bc60c78a8bef57","生抽", "2016-01-12", "XXX生抽,XXX生产")
contract.putAttribute("0x627306090abab3a6e1400e9345bc60c78a8bef57","山梨酸钾", "2017-02-12", "XXX生产")
contract.putAttribute("0x627306090abab3a6e1400e9345bc60c78a8bef57","防腐剂", "2017-02-12", "XXX生产")
contract.putAttribute("0x627306090abab3a6e1400e9345bc60c78a8bef57","牦牛肉", "2017-02-12", "XXX牧场")

contract.putLogistics("0x627306090abab3a6e1400e9345bc60c78a8bef57","2018-02-20",0,"XXX牧场");
contract.putLogistics("0x627306090abab3a6e1400e9345bc60c78a8bef57","2018-02-20",1,"XXX公司生产");
contract.putLogistics("0xc5fdf4076b8f3a5357c5e395ab970b5b54098fef","2018-02-22",2,"XXX通过QA、QC");
contract.putLogistics("0xf17f52151ebef6c7334fad080c5704d77216b732","2018-02-21",3,"XXX一级经销商");
contract.putLogistics("0x821aea9a577a9b44299b9c15c88cf3087f3b5544","2018-02-23",3,"XXX二级经销商");
contract.putLogistics("0x821aea9a577a9b44299b9c15c88cf3087f3b5544","2018-02-24",3,"XXX批发中心");
contract.putLogistics("0x821aea9a577a9b44299b9c15c88cf3087f3b5544","2018-02-25",3,"XXX超市");
contract.putLogistics("0x0d1d4e623d10f9fba5db95830f7d3839406c6af2","2018-02-26",4,"用户包裹收到");

contract.getNode(); // 获得物流经过的转运站数量        

用户留言

代码语言:js
复制
contract.addGuestbook("0x0d1d423e623d10f9d10f9d10f9d10f9d10f9fba5","东西好吃,下次还买,给好评");

以上仅仅是作者的想法,这是一个学习和熟悉只能合约开发的例子,真实场景不太可行,因为以太坊无法处理高TPS的场景。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • Netkiller Blockchain 手札
    • 本文作者最近在找工作,有意向致电 13113668890
      • Mr. Neo Chan, 陈景峯(BG7NYT)
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档