12/08/2018, 17:14

Tạo 1 blockchain với Java (Part 2)

Trong bài viết trước mình đã giới thiệu qua về việc tạo block chain với Java. Các bạn có thể tham khảo bài viết trước ở đây. Trong bài viết này mình sẽ tiếp tục giới thiệu về việc khai thác các block. Chúng ta sẽ yêu cầu người khai thác phải làm việc bằng cách thử nghiệm nhiều giá trị khác nhau ...

Trong bài viết trước mình đã giới thiệu qua về việc tạo block chain với Java. Các bạn có thể tham khảo bài viết trước ở đây. Trong bài viết này mình sẽ tiếp tục giới thiệu về việc khai thác các block.

Chúng ta sẽ yêu cầu người khai thác phải làm việc bằng cách thử nghiệm nhiều giá trị khác nhau trong 1 block cho đến khi hash của block đó bắt đầu với một hoặc nhiều số 0.

Hãy cùng thêm 1 biến int gọi là nonce, biến này sẽ được sử dụng trong phương thức calculateHash() dùng để tính toán hash của block. Tiếp theo chúng ta cần phải thêm phương thức mineBlock(). Class Block sẽ như sau:

package vutachain;

import java.util.Date;

public class Block {

	public String hash;
	public String previousHash;
	private String data; // our data will be a simple message.
	private long timeStamp; // as number of milliseconds since 1/1/1970.
	private int nonce;

	public Block(String data, String previousHash) {
		this.data = data;
		this.previousHash = previousHash;
		this.timeStamp = new Date().getTime();
		this.hash = calculateHash(); // Making sure we do this after we set the other values.
	}

	public String calculateHash() {
		String calculatedhash = StringUtil.applySha256(previousHash + Long.toString(timeStamp) + Integer.toString(nonce) + data);
		return calculatedhash;
	}
	
	public void mineBlock(int difficulty) {
		String target = new String(new char[difficulty]).replace('', '0'); //Create a string with difficulty * "0" 
		while(!hash.substring( 0, difficulty).equals(target)) {
			nonce ++;
			hash = calculateHash();
		}
		System.out.println("Block Mined!!! : " + hash);
	}
}

Trên thực tế, mỗi người khai thác sẽ bắt đầu lặp lại từ một điểm ngẫu nhiên. Một số người khai thác thậm chí có thể thử số ngẫu nhiên cho nonce

Phương thức mineBlock() nhận vào 1 tham số difficulty(Độ khó), đó là số lượng số 0 bắt đầu hash mà người khai thác phải giải quyết. Độ khó thấp có thể rất dễ dàng để giải quyết gần như là tức thời trên phần lớn các máy tính phổ biến. Tuy nhiên dành cho test chúng ta sẽ đặt tạm là 5. Độ khó càng lớn thì càng mất nhiều thời gian để giải quyết.

Hãy cùng thay đổi VutaChain class như sau.

package vutachain;

import java.util.ArrayList;
import com.google.gson.GsonBuilder;

public class VutaChain {

	public static ArrayList<Block> blockchain = new ArrayList<Block>();
	public static int difficulty = 5;

	public static void main(String[] args) {
		// add our blocks to the blockchain ArrayList:
		blockchain.add(new Block("Hi im the first block", "0"));
		System.out.println("Trying to Mine block 1... ");
		blockchain.get(0).mineBlock(difficulty);
		
		blockchain.add(new Block("Yo im the second block", blockchain.get(blockchain.size() - 1).hash));
		System.out.println("Trying to Mine block 2... ");
		blockchain.get(1).mineBlock(difficulty);
		
		blockchain.add(new Block("Hey im the third block", blockchain.get(blockchain.size() - 1).hash));
		System.out.println("Trying to Mine block 3... ");
		blockchain.get(2).mineBlock(difficulty);
		
		System.out.println("
Blockchain is Valid: " + isChainValid());

		String blockchainJson = new GsonBuilder().setPrettyPrinting().create().toJson(blockchain);
		System.out.println("
The block chain: ");
		System.out.println(blockchainJson);
	}

	public static Boolean isChainValid() {
		Block currentBlock;
		Block previousBlock;
		String hashTarget = new String(new char[difficulty]).replace('', '0');

		for (int i = 1; i < blockchain.size(); i++) {
			currentBlock = blockchain.get(i);
			previousBlock = blockchain.get(i - 1);
			// compare registered hash and calculated hash:
			if (!currentBlock.hash.equals(currentBlock.calculateHash())) {
				System.out.println("Current Hashes not equal");
				return false;
			}
			// compare previous hash and registered previous hash
			if (!previousBlock.hash.equals(currentBlock.previousHash)) {
				System.out.println("Previous Hashes not equal");
				return false;
			}
			//check if hash is solved
			if(!currentBlock.hash.substring( 0, difficulty).equals(hashTarget)) {
				System.out.println("This block hasn't been mined");
				return false;
			}
		}
		return true;
	}
}

Sau khi chạy sẽ có kết quả như sau:

Trying to Mine block 1... 
Block Mined!!! : 00000c81c9596943dc73444ca9bb897e9f6e7b9a066b39dea36e947eabd0f17d
Trying to Mine block 2... 
Block Mined!!! : 000006175450b805d1ae2659038ee7342b0f65626e2cb07e4318e1067357dc72
Trying to Mine block 3... 
Block Mined!!! : 00000ed986669fd1893bb1f0ed889472347eec5092213f6e4e59ae94ab108b4f

Blockchain is Valid: true

The block chain: 
[
  {
    "hash": "00000c81c9596943dc73444ca9bb897e9f6e7b9a066b39dea36e947eabd0f17d",
    "previousHash": "0",
    "data": "Hi im the first block",
    "timeStamp": 1520064238409,
    "nonce": 16723
  },
  {
    "hash": "000006175450b805d1ae2659038ee7342b0f65626e2cb07e4318e1067357dc72",
    "previousHash": "00000c81c9596943dc73444ca9bb897e9f6e7b9a066b39dea36e947eabd0f17d",
    "data": "Yo im the second block",
    "timeStamp": 1520064238593,
    "nonce": 3256441
  },
  {
    "hash": "00000ed986669fd1893bb1f0ed889472347eec5092213f6e4e59ae94ab108b4f",
    "previousHash": "000006175450b805d1ae2659038ee7342b0f65626e2cb07e4318e1067357dc72",
    "data": "Hey im the third block",
    "timeStamp": 1520064247068,
    "nonce": 1208603
  }
]

Bạn hoàn toàn có thể thay đổi giá trị của độ khó để kiểm tra xem khi độ khó tăng thì thời gian khai thác sẽ thay đổi như thế nào             </div>
            
            <div class=

0