简述
本文主要的内容试一次关于区块链的作业,本次作业中有很多地方和实际的区块链不符合,比如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
总结
通过做这个作业,我收获很多:
- 什么是挖矿,什么是矿工,他们如何挣钱。提供计算资源的人叫矿工,提供的机器叫矿机,挖矿就是通过记录交易来获取收益。
- 本次作业也给了很多hash函数可以自己选择,比如我使用的CRC variant就是一个比较简单的hash函数(我一般就是用取余哈哈)
- 通过自己的辛苦获得了大洋(很开心)