简述
本文主要的内容试一次关于区块链的作业,本次作业中有很多地方和实际的区块链不符合,比如hash,本文实现的区块链只是用了区块本身的hash并没去区分,头部和数据部分。仅供参考学习。
介绍
内容有点儿多,详情看pdf吧。
以上三个类分别为 存储数据的类,区块类,区块链的实现类
TritonData主要存储的交易(事件)的记录
TritonBlock 主要字段有上一个区块的hash和本区块的hash值
TritonBlockChain 将所有区块组织成区块链
注意:在hash的过程中我使用的是自己写的hash函数(因为作业要求呀),实际在使用的使用请使用比较好的如sha-256等函数。
具体实现
TritonData
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List; public class TritonData { private List<String> transactions;
private int proofId; /**
* Triton Data Constructor
*/
public TritonData() {
transactions = new ArrayList<String>();
proofId = 1;
} /*Constructor if specific values are specified*/
public TritonData(int proofId, List<String> transactions) {
this.transactions = transactions;
this.proofId = proofId;
} /*Get transactions*/
public List<String> getTransactions() {
return transactions;
} /*Get proofId*/
public int getProofId() {
return proofId;
} /*Print the data block*/
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append("DATA Start--------------------------------\n");
sb.append("Proof of work:" + proofId + "\n");
for (int i = 0; i < transactions.size(); ++i) {
sb.append("Transaction " + i + "\n");
sb.append("Transaction Content:" + transactions.get(i) + "\n");
}
sb.append("DATA End --------------------------------\n\n");
return sb.toString();
}
}
TritonBlock
import java.math.BigInteger; public class TritonBlock {
/*Class variables, all the attributes of the block*/
private int index;
private long timestamp;
private TritonData data;
private String prev_hash;
private String self_hash; /*Constructor, builds a block with passed in variables, then creates a hash for curr block*/
public TritonBlock(int index, long timestamp, TritonData data, String prev_hash) {
this.index = index;
this.timestamp = timestamp;
this.data = data;
this.prev_hash = prev_hash;
this.self_hash = hashBlock();
} //使用CRC variant方式
private String hashBlock() {
// BigInteger bigInteger=new BigInteger()
BigInteger bigInteger = new BigInteger("0");
for (String s : data.getTransactions()) {
char[] arr = s.toCharArray();
for (char c : arr) {
bigInteger = bigInteger.add(BigInteger.valueOf(c & 0xf8000000));
}
}
bigInteger = bigInteger.add(BigInteger.valueOf(timestamp));
bigInteger = bigInteger.add(BigInteger.valueOf(index));
char[] arr = prev_hash.toCharArray();
for (char c : arr) {
bigInteger = bigInteger.add(BigInteger.valueOf(c & 0xf8000000));
}
return bigInteger.toString(16);
} /*Get index*/
public int getIndex() {
return index;
} /*Get timestamp*/
public long getTimestamp() {
return timestamp;
} /*Get data block*/
public TritonData getData() {
return data;
} /*Get previous hash*/
public String getPrev_hash() {
return prev_hash;
} /*Get current hash*/
public String getSelf_hash() {
return self_hash;
} /*Print the block*/
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append("TritonBlock " + index + "\n");
sb.append("Index: " + index + "\n");
sb.append("Timestamp: " + timestamp + "\n");
sb.append("Prev Hash: " + prev_hash + "\n");
sb.append("Hash: " + self_hash + "\n");
sb.append(data.toString());
return sb.toString();
}
}
TritonBlockChain
import java.util.*; public class TritonBlockChain { private static final String MINE_REWARD = "1";
/*Blockchain clas variable*/
private List<TritonBlock> blockchain; /*Constructor, takes in genesis block data to start the blockchain*/
public TritonBlockChain(int index, long timestamp, TritonData data, String prev_hash) {
blockchain = new ArrayList<TritonBlock>();
blockchain.add(new TritonBlock(index, timestamp, data, prev_hash));
} /*Makes the next block after the proof of work from mining is finished*/
public TritonBlock makeNewBlock(TritonBlock lastBlock, TritonData newData) {
return new TritonBlock(lastBlock.getIndex() + 1,
System.currentTimeMillis(), newData, lastBlock.getPrev_hash());
} /*Mines the transaction and creates the block to add to the blockchain*/
public boolean beginMine(List<String> curTransactions) {
if (curTransactions.isEmpty()) {
return false;
}
int proofId = proofOfWork();
curTransactions.add("Triton coined earned: " + MINE_REWARD);
// TritonData(int proofId, List<String> transactions)
TritonData newData = new TritonData(proofId, curTransactions);
TritonBlock lastBlock = blockchain.get(blockchain.size() - 1);
TritonBlock newBlock = new TritonBlock(lastBlock.getIndex() + 1,
System.currentTimeMillis(), newData, lastBlock.getSelf_hash());
blockchain.add(newBlock);
return true;
} /*Simple proof of work algorithm to prove cpu usage was used to mine block*/
public int proofOfWork() {
TritonBlock tb = blockchain.get(blockchain.size() - 1);
int lastProofId = tb.getData().getProofId();
//use loop
int temp = Math.max(lastProofId, 13);
++temp;
while (true) {
if (temp % 13 == 0 && temp % lastProofId == 0) {
return temp;
}
++temp;
}
} /*Prints current blockchain*/
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n" +
"T R I T O N B L O C K C H A I N\n" +
"~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\n");
for (TritonBlock tb : blockchain) {
sb.append(tb.toString());
}
return sb.toString();
} /*Validates each block in the chain looking for any hash pointer descrepancies, which can point to a tampering problem*/
public boolean validateChain() {
for (int i = 1; i < blockchain.size(); ++i) {
TritonBlock preBlock = blockchain.get(i - 1);
TritonBlock cntBlock = blockchain.get(i);
if (!cntBlock.getPrev_hash().equals(preBlock.getSelf_hash())) {
return false;
}
}
return true;
} /*Get blockchain*/
public List<TritonBlock> getBlockchain() {
return blockchain;
}
}
测试
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;
import java.io.FileReader;
import java.util.Random;
import java.util.StringTokenizer; /*Sets up server, manages blockchains, takes in and acts on user input*/
public class TritonMiner { private static final int BLOCK_SIZE = 2; public static void main(String[] args) throws IOException {
/*Initialize the local blockchain*/
long timestamp = System.currentTimeMillis();
/*Created local blockchain and added genesis block*/
TritonBlockChain blockchain = new TritonBlockChain(0, timestamp, new TritonData(), "0");
/*Represents the queue for all transactions*/
//read in trascatipn and put in transcation queue
List<String> transaction_queue = new ArrayList<String>();
loadTranscation(transaction_queue, "transaction/transaction_1.txt"); List<String> currentTransaction = new ArrayList<String>();
for (int i = 0; i < transaction_queue.size(); i++) {
currentTransaction.add(transaction_queue.get(i));
if (currentTransaction.size() == BLOCK_SIZE) {
//mine
blockchain.beginMine(new ArrayList<>(currentTransaction));
//reintilize
currentTransaction.clear();
}
}
/*Print blockchain*/
System.out.println(blockchain.toString());
/*Validate the blockchain Mine*/
System.out.println("This block chain is: "+blockchain.validateChain());
} public static boolean loadTranscation(List<String> transaction_queue, String fname) {
String line;
BufferedReader inputStrem;
StringTokenizer st;
try {
inputStrem = new BufferedReader(new FileReader(fname));
while ((line = inputStrem.readLine()) != null) {
transaction_queue.add(line);
}
} catch (IOException e) {
System.out.println (e.toString());
System.out.println("Could not find file " + fname);
}
return true;
} }
结果
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
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函数(我一般就是用取余哈哈)
- 通过自己的辛苦获得了大洋(很开心)