1. 程式人生 > >區塊鏈——java實現

區塊鏈——java實現

簡述

本文主要的內容試一次關於區塊鏈的作業,本次作業中有很多地方和實際的區塊鏈不符合,比如hash,本文實現的區塊鏈只是用了區塊本身的hash並沒去區分,頭部和資料部分。僅供參考學習。

介紹

內容有點兒多,詳情看pdf吧。

    

以上三個類分別為 儲存資料的類,區塊類,區塊鏈的實現類

TritonData主要儲存的交易(事件)的記錄

TritonBlock 主要欄位有上一個區塊的hash和本區塊的hash值

TritonBlockChain 將所有區塊組織成區塊鏈

注意:在hash的過程中我使用的是自己寫的hash函式(因為作業要求呀),實際在使用的使用請使用比較好的如sha-256等函式。

具體實現

TritonData

 1 import java.util.ArrayList;
 2 import java.util.LinkedList;
 3 import java.util.List;
 4 
 5 public class TritonData {
 6 
 7     private List<String> transactions;
 8     private int proofId;
 9 
10     /**
11      * Triton Data Constructor
12      */
13     public
TritonData() { 14 transactions = new ArrayList<String>(); 15 proofId = 1; 16 } 17 18 /*Constructor if specific values are specified*/ 19 public TritonData(int proofId, List<String> transactions) { 20 this.transactions = transactions; 21 this
.proofId = proofId; 22 } 23 24 /*Get transactions*/ 25 public List<String> getTransactions() { 26 return transactions; 27 } 28 29 /*Get proofId*/ 30 public int getProofId() { 31 return proofId; 32 } 33 34 /*Print the data block*/ 35 public String toString() { 36 StringBuilder sb = new StringBuilder(); 37 sb.append("DATA Start--------------------------------\n"); 38 sb.append("Proof of work:" + proofId + "\n"); 39 for (int i = 0; i < transactions.size(); ++i) { 40 sb.append("Transaction " + i + "\n"); 41 sb.append("Transaction Content:" + transactions.get(i) + "\n"); 42 } 43 sb.append("DATA End --------------------------------\n\n"); 44 return sb.toString(); 45 } 46 }

 

TritonBlock 

 1 import java.math.BigInteger;
 2 
 3 public class TritonBlock {
 4     /*Class variables, all the attributes of the block*/
 5     private int index;
 6     private long timestamp;
 7     private TritonData data;
 8     private String prev_hash;
 9     private String self_hash;
10 
11     /*Constructor, builds a block with passed in variables, then creates a hash for curr block*/
12     public TritonBlock(int index, long timestamp, TritonData data, String prev_hash) {
13         this.index = index;
14         this.timestamp = timestamp;
15         this.data = data;
16         this.prev_hash = prev_hash;
17         this.self_hash = hashBlock();
18     }
19 
20     //使用CRC variant方式
21     private String hashBlock() {
22 //        BigInteger bigInteger=new BigInteger()
23         BigInteger bigInteger = new BigInteger("0");
24         for (String s : data.getTransactions()) {
25             char[] arr = s.toCharArray();
26             for (char c : arr) {
27                 bigInteger = bigInteger.add(BigInteger.valueOf(c & 0xf8000000));
28             }
29         }
30         bigInteger = bigInteger.add(BigInteger.valueOf(timestamp));
31         bigInteger = bigInteger.add(BigInteger.valueOf(index));
32         char[] arr = prev_hash.toCharArray();
33         for (char c : arr) {
34             bigInteger = bigInteger.add(BigInteger.valueOf(c & 0xf8000000));
35         }
36         return bigInteger.toString(16);
37     }
38 
39     /*Get index*/
40     public int getIndex() {
41         return index;
42     }
43 
44     /*Get timestamp*/
45     public long getTimestamp() {
46         return timestamp;
47     }
48 
49     /*Get data block*/
50     public TritonData getData() {
51         return data;
52     }
53 
54     /*Get previous hash*/
55     public String getPrev_hash() {
56         return prev_hash;
57     }
58 
59     /*Get current hash*/
60     public String getSelf_hash() {
61         return self_hash;
62     }
63 
64     /*Print the block*/
65     public String toString() {
66         StringBuilder sb = new StringBuilder();
67         sb.append("TritonBlock " + index + "\n");
68         sb.append("Index: " + index + "\n");
69         sb.append("Timestamp: " + timestamp + "\n");
70         sb.append("Prev Hash: " + prev_hash + "\n");
71         sb.append("Hash: " + self_hash + "\n");
72         sb.append(data.toString());
73         return sb.toString();
74     }
75 }

 

TritonBlockChain 

 1 import java.util.*;
 2 
 3 public class TritonBlockChain {
 4 
 5     private static final String MINE_REWARD = "1";
 6     /*Blockchain clas variable*/
 7     private List<TritonBlock> blockchain;
 8 
 9     /*Constructor, takes in genesis block data to start the blockchain*/
10     public TritonBlockChain(int index, long timestamp, TritonData data, String prev_hash) {
11         blockchain = new ArrayList<TritonBlock>();
12         blockchain.add(new TritonBlock(index, timestamp, data, prev_hash));
13     }
14 
15     /*Makes the next block after the proof of work from mining is finished*/
16     public TritonBlock makeNewBlock(TritonBlock lastBlock, TritonData newData) {
17         return new TritonBlock(lastBlock.getIndex() + 1,
18                 System.currentTimeMillis(), newData, lastBlock.getPrev_hash());
19     }
20 
21     /*Mines the transaction and creates the block to add to the blockchain*/
22     public boolean beginMine(List<String> curTransactions) {
23         if (curTransactions.isEmpty()) {
24             return false;
25         }
26         int proofId = proofOfWork();
27         curTransactions.add("Triton coined earned: " + MINE_REWARD);
28 //      TritonData(int proofId, List<String> transactions)
29         TritonData newData = new TritonData(proofId, curTransactions);
30         TritonBlock lastBlock = blockchain.get(blockchain.size() - 1);
31         TritonBlock newBlock = new TritonBlock(lastBlock.getIndex() + 1,
32                 System.currentTimeMillis(), newData, lastBlock.getSelf_hash());
33         blockchain.add(newBlock);
34         return true;
35     }
36 
37     /*Simple proof of work algorithm to prove cpu usage was used to mine block*/
38     public int proofOfWork() {
39         TritonBlock tb = blockchain.get(blockchain.size() - 1);
40         int lastProofId = tb.getData().getProofId();
41         //use loop
42         int temp = Math.max(lastProofId, 13);
43         ++temp;
44         while (true) {
45             if (temp % 13 == 0 && temp % lastProofId == 0) {
46                 return temp;
47             }
48             ++temp;
49         }
50     }
51 
52     /*Prints current blockchain*/
53     public String toString() {
54         StringBuilder sb = new StringBuilder();
55         sb.append("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n" +
56                 "T R I T O N B L O C K C H A I N\n" +
57                 "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\n");
58         for (TritonBlock tb : blockchain) {
59             sb.append(tb.toString());
60         }
61         return sb.toString();
62     }
63 
64     /*Validates each block in the chain looking for any hash pointer descrepancies, which can point to a tampering problem*/
65     public boolean validateChain() {
66         for (int i = 1; i < blockchain.size(); ++i) {
67             TritonBlock preBlock = blockchain.get(i - 1);
68             TritonBlock cntBlock = blockchain.get(i);
69             if (!cntBlock.getPrev_hash().equals(preBlock.getSelf_hash())) {
70                 return false;
71             }
72         }
73         return true;
74     }
75 
76     /*Get blockchain*/
77     public List<TritonBlock> getBlockchain() {
78         return blockchain;
79     }
80 }

 

測試

 1 import java.io.BufferedReader;
 2 import java.io.IOException;
 3 import java.io.InputStreamReader;
 4 import java.util.ArrayList;
 5 import java.util.List;
 6 import java.io.FileReader;
 7 import java.util.Random;
 8 import java.util.StringTokenizer;
 9 
10 /*Sets up server, manages blockchains, takes in and acts on user input*/
11 public class TritonMiner {
12 
13     private static final int BLOCK_SIZE = 2;
14 
15     public static void main(String[] args) throws IOException {
16         /*Initialize the local blockchain*/
17         long timestamp = System.currentTimeMillis();
18         /*Created local blockchain and added genesis block*/
19         TritonBlockChain blockchain = new TritonBlockChain(0, timestamp, new TritonData(), "0");
20         /*Represents the queue for all transactions*/
21         //read in trascatipn and put in transcation queue
22         List<String> transaction_queue = new ArrayList<String>();
23         loadTranscation(transaction_queue, "transaction/transaction_1.txt");
24 
25         List<String> currentTransaction = new ArrayList<String>();
26         for (int i = 0; i < transaction_queue.size(); i++) {
27             currentTransaction.add(transaction_queue.get(i));
28             if (currentTransaction.size() == BLOCK_SIZE) {
29                 //mine
30                 blockchain.beginMine(new ArrayList<>(currentTransaction));
31                 //reintilize
32                 currentTransaction.clear();
33             }
34         }
35         /*Print blockchain*/
36         System.out.println(blockchain.toString());
37         /*Validate the blockchain Mine*/
38         System.out.println("This block chain is: "+blockchain.validateChain());
39     }
40 
41     public static boolean loadTranscation(List<String> transaction_queue, String fname) {
42         String line;
43         BufferedReader inputStrem;
44         StringTokenizer st;
45         try {
46             inputStrem = new BufferedReader(new FileReader(fname));
47             while ((line = inputStrem.readLine()) != null) {
48                 transaction_queue.add(line);
49             }
50         } catch (IOException e) {
51             System.out.println (e.toString());
52             System.out.println("Could not find file " + fname);
53         } 
54         return true;
55     } 
56 
57 }

 

結果

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
T R I T O N B L O C K C H A I N
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

TritonBlock 0
Index: 0
Timestamp: 1541995814844
Prev Hash: 0
Hash: 167061cdfbc
DATA Start--------------------------------
Proof of work:1
DATA End --------------------------------

TritonBlock 1
Index: 1
Timestamp: 1541995814851
Prev Hash: 167061cdfbc
Hash: 167061cdfc4
DATA Start--------------------------------
Proof of work:26
Transaction 0
Transaction Content:mary bob 10$
Transaction 1
Transaction Content:mary bob 12$
Transaction 2
Transaction Content:Triton coined earned: 1
DATA End --------------------------------

TritonBlock 2
Index: 2
Timestamp: 1541995814851
Prev Hash: 167061cdfc4
Hash: 167061cdfc5
DATA Start--------------------------------
Proof of work:52
Transaction 0
Transaction Content:simon tian 3$
Transaction 1
Transaction Content:tian ming 3$
Transaction 2
Transaction Content:Triton coined earned: 1
DATA End --------------------------------


This block chain is: true

 

總結

通過做這個作業,我收穫很多:

  1. 什麼是挖礦,什麼是礦工,他們如何掙錢。提供計算資源的人叫礦工,提供的機器叫礦機,挖礦就是通過記錄交易來獲取收益。
  2. 本次作業也給了很多hash函式可以自己選擇,比如我使用的CRC variant就是一個比較簡單的hash函式(我一般就是用取餘哈哈)
  3. 通過自己的辛苦獲得了大洋(很開心)