赞
踩
1、区块链技术的核心,是去中心化的数据管理,主要应用的是分布式计算,减轻单个节点因为数据泄露而带来的风险。
2、物联网链接终端设备与控制主机之间,需要有设备管理数据,相互认证密钥数据,这些数据的建立和管理,就可以采用区块链的方式,建立分布式服务器集群。
3、技术的难点在于区块链对于物联网设备数据的分布式计算实现。
区块链的基本原理理解起来并不难。基本概念包括:
- 交易(Transaction):一次操作,导致账本状态的一次改变,如添加一条记录;
- 区块(Block):记录一段时间内发生的交易和状态结果,是对当前账本状态的一次共
识;
- 链(Chain):由一个个区块按照发生顺序串联而成,是整个状态变化的日志记录。
二、第一版
1,构造区块
public class Block {
private int previousHash;
private String[] transaction;
private int blockHash;
//
public Block(int previousHash, String[] transaction) {
this.previousHash = previousHash;
this.transaction = transaction;
Object[] contents = {previousHash, transaction};
this.blockHash = Arrays.hashCode(contents);
}
public int getPreviousHash() {
return previousHash;
}
public String[] getTransaction() {
return transaction;
}
public int getBlockHash() {
return blockHash;
}
}

说明:
transaction,每笔交易数据,可以是转账信息,也可以是产品信息等等,这里用数组模拟。
previousHash为前一个节点的hash值
为新区块的hash值,直接在构造函数中,通过Arrays.hashCode计算出来
每个区块都包含上一个区块的hash值,以及当前交易信息。
2,开始挖矿
public class BlockTest {
public static void main(String[] args) {
String[] genesisTransaction = {"zhangjh create genesisBlock", " at 2018-03-03"};
Block genesisBlock = new Block(0, genesisTransaction);
int genesisBlockBlockHash = genesisBlock.getBlockHash();
System.out.println("创世区块:" + genesisBlockBlockHash);
String[] _2Transaction = {"zhangjh pay 10 bitcoin to james", "at 2018-03-03"};
Block _2Block = new Block(genesisBlockBlockHash, _2Transaction);
int _2blockBlockHash = _2Block.getBlockHash();
System.out.println("第2个区块:" + _2blockBlockHash);
String[] _3Transaction = {"james pay 2 bitcoin to rose", "james pay 1 bitcoin to tom", "at 2018-03-03"};
Block _3Block = new Block(_2blockBlockHash, _3Transaction);
System.out.println("第3个区块:" + _3Block.getBlockHash());
}
}

说明:
可以看到相当快就产生的创世区块,因为没有随机数,计算hash相当快。
三、第二版
为了证实模拟挖矿的难度,我加入了和区块链计算新块的随机数,并采用SHA256算法。
1,构造区块
/**
* 挖矿过程:通过找随机数,找到符合的SHA256值
*/
public class BlockRandom {
private String previousSHA256;
private String[] transaction;
private String blockHash;
private final static String flag = "0000000";
public BlockRandom(String previousSHA256, String[] transaction) {
this.previousSHA256 = previousSHA256;
this.transaction = transaction;
this.blockHash = caculateBlockWithRandomNum(previousSHA256, transaction);
}
/**
* 当1-6位全为0时,发布出去
*
* @param previousSHA256
* @param transaction
* @return
*/
private String caculateBlockWithRandomNum(String previousSHA256, String[] transaction) {
String blockSHA256;
int times = 0;
System.out.println("挖矿中...");
while (true) {
times++;
String random = RandomStringUtils.random(100);
Object[] contents = {previousSHA256, transaction, random};
blockSHA256 = HmacSHA256Utils.INSTANCE.encriptSHA256Str(contents.toString());
String subStr = blockSHA256.substring(0, 7);
// System.out.print(".");
if (flag.equals(subStr)) {
break;
}
}
return blockSHA256 + "-" + times;
}
public String getPreviousSHA256() {
return previousSHA256;
}
public String[] getTransaction() {
return transaction;
}
public String getBlockHash() {
return blockHash;
}
}

说明:
Object[] contents = {previousHash, transaction, random};参与计算的的数据有前一个区块的SHA256的值,交易数据,随机数。
需要计算一个随机数,使得计算出来的SHA256值的前6位都为0。
return blockHash + “-” + times; 是为了方便统计每次挖矿过程计算的次数。
2,挖矿
public class BlockRandomTest {
public static void main(String[] args) {
long begainTime = System.currentTimeMillis();
String[] genesisTransaction = {"zhangjh create genesisBlock", " at 2018-03-03"};
BlockRandom genesisBlock = new BlockRandom("0", genesisTransaction);
long endTime = System.currentTimeMillis();
String genesisBlockBlockHashTemp = genesisBlock.getBlockHash();
int index = genesisBlockBlockHashTemp.indexOf("-");
String genesisBlockBlockHash = genesisBlockBlockHashTemp.substring(0, index);
String times = genesisBlockBlockHashTemp.substring(index + 1);
System.err.println("--------------->创世区块:" + genesisBlockBlockHash + ",耗时:" + (endTime - begainTime) + "毫秒,总共计算:" + times + "次");
begainTime = System.currentTimeMillis();
String[] _2Transaction = {"zhangjh pay 10 bitcoin to james", "at 2018-03-03"};
BlockRandom _2Block = new BlockRandom(genesisBlockBlockHash, _2Transaction);
String _2blockBlockHashTemp = _2Block.getBlockHash();
endTime = System.currentTimeMillis();
index = _2blockBlockHashTemp.indexOf("-");
String _2BlockBlockHash = _2blockBlockHashTemp.substring(0, index);
times = _2blockBlockHashTemp.substring(index + 1);
System.err.println("--------------->第2个区块:" + _2BlockBlockHash + ",耗时:" + (endTime - begainTime) + "毫秒,总共计算:" + times + "次");
begainTime = System.currentTimeMillis();
String[] _3Transaction = {"james pay 2 bitcoin to rose", "james pay 1 bitcoin to tom", "at 2018-03-03"};
BlockRandom _3Block = new BlockRandom(_2BlockBlockHash, _3Transaction);
String _3blockBlockHashTemp = _3Block.getBlockHash();
endTime = System.currentTimeMillis();
index = _3blockBlockHashTemp.indexOf("-");
String _3BlockBlockHash = _3blockBlockHashTemp.substring(0, index);
times = _3blockBlockHashTemp.substring(index + 1);
System.err.println("--------------->第3个区块:" + _3BlockBlockHash + ",耗时:" + (endTime - begainTime) + "毫秒,总共计算:" + times + "次");
}
}

3,结果统计
寻找一个随机数,使得前5位都为0的统计情况
寻找一个随机数,使得前6位都为0的统计情况
寻找一个随机数,使得前7位都为0的统计情况
小结
从上图可以看出,寻找一个随机数,使得前7位都为0,创建创世区块总共19分钟,计算了483148100次,大约5亿次。
可想而知,当要寻找的0的位数越多,那么花费的时间将成指数级增长。真实的区块是计算前18位全为0,OMG,PC就别想挖矿了。请给我一台量子计算机,谢谢。
最新出块
四、总结
当然真实的区块链,并没有这么简单:比如真实的区块链数据结构更复杂,P2P网络广播,数据校验,发行激励机制,只能合约等等。
而且,根据现在区块链技术的版本看,上面相当于区块链1.0版本,现在还有以太坊的2.0版本公有链,以及IBM牵头开发的超级账本3.0版本联盟链。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。