Danh mục lưu trữ: Crypto

BITCOIN – BẢN CHẤT VÀ CƠ HỘI ?

Bitcoin: Lịch sử hình thành và cách thức hoạt động (Dành cho người mới)

Trong thị trường ảm đạm hiện nay, hãy cùng nhìn về quá khứ một chút và tìm hiểu quá trình hình thành của toàn bộ thị trường tiền điện tử này. Lý do bạn nên vững tin vào thị trường và có niềm tin rằng 1 thời huy hoàng sẽ trở lại.

Từ xa xưa, nhu cầu trao đổi hàng hóa của con người đã trở thành nhu cầu tất yếu. Người A cần muối, người B cần gạo. Cả 2 đều phải có thứ người kia muốn để trao đổi. Tuy nhiên điều này tạo ra nhiều bất cập và là nguyên nhân ra đời của tiền tệ, vật trung gian giúp trao đổi giữa người với người trở nên dễ dàng hơn. Tuy nhiên, tạo hóa thật biết cách thử thách con người. Lòng tham ở mỗi chúng ta luôn tồn tại và điều gì đảm bảo khi người A đưa tiền và sẽ nhận lại được điều mình muốn ? đặc biệt là những thứ giá trị ? Lòng tin giữa người với người luôn bị thử thách và một thực thể thứ 3 đã được tạo ra, bên trung gian (middleman).

Bên trung gian này có thể là một ngân hàng, một tổ chức hay đơn giản hơn là một ai đó để đứng ra, đảm bảo cho giao dịch được thực hiện và thu lại một khoản phí nhỏ. Dù vậy, dễ thấy bộ máy giao dịch hoạt động vẫn phụ thuộc vào con người. Và con người thì luôn tham lam. Trừ các nhà sư, nhưng mà ai lại đi nhờ nhà sư làm mid man cơ chứ ?. Vì vậy bitcoin ra đời. Lần đầu tiên trong lịch sử, giao dịch của con người được trao quyền cho máy móc thực hiện, hoàn toàn không có chỗ cho lòng tham của con người.

BITCOIN – NHỮNG VIÊN GẠCH ĐẦU TIÊN

Blockchain, được mô tả lần đầu vào năm 1991 bởi 1 nhóm nhà khoa học, với mục đích ban đầu nhằm ghi lại các mốc thời gian. Định hướng ban đầu là giúp các sự kiện lịch sử không thể bị sửa đổi một khi đã được ghi lại (như chúng ta điều biết, lịch sử luôn được viết bởi kẻ chiến thắng).

Tuy nhiên, mãi đến năm 2008, đâu đó trên internet, một kẻ thiên tài (hay một kẻ tội đồ) có tên Satoshi Nakamoto đã có bài luận đầu tiên với tiêu đề:”Bitcoin, a peer – to – peer Electronic Cash System”. Từ đó, một kỷ nguyên mới đã bắt đầu hình thành và thật là một sự trùng hợp khi đúng khoảng thời gian này, cuộc khủng hoảng tài chính với sự sụp đổ của Lehman Brothers đã khiến nền kinh tế thế giới chao đảo.

Một năm sau đó, 2009, dự án Bitcoin đã được thực hiện hóa và khối genesis block đầu tiên đã được khai thác, và Satoshi Nakamoto đã để lại một thông điệp như sau:

” Tờ Time, ngày 03/01/2009, Đại Pháp Quan đứng trên bờ vực phải viện trợ ngân hàng lần thứ hai “

Từ đó, 3-1 hằng năm được coi là ngày sinh nhật của bitcoin và toàn bộ thị trường tiền điện tử. 1 năm sau đó, Satoshi Nakamoto bàn giao lại công việc cho 1 nhóm chuyên gia và biến mất. Điều kì lạ là không ai biết được ông/bà Satoshi Nakamoto là ai. Một tổ chức ? Một cá nhân ? Hay thực thể ngoài hành tinh ? Không một ai biết và điều còn sót lại chỉ là các tin đồn và một hệ thống thanh toán đồ sộ với giá trị mấy trăm tỷ đô ở 2022.

BITCOIN-BẢN CHẤT VÀ CƠ HỘI ?

Ngay từ đầu, viêc sử dụng tiền giấy hay các vật hiện hữu trung gian đã có nhiều bất cập. Vấn đề lưu trữ, độ bền, tính toàn vẹn của tiền tệ,.. Chính vì vậy, ngân hàng và các cuốn sổ cái giúp ghi chép lại các giao dịch được ra đời. Chúng ta không thật sự cần sở hữu tiền, chúng ta chỉ cần quyền sử dụng tiền và điều đó được thực hiện qua các dòng lịch sử giao dịch.

Trước khi bitcoin ra đời, cuốn sổ cái này nằm hoàn toàn trong tay ngân hàng và giới tài phiệt. Việc thay đổi và làm giả “số liệu” đã được chứng minh qua sự sụp đổ của lehman brothers. Suy cho cùng, cuốn sổ cái này phải không bị con người can thiệp. Và đó là khi Satoshi quyết định hướng đi của mình.

Toàn bộ hệ thống blockchain được giải thích đơn giản như sau:

A,B,C,D là là bạn nhau, 4 người thường đi ăn và việc chia tiền bằng tiền mặt thường xuyên rất bất tiện. Thế là 4 người nghĩ ra 1 chiêu, 4 người sẽ giữ sẽ tạo 1 cuốn sổ cái, ghi lại các giao dịch được thực hiện giữa 4 người họ. Ví dụ như

A đưa B 20 đô

B đưa C 30 đô

C đưa A 10 đô

1 cuốn sổ này hoàn toàn giống nhau và được công khai ở đâu đó như 1 website, được truy cập bởi 4 người.

Ai cũng có thể thêm 1 dòng mới đại loại như A đưa B 10 đô. Vào cuối mỗi tháng, mọi người có thể họp lại xem ai chi nhiều thì bỏ thêm tiền vô, ai thu nhiều thì lấy tiền ra.

Tuy nhiên, điều này lại nảy sinh 1 vấn đề, việc ai cũng có thể thêm dòng mới vào cuốn sổ cái thì điều gì ngăn A thêm vào dòng giao dịch: B đưa A 30 đô. mà không được sự chấp thuận của B ?.

Điều này đã được giải quyết bằng cái chúng ta hay sử dụng mỗi khi sử dụng metamask: chữ kí điện tử.

Giống như chữ kí tay, mỗi khi 1 dòng giao dịch từ ai đó được thêm vào sổ cái, theo sau nó là 1 chữ kí điện tử. Điều này giúp giao dịch trở nên uy tính hơn và không thể làm giả do mỗi chữ kí điện tử được mã hóa là duy nhất và không bị giả mạo.

Câu hỏi được đặt ra là: mã hóa như thế nào để trở nên duy nhất ?. Điều này là nguyên nhân ra đời cho cặp Secret key/Public key, được máy tính hiểu dưới dạng chuỗi 0 và 1

Bình thường, chữ ký ở đời thật vẫn có tỷ lệ làm giả được, tuy nhiên với chữ kí điện tử, một xác nhận từ bạn sẽ có dạng như sau:

Sign (nội dung tin nhắn, Secret key) = chữ ký của bạn => dẫn đến việc với mỗi giao dịch, chữ ký của bạn sẽ hoàn toàn khác nhau do có sự thay đổi về tin nhắn.

Ngoài ra, một số bên còn bắt verify trước khi cho bạn ký tên. Để làm điều này. Hàm cơ bản để verify sẽ là:

Verify (message, chữ kí của bạn, public key) = True/False

Tất cả điều giúp xác nhận xem bạn có phải là chủ nhân của giao dịch và giúp cuốn sổ cái trở nên minh bạch hơn.

Cuốn sổ cái lúc này sẽ có dạng

A đưa B 20 đô 0100101010 (với chuỗi 01001010 là chữ kí của bạn)

B đưa C 30 đô 1011010010

C đưa A 10 đô 1000101000

Tuy nhiên, chúng ta lại có một vấn đề khác ở đây, điều gì ngăn cản B copy giao dịch đầu tiên và nhân nó lên nhiều lần

A đưa B 20 đô 0100101010

A đưa B 20 đô 0100101010

A đưa B 20 đô 0100101010

Một ngày đẹp trời và A nhận ra đã nợ B đến 60 đô. Thật không công bằng. Chính vì vậy, cả nhóm họp lại và tìm ra cách giải quyết, thêm 1 ID vào mỗi giao dịch. Lúc này sổ cái sẽ có dạng:

0 A đưa B 20 đô 0100101010

1 B đưa C 30 đô 1011010010

2 C đưa A 10 đô 1000101000

Lúc này cuốn sổ cái của chúng ta đã hoàn thiện, tuy nhiên, nếu đặt ở trên website, ai host thì sẽ có quyền sửa đổi đó theo ý muốn. Rồi website sập thì sao?

Chính vì vậy, Satoshi đề xuất mỗi người sẽ có cuốn sổ cái của riêng họ. Khi một người thêm 1 dòng mới vào cuốn sổ, họ sẽ phát ra tính hiệu kêu gọi 3 người kia thêm dòng đó vô cuốn sổ của riêng mình. Cái này theo thuật ngữ crypto thường gọi là phi tập trung.

Tuy nhiên, điều này có nhiều điểm rất vô lý. Làm sao chúng ta có thể tin tưởng rằng tính hiệu người kia phát ra là đúng ? Làm sao chúng ta biết chắc những người còn lại sẽ điền vô cuốn sổ cái của họ những tính hiệu mà chúng ta phát ra ?

Đây là vấn đề đã được giải quyết trong white paper của bitcoin. Giải pháp được đưa ra ở đây là chúng ta sẽ tin tưởng vào sự làm việc của máy tính hay mã SHA256.

Khi chúng ta gõ SHA256(nội dung bất kì), chúng sẽ xuất ra màn hình một chuỗi các kí tự 0 và 1. Chuỗi này có điểm đặc biệt là không thể dịch ngược lại, tức là khi chúng ta có kết quả, chúng ta không thể nào suy luận ngược lại được nguyên nhân, chúng ta chỉ có thể thử từng tình huống để xem nguyên nhân nào dẫn đến kết quả đó.

Mô hình hoạt động cơ bản như sau:

  • một dãy các giao dịch sẽ được tổng hợp lại thành 1 danh sách( trung bình là 24000 giao dịch), sau đó, nhiệm vụ của máy tính sẽ là dùng hàm Sha256(nội dung danh sách + 1 số bất kì) để kết quả sẽ có số lượng số 0 ở đầu chuỗi theo quy định, trung bình khoảng 30 số 0 liên tục ở đầu. Sau khi tìm ra nội dung + 1 số thỏa mãn, máy tính sẽ đính kèm nội dung và bằng chứng công việc hay ở đây là kết quả hàm SHA256 sau đó đóng gói thành 1 block => đây là cách 1 block hình thành

Tuy nhiên, để không ai có thể thay thế nó, 1 block sẽ có thêm hash = chuỗi 1 và 0 (kết quả của việc giải mã Sha256 của block trước đó). Điều này khiến cho việc thay thế 1 block sẽ dẫn đến thay thế toàn bộ các block trên chuỗi.

Giờ đây, 1 block sẽ bao gồm:

Hash

0 A đưa B 20 đô 0100101010

1 B đưa C 30 đô 1011010010

2 C đưa A 10 đô 1000101000

Proof of work (1 số bất kì )

Một số lưu ý và thuật ngữ:

  • số lượng số 0 cần trung bình luôn được duy trì làm sao để mỗi block được hình thành là 10p. Nếu nhiều thợ đào cùng tham gia giải Sha256, độ khó sẽ tăng lên bằng cách thêm nhiều số 0 cần thiết. Sau khi hoàn thành đóng gói 1 block, thợ đào sẽ nhận 1 phần thưởng nhỏ. Cứ mỗi 210000 block, tức 4 năm 1 lần, phần thưởng sẽ tự động giảm đi 1 nửa.Tuy nhiên, sau khi phần thưởng hoàn toàn cạn vào vài năm nữa, thợ đào hoàn toàn có thể thêm vào 1 dòng trong block để làm reward thưởng như: Thưởng cho thợ đào 0.001 btc như phần thưởng khuyến khích cho việc xử lý giao dịch.

Cuối cùng, nếu nhóm bạn này được mở rộng ra toàn thế giới, chúng ta hoàn toàn không cần dùng đến tiền mặt. Không ai có thể cướp đi hoặc làm mất giá đồng tiền của chúng ta. Chính vì vậy, bitcoin vẫn luôn, và mãi sống nếu còn người tin tưởng vào nó.

Hình 1: Thông điệp đầu tiên trong chuỗi genesis của Satoshi Nakamoto

Hình 2: Dòng code đầu tiên được xem là của dự án bitcoin

Phần 3: Tự tạo ra một đồng tiền ảo Bitcoin của mình

Phần 3: Tự tạo ra một đồng tiền ảo Bitcoin của mình

Tiền ảo là gì?

Ở 2 phần trước ta đã hiểu thế nào là Blockchain, và thế nào là đào Hash để ngăn chặn giao dịch ảo. Tuy nhiên Blockchain của chúng ta vì quá khó để tạo giao dịch. Nó trở nên hoàn toàn kém hấp dẫn và chả ai đi bỏ thời gian ra đào Hash rồi nhét data vào chuỗi của chúng ta làm gì. Chúng ta cần tạo ra cái gì đó để kích cầu.

Lúc này thì khái niệm TIỀN ẢO mới ra đời. Tiền ảo là một PHẦN THƯỞNG dành cho người nào bỏ công sức để đào hash, để xác thực các giao dịch và thêm thành công các Block vào chuỗi của chúng ta. Ban đầu, lượng tiền ảo (hay tiền thưởng) đào được là rất ít, dẫn đến có sự cạnh tranh, sự trao đi đổi lại (trading) lấy tiền thật. Dần dần đồng tiền của ta tạo ra sẽ lên giá.

Với suy nghĩ đơn giản như vậy, ta hãy bắt tay vào sửa file html và tạo nên đồng tiền ảo đầu tiên của mình.

Thuật toán để tạo ra một đồng tiền ảo

Để tạo ra một đồng tiền ảo hoàn chỉnh, ta cần cho phép giao dịch bằng đồng tiền ảo đó. Ở ví dụ trước ta đã tạo ra một dạng DuLieu có thể chứa giao dịch. Nhưng để chính thức hỗ trợ giao dịch, ta tạo một class mới dùng để chứa giao dịch như sau:

/*=== ĐÂY LÀ CLASS MÔ TẢ CẤU TRÚC CỦA MỘT GIAO DỊCH ===*/
class GiaoDich { //Các thông tin của một giao dịch vẫn cơ bản như cũ
    constructor(DiaChiGui, DiaChiNhan, GiaTri) {
        this.DiaChiGui = DiaChiGui;
        this.DiaChiNhan = DiaChiNhan;
        this.GiaTri = GiaTri;
    }
}

Lúc này trong phần định nghĩa của Blockchain, ta cần tạo thêm 2 biến mới.

/*Phần này mới được thêm vào*/
this.GiaoDichTamHoan = []; //Là mảng các giao dịch mới thêm vào mảng Blockchain và chưa được Hash xong.
this.TienThuong = 100; //Là phần thưởng dành cho các miner (người đào hash) cho việc thêm mới thành công mảng GiaoDichTamHoan vào Blockchain.

Thứ nhất là mảng GiaoDichTamHoan. Mảng này sẽ chứa toàn bộ các giao dịch mà chưa có mã Hash, đang đợi máy đào để được thêm vào Blockchain. Điều này sẽ cho phép nhiều giao dịch được thêm đồng thời vào Blockchain và cùng nằm trên một Block. Người giao dịch và người đào Block cũng độc lập với nhau.

Thứ hai là biến TienThuong để lưu giá trị mặc định của khoản tiền thưởng cho Người đào coin. Lượng tiền thưởng này như đã nói ở phần trước, sẽ bị giới hạn, bởi vì đến một lúc nào đó không thể tạo thêm Hash => không ai có thêm tiền thưởng nữa. Và như vậy nghĩa là đồng MyCoin của chúng ta có tính chất khan hiếm, y như vàng bạc vậy.

Trong số các hàm của Blockchain, ta thay hàm DaoBlock() bằng hàm DaoTienAo(). Bởi vì một Block lúc này không thể dễ dàng thêm vào Blockchain được nữa, mà phải có ai đó đào Hash cho Block đó để nó đc thêm vào chuỗi.

Định nghĩa hàm đào tiền ảo như sau:

DaoTienAo(DiaChiViNhanTienThuong) { //Hàm dùng để đào (thêm mới) một Block vào Blockchain.
    //Lúc này ta sẽ tạo mới một Block, trong Block này sẽ chứa toàn bộ các giao dịch đã bị tạm hoãn trước đó, do nó chưa được đào và chưa có Hash.
    let block = new Block(new Date(), this.GiaoDichTamHoan, this.PhanTuCuoiCung().Hash);

    block.DaoBlock(this.DoKho); //Vẫn phải đào Hash bình thường cho lần này.
    this.MangBlock.push(block); //Nối phần tử block vào làm phần tử cuối cùng của mảng Blockchain sau khi đã "đào" được.

    //Sau khi đã bỏ công ra đào 1 Hash cho giao dịch hiện tại, ta sẽ có quyền được thưởng một phần tiền thưởng cố định sẵn. GiaoDichTamHoan đã được xử lý xong nên có thể xóa nó đi, sau đó ta gán một GiaoDichTamHoan mới, trong đó chuyển lượng tiền ta nhận được vào ví của chính mình.
    this.GiaoDichTamHoan = [
        new GiaoDich(null, DiaChiViNhanTienThuong, this.TienThuong)
    ];
    //Chú ý là chỗ này ta không thể nhận được ngay lượng tiền này trong ví, vì giao dịch chưa được tạo và chưa có Hash. Nên trong Blockchain chưa có bản ghi mới ghi nhận số tiền đã chuyển vào ví nhận tiền thưởng.
    //Để nhận được khoản tiền thưởng cho lần đào này. Thì ta phải đợi đến lần đào kế tiếp, giao dịch tạm hoãn này sẽ được khớp lệnh và lúc đó tiền thưởng mới có trong ví.
}

Hàm đào tiền ảo như trong code đã comment, sẽ giúp cho người đào nhét được các giao dịch đang hoãn vào chuỗi. và để lần đào tiếp theo sẽ lấy được giá trị tiền thưởng.

Tại sao lại cần phải lần đào thứ 2 mới lấy được tiền thưởng của lần đào thứ 1. Như thế này thì ăn chặn của người ta à?

Mục đích của việc này có 2 tác dụng:

  1. Để tránh việc người đào “ăn non”. Lấy tiền thưởng của Block này đập vào Block kia.
  2. Đó là để khuyến khích đào đào và đào. Người mới tham gia đào, sẽ luôn có một giao dịch chờ sẵn để người đó đào lấy tiền xài.

Trong thực tế thì đối với BitCoin, một giao dịch trong Blockchain chỉ được xác nhận khi mà phía sau Block chứa nó đã có thêm 6 Block khác được thêm vào. Lúc này thì ví tiền của bạn mới được cộng hoặc trừ tiền. Và chỉ khi đó thì bạn mới tiếp tục giao dịch tiếp được.

Khoảng thời gian bạn chờ cho có thêm 6 Block khác được insert vào thường được gọi là thời gian “tiền bị đóng băng” trong hệ thống. Tuy nhiên việc này thường chỉ diễn ra trong vài phút.

6 Block giao dịch xong mới được chứng nhận trong ví có tiền thường được gọi là cơ chế đồng thuận trong hệ thống. Khi mà có nhiều người cùng đào chuỗi Blockchain chứa Block có tiền của bạn. Họ sẽ gián tiếp xác nhận là giao dịch của bạn đáng tin

Việc ngăn không cho người đào lấy ngay được tiền thưởng đó là tùy vào từng đồng coin họ có áp dụng hay không. Đối với BitCoin thì là có. Ta hoàn toàn có thể tùy biến thuật toán chỗ này để áp dụng cho đồng MyCoin của ta.

Chú ý nữa đó là mảng GiaoDichTamHoan sau mỗi một lần đào Hash xong, sẽ nhét toàn bộ mảng này vào chung một Block. Như vậy là có thể có Block chứa tới 100 giao dịch. Ở đây hoàn toàn là do code của ta cho phép việc này. Đối với BitCoin hoặc Etherium, họ chỉ cho phép 2 giao dịch trong cùng một Block thôi. Do đó đào xong Hash, ta phải nhặt 2 GiaoDich trong mảng GiaoDichTamHoan để đưa vào Block mới tạo. Máy đào tiền ảo thực tế thì nó sẽ chọn random 2 GiaoDich bất kỳ (tất nhiên là ưu tiên cái giao dịch nhét tiền vào ví của chính mình trong mảng GiaoDichTamHoan rồi).

Rồi sau khi có thuật toán DaoTienAo. Ta cần một hàm nữa là hàm khởi tạo GiaoDich và nhét vào GiaoDichTamHoan

/* - Đây là hàm sẽ tạo ra một giao dịch mới. Đưa giao dịch vào mảng GiaoDichTamHoan. Như vậy là một Block sẽ có thể chứa nhiều giao dịch mà đang đợi Hash để được công nhận chính thức và thêm được vào Blockchain - */
TaoGiaoDich(GiaoDichMoi) {
    this.GiaoDichTamHoan.push(GiaoDichMoi);
}

Chúng ta cần một hàm nữa đó là hàm tính toán ra số tiền trong ví của mỗi người sau khi trao đổi mua bán bằng tiền ảo của chúng ta.

//Chúng ta cũng cần một hàm để kiểm tra được lượng tiền đang có trong một địa chỉ ví nào đó. 
//Mỗi một ví tiền không hề có một con số tổng tiền được lưu trữ lại. Mà việc tính toán số tiền của một địa chỉ ví trong toàn bộ Blockchain ta phải lần tìm lần lượt toàn bộ các giao dịch bên trong Blockchain để kiểm đếm số tiền của một ví. Điều này sẽ rất an toàn và trung thực.
//Một điều quan trọng là tính minh bạch ở đây vì bất kỳ ai khi có địa chỉ ví của bạn cũng sẽ nhìn thấy hết toàn bộ giao dịch bạn đã từng thực hiện trong hệ thống.
KiemTraTienTrongVi(DiaChiVi) {
    let TienTrongVi = 0;
    for (const block of this.MangBlock) {              //Đi duyệt qua toàn bộ các Block trong Blockchain
        for (const gd of block.DanhSachGiaoDich) {     //Đi duyệt qua toàn bộ các giao dịch trong Block (Vì một Block là 1 mảng các giao dịch)
            if (gd.DiaChiGui === DiaChiVi) {           //Nếu địa chỉ gửi là ví tiền này, thì tức là phải trừ ở Ví đi số tiền tương ứng trong giao dịch
                TienTrongVi -= gd.GiaTri;
            }

            if (gd.DiaChiNhan === DiaChiVi) {          //Nếu địa chỉ nhận là ví tiền này, thì tức là phải cộng vào Ví số tiền tương ứng trong giao dịch
                TienTrongVi += gd.GiaTri;
            }
        }
    }
    return TienTrongVi;                                //Kiểm đếm xong ta sẽ được con số tổng.
}

Như trong code cũng đã nói, mỗi một ví tiền không hề có một con số tổng tiền được lưu trữ lại ở đâu cả. Mà việc tính toán số tiền của một địa chỉ ví trong toàn bộ Blockchain ta phải lần tìm lần lượt toàn bộ các giao dịch bên trong Blockchain để kiểm đếm số tiền của một ví. Điều này sẽ rất an toàn và trung thực.

Điều quan trọng là tính minh bạch ở đây vì bất kỳ ai khi có địa chỉ ví của bạn cũng sẽ nhìn thấy hết toàn bộ giao dịch bạn đã từng thực hiện trong hệ thống.

Bây giờ thì đã có thể chạy thử rồi.

Các bạn có thể xem DEMO tại link này: LINK_DEMO

Download file example3.html tại đây: LINK_DOWNLOAD

Thực tế có như DEMO?

Chúng ta hãy đi xem một trang web thực tế, nơi mà họ thực sự tạo ra một đồng tiền ảo có thể đào được ngay bằng trình duyệt. Bạn có thể đào tiền ảo, trao đổi và giao dịch với mọi người trong mạng trên toàn thế giới. Đồng tiền mà tôi đang nói tới, đó chính là NIMIQ.

Hãy vào thử trang web này: https://nimiq.com/miner/ Kích vào Connect to Network. Ta sẽ thấy như sau: 

Hãy xem kỹ hơn các thông tin mà máy bạn đang đào.

Chúng ta thấy là quá trình đào được diễn ra một cách tự động, vậy là bạn đã biến laptop của mình thành một con Trâu cày tiền ảo rồi đấy.

Xem lại lịch sử một chút:

  • Vào năm 2009 BitCoin ra đời. Số tiền thưởng của đồng tiền ảo BitCoin là 50 BTC nếu Hash được 1 Block. Đến năm 2012 thì bị giảm 1 nửa còn 25 BTC nếu Hash thành công 1 Block. Và đến năm 2017 thì bị giảm tiếp 1 nửa còn 12.5 BTC/Block. Người ta tính ra là cứ 210.000 Block đào được thì tiền thưởng bị giảm một nửa. Giảm 64 lần là số tiền thưởng sẽ về 0. Và với tốc độ tính toán hiện tại thì khoảng năm 2140 là không còn tiền thưởng để đào nữa. Và hiện nay cả thế giới đang hóng một sự kiện, đó là ngày 31 tháng 5 năm 2020 thì tiền thưởng sẽ bị giảm tiếp một nửa chỉ còn 6.5 BTC/Block mà thôi. Chúng ta có thể xem đếm ngược ở đây cho vui: http://www.bitcoinblockhalf.com. Để xem tỉ giá đào BTC hãy vào đây: https://bitinfocharts.com/bitcoin/
  • Đồng tiền Ethereum thì không có cơ chế thưởng tiền sau khi đào xong 1 Block. Thay vào đó, mỗi một giao dịch sẽ có một khoản phí nhất định. Và tiền phí này được trả cho máy đào. Hiện tại tính ra thì 1 Block đào được sẽ có giá 3 ETH. Trung bình thì cứ 14.6 giây là đào được 1 Block ETH. Xem thêm tại https://bitinfocharts.com/ethereum/

Kết luận

Như vậy là kết thúc bài 3 trong loạt bài về Blockchain và Tiền ảo. Tôi đã lấy ra các thuật toán “đơn giản” nhất để minh họa và giúp bạn dễ hiểu hơn về cách hoạt động của 2 công nghệ đang làm mưa làm gió.

Đây chỉ là những gì sơ khai nhất về ứng dụng Blockchain vào xây dựng thử một loại Tiền ảo. Để có thể hình thành nên cả một đế chế tiền ảo riêng, có những đặc tính riêng biệt nhau. Thì rõ ràng thuật toán của họ phải rất kinh khủng

Vì Blockchain và Tiền ảo có rất nhiều cái hay, cách thực hiện nó cũng dễ. Nên hiện nay có thể thấy các đồng Coin mới ra đời cứ như mưa. Mỗi quốc gia hoàn toàn có thể tự tạo đồng Coin cho riêng mình.

Hạn chế trước mắt của Blockchain và tiền ảo là gì? Đó là mỗi Blockchain và mỗi đồng tiền ảo với thuật toán khác nhau thì hoàn toàn khác nhau và không thể trao đổi tay đôi được. Bạn không thể nào đặt lệnh giao dịch địa chỉ ví chứa BitCoin và lấy đồng Etherium nhét vào được. Vì đơn giản là 2 Blockchain này là hai array chứa thông tin khác hẳn nhau. Bạn bỏ tiền ra mua BitCoin thì không thể trao đổi ngang hàng với Etherium được mà phải dùng trung gian là đổi BTC ra tiền USD chẳng hạn, rồi dùng tiền đó đi mua ETH.

Nhiều dân Trader (người mua đi bán lại) các đồng tiền ảo cũng thấy rằng, họ giao dịch giữa người A với người B nhưng vẫn bị mất một phần nhỏ chi phí giao dịch bị ghi là chi phí dành cho máy đào. Giờ thì bạn đã biết là tại sao rồi chứ nhỉ?

Blockchain và tiền ảo mới đang ở thủa sơ khai của nó. Còn rất nhiều thứ cần được nâng cấp và thuật toán cần được mở rộng. Do đó hãy cùng chờ đợi sự bùng nổ của 2 công nghệ này trong năm 2018 nhé bạn.

Bài này hi vọng nó đã giúp cho bạn có một cái nhìn tổng quan và hiểu biết nhất định để đọc các bài viết khác về Blockchain không bị bỡ ngỡ.

Các bạn hãy comment và share các link tham khảo mà bạn đang đọc về Blockchain và Bitcoin để cùng trao đổi nhé.

Phần 2: Tạo ra công nghệ đào tiền ảo

Phần 2: Tạo ra công nghệ đào tiền ảo

Sơ hở của Blockchain hiện tại

Tiếp nối phần một, ta đã tìm hiểu về công nghệ Blockchain, về tính phân tán và minh bạch của nó.

Ta cũng thấy là công nghệ vừa tạo ra có nhược điểm là rất dễ bị hack. Bởi vì ta có được giao dịch cuối cùng trong chuỗi, thì lần theo dấu vết lần lượt các Hash của từng phần tử, ta sẽ xâu chuỗi lại được toàn bộ mảng Blockchain. Việc chỉnh sửa bằng cách tính toán lại toàn bộ Hash cho khớp và đồng bộ lúc này chỉ cần vài động tác và data sẽ nghiễm nhiên là toàn vẹn ở tất cả các máy trong mạng ngang hàng.

Có bạn sẽ bảo là có thuật toán để check MangBlock ở máy mình và MangBlock được tải về từ mạng P2P để xem sự khác nhau trước khi đồng bộ. Đúng là có thuật toán đó. Nhưng thuật toán này lại ưu tiên mảng nào “dài hơn” lại là mảng được cân nhắc là mảng đúng. Do đó nó không đủ mạnh để giải quyết vấn nạn hack.

Có một cách hay hơn để ngăn chặn việc này. Đó là giới hạn thời gian Hash được một Blockchain. Ta phải tăng độ khó của thuật toán Hash lên để Hash được một chuỗi sẽ cần rất nhiều thời gian. Điều này cũng có nghĩa là phải sau một thời gian nhất định mới có thể thêm mới 1 Block vào hệ thống. Ví dụ đồng tiền BitCoin thì quy định, sau mỗi 10 phút mới cho phép một bản ghi mới được thêm vào.

Làm điều này để làm gì?

  1. Ngăn chặn hệ thống Blockchain bị SPAM, liên tục có người thêm mới giao dịch giả vào hệ thống. Dẫn đến Blockchain bị DDOS, và có thể sập. Dữ liệu thật thì bị lấy đi.
  2. Ngăn chặn việc làm giả hệ thống, vì thời gian hacker Hash được 100 bản ghi sẽ bằng 100×10 phút = 1000 phút. Do đó hắn sẽ không dễ dàng clone toàn bộ hệ thống và Hash ra mã mới.

Khi một người dùng muốn thêm mới một bản ghi vào hệ thống, người đó phải chứng tỏ mình thực sự muốn giao dịch. Và để chứng minh điều đó anh ta cần bỏ tài nguyên của máy ra để tính toán Hash, và sau một thời gian nhất định, anh ta sẽ đăng ký thành công bản ghi nối tiếp (chain) vào Blockchain. Quá trình này người ta gọi là Proof-Of-Work.

Proof of Work

Ta hãy thử minh họa bằng cách sửa đổi file Class Block 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.
        this.GiaTriTuTang = 0; //THÊM VÀO Giá trị tự tăng của Block 
    }
    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) + this.GiaTriTuTang)  //Chỗ này có thêm GiaTriTuTang
            .toString(); //chú ý: JSON.stringify(this.DuLieu) sẽ convert biến Object this.DuLieu thành chuỗi
    }

    //thay đổi hàm TaoBlock thành hàm DaoBlock
    DaoBlock(DoKho) {
        while (this.Hash.substring(0, DoKho) !== Array(DoKho + 1).join("0")) { //Kiểm tra xem giá trị Hash hiện tại đã đạt đủ số 0 ở đầu tiên như yêu vầu về độ khó đặt ra chưa. Lặp đi lặp lại hàm cho đến khi tìm được giá trị Hash đáp ứng yêu cầu.
            this.GiaTriTuTang++; //Tăng giá trị trong Block lên, để Hash mỗi lần sẽ nhận được một giá trị khác nhau. Nếu Hash không có 2 hoặc n số 0 ở đầu thì sẽ không đạt yêu cầu và phải tiếp tục Hash cái khác.
            this.Hash = this.TinhToanHash(); //Tính toán lại Hash của toàn bộ Block ứng với lần tăng này.
        }
        console.log("Đã đào xong Block: " + this.Hash); //Nếu đã tìm được Hash thì ta coi đấy là một lần "đào" (hashing) thành công.
    }
}

Trong class Block ta thêm vào một GiaTriTuTang, đây là một biến được dùng khi tính toán Hash.

Vì ta cần phải tăng độ khó mỗi khi Hash, hàm TinhToanHash vẫn không đổi, tuy nhiên ta tạo ra một thuật toán đơn giản, đó là không chấp nhận mã Hash tạo ra không đáp ứng yêu cầu. Yêu cầu của ta ở đây là mã Hash phải bắt đầu bằng 2 hoặc 3 hoặc 4 thậm chí 5 số “0” liên tiếp ở đầu.

Vì thuật toán SHA256 không bao giờ thay đổi đầu ra đối với 1 chuỗi đầu vào, bắt buộc phải thay đổi chuỗi đầu vào để tìm ra được Hash ở đầu ra thỏa mãn.

Do đó ta viết một hàm gọi là DaoBlock để lặp đi lặp lại quá trình “đào” cái mã Hash cho Block hiện tại. Và việc đào này có độ khó phụ thuộc vào biến DoKho. Nếu tăng số chữ số 0 liên tiếp lên thì cần lặp khá lâu mới tìm được chuỗi Hash ưng ý.

Ví dụ:

  • DoKho = 2 thì cần 0.001s là tìm đc Hash có 2 chữ số 0 liền nhau ở đầu.
  • DoKho = 3 thì cần 0.5s là tìm đc Hash có 3 chữ số 0 liền nhau ở đầu.
  • DoKho = 4 thì cần 3s là tìm đc Hash có 4 chữ số 0 liền nhau ở đầu.
  • DoKho = 5 thì cần 20s là tìm đc Hash có 5 chữ số 0 liền nhau ở đầu.

Đối với đồng ‘tiền ảo BitCoin, thì độ khó của thuật toán được điều chỉnh để làm sao với mỗi 10 phút sẽ có một mã Hash ra đời. Dĩ nhiên là thuật toán của BitCoin không cùi bắp như thuật toán ở đây. Nhưng các bạn đã hình dung ra nó rồi đấy.

Proof-Of-Work còn được viết tắt là PoW. Khái niệm PoW được áp dụng vào Blockchain tương tự như cơ chế chống SPAM và DDOS 1 trang web bằng ReCapcha, người dùng muốn chứng thực mình không phải robot tự động thì phải bỏ công ra ngồi gõ một chuỗi ký tự lạ.

Giờ ta sửa lại class Blockchain để đưa thuật toán “Đào’ Block vào:

/*=== ĐÂ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.
 
        this.DoKho = 5; //Thêm độ khó cho Blockchain;
    }

    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(); //Lúc này ta không tính toán Hash đơn thuần nữa mà phải "đào" thì mới có Hash cho Block mới.
        newBlock.DaoBlock(this.DoKho);
        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 sau khi đã "đào" được.
    }

    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.
    }
}

Ta cần tạo một biến this.DoKho trong Blockchain. Sau đó ta gọinewBlock.DaoBlock(this.DoKho); để mỗi khi tạo mới Block, ta phải đào mới có mã Hash cho nó.

Giờ thì test thôi nào. Hãy chạy thử LINK_DEMO dưới đây và nhớ bật F12 để xem console.log() ở tab Console ở màn hình Chrome Dev Tools.

Khi chạy ta thấy trình duyệt bị đơ một lúc, và một lúc sau mới hiện ra các giao dịch. Cửa sổ console sẽ cho thấy các mã Hash sau khi đào được.

Các bạn có thể xem DEMO tại link này: LINK_DEMO

Download file example2.html tại đây: LINK_DOWNLOAD

Có bạn đã hỏi tôi chỗ này:

Có vẻ như Blockchain và Tiền ảo (Cryptocurrency) thường đi cùng với nhau?

Đúng là như vậy. Blockchain không thể sống thiếu Cryptocurrency và Cryptocurrency cũng không thể sống mà không có Blockchain, như thể sinh ra đã là của nhau vậy. Blockchain nếu không có quá trình đào tiền ảo bằng các thuật toán Proof-Of-Work thì sẽ không có gì hấp dẫn người dùng, và quá ít người dùng trong hệ thống cùng đào sẽ dẫn đến 1 Hacker có máy tính đủ mạnh có thể đánh bại tất cả. Do đó một công ty nào đó muốn sử dụng Blockchain để làm cơ sở dữ liệu lưu trữ, họ phải liên tục tạo ra sự cạnh tranh và sự hấp dẫn cho những người tham gia xây dựng CSDL Blockchain đó.

Tuy nhiên nhiều đồng tiền ảo hiện nay đã có sự lo ngại là đến một giai đoạn thoái trào, phong trào đào tiền ảo sẽ nguội bớt, và người ta không cắm máy để đào nữa vì phần thưởng ít dần. Lúc này Proof-Of-Work không còn là liều thuốc mạnh. Người ta đang thay thế bằng một thứ mới, đó là Proof-Of-Stake.

Proof-Of-Stake

Proof-Of-Stake (viết tắt là PoS) ra đời vì 2 lý do:

  1. Người dùng dần dần mất đi hứng thú đào tiền ảo vì nó dần đi đến giới hạn không thể đào tiếp nữa. Và vì quá nhiều Blockchain + Tiền ảo mới ra đời, người dùng sẽ đổ xô đi đào đồng tiền mới, bỏ rơi đồng tiền cũ.
  2. Phong trào đào tiền ảo ngày nay đã dẫn đến sự lãng phí điện năng và công suất máy tính vào việc duy nhất là chạy SHA265 lấy mã Hash. Điều này là hệ lụy không đáng có chỉ vì mục đích bảo vệ một chuỗi BlockChain. Giả sử hàng nghìn loại Blockchain mới ra đời thì phải bao nhiêu phần cứng và điện năng mới đủ để bảo vệ và tấn công nó.

PoW sinh ra là để ngăn chặn việc SPAM Blockchain, và cũng chống hack. Vậy thì cách làm của PoS như sau:

  1. Những người tham gia vào mạng lưới Blockchain không còn gọi là Thợ đào mỏ (Miners) nữa mà được gọi là Nhân viên kiểm soát (Validators)
  2. Nhân viên lúc này sẽ phải đánh cược, khi chèn một Block vào Blockchain, anh ta phải hi sinh một ít tiền ảo đang sở hữu ở ví của mình vào đó. Nhiều người cùng chèn Block. Và người nào chịu hi sinh nhiều nhất sẽ là người chiến thắng, chèn được Block thành công và nhận được tiền phí mà mỗi giao dịch đã bỏ ra trả cho người đào.

Điều này có nghĩa là người đào sẽ đánh cược để có được tiền ảo?

Như này thì người nào càng giàu thì sẽ càng giàu nhanh. Người mới tham gia hệ thống chưa có đồng nào trong tay thì làm sao mà kiếm được lợi nhuận đây?

Thực tế thì PoS đang trong quá trình chế tạo và còn nhiều ý tưởng của nó chưa được kiểm chứng hết. Đồng tiền Ethereum dự kiến đến 2019 sẽ đưa PoS vào hệ thống thay cho PoW. Chúng ta hãy chờ xem sao.

Kết luận

Như vậy ta đã áp dụng thành công thuật toán ĐÀO cho Blockchain của mình. Tuy nhiên đây không phải Đào BitCoin mà chỉ là Đào BLock.

Để có thể ứng dụng Blockchain này và tạo ra một đồng tiền ảo BitCoin của riêng mình, ta cần phải tạo ra được “Phần Thưởng” cho người đào Hash. Đó chính là tiền ảo, một dạng tiền thưởng cho người bỏ công ra đào Hash.

Vì mã Hash là giới hạn bởi độ dài số ký tự. Do đó đến một lúc nào đó sẽ không còn tìm được mã Hash nào thỏa mãn yêu cầu đặt ra nữa. Đó chính là điểm mấu chốt tạo ra giá trị của đồng tiền ảo. Người nào bỏ công ra tìm Hash, sẽ nhận được Tiền ảo. Và chúng ta cũng sẽ tạo ra một Ví tiền ảo để có thể gửi và nhận BitCoin sau khi đã đào xong.

Để tự mình tạo ra một đồng tiền ảo của riêng mình, sử dụng HTML và Javascript, mời các bạn đón đọc phần 3 của Series này nhé.


Ghi chú: Các thuật ngữ chuyên ngành tiếng Anh các bạn có thể biết để tham khảo và đọc tài liệu cho rõ hơn như sau:

  • DaoBlock trong blockchain thì hàm này thường có tên là Mining hoặc MineBlock
  • GiaTriTuTang trong blockchain thì biến này thường có tên là nonce
  • NgayGioTao trong blockchain thì biến này thường có tên là timestamp
  • KiemTraTinhToanVen trong blockchain thì hàm này thường có tên là Validatehoặc Accept

Phần 1: Tự tạo ra một công nghệ Blockchain của riêng mình

Phần 1: Tự tạo ra một công nghệ Blockchain của riêng mình

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:

  1. Tính toán toàn bộ Hash của Block hiện tại và lưu lại.
  2. 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:

  1. Dữ liệu nằm phân tán.
  2. 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.
  3. 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ở:

  1. 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.
  2. 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.