用Java编写第一个区块链

原文地址:https://www.cnblogs.com/zacky31/p/9057193.html

目标:

  • 创建一个最基本的“区块链”
  • 实现一个简单的挖矿系统

前提:

  对面向对象编程有一定的基础

注意:

  值得注意的是,这不会是一个完整的功能,恰恰相反,这是一个概念证明的实例,可以帮助您进一步了解区块链。

准备:

  我将会使用Java来实现,当然你也可以使用任何面向对象的语言。

环境:

  • JDK 8
  • IDEA
  • Maven

开始吧

  区块链就好比多个块连接起来。其中每一块都将拥有自己的签名,签名中包含其前面的块信息和一些数据(例如交易信息)。

  每个块不仅仅包含它之前的块信息,同时也包含自身。如果前面一块内容改变了,其 hash 值也会改变,将会导致其后面所有的块发生变化。通过计算和比较所得的 hash 值,我们可以判断区块链是否合法。换句话说,改变区块链中的任意内容,将会改变整个区块链的签名。

  根据上面的分析,我们先创建一个 Block 类。

import java.util.Date;

public class Block {
    public String hash; //存放数字签名
    public String preHash; //前面块的签名
    private String data;
    private long timeStamp;

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

  接下来,我们需要一个生成签名的方法。有很多加密算法可供选择,这里使用 SHA256 刚刚好。

import java.security.MessageDigest;

public class StringUtil {
    public static String applySha256(String input) {
        try {
            MessageDigest digest = MessageDigest.getInstance("SHA-256");

            byte[] hash = digest.digest(input.getBytes("UTF-8"));
            StringBuilder hexString = new StringBuilder();
            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);
        }
    }
}

  现在,我们向 Block 类中添加计算数字签名的方法,并修改一下其构造方法。

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

    public String calculateHash() {
        String calculatedhash = StringUtil.applySha256(preHash + Long.toString(timeStamp) + data);
        return calculatedhash;
    }

  到这里,可以写个 Main 方法看一下效果。

public class Main {

    public static void main(String[] args) {
        Block first = new Block("Hi i am the first block", "0");
        System.out.println("Hash for block 1 : " + first.hash);
        Block second = new Block("Hi i am the second block", first.hash);
        System.out.println("Hash for block 2 : " + second.hash);
        Block third = new Block("Hi i am the third block", second.hash);
        System.out.println("Hash for block 3 : " + third.hash);
    }
}

  可以看见每个 Block 都有自己唯一的 数字签名,当然,现在还没有构成一个区块链,将这些块存放到一个 ArrayList 中吧。修改 Main 类后再次运行。

import com.google.gson.GsonBuilder;

import java.util.ArrayList;

public class Main {

    public static ArrayList<Block> blockchain = new ArrayList<Block>();

    public static void main(String[] args) {
        blockchain.add(new Block("Hi i am the first block", "0"));
        blockchain.add(new Block("Hi i am the second block", blockchain.get(blockchain.size() - 1).hash));
        blockchain.add(new Block("Hi i am the third block", blockchain.get(blockchain.size() - 1).hash));

        String blockchainJson = new GsonBuilder().setPrettyPrinting().create().toJson(blockchain);
        System.out.println(blockchainJson);
    }
}

  现在,需要一种方法去验证创建的区块链。编写一段 isChainValid() 方法。任何块的改变将会导致这个方法失效。

public static Boolean isChainValid() {
        Block currentBlock;
        Block previousBlock;

        for (int i = 1; i < blockchain.size(); i++) {
            currentBlock = blockchain.get(i);
            previousBlock = blockchain.get(i - 1);

            if (!currentBlock.hash.equals(currentBlock.calculateHash())) {
                System.out.println("Current Hashes not equal!");
                return false;
            }

            if (!previousBlock.hash.equals(currentBlock.preHash)) {
                System.out.println("Previous Hashes not equal!");
                return false
            }
        }
        return true;
    }

  接下来,尝试一下挖矿!

  

  在 Block 类中,新增一个变量 nonce,并且添加到 calculateHash() 这个方法中,同时需要 mineBlock() 这个方法。这个方法中的 difficulty 变量就是用来控制计算量的。当设置的值较低时,大部分计算机很快就能算出来。

import java.util.Date;

public class Block {
    public String hash;
    public String preHash;
    private String data;
    private long timeStamp;
    private int nonce;

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

    public String calculateHash() {
        String calculatedhash = StringUtil.applySha256(preHash + Long.toString(timeStamp) + Integer.toString(nonce) +
                data);
        return calculatedhash;
    }

    public void mineBlock(int difficulty) {
        String target = new String(new char[difficulty]).replace(‘\0‘, ‘0‘);
        while (!hash.substring(0, difficulty).equals(target)) {
            nonce++;
            hash = calculateHash();
        }
        System.out.println("Block Mined!!!" + hash);
    }
}

  我们可以在 Main 类中定义个静态变量。尝试在每次创建新块去调用 mineBlock() 方法。

import com.google.gson.GsonBuilder;

import java.util.ArrayList;
import java.util.Date;

public class Main {

    public static ArrayList<Block> blockchain = new ArrayList<Block>();
    public static int difficulty = 5;

    public static void main(String[] args) {
        long beginTime1 = new Date().getTime();
        blockchain.add(new Block("Hi i am the first block", "0"));
        System.out.println("Trying to  mine block 1...");
        blockchain.get(0).mineBlock(difficulty);
        long endTime1 = new Date().getTime();
        System.out.println("Mining block 1 cost " + (endTime1 - beginTime1));

        long beginTime2 = new Date().getTime();
        blockchain.add(new Block("Hi i am the second block", blockchain.get(blockchain.size() - 1).hash));
        System.out.println("Trying to  mine block 2...");
        blockchain.get(1).mineBlock(difficulty);
        long endTime2 = new Date().getTime();
        System.out.println("Mining block 1 cost " + (endTime2 - beginTime2));

        long beginTime3 = new Date().getTime();
        blockchain.add(new Block("Hi i am the third block", blockchain.get(blockchain.size() - 1).hash));
        System.out.println("Trying to  mine block 3...");
        blockchain.get(2).mineBlock(difficulty);
        long endTime3 = new Date().getTime();
        System.out.println("Mining block 1 cost " + (endTime3 - beginTime3));

        System.out.println("\nBlockchain is Valid: " + isChainValid());

        String blockchainJson = new GsonBuilder().setPrettyPrinting().create().toJson(blockchain);
        System.out.println(blockchainJson);
    }

    public static Boolean isChainValid() {
        Block currentBlock;
        Block previousBlock;
        String hashTarget = new String(new char[difficulty]).replace(‘\0‘, ‘0‘);

        for (int i = 1; i < blockchain.size(); i++) {
            currentBlock = blockchain.get(i);
            previousBlock = blockchain.get(i - 1);

            if (!currentBlock.hash.equals(currentBlock.calculateHash())) {
                System.out.println("Current Hashes not equal!");
                return false;
            }

            if (!previousBlock.hash.equals(currentBlock.preHash)) {
                System.out.println("Previous Hashes not equal!");
                return false;
            }

            if (!currentBlock.hash.substring(0, difficulty).equals(hashTarget)) {
                System.out.println("This block hasn‘t been mined");
                return false;
            }
        }
        return true;
    }
}

  运行发现,挖矿过程还是很费时间的。把计算量改成7,差不多每挖一个需要一分钟。。。

  如果在此过程中,有人篡改了数据,将会导致:

  • 区块链将会无效
  • 不能够创建一个更长的区块链
  • 网络中的诚实链将会比较长的区块链有时间上的优势

  不过如果篡改数据拥有更强的运算速度,可能成功篡改。

  这样,基本上简单实现了一个区块链了。

原文地址:https://www.cnblogs.com/Vito-Yan/p/9589190.html

时间: 2024-10-04 16:33:10

用Java编写第一个区块链的相关文章

大数据、java、Python、区块链、人工智能哪个发展前景刚好?

在这个信息时代高速发展的情况下,很多人会对自己该往哪个方向发展感到迷茫,下面我就浅显的给大家介绍一下五大流行区域的发展前景. 大数据的发展前景: 当前大数据行业真的是人才稀缺吗? 学了几年后,大数据行业会不会产能过剩? 大数据行业最终需要什么样的人才? 接下来就带你们看看分析结果: 当前大数据行业真的是人才稀缺吗? 对!未来人才缺口150万,数据分析人才最稀缺. 先看大数据人才缺口有多大? 根据LinkedIn(领英)发布的<2016年中国互联网最热职位人才报告>显示,研发工程师.产品经理.人

基于java实现的简单区块链

技术:maven3.0.5 + jdk1.8 概述 区块链是分布式数据存储.点对点传输.共识机制.加密算法等计算机技术的新型应用模式.所谓共识机制是区块链系统中实现不同节点之间建立信任.获取权益的数学算法 . 详细 代码下载:http://www.demodashi.com/demo/14933.html 前言 使用java创建第一个非常基本的区块链 实现一个简单的工作量证明系统即挖矿 创建区块链 区块链就是一串或者是一系列区块的集合,类似于链表的概念,每个区块都指向于后面一个区块,然后顺序的连

中科物缘第一作者区块链论文被顶级SCI刊物录用

近日,中科物缘焦臻桢博士为第一作者撰写的学术论文<A Blockchain based Computing Architecture for Mobile Ad-Hoc Cloud>被顶级SCI刊物IEEE Network录用. 该篇论文国内外首次阐述并论证了基于区块链构建物联网节点自组织云的关键理论及技术. 自组织云是多个物联网设备在本地自发组成计算资源池并进行计算协作和资源分享的一种计算范式.在弱网络覆盖或应用有超低时延需求等场景中,物联网节点往往无法依赖远端云服务提供及时的计算支持,此时

JAVA区块链项目实战

课程介绍 全国首套,基于java的区块链实战教程.目的是让更多的java编程者了解区块链,掌握区块链开发.1.区块链理论:以node.js例子区块链原理有深刻理解:2.区块链java实战:深刻理解区块链原理后能用java编写区块链项目. ------第一部分 项目演示 目录------------------------------------------------------------ 1-第一章-01-java区块链项目实战教程前言 2-第一章-02-Java项目三台内网服务器演示 3-

Java开发区块链的三大sdk库

如果你想将区块链合并到一个Java项目中,现在我们来看看就是这个细分领域中三个最大的OSS玩家. 好的伙计们,我们都听说过比特币,以太坊或其他加密货币,其中有一些时髦的名字围绕着我们常见的新闻,但我们作为Java开发人员知道如何轻松地与这些区块链技术进行交互吗?以下是可用于利用区块链趋势的前三大Java项目.该列表基于GitHub存储库星级排序.非常感谢评论和意见. BitcoinJ 这个名字很具描述性,你不觉得吗?如果你想知道如何创建比特币钱包并管理节点之间的交易,那么你应该尝试使用Bitco

【区块链Go语言实现】第一部分:区块链基本原型

0x00 介绍 区块链(Blockchain)是21世纪最具革命性的技术之一,目前它仍处于逐渐成熟阶段,且其发展潜力尚未被完全意识到.从本质上讲,区块链只是一种记录的分布式数据库.但它之所以独特,是因为它并不是一个私有的数据库,而是一个公共数据库,也就是说,每个使用它的人都有一份完整或部分的数据副本.并且,只有在数据库的其他持有者同意的情况下,才可以向区块链中添加新的记录.此外,正是区块链使得加密货币和智能合约成为可能. 在本系列文章中,我们将基于区块链构建一种简单的加密货币. 0x01 区块

“链”上雄安,雄安新区城市发展新思路,未来区块链第一城?

日前,欧洲金融工具市场指令(MiFiD II)立法设计师兼欧洲议会会员Kay Swinburne在接受外媒Business Insider采访时表示,如果伦敦金融城还想继续成为欧洲金融科技中心的话,就应该拥抱区块链技术,这样才能在脱欧之后确保未来前景光明. Kay Swinburne表示:"对我来说,我们必须要拥抱分布式账本技术.英国脱欧之后,伦敦金融城如何能够继续保持相关性?答案就是要成为新技术的支持者,而不是仅仅修补一下现有系统.在脱欧之后,我们需要把区块链技术真正应用起来,实现跨越式发展.

区块链项目实战视频课程(Java版)

区块链项目实战视频课程(Java版)网盘地址:https://pan.baidu.com/s/1EiONxCp7JBw6GJKhjK_zHQ 提取码:tzr1备用地址(腾讯微云):https://share.weiyun.com/5al0zSz 密码:3rgeye 本课程是基于java语言的区块链实战教程.目的是让更多的java编程者了解区块链,掌握区块链开发. 区块链是分布式数据存储.点对点传输.共识机制.加密算法等计算机技术的新型应用模式. 区块链(Blockchain)是比特币的一个重要概

以太坊开发完整去中心化应用 —— 区块链投票系统

第一节 课程概述 本课程面向初学者,内容涵盖以太坊开发相关的基本概念,并将手把手地教大家如何构建一个 基于以太坊的完整去中心化应用 -- 区块链投票系统. ethereum logo 通过本课程的学习,你将掌握: 以太坊区块链的基本知识 开发和部署以太坊合约所需的软件环境 使用高级语言(solidity)编写以太坊合约 使用NodeJS编译.部署合约并与之交互 使用Truffle框架开发分布式应用 使用控制台或网页与合约进行交互 前序知识要求 为了顺利完成本课程,最好对以下技术已经有一些基本了解