前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >单机区块链实现

单机区块链实现

作者头像
算法之名
发布2020-12-25 11:30:42
6210
发布2020-12-25 11:30:42
举报
文章被收录于专栏:算法之名算法之名

区块链就是一串或者是一系列区块的集合,类似于链表的概念,每个区块都指向于后面一个区块,然后顺序的连接在一起。在区块链中的每一个区块都存放了很多很有价值的信息,主要包括三个部分:自己的数字签名,上一个区块的数字签名,还有一切需要加密的数据(这些数据在比特币中就相当于是交易的信息,它是加密货币的本质)。每个数字签名不但证明了自己是特有的一个区块,而且指向了前一个区块的来源,让所有的区块在链条中可以串起来,而数据就是一些特定的信息,你可以按照业务逻辑来保存业务数据。

这里的hash指的就是数字签名

所以每一个区块不仅包含前一个区块的hash值,同时包含自身的一个hash值,自身的hash值是通过之前的hash值和数据data通过hash计算出来的。如果前一个区块的数据一旦被篡改了,那么前一个区块的hash值也会同样发生变化(因为数据也被计算在内),这样也就导致了所有后续的区块中的hash值。所以计算和比对hash值会让我们检查到当前的区块链是否是有效的,也就避免了数据被恶意篡改的可能性,因为篡改数据就会改变hash值并破坏整个区块链。

代码语言:javascript
复制
/**
 * 区块
 */
@ToString
@Getter
public class Block {
    //数字签名
    private String hash;
    //上一个区块的数字签名
    private String preHash;
    //保存的数据
    private String data;
    //时间戳
    private long timeStamp;
    //工作量证明
    private int nonce;

    public Block(String data,String preHash) {
        this.data = data;
        this.preHash = preHash;
        timeStamp = new Date().getTime();
        hash = calculateHash();
    }

    /**
     * 计算数字签名
     * @return
     */
    public String calculateHash() {
        return StringUntil.applySha256(preHash + timeStamp + nonce + data);
    }

    /**
     * 挖矿
     * @param difficuity 挖矿难度
     */
    public void mineBlock(int difficuity) {
        String target = new String(new char[difficuity]).replace('\0','0');
        while (!hash.substring(0,difficuity).equals(target)) {
            nonce++;
            hash = calculateHash();
        }
        System.out.println("Block Mind!!!: " + hash);
    }
}
代码语言:javascript
复制
public class StringUntil {
    /**
     * Sha256离散
     * @param input
     * @return
     */
    public static String applySha256(String input){
        try {
            MessageDigest digest = MessageDigest.getInstance("SHA-256");
            //Applies sha256 to our input,
            byte[] hash = digest.digest(input.getBytes("UTF-8"));
            StringBuffer hexString = new StringBuffer(); // This will contain hash as hexidecimal
            for (int i = 0; i < hash.length; i++) {
                String hex = Integer.toHexString(0xff & hash[i]);
                if(hex.length() == 1) hexString.append('0');
                hexString.append(hex);
            }
            return hexString.toString();
        }
        catch(Exception e) {
            throw new RuntimeException(e);
        }
    }
}
代码语言:javascript
复制
public class BlockChain {
    public static List<Block> blockChain = new ArrayList<>();
    public static int difficulty = 5;

    /**
     * 判断整条区块链是否有效
     * @return
     */
    public static boolean isChainValid() {
        Block currentBlock;
        Block prevBlock;
        String hashTarget = new String(new char[difficulty]).replace('\0','0');

        for (int i = 1; i < blockChain.size(); i++) {
            currentBlock = blockChain.get(i);
            prevBlock = blockChain.get(i - 1);
            if (!currentBlock.getHash().equals(currentBlock.calculateHash())) {
                System.out.println("当前区块哈希值不匹配");
                return false;
            }
            if (!prevBlock.getHash().equals(currentBlock.getPreHash())) {
                System.out.println("前一个区块哈希值不匹配");
                return false;
            }
            if (!currentBlock.getHash().substring(0,difficulty).equals(hashTarget)) {
                System.out.println("当前区块有异常");
                return false;
            }
        }
        return true;
    }

    public static void main(String[] args) {
        //生成首区块
        Block genesisBlock = new Block("first","0");
        blockChain.add(genesisBlock);
        //挖矿
        blockChain.get(0).mineBlock(difficulty);
        System.out.println(genesisBlock);
        //第二个区块
        Block secBlock = new Block("second",genesisBlock.getHash());
        blockChain.add(secBlock);
        blockChain.get(1).mineBlock(difficulty);
        System.out.println(secBlock);
        //第三个区块
        Block thirdBlock = new Block("third",secBlock.getHash());
        blockChain.add(thirdBlock);
        blockChain.get(2).mineBlock(difficulty);
        System.out.println(thirdBlock);
        System.out.println("区块链有效性: " + isChainValid());
        System.out.println(JSONObject.toJSONString(blockChain));
    }
}

运行结果

代码语言:javascript
复制
Block Mind!!!: 000000dcabbe4bbeccbedc1efc25a886c598652e1efac0dfe1a3d74d9bc9f858
Block(hash=000000dcabbe4bbeccbedc1efc25a886c598652e1efac0dfe1a3d74d9bc9f858, preHash=0, data=first, timeStamp=1608653349150, nonce=1196438)
Block Mind!!!: 00000f6e06be2d09e9e8ba232d84ebe0de75b8e395feaa0f3ddb01377b55c72d
Block(hash=00000f6e06be2d09e9e8ba232d84ebe0de75b8e395feaa0f3ddb01377b55c72d, preHash=000000dcabbe4bbeccbedc1efc25a886c598652e1efac0dfe1a3d74d9bc9f858, data=second, timeStamp=1608653351114, nonce=1312709)
Block Mind!!!: 0000004bdf0b2af602460d79cdd247ac1b57fb651eb68ae68198b514de490569
Block(hash=0000004bdf0b2af602460d79cdd247ac1b57fb651eb68ae68198b514de490569, preHash=00000f6e06be2d09e9e8ba232d84ebe0de75b8e395feaa0f3ddb01377b55c72d, data=third, timeStamp=1608653353097, nonce=1552650)
区块链有效性: true
[{"data":"first","hash":"000000dcabbe4bbeccbedc1efc25a886c598652e1efac0dfe1a3d74d9bc9f858","nonce":1196438,"preHash":"0","timeStamp":1608653349150},{"data":"second","hash":"00000f6e06be2d09e9e8ba232d84ebe0de75b8e395feaa0f3ddb01377b55c72d","nonce":1312709,"preHash":"000000dcabbe4bbeccbedc1efc25a886c598652e1efac0dfe1a3d74d9bc9f858","timeStamp":1608653351114},{"data":"third","hash":"0000004bdf0b2af602460d79cdd247ac1b57fb651eb68ae68198b514de490569","nonce":1552650,"preHash":"00000f6e06be2d09e9e8ba232d84ebe0de75b8e395feaa0f3ddb01377b55c72d","timeStamp":1608653353097}]
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
区块链
云链聚未来,协同无边界。腾讯云区块链作为中国领先的区块链服务平台和技术提供商,致力于构建技术、数据、价值、产业互联互通的区块链基础设施,引领区块链底层技术及行业应用创新,助力传统产业转型升级,推动实体经济与数字经济深度融合。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档