Home | 簡體中文 | 繁體中文 | 雜文 | 知乎專欄 | Github | OSChina 博客 | 雲社區 | 雲棲社區 | Facebook | Linkedin | 視頻教程 | 打賞(Donations) | About
知乎專欄多維度架構 | 微信號 netkiller-ebook | QQ群:128659835 請註明“讀者”

第 2 章 區塊鏈探索

目錄

2.1. 以太坊物流場景解決方案
2.2. 區塊鏈防偽溯源應用場景
2.2.1. 背景
2.2.2. 如何實現
2.2.3. 安全問題
2.2.4. 防偽問題
2.2.5. 性能問題
2.2.6. 顆粒度問題
2.2.7. 存儲規劃
2.2.8. 大數據問題
2.2.9. BI商業智能
2.2.10. 採集終端
2.2.11. 多媒體數據
2.2.12. 物流介面
2.2.13. 如何激勵用戶
2.2.14. 上鏈
2.2.15. 以太坊解決方案
2.2.15.1. 應用場景一
2.2.15.2. 應用場景二
2.2.15.3. 用戶留言
2.2.16. Hyperledger 解決方案
2.2.16.1. 溯源合約涉及
2.2.16.1.1. 食品安全朔源
2.2.16.1.2. 水平移植
2.2.16.2. 積分通正(代幣)
2.2.17. 總結
2.3. 以太坊·電影院場景區塊鏈應用探索
2.3.1. 合約檔案
2.3.2. 合約用法
2.4. 遊戲領域區塊鏈探索
2.4.1. 遊戲代幣
2.4.2. 玩家屬性與遊戲裝備
2.4.3. 裝備屬性與規範
2.4.4. 物品合成計算
2.4.5. 實施步驟
2.5. 以太坊競猜活動區塊鏈探索
2.6. 使用代幣替代傳統積分系統
2.6.1. 規劃
2.6.1.1. 賬號規劃
2.6.1.2. 日誌規劃
2.6.1.3. 監控規劃
2.6.1.4. 代幣構成規劃
2.6.2. 實施步驟
2.6.3. ERC20 代幣合約
2.6.4. 打通用戶註冊
2.6.5. 現有用戶怎麼處理
2.6.6. 贈送代幣
2.6.7. 賺取代幣
2.6.8. 用戶登錄
2.6.9. 積分商城
2.6.10. 代幣報表
2.6.10.1. 曾幣報表
2.6.10.2. 積分商城報表
2.6.11. 代幣交易
2.7. 區塊鏈徵信解決方案探索
2.7.1. 需求分析與概要設計
2.7.2. 資料結構
2.7.3. 將徵信資料寫入區塊鏈
2.7.4. 查詢區塊數據
2.7.5. 刪除區塊
2.8. Hyperledger fabric 銀行應用探索
2.8.1. 電匯年代
2.8.2. 通存通取年代
2.8.3. 跨境匯款
2.8.4. 區塊鏈能做什麼
2.8.5. 智能合約怎麼落地
2.8.6. 總結
2.9. 區塊鏈醫院應用探索
2.9.1. 背景
2.9.2. 藥品和器械上鏈
2.9.2.1. 藥品上鏈
2.9.2.2. 器械上鏈
2.9.3. 電子病歷上鏈
2.9.3.1. 醫學影像上鏈
2.9.4. 健康信息
2.9.5. 出生證明
2.9.6. 保險
2.9.6.1. 保險信息上鏈
2.9.6.2. 區塊鏈解決出險理賠過程
2.9.7. 智能合約
2.10. 藝術品區塊鏈溯源防偽平台
2.10.1. 都有哪些角色參與其中
2.10.2. 需要運用的防偽技術
2.10.3. 技術架構
2.10.3.1. 前端技術
2.10.3.2. 微服務端
2.10.3.3. 存儲層
2.10.3.4. 消息隊列層
2.10.3.5. 搜索層
2.10.3.6. 區塊鏈
2.10.3.7. 支持層
2.10.4. RFID/NFC
2.10.4.1. RFID
2.10.4.2. NFC
2.10.4.3. RFID/NFC 兩種技術的差異
2.10.5. 資產投資與份額持有
2.10.6. 資產上鏈的
2.10.7. 原型設計
2.10.7.1. 註冊與登錄
2.10.7.2. 用戶角色
2.10.7.3. 鑒定師角色
2.10.7.4. 機構角色
2.10.7.4.1. 地址管理
2.10.7.4.2. 申請溯源標籤
2.10.7.4.3. 數字資產上鏈
2.10.7.4.4. 機構成員管理
2.10.7.4.5. 資產審核
2.10.7.4.6. 鑒定師隷屬於機構
2.10.7.4.7. 評論
2.10.7.4.8. 安全
2.10.7.5. 錢包

2.1. 以太坊物流場景解決方案

網上談關於物流行業區塊鏈的文章很多,但是你會發現找遍互聯網也找不到具體怎樣將物流落地到區塊鏈的文章,於是我只能自己搗鼓。

背景,使用區塊鏈記錄物流信息,實現信息朔源。

我想法是,將物流信息放到區塊鏈中,實現物流中轉信息的添加,當用戶簽收後合約關閉,不再允許增加新信息。

首先,每個物流單一張合約

其次,以太坊賬號代表轉運站,或者用戶,這裡我們使用5個賬號分別代表不同的角色。

			
pragma solidity ^0.4.20;

contract Logistics {

    enum State { New, Reviewed, Pending, Shipping, Received }

    struct Node {
        address owner;	// 中轉站
        string date;    // 轉運日期
        State status;   // 狀態
        string message; // 留言信息
    }

    mapping (uint  => Node) stations;
    
    uint number = 1;		
    string name;			//商品名稱
    bool close = false;	//合約狀態
    
	function Logistics(string _name) public {
        name = _name;
	}
    function getName() public view returns(string){
        return name;
    }
    
    // 增加物流中轉信息
    function put(address _owner,string _date, State _status, string _message ) public{
        if(close == false){
            Node memory node = Node(_owner,_date,_status,_message);
            stations[number] = node;
            number = number + 1;
        }
        if (_status == State.Received) {
            close = true;
        }
    }

	// 獲得中轉信息
    function get(uint _number) public view returns(address, string, State, string) {
        require(_number < number);

        Node memory node = stations[_number];
        
		return (node.owner, node.date, node.status, node.message);
	}
	
	// 或者轉中站數量
	function getNode() public view returns(uint){
	    return number;
	}
}			

			
	

保存合約到 Truffle 的 contracts/Logistics.sol

部署代碼

			
neo@MacBook-Pro ~/ethereum/truffle % cat migrations/1_initial_migration.js

var Logistics = artifacts.require("./Logistics.sol");

module.exports = function(deployer) {
  deployer.deploy(Logistics,"Mackbook");
};			
			
	

Mackbook 就是商品名稱。

編譯部署合約

			
neo@MacBook-Pro ~/ethereum/truffle % truffle compile --all                
Compiling ./contracts/Logistics.sol...
Writing artifacts to ./build/contracts

neo@MacBook-Pro ~/ethereum/truffle % truffle migrate --reset              
Using network 'development'.

Running migration: 1_initial_migration.js
  Replacing Logistics...
  ... 0x14b6b6bfb84383b8325f5e97a6b7a5c1d1f5c2e162a4bd201b93a9d30cd75d8e
  Logistics: 0x1cff61b8259f05f4bbf7aa4f769321e5fa70b22d
Saving successful migration to network...
  ... 0x26d544c8db7b1cf06034963e5f5bea7b28d11e7295a018f1b80a7555c38f26e7
Saving artifacts...
			
	

啟動開發環境

			
neo@MacBook-Pro ~/ethereum/truffle % truffle develop                                                                                                               
Truffle Develop started at http://localhost:9545/

Accounts:
(0) 0x627306090abab3a6e1400e9345bc60c78a8bef57
(1) 0xf17f52151ebef6c7334fad080c5704d77216b732
(2) 0xc5fdf4076b8f3a5357c5e395ab970b5b54098fef
(3) 0x821aea9a577a9b44299b9c15c88cf3087f3b5544
(4) 0x0d1d4e623d10f9fba5db95830f7d3839406c6af2
(5) 0x2932b7a2355d6fecc4b5c0b6bd44cc31df247a2e
(6) 0x2191ef87e392377ec08e7c08eb105ef5448eced5
(7) 0x0f4f2ac550a1b4e2280d04c21cea7ebd822934b5
(8) 0x6330a553fc93768f612722bb8c2ec78ac90b3bbc
(9) 0x5aeda56215b167893e80b4fe645ba6d5bab767de

Private Keys:
(0) c87509a1c067bbde78beb793e6fa76530b6382a4c0241e5e4a9ec0a0f44dc0d3
(1) ae6ae8e5ccbfb04590405997ee2d52d2b330726137b875053c36d94e974d162f
(2) 0dbbe8e4ae425a6d2687f1a7e3ba17bc98c673636790f1b8ad91193c05875ef1
(3) c88b703fb08cbea894b6aeff5a544fb92e78a18e19814cd85da83b71f772aa6c
(4) 388c684f0ba1ef5017716adb5d21a053ea8e90277d0868337519f97bede61418
(5) 659cbb0e2411a44db63778987b1e22153c086a95eb6b18bdf89de078917abc63
(6) 82d052c865f5763aad42add438569276c00d3d88a2d062d36b2bae914d58b8c8
(7) aa3680d5d48a8283413f7a108367c7299ca73f553735860a87b08f39395618b7
(8) 0f62d96d6675f32685bbdb8ac13cda7c23436f63efbb9d07700d8669ff12b7c4
(9) 8d5366123cb560bb606379f90a0bfd4769eecc0557f1b362dcae9012b548b1e5

Mnemonic: candy maple cake sugar pudding cream honey rich smooth crumble sweet treat

truffle(develop)> 
			
	

開發環境會創建10個賬號用戶測試。我們需要使用前5個賬號,每個賬號代表一個轉運站,或者用戶

進入控制台驗證合約

			
var contract;
Logistics.deployed().then(function(instance){contract=instance;});
contract.getName();

contract.put("0x627306090abab3a6e1400e9345bc60c78a8bef57","2018-02-20",0,"寄包裹");
contract.get(1);
contract.put("0xf17f52151ebef6c7334fad080c5704d77216b732","2018-02-21",1,"包裹攬件");
contract.get(2);
contract.put("0xc5fdf4076b8f3a5357c5e395ab970b5b54098fef","2018-02-22",2,"運輸處理中");
contract.get(3);
contract.put("0x821aea9a577a9b44299b9c15c88cf3087f3b5544","2018-02-23",3,"運輸處理中");
contract.get(4);
contract.put("0x0d1d4e623d10f9fba5db95830f7d3839406c6af2","2018-02-24",4,"包裹收到");
contract.get(5);
contract.getNode();


contract.put("0x0d1d4e623d10f9fba5db95830f7d3839406c6af2","2018-02-22",5,"已經收到包裹,合約關閉,不允許在修改");
contract.get(6);
			
	

操作演示如下

			
truffle(development)> var contract;
undefined
truffle(development)> Logistics.deployed().then(function(instance){contract=instance;});
undefined
truffle(development)> contract.getName();
'Mackbook'
truffle(development)> contract.put("0x627306090abab3a6e1400e9345bc60c78a8bef57","2018-02-20",0,"寄包裹");
{ tx: '0x74992b7cccb214600ac2f1257486053202736714cf7e9e69fb62cba692bc6592',
  receipt: 
   { transactionHash: '0x74992b7cccb214600ac2f1257486053202736714cf7e9e69fb62cba692bc6592',
     transactionIndex: 0,
     blockHash: '0xc838fb9c5352544f4d743b170d146a9ef1b1ef6a30019c33e2a77df24e808964',
     blockNumber: 86,
     gasUsed: 98633,
     cumulativeGasUsed: 98633,
     contractAddress: null,
     logs: [],
     status: 1 },
  logs: [] }
truffle(development)> contract.get(1);
[ '0x627306090abab3a6e1400e9345bc60c78a8bef57',
  '2018-02-20',
  BigNumber { s: 1, e: 0, c: [ 0 ] },
  '寄包裹' ]
truffle(development)> contract.put("0xf17f52151ebef6c7334fad080c5704d77216b732","2018-02-21",1,"包裹攬件");
{ tx: '0x3f8dcd5f0d9a9ec60942e6a1c73556dfcfde59354fc24474ffc8e32b9b00ac61',
  receipt: 
   { transactionHash: '0x3f8dcd5f0d9a9ec60942e6a1c73556dfcfde59354fc24474ffc8e32b9b00ac61',
     transactionIndex: 0,
     blockHash: '0x96c889cae1001265bcdf32c808770a7f9f0c325467912524c10100bc04cf8271',
     blockNumber: 87,
     gasUsed: 113889,
     cumulativeGasUsed: 113889,
     contractAddress: null,
     logs: [],
     status: 1 },
  logs: [] }
truffle(development)> contract.get(2);
[ '0xf17f52151ebef6c7334fad080c5704d77216b732',
  '2018-02-21',
  BigNumber { s: 1, e: 0, c: [ 1 ] },
  '包裹攬件' ]
truffle(development)> contract.put("0xc5fdf4076b8f3a5357c5e395ab970b5b54098fef","2018-02-22",2,"運輸處理中");
{ tx: '0x1ebe589e6b63479f9542ba67650d63757ca45ac38cb43d395b5bc2a573d0363b',
  receipt: 
   { transactionHash: '0x1ebe589e6b63479f9542ba67650d63757ca45ac38cb43d395b5bc2a573d0363b',
     transactionIndex: 0,
     blockHash: '0x83edf5fc1e38062dafc49a21b3d9a1fa0f9ddfb0f2e749b2b1945d03360a5209',
     blockNumber: 88,
     gasUsed: 114081,
     cumulativeGasUsed: 114081,
     contractAddress: null,
     logs: [],
     status: 1 },
  logs: [] }
truffle(development)> contract.get(3);
[ '0xc5fdf4076b8f3a5357c5e395ab970b5b54098fef',
  '2018-02-22',
  BigNumber { s: 1, e: 0, c: [ 2 ] },
  '運輸處理中' ]
truffle(development)> contract.put("0x821aea9a577a9b44299b9c15c88cf3087f3b5544","2018-02-22",3,"運輸處理中");
{ tx: '0x44b2bf7853e6b4c86f732bb8f1bcee17f00e0f850530e359753b4d7c55c35b4d',
  receipt: 
   { transactionHash: '0x44b2bf7853e6b4c86f732bb8f1bcee17f00e0f850530e359753b4d7c55c35b4d',
     transactionIndex: 0,
     blockHash: '0x7e79ca2570f5045f4c226805866803f898109d238518fa1e5abe6b4ee4c1c552',
     blockNumber: 89,
     gasUsed: 114081,
     cumulativeGasUsed: 114081,
     contractAddress: null,
     logs: [],
     status: 1 },
  logs: [] }
truffle(development)> contract.get(4);
[ '0x821aea9a577a9b44299b9c15c88cf3087f3b5544',
  '2018-02-22',
  BigNumber { s: 1, e: 0, c: [ 3 ] },
  '運輸處理中' ]
truffle(development)> contract.put("0x0d1d4e623d10f9fba5db95830f7d3839406c6af2","2018-02-22",4,"包裹收到");
{ tx: '0xb2b0223dc7cc90744a97ea002ecd468796d7596e38f8bb105c9f2103da6dfa19',
  receipt: 
   { transactionHash: '0xb2b0223dc7cc90744a97ea002ecd468796d7596e38f8bb105c9f2103da6dfa19',
     transactionIndex: 0,
     blockHash: '0xeb1051e80fe920fc166288036e6d27b38aca27144d2b636decade338f787371b',
     blockNumber: 90,
     gasUsed: 134156,
     cumulativeGasUsed: 134156,
     contractAddress: null,
     logs: [],
     status: 1 },
  logs: [] }
truffle(development)> contract.get(5);
[ '0x0d1d4e623d10f9fba5db95830f7d3839406c6af2',
  '2018-02-22',
  BigNumber { s: 1, e: 0, c: [ 4 ] },
  '包裹收到' ]
truffle(development)> contract.getNode();
BigNumber { s: 1, e: 0, c: [ 6 ] }
truffle(development)> 
			
	

合一已經關閉,添加不會出錯,但是沒有數據進入區塊中,使用 contract.get(6); 獲取數據會拋出異常。

			
truffle(development)> contract.put("0x0d1d4e623d10f9fba5db95830f7d3839406c6af2","2018-02-22",3,"已經收到包裹,合約關閉,不允許在修改");
{ tx: '0x72999fc308f2f3bc1f70fbc919c8b08594f177318dc4e57dd5ea590248e9a6cc',
  receipt: 
   { transactionHash: '0x72999fc308f2f3bc1f70fbc919c8b08594f177318dc4e57dd5ea590248e9a6cc',
     transactionIndex: 0,
     blockHash: '0xa3d9bc835bd5de6067271baa7899c3aaada6088362371b5139f4fa7cbd9f4050',
     blockNumber: 91,
     gasUsed: 29360,
     cumulativeGasUsed: 29360,
     contractAddress: null,
     logs: [],
     status: 1 },
  logs: [] }
truffle(development)> contract.get(6);
Error: VM Exception while processing transaction: revert
    at XMLHttpRequest._onHttpResponseEnd (/usr/local/lib/node_modules/truffle/build/webpack:/~/xhr2/lib/xhr2.js:509:1)
    at XMLHttpRequest._setReadyState (/usr/local/lib/node_modules/truffle/build/webpack:/~/xhr2/lib/xhr2.js:354:1)
    at XMLHttpRequestEventTarget.dispatchEvent (/usr/local/lib/node_modules/truffle/build/webpack:/~/xhr2/lib/xhr2.js:64:1)
    at XMLHttpRequest.request.onreadystatechange (/usr/local/lib/node_modules/truffle/build/webpack:/~/web3/lib/web3/httpprovider.js:128:1)
    at /usr/local/lib/node_modules/truffle/build/webpack:/~/truffle-provider/wrapper.js:134:1
    at /usr/local/lib/node_modules/truffle/build/webpack:/~/web3/lib/web3/requestmanager.js:86:1
    at Object.InvalidResponse (/usr/local/lib/node_modules/truffle/build/webpack:/~/web3/lib/web3/errors.js:38:1)
truffle(development)> 
			
	

這個合約還不是很完善,僅僅是作者的想法,是否在實際項目中可行,尚未知,區塊鏈應用場景實例的文章還比較少,只能摸索前進。