Netkiller Blockchain 手札
本文作者最近在找工作,有意向致电 13113668890
文档始创于2018-02-10
版权 © 2018 Netkiller(Neo Chan). All rights reserved.
版权声明
转载请与作者联系,转载时请务必标明文章原始出处和作者信息及本声明。
|
|
|
|
$Data$
内容摘要
这一部关于区块链开发及运维的电子书。
为什么会写区块链电子书?因为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
4.10.4. 以太坊物流场景解决方案初探
网上谈关于物流行业区块链的文章很多,但是你会发现找遍互联网也找不到具体怎样将物流落地到区块链的文章,于是我只能自己捣鼓。
背景,使用区块链记录物流信息,实现信息朔源。
我想法是,将物流信息放到区块链中,实现物流中转信息的添加,当用户签收后合约关闭,不再允许增加新信息。
首先,每个物流单一张合约
其次,以太坊账号代表转运站,或者用户,这里我们使用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)>
这个合约还不是很完善,仅仅是作者的想法,是否在实际项目中可行,尚未知,区块链应用场景实例的文章还比较少,只能摸索前进。
有兴趣可以加我的QQ群讨论,共同学习。