文档章节

食品安全溯源区块链解决方案探索

netkiller-
 netkiller-
发布于 03/14 08:12
字数 4149
阅读 332
收藏 7
点赞 0
评论 10

食品安全溯源区块链解决方案探索

 

本文节选自电子书《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.

版权声明

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

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

QQ:13721218 请注明“读者”

QQ群:128659835 请注明“读者”

网站:http://www.netkiller.cn

内容摘要

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

为什么会写区块链电子书?因为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

==============================

33.2. 食品溯源案例

33.2.1. 背景

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

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

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

生产销售链条跟踪

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

参与者角色,我们为每个环节的参与者分配一个以太坊账号,例如每个供应商一个账号,每个代理商一个账号。这样任何一方经手后都会使用自己的账号想合约中添加数据。

33.2.2. 安全问题

我将安全划分为六层,分别是:

+----------+-----------------------------+
	| 实体层    | 物                          |
	+----------+-----------------------------+
	| 用户层    | 人                          |
	+----------+-----------------------------+
	| 网络层    | 网络                         |
	+----------+-----------------------------+
	| 应用层    | 操作系统,应用服务器           |
	+----------+-----------------------------+
	| 业务逻辑层 | 功能,业务逻辑                |
	+----------+-----------------------------+
	| 存储层    | 物理存储,文件系统,硬盘                |
	+----------+-----------------------------+

并不是实施了区块链技术就安全无忧了,安全分为很多层,区块链只能做到存储层的安全。区块链无法解决用户层,应用层,逻辑层等安全问题,他只能保证存储在硬盘上的区块不被修改。

因为区块链仅仅能解决数据存储层的安全问题,不能保证上链的数据是真实的,上链前绝对不会被篡改;所以仅仅朔源,不考虑防伪是没有意义的,防伪仍然是重中之重。

33.2.3. 防伪问题

如何做防伪呢,这个领域很多公司已经探索多年,各种高科技应用,武装到牙齿,但仍没有解决假货问题。

区块链的出现很可能是一个突破,我们只需将现有成熟的防伪技术与区块链结合即可。

现在流行的访问技术太多了,我倾向于采用二维码技术,二维码与互联网紧密相连。

33.2.4. 性能问题

区块链目前的底层只适合做,低频高价值的业务。

区块链的读取性能通常是没有问题的,但是区块链的写入实际上无论你用多少个服务器节点都不能提升,因为写入区块需要做共识算法,这步操作,会在所有节点上进行,同时还需要加密运算,这些操作都是 CPU 密集型操作。所以写入操作是存在瓶颈的。

解决这个问题,我想出了几种方案:

性能解决方案

  • 通过消息队列技术异步写入,将需要写入的区块放入队列,异步完成上链操作。
  • 并行写入,我们可以建设多个区块链平台。多个平台同时服务于业务。

为了达到去中心化并行写入,我们将在客户端通过算法,匹配服务器。而不是在两个平台前面增加负载均衡。因为这样又回到了中心化系统。

33.2.5. 颗粒度问题

朔源的颗粒度问题,例如“红酒”的溯源,我们是将单位溯源做到箱呢?还是打,或是瓶呢?

我们用“四象限法则”分析

高价值
                   o     |
                         |    o
                         |
    低频率  --------------+-------------  高频率 操作频率
                         |
            o            |	o	
                         |
                       低价值		
                        
                      物品价值

通过观察上面图,我们可以看到可以有四种情况,低频低价值,低频高价值,高频高价值,高频低价值

我认为对于低频高价值和高频高价值的业务,尽量做到最小颗粒度。

而对于低频低价值和高频低价值的业务,可以颗粒度更粗。

33.2.6. 存储规划

如果是高频低价值的业务,那么溯源数据源源将会不断的被添加到区块,以此同时区块的访问率极低。迟早会达到一个临界值。

所以你要规划存储,例如溯源数据的过期时间,对于 hyperledger 可以使用 DelState(key) 删除历史数据。

如果是高频高价值的业务是否要考虑永久保留数据呢?

这些问题都是需要考虑的。因为目前我们还不知道区块链的存储临界值。

33.2.7. 大数据问题

区块链替代不了数据库,它与数据库是互补关系。

对于低频的业务,通常传统数据库足以应付。那么对于高频操作的业务呢?暂时可能没有问题,但总有一天会遇到瓶颈。

综上所述,溯源项目数据库规划决不能少。同时还要考虑数据仓库和后期数据挖掘。因为用户使用微信或者我们的APP扫描二维码,我们可以获得很多有价值的数据。

手上没有 Vision 使用文本简单的绘制了一幅图

+------------------------+
                             |    User -> QR Code     |
                             +------------------------+
                                 |              |    
                                 V              V
+---------------+    +---------------+    +---------------+
| Search Engine |<-- | Microservice  |    |  Microservice |
+---------------+    +---------------+    +---------------+
                           |                     |
         +----------------------------------+    |
         |                 |                |    |
         V                 V                V    V
    +----------+     +------------+    +-------------+ 
    | Database |     | Big Data   |    | Blockchain  |
    +----------+     +------------+    +-------------+
    | MySQL    |     | Hadoop     |    | Hyperledger |
    | NoSQL    |     | Hive/Hbase |    | Chaincode   |
    +----------+     +------------+    +-------------+	
         |   |                ^               ^
         |   +------ ETL -----|               |
         |                                    |
         +----------- Message Queue ----------o

区块链之外的很多复杂的需求我们需要借助大数据系统和搜索技术。

区块链的弱点是无法做复杂的查询,这里我们会用到搜索引擎技术解决,实际上搜索引擎角色是给区块链做索引。

上图数据写入时,保存了四份,分别在搜索引擎,关系型数据库,数据仓库和区块的

具体怎么实现,有很多方式,这里就不讨论了,否则就跑题了。

33.2.8. BI商业智能

数据采集,大数据分析

溯源信息的查询是通过用户手机终端实现,有几种途径,微信扫二维码,APP扫二维码,微信小程序等等。

我们可以收集到很多有价值的数据,例如地理位置,手机号码,性别,年龄等等......

有了这些数据便可以挖掘出有价值的数据。例如用户行为分析,消费与地理分析的关系,年龄段与购买力的关系等等....

33.2.9. 采集终端

溯源数据怎么录入呢?

例如我们开发一个设备,二维码扫描枪,内置安卓系统。

我们不清楚他们的教育背景以及学习能力,所以设计原则是尽量傻瓜化,降低数据录入难度和学习难度,终端开机后互动教学,走一遍流程即可上手。

首先将溯源环节的每个节点通过后台事先写入数据库,接下来通过GIS地理信息系统匹配。

UUID -> 二维码 -> 设备扫描二维码激活-> 入数据库 -> 异步消息队列 -> 上链 > ---+
                       ^                                             |
                       |                                             |
                       +------------------- 追加数据 ------------------+

终端会帮助用户欲录入信息,用户可以在信息基础上修改或者重写。同时终端支持图片,图像记录上传。对于图片还能实现 EXIF 数据保存,包括图片描述信息,地理信息等等......

多媒体数据

这里我们需要考虑是否需要记录多媒体数据,这里的多媒体指图像,声音,甚至3D扫描数据等等......

对于图片、音频与视频,我们可以将它集成到采集终端上,然后异步上传到去中心化的分布式文件系统中。

去中心化的分布式文件系统能实现,一张图片一个hash值,通过hash值访问图片,图片被同步到相邻节点实现去中心化,图片被修改hash值随之变化数据便无效。

33.2.10. 物流接口

使用物流单好通过物流公司提供的借口获得物流数据,然后写入到区块。

 

33.2.12. 如何激励用户

防伪技术做了,区块链溯源也做了,那么对于用户来说,他可能懒得去扫你的二维码,怎么办呢?

这里需要激励用户,怎样激励用户,我的方案是送代币。

首先代币不仅能够购买物品,还能交易,流通,形成一个小的商业闭环。其次目前代币已经泛滥 99% 可能是空气币,这里我们需要将代币的价值与物品对价,类似金本位/银本位。

怎样操作呢?例如一个代币等于一斤水果,无论代币怎样炒作,最终用户不想玩下去了,就来换水果,也可以是大米,食用油等等...

关于怎样使用代币来做积分系统请参考我的另一篇文章《使用代币替代传统积分系统》,你可以在搜索引擎中找到,或者访问 https://cloud.tencent.com/developer/article/1057118

扫描二维码显示溯源防伪信息的同时我们有很多可以操作空间,可以获取用户地理位置,手机号码等等信息,为后面大数据分析埋点。

33.2.11. 以太坊解决方案

我们设计一个简单的合约,模拟上面提到的解决方案

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;
	}
}

怎样使用这个合约呢?合约部署,需要输入三个参数,分别是名称,价格和装量

Trace(string _name, uint _price, uint _weight)

产品属性可以在出厂前设置,一旦出厂进入物流阶段就不允许在更改了。

33.2.11.1. 应用场景一

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

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(); // 获得物流经过的转运站数量

33.2.11.2. 应用场景二

调用合约案例二,这是深加工的产品案例。例如 Trace("牦牛肉干", 80, 500)

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(); // 获得物流经过的转运站数量

33.2.11.3. 用户留言

contract.addGuestbook("0x0d1d423e623d10f9d10f9d10f9d10f9d10f9fba5","东西好吃,下次还买,给好评");

33.2.12. Hyperledger 解决方案

由于家里在刷墙,服务器收起来了,没有开发环境,只能提供部分参考代码,给大家一个思路

将代码放到合约中,使用PutState存储即可

package main

import "fmt"
import "encoding/json"

const (
	Origin = iota 	// 0
	Factory        	// 1
	QA       		// 2
	Shipping		// 3
	Received		// 4
	Pending			// 5
	Supermarket		// 6
)

type structElement struct {
	Name string `json:"name"`
	Company string `json:"company"`
	Description string `json:"description"`
}

type structLogistics struct {
    Stations string `json:"stations"`	// 中转站
	Date	string  `json:"date"`  // 转运日期
	Status	uint8	`json:"status"`  // 状态
    Message    string `json:"message"` // 留言信息
}

type Trace struct {
	Name string	`json:"name"`
	Address string	`json:"address"`
	Attribute	map[string]string 	`json:"attribute"`
	Element		[]structElement		`json:"element"`
	Logistics	map[string]structLogistics	`json:"logistics"`
}

func (trace *Trace) setName(_name string) {
    trace.Name = _name
}

func (trace *Trace) getName() string {
    return trace.Name
}

func (trace *Trace) putAttribute(_key string, _value string) {
    trace.Attribute[_key] = _value
}

func (trace *Trace) putLogistics(_key string, _value structLogistics) {
    trace.Logistics[_key] = _value
}

func main(){
	
	trace := &Trace{
		Name: "牦牛肉干",
		Address: "内蒙古呼和浩特",
		Attribute: map[string]string{},
		Element: []structElement{structElement{Name:"塑料袋",Company: "XXX塑料制品有限公司", Description: "外包装"},structElement{Name:"辣椒粉",Company: "XXX调味品有限公司", Description: "采摘年份2016-10-10"},structElement{Name:"调和油",Company: "XXX调味品有限公司", Description: "生产日期2016-10-10"}},
		Logistics: map[string]structLogistics{}}
	
	trace.putAttribute("Color","Red")
	trace.putAttribute("Size","10")
	trace.putAttribute("Weight","100kg")
	
	trace.putLogistics("1", structLogistics{"呼和浩特","2016-10-15", Origin, "牦牛收购"})
	trace.putLogistics("2", structLogistics{"呼和浩特","2016-10-18", Factory, "牦牛宰杀"})
	trace.putLogistics("3", structLogistics{"呼和浩特","2016-10-15", QA, "经过质检"})
	trace.putLogistics("4", structLogistics{"北京市","2016-10-15", Shipping, "运输中"})
	trace.putLogistics("5", structLogistics{"杭州市","2016-10-15", Shipping, "XXX冷库"})
	trace.putLogistics("5", structLogistics{"深圳市","2016-10-15", Supermarket, "XXX超市"})
	trace.putLogistics("5", structLogistics{"龙华区","2016-10-15", Received, "用户签收"})
	

	traceJson, _ := json.Marshal(trace)
	fmt.Println(string(traceJson))

}

现在是晚上12点,大脑一片浆糊,已经无法在继续写下去了,就写到这里。洗洗睡了

© 著作权归作者所有

共有 人打赏支持
netkiller-

netkiller-

粉丝 667
博文 240
码字总数 322337
作品 10
深圳
部门经理
加载中

评论(10)

w
wo是wo

引用来自“wo是wo”的评论

不看好区块链,我认为就是炒概念罢了

引用来自“neo-chen”的评论

跳出你的技术思维,大家都在好,两会也重视,区块链是一个风口。看你能不能搭上这班车。
技术思维?你说说目前来说区块链有什么用,除了比特币之类的,任何东西都不需要区块链这种不可控的技术或者其他更简单、更便宜的方式实现
xiaomin0322
xiaomin0322
哥们,看你找工作,找很久了
c
cep

引用来自“neo-chen”的评论

引用来自“cep”的评论

如果抓到违法的就把他弄进塔克拉玛干沙漠挖沙子40年,这个系统你就不用做了

回复@cep : 说明你不懂法律:),法律条文的设计,是由框架,规则的,是一门科学,这也就造成了法律不公平现象。
我只是想说:这个方案是解决不了食品安全问题的
魔力猫
魔力猫

引用来自“魔力猫”的评论

去中心化本身就是伪认识。实际上现在的区块链都是在某个中心里面自己嗨。

引用来自“neo-chen”的评论

这些都不重要,想想为什么我们还是码农,就是因为我们思维格局不够大。
马云看到的区块链,觉对不是“去中心化本身就是伪认识”。
区块链去中心化,这个搞错了,是从哪里来的,你知道吗?
netkiller-
netkiller-

引用来自“魔力猫”的评论

去中心化本身就是伪认识。实际上现在的区块链都是在某个中心里面自己嗨。
这些都不重要,想想为什么我们还是码农,就是因为我们思维格局不够大。
马云看到的区块链,觉对不是“去中心化本身就是伪认识”。
netkiller-
netkiller-

引用来自“wo是wo”的评论

不看好区块链,我认为就是炒概念罢了
跳出你的技术思维,大家都在好,两会也重视,区块链是一个风口。看你能不能搭上这班车。
w
wo是wo
不看好区块链,我认为就是炒概念罢了
魔力猫
魔力猫
去中心化本身就是伪认识。实际上现在的区块链都是在某个中心里面自己嗨。
netkiller-
netkiller-

引用来自“cep”的评论

如果抓到违法的就把他弄进塔克拉玛干沙漠挖沙子40年,这个系统你就不用做了

回复@cep : 说明你不懂法律:),法律条文的设计,是由框架,规则的,是一门科学,这也就造成了法律不公平现象。
c
cep
如果抓到违法的就把他弄进塔克拉玛干沙漠挖沙子40年,这个系统你就不用做了
区块链真实落地调查(一):区块链溯源,能让食品更安全吗?

区块链已被捧至神坛。 被包装得神乎其神的区块链,到底在哪个场景落地了? 一本君将从今日开始,遍访区块链项目,探访实际落地情况,并展望未来。 以下是第一篇,区块链真的能解决食品安全问...

雪花又一年 ⋅ 04/23 ⋅ 0

区块链应用创新的加速器 - 阿里云容器服务区块链解决方案

区块链(Blockchain)近年来在全球得到越来越广泛的关注,吸引了越来越多的开发者、企业、高校、研究机构、政府组织等参与到区块链技术、应用的研究和探索之中。区块链的本质是一种防篡改的、...

阿里云头条 ⋅ 04/13 ⋅ 0

利用区块链的技术特点解决消费者“信任”难题

  TCP/IP 协议的发明,促进了互联网时代的到来。区块链技术的出现,正在引发下一代价值互联网的革命。在区块链世界里,比特币为区块链的概念画下了美好世界的蓝图,基于智能合约的以太坊牢...

海外网 ⋅ 02/02 ⋅ 0

区块链应用 | “再不做区块链就老了”,但落地还有诸多难题

从去年下半年开始,区块链走进大众视野。区块链游戏、区块链食品溯源、区块链电商……沾上区块链的中概股股价飙升,大小互联网公司纷纷入局,下一场革命似乎即将来临。 人们试图用这一技术解...

雪花又一年 ⋅ 04/20 ⋅ 0

技术、产品、生态逐个落子, TAC溯源链应用落地越来越清晰

-------- 作者:刘学习 伴随着区块链项目如井喷状的涌现,区块链被寄予厚望,也得到了从技术、人才、资本到政策等的加持,热度如日中天。然而,在区块链发展大潮中,公众最关心的却是区块链应...

z1y492vn3zyd9et3b06 ⋅ 05/25 ⋅ 0

“华为区块链白皮书”重磅发布(附下载链接)

Hardy 架构师技术联盟 替换高清大图 请点击此处输入图片描述 请点击此处输入图片描述 在2018华为分析师大会(HAS2018)期间,华为云正式重磅发布“华为区块链白皮书”,白皮书系统介绍了区块链...

hardywang ⋅ 04/21 ⋅ 0

不搞数字货币的科技巨头们,在区块链的布局上有这三个方向

此前《中国区块链技术和应用发展白皮书》中显示,阿里巴巴以49的专区块链利总量排名第一,如果将这些能力用于“挖矿”或者用于“发币”毫无疑问阿里巴巴的股票也将大为受益,不过阿里巴巴显然...

北丐09 ⋅ 04/13 ⋅ 0

阿里云发布区块链解决方案 支持天猫奢侈品正品溯源

4月12日,阿里云发布全新区块链解决方案,支持天猫奢侈平台Luxury Pavilion推出全球首个基于区块链技术的正品溯源功能。该方案旨在帮助进一步打造和拓展奢侈品供应链应用生态。 借助阿里云区...

木环 ⋅ 04/13 ⋅ 0

阿里云发布区块链解决方案,帮助奢侈平台正品溯源

自去年10月份开始,阿里云已经推出了一系列区块链解决方案。 今天,阿里云发布区块链解决方案,支持天猫奢侈平台Luxury Pavilion推出全球首个基于区块链技术的正品溯源功能。 据官方介绍,借...

行者武松 ⋅ 05/15 ⋅ 0

工信部发布区块链白皮书 众安科技旗下众安链进展明显

6 月 15 日,工业和信息化部中国电子技术标准化研究院(简称“标准院”)发布《中国区块链技术和应用发展白皮书(2018)》(下称《白皮书》)。据白皮书显示,此前工信部标准院公布的首批开源...

木子 ⋅ 06/15 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

【elasticsearch】 随笔 Date datatype

一。时间类型的本质 首先json是没有时间类型的,对于es来说,时间类型的标示可以是下面三种情况 1.一个时间格式的字符串,如:"2014-11-27T08:05:32Z","2015-01-01" or "2015/01/01 12:10:3...

xiaomin0322 ⋅ 16分钟前 ⋅ 0

阿里云资源编排ROS使用教程

阿里云资源编排ROS详细内容: 阿里云资源编排ROS使用教程 资源编排(Resource Orchestration)是一种简单易用的云计算资源管理和自动化运维服务。用户通过模板描述多个云计算资源的依赖关系、...

mcy0425 ⋅ 18分钟前 ⋅ 0

适配器设计模式

1、适配器模式 把一个类的接口变换成客户端所期待的另一种接口 使原本因接口不匹配而无法在一起工作的两个类能够在一起工作 分为类的适配器模式和对象的适配器模式 2、类适配器模式 类的适配...

职业搬砖20年 ⋅ 22分钟前 ⋅ 0

npm操作报错 _stream_writable.js:61

有一天 不知道什么原因(估计和node的版本有关),无论你做什么npm的操作 都会报错/usr/local/lib/node_modules/npm/node_modules/readable-stream/lib/_stream_writable.js:61 这时候只要执...

lilugirl ⋅ 26分钟前 ⋅ 0

Eclipse安装插件的几种方式

Eclipse魅力之一就是支持可扩展的插件,来丰富自身的功能,这种方式也是建立在开源思想之上的。具体使用什么方式去安装插件,要看我们拿到的是什么。 1. 拿到的是一串URL,如http://subclips...

GordonNemo ⋅ 29分钟前 ⋅ 0

div图片叠加

css实现代码如下: <div style="position: relative;"><!--这个层为外面的父层,需设置相对位置样式--> <div style="position: absolute;"><!--子层,需设置绝对位置样式--> <i......

niithub ⋅ 30分钟前 ⋅ 0

作用域slot

如果父组件需要使用子组件中的内容怎么办,比如父组件需要控制子组件的显示 <div id="root"><child><template slot-scope="props"><h1>{{props.item}} <div>编辑</div></h1><......

金于虎 ⋅ 33分钟前 ⋅ 1

HongHu commonservice-eureka 项目构建过程

上一篇我们回顾了关于 spring cloud eureka的相关基础知识,现在我们针对于HongHu cloud的eureka项目做以下构建,整个构建的过程很简单,我会将每一步都构建过程记录下来,希望可以帮助到大家...

明理萝 ⋅ 35分钟前 ⋅ 1

xml和对象的相互转化

@Data//setter和getter方法,toString和equals,hashcode方法@EqualsAndHashCode//代表重写equals和hashcode方法@XmlAccessorType(XmlAccessType.FIELD)public class Classroom {@X......

拐美人 ⋅ 36分钟前 ⋅ 0

tableView cell的高度 分组头部尾部的高度 自适应

@property (nonatomic) CGFloat rowHeight; // default is UITableViewAutomaticDimension@property (nonatomic) CGFloat sectionHeaderHeight; // default is UITableViewA......

娜一片蓝色星海 ⋅ 37分钟前 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部