Java实现简单的区块链(一)

区块

一个区块由该区块的hash,前一区块的hash,区块存储的数据prehash,时间戳timestamp,填充数nonce构成

hash的计算

我们将prehash,timestamp,data以及nonce连接起来计算sha256

//编写了一个工具类
public class Sha256Utils {

   public static String getSha256(String s) throws NoSuchAlgorithmException, UnsupportedEncodingException {
       MessageDigest sha = MessageDigest.getInstance("SHA-256");
       sha.update(s.getBytes("UTF-8"));
       byte[] digest = sha.digest();
       return byte2Hex(digest);
  }
   private static String byte2Hex(byte[] bytes) {
       StringBuilder sb = new StringBuilder();
       String temp = null;
       for (byte aByte : bytes) {
           temp = Integer.toHexString(aByte & 0xFF);
           if (temp.length() == 1) {
               // 1得到一位的进行补0操作
               sb.append("0");
          }
           sb.append(temp);
      }
       return sb.toString();
  }

}

挖矿

挖矿是比特币中的共识算法,叫工作量证明,首先设定一个targetBit 表明hash值的(16位表示)前多少位为0,也就是说我们通过调整nonce的值算出来的hash必须小于目标hash。在实际中,这个targetBit是会动态调整的以确保挖矿速度恒定。

代码

public class Block {
   private String hash;
   private String prehash;
   private String data;
   private long timestamp;
   private int nonce;

   public Block(String prehash, String data) {
       this.prehash = prehash;
       this.data = data;
       this.timestamp = new Date().getTime();
       this.hash=setHash();
       this.nonce=0;

  }
   public String setHash(){
       String sha256=null;
       try {
           sha256 = Sha256Utils.getSha256(prehash + data + timestamp+Integer.toString(nonce));

      } catch (Exception e) {
           System.out.println("区块计算hash出现错误");
      }
       return sha256;

  }

   public String getHash() {
       return hash;
  }

   public void mine(int targetBits){
       String target = new String(new char[targetBits]).replace('\0', '0'); //Create a string with difficulty * "0"
       while(!hash.substring( 0, targetBits).equals(target)) {
           nonce ++;
           hash = setHash();
      }


  }
   public static String str2HexStr(String str)
  {

       char[] chars = "0123456789ABCDEF".toCharArray();
       StringBuilder sb = new StringBuilder("");
       byte[] bs = str.getBytes();
       int bit;

       for (int i = 0; i < bs.length; i++)
      {
           bit = (bs[i] & 0x0f0) >> 4;
           sb.append(chars[bit]);
           bit = bs[i] & 0x0f;
           sb.append(chars[bit]);
           sb.append(' ');
      }
       return sb.toString().trim();
  }

   @Override
   public String toString() {
       return "Block{" +
               "hash='" + hash + '\'' +
               ", prehash='" + prehash + '\'' +
               ", data='" + data + '\'' +
               ", timestamp=" + timestamp +
               ", nonce=" + nonce +
               '}';
  }
}

 

区块链

区块链实际是一个有序的链表,所以我们这里实际采用ArrayList存储

public class BlockChain extends ArrayList<Block> {
   public ArrayList<Block> blockChain=  new  ArrayList<Block>();
   public int targetBits=24;
   public BlockChain() {
  }
   public void setTargetBits(int num){
       targetBits=num;
  }

   @Override
   public int size() {
       return blockChain.size();
  }

   @Override
   public boolean add(Block block) {
       return blockChain.add(block);
  }
   @Override
   public String toString() {
       return blockChain.toString();
  }

   @Override
   public Block get(int index) {
       return blockChain.get(index);
  }
}

 

 

 

posted @ 2021-03-16 12:20  刚刚好。  阅读(244)  评论(0编辑  收藏  举报