您的位置 首页 java

用java创建一个简单的区块链程序

创建 区块链

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

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

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

一、封装区块对象

  1. package com.pibigstar.blockchain;
  2. import java.util.Date;
  3. /**
  4. * 封装区块对象
  5. * @author pibigstar
  6. *
  7. */
  8. public class Block {
  9. public String hash;
  10. //上一个区块的hash值
  11. public String previousHash;
  12. //每个区块存放的信息,这里我们存放的是一串 字符串
  13. private String data;
  14. //时间戳
  15. private long timeStamp;
  16. //挖矿者的工作量证明
  17. private int nonce;
  18. //构造
  19. public Block(String data,String previousHash ) {
  20. this.data = data;
  21. this.previousHash = previousHash;
  22. this.timeStamp = new Date().getTime();
  23. //根据previousHash、data和timeStamp产生唯一hash
  24. this.hash = calculateHash();
  25. }
  26. //基于上一块的内容计算新的散列
  27. public String calculateHash() {
  28. String calculatedhash = StringUtil.applySha256(
  29. previousHash +
  30. Long. toString (timeStamp) +
  31. Integer .toString(nonce) +
  32. data
  33. );
  34. return calculatedhash;
  35. }
  36. //挖矿
  37. public void mineBlock(int difficulty) {
  38. //目标值,difficulty越大,下面计算量越大
  39. String target = StringUtil.getDificultyString(difficulty);
  40. //difficulty如果为5,那么target则为 00000
  41. while(!hash.substring( 0, difficulty).equals(target)) {
  42. nonce ++;
  43. hash = calculateHash();
  44. }
  45. System.out.println(“创建区块:” + hash);
  46. }
  47. }

二、封装工具类

  1. package com.pibigstar.blockchain;
  2. import java.security.MessageDigest;
  3. import com.google.gson.GsonBuilder;
  4. /**
  5. * 工具类
  6. * 创建数字签名、返回 JSON 格式数据、返回难度字符串目标
  7. * @author pibigstar
  8. *
  9. */
  10. public class StringUtil {
  11. //将Sha256应用到一个字符串并返回结果
  12. public static String applySha256(String input){
  13. try {
  14. MessageDigest digest = MessageDigest.getInstance(“SHA-256”);
  15. byte[] hash = digest.digest(input.getBytes(“UTF-8”));
  16. StringBuffer hexString = new StringBuffer();
  17. for (int i = 0; i < hash.length; i++) {
  18. String hex = Integer.toHexString(0xff & hash[i]);
  19. if(hex.length() == 1) hexString. append (‘0’);
  20. hexString.append(hex);
  21. }
  22. return hexString.toString();
  23. }
  24. catch(Exception e) {
  25. throw new RuntimeException(e);
  26. }
  27. }
  28. //返回JSON格式数据
  29. public static String getJson(Object o) {
  30. return new GsonBuilder().setPrettyPrinting().create().toJson(o);
  31. }
  32. //返回难度字符串目标,与散列比较。难度5将返回“00000”
  33. public static String getDificultyString(int difficulty) {
  34. return new String(new char[difficulty]).replace(‘\0’, ‘0’);
  35. }
  36. }

三、主函数,开始创建区块链

  1. package com.pibigstar.blockchain;
  2. import java.util.ArrayList;
  3. import com.google.gson.GsonBuilder;
  4. /**
  5. * 创建区块链
  6. * @author pibigstar
  7. *
  8. */
  9. public class BlockChain{
  10. //存放所有的区块集合
  11. public static ArrayList<Block> blockchain = new ArrayList<Block>();
  12. public static int difficulty = 5;//挖矿的难度,数字越大越难
  13. public static void main(String[] args) {
  14. System.out.println(“正在创建第一个区块链……. “);
  15. addBlock(new Block(“我是第一个区块链”, “0”));//创世块
  16. System.out.println(“正在创建第二个区块链……. “);
  17. addBlock(new Block(“我是第二个区块链”,blockchain.get(blockchain.size()-1).hash));
  18. System.out.println(“正在创建第三个区块链…….”);
  19. addBlock(new Block(“我是第三个区块链”,blockchain.get(blockchain.size()-1).hash));
  20. System.out.println(“区块链是否有效的: ” + isChainValid());
  21. String blockchainJson = StringUtil.getJson(blockchain);
  22. System.out.println(blockchainJson);
  23. }
  24. /**
  25. * 检查区块链的完整性
  26. * @return
  27. */
  28. public static Boolean isChainValid() {
  29. Block currentBlock;
  30. Block previousBlock;
  31. String hashTarget = new String(new char[difficulty]).replace(‘\0’, ‘0’);
  32. //循环区块链检查散列:
  33. for(int i=1; i < blockchain.size(); i++) {
  34. currentBlock = blockchain.get(i);
  35. previousBlock = blockchain.get(i-1);
  36. //比较注册散列和计算散列:
  37. if(!currentBlock.hash.equals(currentBlock.calculateHash()) ){
  38. System.out.println(“Current Hashes not equal”);
  39. return false;
  40. }
  41. //比较以前的散列和注册的先前的散列
  42. if(!previousBlock.hash.equals(currentBlock.previousHash) ) {
  43. System.out.println(“Previous Hashes not equal”);
  44. return false;
  45. }
  46. //检查哈希是否被使用
  47. if(!currentBlock.hash.substring( 0, difficulty).equals(hashTarget)) {
  48. System.out.println(“这个区块还没有被开采。。。”);
  49. return false;
  50. }
  51. }
  52. return true;
  53. }
  54. /**
  55. * 增加一个新的区块
  56. * @param newBlock
  57. */
  58. public static void addBlock(Block newBlock) {
  59. newBlock.mineBlock(difficulty);
  60. blockchain.add(newBlock);
  61. }
  62. }

文章来源:智云一二三科技

文章标题:用java创建一个简单的区块链程序

文章地址:https://www.zhihuclub.com/192704.shtml

关于作者: 智云科技

热门文章

评论已关闭

5条评论

  1. 66 and may contain milk by products, whereas peripheral abscesses in nonpuerperal mastitis often arise within inflamed cysts

网站地图