用Java 实现区块链:基本原型(第一章)

参考网站:

https://jeiwan.cc/posts/building-blockchain-in-go-part-1/

https://github.com/liuchengxu/blockchain-tutorial/blob/master/content/part-1/basic-prototype.md#%E5%8C%BA%E5%9D%97%E9%93%BE

  前言:

  区块链是 21 世纪最具革命性的技术之一,它仍然处于不断成长的阶段,而且还有很多潜力尚未显现。 本质上,区块链只是一个分布式数据库而已。 不过,使它独一无二的是,区块链是一个公开的数据库,而不是一个私人数据库,也就是说,每个使用它的人都有一个完整或部分的副本。 只有经过其他“数据库管理员”的同意,才能向数据库中添加新的记录。 此外,也正是由于区块链,才使得加密货币和智能合约成为现实。

  区块:

  首先从 “区块” 谈起。在区块链中,真正存储有效信息的是区块(block)。而在比特币中,真正有价值的信息就是交易(transaction)。实际上,交易信息是所有加密货币的价值所在。除此以外,区块还包含了一些技术实现的相关信息,比如版本,当前时间戳和前一个区块的哈希。

  不过,我们要实现的是一个简化版的区块链,而不是一个像比特币技术规范所描述那样成熟完备的区块链。所以在我们目前的实现中,区块仅包含了部分关键信息,它的数据结构如下:

@Getter
public class Block {
    private long timestamp; // 区块创建的时间
    private byte[] data; //区块储存的有效信息
    private byte[] prevBlockHash; //上一个区块的哈希值
    private byte[] hash; //当前块的Hash块
}
Block.java

  在比特币中,有两部分数据,一种是Header数据(timestamp、preBlockHash、hash等)和交易数据 (data),这里简化模型,将两部分数据合并在一起。

  下面创建Block的构造函数和hash处理函数,我们这里将timestamp、preBlockHash和data拼接起来使用SHA-256计算得到一个哈希。

public void setHash() {
    byte[] time = (timestamp + "").getBytes();
    byte[] target = new byte[time.length + data.length + prevBlockHash.length];
    int index = 0;
    System.arraycopy(time, 0, target, index, time.length);
    index += time.length;
    System.arraycopy(prevBlockHash, 0, target, index, prevBlockHash.length);
    index += prevBlockHash.length;
    System.arraycopy(data, 0, target, index, data.length);
    hash = SHA256Util.getSHA256Bytes(target);
}
public Block(byte[] data, byte[] prevBlockHash) {
    if (data == null || prevBlockHash == null || data.length == 0) {
        throw new RuntimeException("error block!");
    }
    this.data = data;
    this.prevBlockHash = prevBlockHash;
    this.timestamp = new Date().getTime();
    setHash();
}
View Code

  区块链:

  有了区块,下面让我们来实现区块。本质上,区块链就是一个有着特定结构的数据库,是一个有序,每一个块都连接到前一个块的链表。也就是说,区块按照插入的顺序进行存储,每个块都与前一个块相连。这样的结构,能够让我们快速地获取链上的最新块,并且高效地通过哈希来检索一个块。

public class BlockChain {

    //这里暂时只用一个List就OK
    private List<Block> blocks;

    public BlockChain() {
        blocks = new ArrayList<>();
//添加初始块
        blocks.add(new Block("Genesis Block".getBytes(), new byte[]{}));
    }
    public void addBlock(byte[] data) {
        if (data == null || data.length == 0) {
            throw new RuntimeException("data can't be empty");
        }
        Block preBlock = blocks.get(blocks.size() - 1);
        blocks.add(new Block(data, preBlock.getHash()));
    }
    @Override
    public String toString() {
        StringBuilder sb = new StringBuilder();
        for (Block block : blocks) {
            sb.append("================\n");
            sb.append("data : ").append(new String(block.getData())).append("\n");
            sb.append("preHash : ").append(ByteUtils.byte2Hex(block.getPrevBlockHash())).append("\n");
            sb.append("hash : ").append(ByteUtils.byte2Hex(block.getHash())).append("\n");
        }
        sb.append("length : ").append(blocks.size());
        return sb.toString();
    }
}
BlockChain.java

  测试效果

public static void main(String[] args) {
    BlockChain blockChain = new BlockChain();
    blockChain.addBlock("Block1".getBytes());
    blockChain.addBlock("Block2".getBytes());
    System.out.println(blockChain.toString());
}
结果
================
data : Genesis Block
preHash : 
hash : cde7c1538c6b384fa7af18e6ce6f7cde3440028c5d599ffd8bb61121e6b46681
================
data : Block1
preHash : cde7c1538c6b384fa7af18e6ce6f7cde3440028c5d599ffd8bb61121e6b46681
hash : 074d9d9f9bba1d6d2471e2f97e95564841107368f773112df5e1d05d7381ee58
================
data : Block2
preHash : 074d9d9f9bba1d6d2471e2f97e95564841107368f773112df5e1d05d7381ee58
hash : c6079e03785a5093ce0caa4116e78ada790d227425337f65668d6ed8fb9a3baa
length : 3

  总结:

  我们创建了一个非常简单的区块链原型:它仅仅是一个数组构成的一系列区块,每个块都与前一个块相关联。真实的区块链要比这复杂得多。在我们的区块链中,加入新的块非常简单,也很快,但是在真实的区块链中,加入新的块需要很多工作:你必须要经过十分繁重的计算(这个机制叫做工作量证明),来获得添加一个新块的权力。并且,区块链是一个分布式数据库,并且没有单一决策者。因此,要加入一个新块,必须要被网络的其他参与者确认和同意(这个机制叫做共识(consensus))。还有一点,我们的区块链还没有任何的交易!

猜你喜欢

转载自www.cnblogs.com/starktan/p/9756759.html