Phần 1: Tự tạo ra một công nghệ Blockchain của riêng mình
This post hasn't been updated for 6 years
Công nghệ Blockchain
Blockchain khá đơn giản và dễ hiểu. Đó là một dạng cơ sở dữ liệu nhưng lưu trữ phân tán. Rất khó để chỉnh sửa một bản ghi sau khi đã được thêm vào. Thường được sử dụng như là muốn cuốn sổ giao dịch.
Chúng ta thường nhầm lẫn là chỉ có ngân hàng mới cần chứng chỉ giao dịch không sửa được. Nhưng chúng ta hàng ngày gặp các trường hợp này rất nhiều. Chúng ta cần dữ liệu không thể sửa đổi để tránh bị lừa đảo khi giao dịch tay đôi. Ví dụ: bạn đi thuê nhà, hợp đồng thuê nhà ghi rõ giá tiền thuê hàng tháng, và ngày bắt đầu thuê. Sau đó hợp đồng được viết làm 2 bản và bạn giữ 1 bản, chủ nhà giữ một bản. Nếu một ngày đẹp trời, chủ nhà nói bạn chưa đóng tiền tháng này. Bạn cần có 2 tờ giấy hợp đồng để đối chiếu lại ngày bắt đầu đóng tiền. 2 tờ giấy hợp đồng mà tôi vừa nói là 1 dạng nguyên thủy của dữ liệu phân tán không thể sửa đổi. Và cũng có thể hiểu đó là 2 bản ghi của 1 blockchain. Nó là phân tán vì lưu ở 2 phía người dùng và không cần đến một nơi trung gian thứ 3 để lưu trữ.
Nếu có nhiều hơn 2 người dùng, thì công nghệ Blockchain cũng vẫn không thay đổi cách hoạt động, lúc này 2 hoặc nhiều người dùng trao đổi với nhau thì các giao dịch trong cùng một hệ thống (cùng một mạng) phải được liên kết (nối lại, xích lại, chaining) lại với nhau thành một mảng duy nhất. Và mỗi người trong mạng sẽ có được toàn bộ lịch sử giao dịch của những người khác trước đó. Như vậy nếu có 5 người chơi, thì sẽ có tới 5 bản ghi của lịch sử giao dịch được phân tán trong mạng. Nếu một trong 5 người tự ý sửa đổi bản ghi để đưa cho 4 người còn lại, 4 người kia sẽ biết ngay có gian dối và họ sẽ không chấp nhận.
Đó chính là SỰ PHÂN TÁN, và SỰ MINH BẠCH của công nghệ Blockchain.
Thử tự xây dựng một Blockchain hoàn chỉnh
Ngay bây giờ, ta hãy thử sử dụng javascript thuần và HTML để tự xây dựng một công nghệ Blockchain xem sao.
Để mô tả một Block (phần tử giao dịch) trong Blockchain (mảng các giao dịch), ta cần một class như sau:
/*=== ĐÂY LÀ CLASS MÔ TẢ CẤU TRÚC CỦA MỘT BLOCK. MỘT PHẦN TỬ CỦA BLOCKCHAIN ===*/
class Block {
constructor(NgayGioTao, DuLieu, HashTruocDo = '') { //Để tạo ra một Block chúng ta cần truyền vào các tham số như sau:
this.NgayGioTao = NgayGioTao; //Ngày tháng hiện tại tạo ra Block này
this.DuLieu = DuLieu; //Dữ liệu sẽ được lưu trong BLock này. Nó có thể là bất cứ cái gì, từ String, Array, Object JSON...
this.HashTruocDo = HashTruocDo; //Lưu trữ Hash của Block ngay trước Block này. Vì các Block sẽ được nối lại thành chuỗi (mảng).
this.Hash = this.TinhToanHash(); //Mã hóa toàn bộ nội dung của BLock này theo thuật toán SHA256 và lưu lại vào chính Block này.
}
TinhToanHash() { //Hàm mã hóa nội dung của toàn bộ Block. Do đó ta cần lấy toàn bộ các thuộc tính của Block đưa vào SHA256 để mã hóa ra một chuỗi.
return CryptoJS.SHA256(this.HashTruocDo + this.NgayTao + JSON.stringify(this.DuLieu)).toString(); //chú ý: JSON.stringify(this.DuLieu) sẽ convert biến Object this.DuLieu thành chuỗi.
}
}
Dữ liệu trong một Block rất đơn giản. Hàm quan trọng nhất trong mỗi Block chính là hàm tính toán giá trị Hash (mã hóa) của toàn bộ Block đó. Vì hàm tính toán Hash cần đến một thuật toán mã hóa mạnh là mã hóa SHA 256 bit, do đó ta cần một thư viện. Ở đây tôi dùng CryptoJS. Tôi sẽ load thư viện này từ cdn:
<script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/3.1.9-1/core.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/3.1.9-1/sha256.min.js"></script>
Chúng ta cần tạo một class Blockchain để chứa mảng các phần tử Block. Hãy xem đoạn code sau và đọc comment:
/*=== ĐÂY LÀ CLASS MÔ TẢ CẤU TRÚC CỦA MỘT BLOCKCHAIN. LÀ MỘT MẢNG CÁC BLOCK ===*/
class Blockchain {
constructor() { //Cấu trúc của Blockchain như sau
this.MangBlock = []; //Tạo ra một mảng rỗng để chứa các Block.
this.MangBlock.push(new Block("01/01/2018", "Genesis Block", "0")); //Tạo phần tử đầu tiên của Blockchain. Đây thường được gọi là Genesis Block, hay chính là "phần tử khởi tạo". Các phần tử tiếp theo sẽ nối tiếp vào phần tử này.
}
PhanTuCuoiCung() {
return this.MangBlock[this.MangBlock.length - 1]; //Lấy ra phần tử cuối cùng của Blockchain
}
TaoMoiBlock(newBlock) { //Hàm dùng để thêm mới một Block vào Blockchain.
newBlock.HashTruocDo = this.PhanTuCuoiCung().Hash; //Lấy Hash của phần tử cuối cùng của mảng và lưu vào HasTruocDo của phần tử này
newBlock.Hash = newBlock.TinhToanHash(); //Tính toán Hash của chính phần tử này.
this.MangBlock.push(newBlock); //Nối phần tử newBlock vào làm phần tử cuối cùng của mảng Blockchain.
}
KiemTraTinhToanVen() {
for (let i = 1; i < this.MangBlock.length; i++) {
const BlockHienTai = this.MangBlock[i]; //Lấy ra phần tử ở vị trí hiện tại
const BlockTruocDo = this.MangBlock[i - 1]; //Lấy ra phần tử ở ngay trước vị trí hiện tại
if (BlockHienTai.Hash !== BlockHienTai.TinhToanHash()) { //Kiểm tra lại Hash của toàn bộ Block hiện tại và Hash đã lưu xem có trùng nhau không.
return false; //Nếu không trùng tức là Dữ liệu trong Block hiện tạiđã bị chỉnh sửa, hàm KiemTraToanVen sẽ trả về false luôn.
}
if (BlockHienTai.HashTruocDo !== BlockTruocDo.Hash) { //Lấy Hash hiện tại và Hash phần tử trước đó đã lưu xem có trùng nhau không.
return false; //Nếu không trùng tức là Hash của Block hiện tại đã bị chỉnh sửa, hàm KiemTraToanVen sẽ trả về false luôn.
}
}
return true; //Nếu kiểm tra hết toàn bộ trong vòng For mà không vấn đề gì thì tức là Blockchain vẫn toàn vẹn, chưa bị sửa đổi.
}
}
Hàm TaoMoiBlock()
là hàm sẽ đảm bảo 2 việc:
- Tính toán toàn bộ Hash của Block hiện tại và lưu lại.
- Lấy Hash của Block cuối cùng để lưu vào biến HashTruocDo của Block hiện tại. Như vậy thì các Block sẽ được nối (chain-xích) lại với nhau thông qua ràng buộc là mã Hash.
Hàm KiemTraTinhToanVen()
là một hàm rất quan trọng, đóng vai trò trái tim trong Blockchain. Mỗi khi một người dùng bất kỳ muốn kiểm tra toàn bộ Blockchain hiện tại xem có an toàn hay không để tiếp tục giao dịch. Toàn bộ các Hash trong chuỗi được lấy ra so sánh. Tính toàn vẹn của từng Block và tính liên kết của toàn bộ Block phải được đảm bảo không bị sai mã Hash. Nếu có một trường hợp sai, tức là data đã bị ai đó trong mạng chỉnh sửa.
Như vậy là công nghệ Blockchain tự tạo đã xong, giờ ta có thể bắt đầu test nó:
var MyCoin = new Blockchain(); //Tạo mới một Blockchain để chứa các giao dịch. Ở đây ta có thể coi là lịch sử giao dịch của đồng tiền MyCoin.
MyCoin.TaoMoiBlock(new Block("02/01/2018", { //Thêm một giao dịch mới, Data là một Object chứa nội dung chuyển tiền
NguoiGui: "Ong A",
NguoiNhan: "Ba B",
Tien: 350
}));
MyCoin.TaoMoiBlock(new Block("03/01/2018", {//Thêm một giao dịch mới, Data là một Object chứa nội dung chuyển tiền
NguoiGui: "Ba B",
NguoiNhan: "Ong C",
Tien: 200
}));
Thêm chút mắm muối, ta sẽ được một file html hoàn chỉnh. Bạn có thể lưu lại và bật trực tiếp bằng trình duyệt chrome hoặc firefox.
Các bạn có thể xem DEMO tại link này: LINK_DEMO
Sau khi chạy kết quả ta sẽ thấy sự toàn vẹn của dữ liệu đã được kiểm tra đúng. Và dữ liệu MangBlock cũng đã liên kết đúng giữa HashTruocDo và Hash của 2 phần tử liền kề nhau.
Download file example1.html
tại đây: LINK_DOWNLOAD
Kết luận
Chỉ đơn giản như vậy là ta đã tạo thành công một công nghệ Blockchain. Để có thể giao dịch được thì file example1.html
này của chúng ta phải được copy đến các máy cá nhân của người dùng trong mạng. Và giá trị MangBlock phải là cố định và được sync (đồng bộ) bằng mạng ngang hàng P2P để mỗi khi có giao dịch mới ở máy một người, toàn bộ những người khác sẽ Validate (kiểm tra lại tính toàn vẹn những gì được thêm vào) và tiếp tục giao dịch tiếp.
Công nghệ Blockchain sơ khai này mới đáp ứng được một số yêu cầu đơn giản của Blockchain:
- Dữ liệu nằm phân tán.
- Dữ liệu và mã nguồn được minh bạch. Người dùng sẽ dễ dàng kiểm tra tính toàn vẹn.
- Một khi dữ liệu đã thêm vào hệ thống thì không thể xóa hoặc sửa được nữa. Nếu mất đi một phần tử thì chuỗi của chúng ta không toàn vẹn. Điều này đảm bảo tính minh bạch của toàn hệ thống, không ai có thể tác động vào hệ thống và mọi người đều nhìn thấy rõ dữ liệu một khi đã thêm vào thành công.
Tuy nhiên công nghệ Blockchain vừa tạo vẫn còn một số sơ hở:
- Người dùng dễ dàng thêm hàng trăm ngàn giao dịch vào hệ thống mỗi giây. Dẫn đến hệ thống bị SPAM và toàn giao dịch rác. Blockchain dài nhất cũng sẽ được coi là đúng nhất do đó khả năng sai lệch hệ thống.
- Hacker dễ dàng clone (copy) toàn bộ biến
MangBlock
rồi sửa một bản ghi, rồi ghi đè toàn bộ MangBlock fake đó vào hệ thống của hắn. Tiếp theo MangBlock đó sẽ được tính toán lại Hash cho thành chuỗi mới và đồng bộ tự động, và ghi đè vào máy của những người còn lại. Dẫn đến sự "tèo" của hệ thống chúng ta khổ công gây dựng.
Để nâng cấp hệ thống vừa xây dựng, chúng ta cần tìm hiểu đến một công nghệ cao siêu hơn. Đó chính là các công nghệ "đào" tiền ảo, hay còn gọi là Mining. Mời các bạn theo dõi tiếp ở phần 2.
All Rights Reserved