Kiến trúc Blockchain - Tạo Blockchain đơn giản với Javascript - Phần 1

1. GIỚI THIỆU

Blockchain là gì? Chắc hẳn các bạn đã nghe rất nhiều rồi. Vậy cụ thể cấu tạo và hoạt động của blockchain ra sao thì trong bài viết này mình sẽ cùng tìm hiểu cụ thể hơn nhé.

Blockchain là gồm hai từ block và chain ghép lại.

Block là một khối, trong mỗi khối sẽ chứa những thông tin cần thiết để tạo nên một block.

Chain là chuỗi.

Vậy Blockchain nghĩa là một chuỗi các block có liên quan đến nhau.

2. CẤU TRÚC BLOCKCHAIN

Cụ thể một block chứa những thông gì? Và những thông tin đó liên quan gì nhau để khiến cho các block tạo nên một chuỗi?

Cùng xem thử hình bên dưới.

Ở đây mình định nghĩa một block bao gồm:

index là thứ tự của block, từ 1 -> n
prevHash là một chuỗi mã hash của khối trước nó
timestamp là thời gian block đó được tạo
data dữ liệu muốn lưu trữ
hash là một chuỗi mã đã được mã hoá bằng thuật toán SHA256. Dữ liệu dùng để mã hoá bao gồm những thông tin của block: index, hash của khối trước (prevHash), timestamp, data.

Vd: SHA256(index + prevHash + timestamp + JSON.stringify(data));

Chính vì khối sau luôn chứa dữ liệu hash của khối trước nó, nên dữ liệu được mã hoá là chặc chẽ.

Nếu ở block thứ 2, chúng ta cố thay đổi data khác đi, thì chắc chắn khi block 2 tạo mã băm hash sẽ ra một hash có giá trị khác. Dẫn đến các block 3, block 4, … , block n sẽ sai theo, và chuỗi lúc này bị gẫy ở block thứ 2.

3. BLOCKCHAIN ĐƠN GIẢN VỚI JAVASCRIPT

Để dễ hiểu hơn, chúng ta làm demo tạo Blockchain đơn giản với javascript.

Tải thư viện crypto về, nó có sẵn thuật toán sha.

npm install crypto-js

Trước tiên, định nghĩa Block như sau:

const SHA256 = require("crypto-js/sha256");

// tạo một class là có tên là Block
// trong class này, chứa thông tin cần thiết của block cần có
// index            : số thứ tự của block
// timestamp        : thời gian block được tạo ra
// data             : dữ liệu muốn lưu trữ. Có thể là string, json, array, ...
// previousHash     : mã hash của block trước đó
// hash             : mã băm của block từ các dữ liệu của block đó
class Block {
    constructor(index, timestamp, data, previousHash = '') {
        this.index          = index;
        this.previousHash   = previousHash;
        this.timestamp      = timestamp;
        this.data           = data;
        this.hash           = this.calculateHash();
    }
    //
    // hàm tạo mã hash cho block bằng thuật toán SHA256
    calculateHash() {
        return SHA256(
            this.index + 
            this.previousHash + 
            this.timestamp + 
            JSON.stringify(this.data)
        ).toString();
    }
}

Tiếp đến là định nghĩa Blockchain

class Blockchain{
    // khởi tạo một blockchain cần có khối đầu tiên.
    // nên khi khởi tạo, gọi hàm createGenesisBlock() để tạo block đầu tiên và add vào chuỗi chain
    constructor() {
        this.chain = [this.createGenesisBlock()];
    }
    //
    // tạo block đầu tiên trong chuỗi với index = 0, prevHash = 0
    createGenesisBlock() {
        return new Block(0, "01/01/2018", "yesterday I bought a cat", "0");
    }
    //
    // trả về block mới nhất trong chuỗi
    getLatestBlock() {
        return this.chain[this.chain.length - 1];
    }
    //
    // add block vào chuỗi blockchain
    // trước khi add: lưu lại prevHash của block trước đó + tính toán hash
    addBlock(newBlock) {
        newBlock.previousHash = this.getLatestBlock().hash;
        newBlock.hash = newBlock.calculateHash();
        this.chain.push(newBlock);
    }
}

Để check tính chính xác của Blockchain, mình viết thêm một hàm trong class Blockchain để check các khối nối với nhau là đúng.

class Blockchain{
    //
    //.........
    //
    // viết thêm hàm này để check sự tường mình của blockchain
    // hàm sẽ check từ khối đầu tiên đến khối cuối cùng của chain
    // blockchain chỉ đúng khi:
    //  1. prevHash của khối hiện tại bằng hash của khôi trước đó
    //  2. tính lại hash của khối hiện có bằng giá trị của hash đã lưu trong block không
    isChainValid() {
        for (let i = 1; i < this.chain.length; i++){
            const currentBlock = this.chain[i];
            const previousBlock = this.chain[i - 1];
            if (currentBlock.hash !== currentBlock.calculateHash()) {
                return false;
            }
            if (currentBlock.previousHash !== previousBlock.hash) {
                return false;
            }
        }
        return true;
    }
}

Thế là xong cái demo nho nhỏ tạo Blockchain bằng javascript. Bây giờ chạy thử nhé.

// tạo một blockchain - khi gọi như vậy đồng nghĩa là tạo luôn block đầu tiên trong blockchain như đã giải thích trên
let vnlabCoin = new Blockchain();

// add khối thứ 2, khối thứ 3 vào blockchain
vnlabCoin.addBlock(new Block(1, "01/02/2017", "today I bought a dog"));
vnlabCoin.addBlock(new Block(2, "01/03/2017", "tomorrow I buy a flower"));

// check blockchain hoạt động OK không?
console.log('Blockchain valid? ' + vnlabCoin.isChainValid());
//>>> Blockchain valid? true

// Thử thay đổi dữ liệu ở block số 2
console.log('Try to change a block...');
vnlabCoin.chain[1].data = "Hề Hề, ta là hacker đây";
//>>> Changing a block...

// check thử lại blockchain có bị sai gì không? Kết quả output ra false, nghĩa là đã có sự thay đổi ở 1 block nào đó
console.log("Blockchain valid? " + vnlabCoin.isChainValid());
//>>> Blockchain valid? false

4. KẾT THÚC

Qua mô phỏng trên, chúng ta cũng phần nào hiểu và hình dung được cấu trúc bên trong của Blockchain. Nhưng chắc hẳn các bạn đang thắc mắc vậy mấy phần gọi là phần thưởng đào, rồi thợ đào đóng vai trò gì trong Blockchain. Vâng, Blockchain với demo trên là blockchain cơ bản, chưa áp dụng thuật toán Proof-of-work. Khi áp dụng thuật toán đó, thì blockchain sẽ chia phần thưởng cho thợ mỏ xuất sắc giải mã được mã khối nhanh nhất. Cụ thể như thế nào mình sẽ viết trong phần tiếp nhé.