
Thảo luận về nguyên lý và chi tiết kỹ thuật của giao thức铭文 Ordinal
Tuyển chọn TechFlowTuyển chọn TechFlow

Thảo luận về nguyên lý và chi tiết kỹ thuật của giao thức铭文 Ordinal
Các satoshi trong UTXO được theo dõi như thế nào, nội dung khắc thực sự được đặt ở đâu trong script, và tại sao BRC20 lại cần hai thao tác khi chuyển nhượng?
Tác giả: @hicaptainz
Trong hai tuần gần đây khi tìm hiểu về hệ sinh thái BTC và các dự án inscriptions khác nhau, tôi nhận thấy rất ít bài viết có thể làm rõ nguyên lý và chi tiết kỹ thuật: ví dụ như giao dịch được khởi tạo ra sao khi đúc inscription, các satoshi (sats) bên trong UTXO được theo dõi thế nào, nội dung inscription thực sự nằm ở đâu trong script, và tại sao BRC20 cần tới hai thao tác khi chuyển khoản? Tôi nhận thấy rằng nếu không nắm rõ những chi tiết kỹ thuật này thì sẽ rất khó hiểu được sự khác biệt giữa các giao thức như BRC20, BRC420, atomicals, stamps hay runes. Bài viết này sẽ đi sâu vào kiến thức nền tảng của blockchain BTC để cố gắng trả lời các câu hỏi trên.
Cấu trúc khối của BTC
Blockchain về bản chất là một công nghệ kế toán đa người dùng, nói theo thuật ngữ khoa học máy tính thì đó là một cơ sở dữ liệu phân tán. Các ghi chép (sổ sách) trong một khoảng thời gian nhất định sẽ tạo thành một khối (block), sau đó sổ cái được mở rộng theo thứ tự thời gian.

Chúng tôi dùng bảng tính Excel để minh họa cách hoạt động của blockchain. Một file Excel đại diện cho một blockchain, mỗi sheet riêng lẻ biểu thị từng khối, các khối được sắp xếp theo thứ tự thời gian từ 560331, 560332 đến khối mới nhất là 560336. Khối 560336 sẽ đóng gói các giao dịch gần đây nhất. Phần chính bên trong khối là phương pháp kế toán kép mà chúng ta thường thấy trong lĩnh vực kế toán: một bên địa chỉ ghi là nợ (debit) tức là "inputs from", bên kia ghi là có (credit) tức là "outputs to". Value tương ứng với số lượng BTC tại địa chỉ tương ứng. Số lượng BTC ở Inputs luôn lớn hơn Outputs, phần chênh lệch chính là phí giao dịch ở cấp người dùng, cũng là phí thưởng cho thợ đào (người ghi sổ). Đầu khối chứa thông tin về chiều cao khối trước đó, giá trị băm (hash) của khối trước, thời gian tạo khối (timestamp) và số ngẫu nhiên (nonce). Với tư cách là một công nghệ ghi sổ phi tập trung, ai sẽ giành được quyền ghi sổ khối tiếp theo? Câu trả lời nằm ở nonce và giá trị hash tương ứng. Các thợ đào sở hữu sức mạnh tính toán sẽ thực hiện băm giá trị nonce của khối hiện tại, thợ đào nào tìm ra giá trị hash thỏa mãn điều kiện trước tiên sẽ giành được quyền ghi sổ khối tiếp theo và nhận phần thưởng khối cùng phí giao dịch. Cuối cùng là khu vực script, có thể dùng để phát triển các ứng dụng mở rộng, ví dụ như script op_return có thể dùng như mục ghi chú. Cần lưu ý rằng trong khối thực tế, vùng script được gắn vào thông tin input và output chứ không phải là một vùng riêng biệt hoàn toàn. Ví dụ script gắn vào input gọi là script giải khóa (ScriptSig), cần chữ ký riêng tư từ ví để cho phép chuyển tiền ra; còn script gắn vào output gọi là script khóa (ScriptPubKey), dùng để thiết lập điều kiện mở khóa BTC nhận được (thông thường điều kiện là "chỉ người sở hữu khóa riêng mới được tiêu dùng").


Hai hình ảnh trên là bảng cấu trúc dữ liệu gốc của input và output. Về mặt thực thi, script xuất hiện dưới dạng tham số kèm theo thông tin giao dịch, trong đó script giải khóa (ScriptSig) do yêu cầu chữ ký riêng tư nên còn được gọi là "dữ liệu chứng cứ" (witness data).
Witness隔離 và Taproot
Mặc dù mạng Bitcoin đã vận hành hơn 10 năm mà không xảy ra sự cố đáng kể nào, nhưng nhiều lần giá phí giao dịch tăng vọt đến mức không còn khả thi. Do đó, các nhà phát triển Bitcoin luôn tranh luận về cách tốt nhất để mở rộng mạng lưới nhằm xử lý khối lượng giao dịch ngày càng tăng trong tương lai.
Năm 2017, cuộc tranh luận này lên đến đỉnh điểm, cộng đồng phát triển Bitcoin bị chia rẽ thành hai phe: một phe ủng hộ việc sử dụng soft fork để triển khai chức năng SegWit, phe còn lại ủng hộ việc mở rộng trực tiếp kích thước khối ("khối lớn").
Như đã đề cập ở trên, script giải khóa cần dùng khóa riêng để tạo ra "dữ liệu chứng cứ", vậy liệu có thể tách dữ liệu chứng cứ này ra khỏi khối để gián tiếp tăng số lượng giao dịch mỗi khối không? Witness隔離 (Segregated Witness) chính thức được kích hoạt vào tháng 8 năm 2017. Cách thực hiện của nó là chia dữ liệu giao dịch thành hai phần: một phần là thông tin cơ bản của giao dịch (Transaction Data), phần còn lại là thông tin chữ ký (Witness Data), đồng thời lưu trữ thông tin chữ ký vào một cấu trúc dữ liệu mới được gọi là "witness" (chứng cứ), đặt trong một khối mới riêng biệt và truyền tải độc lập với giao dịch gốc.

Về mặt kỹ thuật, việc triển khai SegWit có nghĩa là giao dịch không còn cần bao gồm dữ liệu chứng cứ (do đó không chiếm dụng không gian 1MB vốn dành cho khối Bitcoin). Thay vào đó, một không gian bổ sung riêng biệt được tạo ra ở cuối mỗi khối để chứa dữ liệu chứng cứ. Không gian này hỗ trợ truyền tải dữ liệu tùy ý và có hệ số giảm giá "trọng lượng khối (block weight)", khéo léo giữ lượng dữ liệu lớn trong giới hạn kích thước khối của Bitcoin nhằm tránh nhu cầu hard fork. Như vậy, giới hạn kích thước dữ liệu giao dịch Bitcoin được nâng cao, đồng thời giảm phí giao dịch cho dữ liệu chữ ký. Trước khi nâng cấp SegWit, giới hạn dung lượng Bitcoin là 1MB, còn sau SegWit, mặc dù giới hạn dung lượng giao dịch thuần túy vẫn là 1MB, nhưng không gian witness đạt tới 4MB.
Taproot được triển khai vào tháng 11 năm 2021, bao gồm 3 đề xuất cải tiến Bitcoin (BIP) khác nhau: Taproot, Tapscript và sơ đồ chữ ký số mới mang tên "Schnorr Signature". Taproot nhằm mang lại nhiều lợi ích cho người dùng Bitcoin như tăng tính riêng tư và giảm phí giao dịch. Đồng thời cho phép Bitcoin thực hiện các giao dịch phức tạp hơn, mở rộng phạm vi ứng dụng (bổ sung thêm một số opcode).
Các nâng cấp này là yếu tố then chốt thúc đẩy NFT Ordinals, nơi dữ liệu NFT được lưu trữ trong script đường dẫn Taproot (script đã chi tiêu) – tức là không gian dữ liệu chứng cứ. Đợt nâng cấp này khiến việc cấu trúc hóa và lưu trữ dữ liệu chứng cứ tùy ý trở nên dễ dàng hơn, đặt nền móng cho chuẩn "ord". Khi yêu cầu dữ liệu được nới lỏng, giả sử một giao dịch có thể dùng dữ liệu giao dịch và chứng cứ để lấp đầy toàn bộ khối — đạt đến giới hạn kích thước khối 4MB (không gian dữ liệu chứng cứ) — điều này mở rộng đáng kể loại phương tiện có thể đặt trên chuỗi.
Có người có thể hỏi, vì đã đặt một vài chuỗi ký tự vào script rồi, vậy có giới hạn gì đối với những chuỗi ký tự này không? Nếu chẳng may thực thi những script này thì sao? Nếu đặt nội dung tùy tiện, liệu có xuất hiện mã lỗi khiến khối bị từ chối không? Đây chính là lúc cần nhắc đến lệnh OP_FALSE. OP_FALSE (trong script Bitcoin cũng được biểu thị là "0") đảm bảo rằng đường dẫn thực thi trong ngôn ngữ script sẽ không bao giờ đi vào nhánh OP_IF và giữ trạng thái chưa thực thi. Nó hoạt động như một placeholder hoặc thao tác rỗng (No Operation) trong script, tương tự như "comment" trong ngôn ngữ lập trình bậc cao, nhằm đảm bảo đoạn mã phía sau không bị thực thi.

Mô hình chuyển khoản UTXO
Tất cả những phần trên đều nghiên cứu nguyên lý cơ bản của BTC từ góc độ cấu trúc dữ liệu máy tính. Bây giờ chúng ta hãy thảo luận về mô hình UTXO từ góc độ mô hình tài chính.
UTXO là viết tắt của Unspent Transaction Outputs, dịch sang tiếng Việt là "đầu ra giao dịch chưa tiêu dùng", thực tế có thể hiểu là số tiền còn dư sau khi chuyển khoản trong một lần giao dịch. Vậy tại sao Bitcoin lại sử dụng khái niệm này? Điều này liên quan đến hai phương pháp kế toán: mô hình giao dịch tài khoản và mô hình số dư tài khoản.
Vì chúng ta sống quá lâu trong hệ thống tập trung nên đã quen với cách ghi sổ theo mô hình số dư tài khoản. Khi người dùng A chuyển 100 nhân dân tệ cho người dùng B, ngân hàng sẽ kiểm tra xem tài khoản của A có đủ 100 tệ hay không, nếu có thì trừ 100 tệ khỏi tài khoản A và cộng 100 tệ vào tài khoản B, như vậy giao dịch được hoàn tất.
Tuy nhiên, thuật toán kế toán của Bitcoin không có khái niệm số dư. Trên sổ cái phân tán blockchain chỉ ghi lại từng giao dịch cụ thể, chứ không ghi trực tiếp số dư hiện tại của một tài khoản (ghi số dư thường cần nút máy chủ chuyên biệt để theo dõi, như vậy sẽ gây tập trung hóa). Giả sử người dùng A hiện có số dư 1000 tệ, nếu A chuyển 100 tệ cho B, giao dịch này sẽ được ghi lại như sau:
Giao dịch 1: Người dùng A chuyển 100 tệ cho người dùng B
Giao dịch 2: Người dùng A chuyển 900 tệ cho chính mình (UTXO)

Giao dịch 2 ở đây tuy là một giao dịch nhưng về chức năng thì đóng vai trò như số dư tài khoản, thể hiện rằng sau khi hoàn tất giao dịch chuyển 100 tệ, tài khoản A còn lại 900 tệ.
Vậy vấn đề đặt ra là, tại sao phải tạo ra UTXO kiểu này? Vì trên blockchain BTC chỉ có thể ghi lại giao dịch chứ không thể ghi lại số dư tài khoản. Nếu không có UTXO này, việc tính toán số dư sẽ cần cộng dồn tất cả các giao dịch vào và ra của một tài khoản, điều này cực kỳ tốn thời gian và tài nguyên tính toán. Sự xuất hiện của UTXO khéo léo tránh được vấn đề đau đầu này khi tính toán số dư.
UTXO có đặc điểm giống như tiền xu, không thể chia nhỏ để dùng. Trong quá trình giao dịch, làm sao để gom đủ số tiền đầu vào và cách trả lại tiền thừa như thế nào? Chúng ta có thể dùng tiền xu làm ví dụ (thực tế mỗi khi bạn nhìn thấy từ UTXO hãy tự động dịch thành "tiền xu" thì sẽ dễ hiểu hơn).
Tiểu Minh chuyển 1 BTC cho Tiểu Cương. Toàn bộ quá trình như sau: Tiểu Minh cần thu thập đủ đầu vào, ví dụ trong các giao dịch trước đó tại địa chỉ của mình, anh tìm thấy một UTXO trị giá 0,9, chưa đủ 1 BTC. May mắn là giao dịch cho phép nhiều đầu vào, nên Tiểu Minh lại tìm thêm một UTXO trị giá 0,2. Như vậy trong giao dịch chuyển tiền lần này sẽ có hai đầu vào. Đồng thời cũng có hai đầu ra: một hướng đến địa chỉ của Tiểu Cương trị giá 1 BTC, một hướng về địa chỉ của chính Tiểu Minh trị giá 0,1 BTC, đây chính là tiền thừa (ví dụ này bỏ qua phí gas).
Nói cách khác, trong túi Tiểu Minh có hai đồng xu, một đồng trị giá 0,9, một đồng trị giá 0,2. Khi cần thanh toán đồng xu trị giá 1, anh phải đưa cả hai đồng xu này cho Tiểu Cương, sau khi nhận được tiền, Tiểu Cương trả lại 0,1 cho Tiểu Minh. Bản chất của mô hình kế toán này chính là thông qua hành động "trả lại tiền thừa" để tránh việc "tính toán số dư".
Hệ thống sắp xếp của giao thức Ordinal
Giao thức Ordinal có thể nói là nguồn cơn của đợt bùng nổ hệ sinh thái BTC hiện nay, phân tách BTC đồng nhất thành đơn vị nhỏ nhất là sat, sau đó đánh số thứ tự cho từng sat. Làm như thế nào?
Chúng ta biết rằng tổng cung BTC là 21 triệu, mỗi BTC có thể chia nhỏ đến 100 triệu phần (sat), do đó đơn vị nhỏ nhất của BTC là sat. Dù là BTC hay sat thì đều là token không thể thay thế điển hình (FT). Bây giờ chúng ta thử phân phối một số thứ tự (ordinal) cho các sat này.
Khi bàn về cấu trúc dữ liệu khối ở phần trước, chúng ta đã đề cập rằng thông tin giao dịch cần ghi rõ địa chỉ và số lượng input, cũng như địa chỉ và số lượng output. Mỗi khối bao gồm hai loại giao dịch: phần thưởng khai thác khối và phí chuyển khoản. Giao dịch phí chắc chắn có input và output, nhưng giao dịch thưởng khai thác do BTC được tạo ra từ hư không nên không có địa chỉ input, do đó trường "input from" là trống, còn được gọi là "giao dịch coinbase". Tổng cộng 21 triệu BTC của BTC đều đến từ giao dịch coinbase này, và luôn là giao dịch đầu tiên trong danh sách giao dịch của mọi khối.
Giao thức Ordinal quy định như sau:
-
Đánh số: Mỗi sat được đánh số theo thứ tự được khai thác
-
Chuyển giao: Theo nguyên tắc FIFO (vào trước ra trước), chuyển từ input sang output
Quy tắc đầu tiên khá đơn giản, nó quyết định rằng việc đánh số chỉ có thể được tạo ra từ giao dịch coinbase trong phần thưởng khai thác. Ví dụ, nếu phần thưởng khối đầu tiên là 50 BTC, thì khối đầu tiên sẽ phân phối sats trong phạm vi [0;1;2;...;4.999.999.999]; khi khối thứ hai cũng có phần thưởng 50 BTC, khối thứ hai sẽ phân phối sats trong phạm vi [5.000.000.000;5.000.000.001;...;9.999.999.999].

Phần khó hiểu hơn nằm ở chỗ, vì UTXO thực tế chứa rất nhiều sat, mỗi sat trong UTXO này trông đều giống nhau, vậy làm sao để sắp xếp thứ tự cho chúng? Đây chính là điều do quy tắc thứ hai quyết định, hãy lấy một ví dụ đơn giản:
Tôi tạm giả sử đơn vị chia nhỏ nhất của BTC là 1, tổng cộng đã xuất hiện 10 khối, phần thưởng mỗi khối là 10 BTC, tức tổng cung là 100 BTC. Chúng ta có thể trực tiếp gán số thứ tự (0-99) cho 100 BTC này. Nếu không có bất kỳ giao dịch nào, chúng ta chỉ biết 10 BTC của khối đầu tiên có số thứ tự (0-9), 10 BTC của khối thứ hai có số thứ tự (10-19), cho đến 10 BTC của khối thứ mười có số thứ tự (90-99). Trong trường hợp này do không có chi tiêu nào nên cũng không có output nào, chúng ta chỉ có thể gán một phạm vi số thứ tự cho mỗi 10 BTC.
Giả sử trong khối thứ hai thêm hai khoản chi (output), một là 3 BTC, một là 7 BTC "tiền thừa", tương ứng với việc chuyển 3 BTC cho người khác và tự trả lại 7 BTC. Lúc này trong danh sách giao dịch của khối, giả sử 7 BTC trả lại cho mình đứng đầu tiên (số thứ tự tương ứng là 10-16), 3 BTC chuyển cho người khác đứng thứ hai (số thứ tự tương ứng là 17-19). Như vậy thông qua việc chuyển output mà xác nhận được tập hợp thứ tự sats chứa trong một UTXO cụ thể.
Lưu ý là mỗi sat chứ không phải UTXO! Vì UTXO là đơn vị giao dịch nhỏ nhất không thể chia nhỏ, do đó sat chỉ có thể tồn tại bên trong UTXO, và UTXO chứa một phạm vi nhất định các sat, chỉ có thể chia nhỏ việc đánh số sat trong các output mới sau khi tiêu dùng một UTXO.
Còn về cách biểu diễn "số thứ tự" này, Ordinal hỗ trợ nhiều hình thức như phương pháp số nguyên vừa đề cập, còn có phương pháp số thập phân, phương pháp độ, phương pháp tỷ lệ phần trăm, phương pháp đặt tên bằng chữ cái thuần túy.

Sau khi các sat có số thứ tự thống nhất, chúng ta có thể xem xét đến việc khắc ghi (inscription). Như đã đề cập ở trên, chúng ta có thể tải lên tệp tin bất kỳ loại dữ liệu nào vào vùng dữ liệu chứng cứ có dung lượng 4MB, dù là văn bản, hình ảnh hay video, sau khi tải lên, tệp tin sẽ tự động chuyển thành dạng hexa và được lưu trong vùng script Taproot. Như vậy, 1 UTXO tương ứng với 1 vùng script Taproot, và 1 UTXO này sẽ chứa nhiều sat (toàn bộ là một tập hợp chuỗi sats, để tránh tấn công bụi, giới hạn số lượng BTC trong một UTXO đơn lẻ không được ít hơn 546 sat). Để thuận tiện ghi chép, giao thức Ordinal quy định nhân tạo rằng "sử dụng số thứ tự của sat đầu tiên trong tập hợp này để biểu thị mối quan hệ ràng buộc" (lời nguyên bản trong sách trắng là "số thứ tự của sat đầu tiên trong output đầu tiên"), ví dụ như UTXO chứa sats (17-19) sẽ được thay thế trực tiếp bằng số 17 để liên kết với nội dung khắc ghi.
Việc đúc và chuyển nhượng tài sản Ordinal
Ordinal NFT rõ ràng là việc tải các loại tệp tin khác nhau lên script trong vùng chứng cứ và liên kết nó với một tập hợp chuỗi sats, từ đó thực hiện phát hành tài sản NFT trên chuỗi BTC. Tuy nhiên ở đây vẫn còn một vấn đề: script trong vùng chứng cứ bao gồm cả script giải khóa input và script khóa output, vậy nội dung được đặt ở script nào? Câu trả lời đúng là cả hai. Ở đây không thể không nhắc đến cơ chế commit-reveal (cam kết - tiết lộ) trong công nghệ blockchain.
Cơ chế Commit-Reveal trong blockchain là một giao thức nhằm đảm bảo xử lý thông tin một cách công bằng và minh bạch. Cơ chế này thường được dùng trong các tình huống cần gửi ẩn thông tin (như bỏ phiếu hay đấu thầu), sau đó tại một thời điểm nhất định trong tương lai sẽ tiết lộ thông tin này. Cơ chế Commit-Reveal gồm hai giai đoạn: giai đoạn cam kết (Commit) và giai đoạn tiết lộ (Reveal).
1. Giai đoạn cam kết (Commit): Trong giai đoạn này, người dùng gửi thông tin của họ (ví dụ lựa chọn bỏ phiếu hay giá đấu thầu), nhưng thông tin này được mã hóa. Thông thường, người dùng sẽ tạo giá trị băm (hash) của thông tin này (tức là bản tóm tắt mã hóa của thông tin), sau đó gửi giá trị băm này lên blockchain. Do đặc tính của hàm băm, chúng có thể tạo ra một đầu ra duy nhất (giá trị băm), đầu ra này không thể đảo ngược đối với thông tin gốc. Nghĩa là không thể suy ra thông tin gốc từ giá trị băm. Quá trình này đảm bảo tính bảo mật của thông tin khi gửi.
2. Giai đoạn tiết lộ (Reveal): Tại một thời điểm đã định sau này, người dùng phải tiết lộ thông tin gốc và chứng minh rằng nó khớp với giá trị băm đã gửi trước đó. Điều này thường được thực hiện bằng cách gửi thông tin gốc cùng với bất kỳ dữ liệu bổ sung nào dùng để tạo giá trị băm (như số ngẫu nhiên hay "muối"). Mạng sau đó xác minh xem giá trị băm của thông tin gốc có trùng khớp với giá trị băm đã gửi trước đó hay không. Nếu khớp, thông tin gốc được chấp nhận là hợp lệ.
Như đã nói trước đó, nội dung khắc ghi cần được liên kết với tập hợp chuỗi sats chứa trong UTXO, còn UTXO trong khối là một output, do đó phải gắn vào script khóa của output. Tuy nhiên các nút đầy đủ (full node) của BTC cần duy trì và truyền tải tập hợp UTXO của toàn mạng lưới tại chỗ. Hãy tưởng tượng nếu có 10.000 tệp video 4MB được tải trực tiếp lên script khóa của 10.000 UTXO, thì tất cả các nút đầy đủ sẽ cần không gian lưu trữ cực lớn và tốc độ mạng cực nhanh, có thể nói toàn bộ chuỗi sẽ sụp đổ ngay lập tức. Do đó, giải pháp duy nhất là đặt nội dung vào script giải khóa của input, sau đó để nội dung này "trỏ tới" một output khác.
Do đó, việc đúc tài sản Ordinal cần chia thành hai bước (ví tiền sẽ hợp nhất hai bước này, khi xây dựng giao dịch thì đồng thời tạo cặp giao dịch cha-con commit-reveal, trải nghiệm người dùng cảm giác như chỉ có một bước và tiết kiệm phí gas).
Trong giai đoạn đúc, người dùng trước tiên cần tải giá trị băm của một tệp tin lên script khóa của UTXO trong giao dịch cam kết (chuyển từ địa chỉ A của mình sang địa chỉ B của mình). Vì là giá trị băm nên không chiếm dụng nhiều không gian cơ sở dữ liệu UTXO của các nút đầy đủ. Tiếp theo, người dùng tạo một giao dịch mới (từ địa chỉ B của mình chuyển về địa chỉ A), gọi là giao dịch tiết lộ (reveal), lúc này input cần sử dụng UTXO chứa giá trị băm tệp tin từ bước cam kết trước đó, và script giải khóa của input này phải chứa tệp tin khắc ghi gốc. Như lời nguyên bản trong sách trắng: "Trước tiên, trong commit, tạo một đầu ra taproot cam kết đến script chứa nội dung khắc ghi. Thứ hai, trong giao dịch reveal, sử dụng đầu ra tạo ra từ giao dịch commit để hiển thị nội dung khắc ghi trên chuỗi."
Trong giai đoạn chuyển nhượng, Ordinal NFT và BRC20 hơi khác nhau. Ordinal NFT do là chuyển nhượng toàn bộ, chỉ cần chuyển trực tiếp NFT liên kết với một UTXO cụ thể cho người nhận, tương tự như giao dịch BTC thông thường. Nhưng BRC20 do liên quan đến việc chuyển khoản số lượng tùy chỉnh, cũng chia thành hai bước: bước đầu gọi là giao dịch "chuyển nhượng" (Inscribe "TRANSFER"), bước thứ hai gọi là giao dịch chuyển khoản "TRANSFER" (Transfer "TRANSFER"). Thực tế giao dịch khắc ghi bước đầu giống như quá trình đúc Ordinal NFT, ngầm chứa cặp giao dịch cha-con commit-reveal; còn giao dịch chuyển khoản bước thứ hai giống như việc chuyển nhượng Ordinal NFT thông thường, chuyển trực tiếp tài sản BRC20 liên kết với một UTXO cho người nhận. Một số ví tiền sẽ đồng thời xây dựng cả ba giao dịch (cha-con-cháu) để tiết kiệm thời gian và phí gas.

Tóm lại, giao dịch commit dùng để liên kết nội dung khắc ghi (giá trị băm của nội dung gốc) với sats có số thứ tự (UTXO), giao dịch reveal dùng để hiển thị nội dung (nội dung gốc). Cặp giao dịch cha-con này cùng nhau hoàn tất việc đúc NFT.
P2TR và một ví dụ
Cuộc thảo luận kỹ thuật về việc đúc ở trên vẫn chưa kết thúc, vì có người sẽ thắc mắc: giao dịch reveal thực sự xác minh thông tin khắc ghi trong giao dịch commit như thế nào? Tại sao khi xây dựng giao dịch cần chuyển tiền qua lại giữa hai địa chỉ AB của chính mình? Khi khắc ghi cũng không thấy cần chuẩn bị hai ví tiền. Ở đây cần nói đến một trong những nâng cấp lớn của Taproot là P2TR.
P2TR (Pay-to-Taproot) là một loại giao dịch Bitcoin mới được giới thiệu bởi nâng cấp Taproot. Giao dịch P2TR cho phép người dùng sử dụng một khóa công khai đơn lẻ hoặc script phức tạp hơn (như ví đa chữ ký hay hợp đồng thông minh) để tiêu dùng Bitcoin, từ đó đạt được mức độ riêng tư và linh hoạt cao hơn. Điều này được thực hiện thông qua việc sử dụng Merkleized Abstract Syntax Trees (MAST) và chữ ký Schnorr, những công nghệ này cho phép mã hóa hiệu quả nhiều điều kiện tiêu dùng trong một giao dịch đơn lẻ.
-
Tạo điều kiện tiêu dùng
Để tạo một giao dịch P2TR, người dùng trước tiên định nghĩa một điều kiện tiêu dùng, ví dụ như một khóa công khai đơn lẻ hoặc script phức tạp hơn, chỉ rõ các yêu cầu để tiêu dùng Bitcoin (ví dụ như ví đa chữ ký hay hợp đồng thông minh).
-
Tạo đầu ra Taproot
Sau đó, người dùng tạo một đầu ra Taproot, bao gồm một khóa công khai đơn lẻ (khóa công khai đại diện cho điều kiện tiêu dùng). Khóa công khai này được suy ra từ sự kết hợp giữa khóa công khai của người dùng và băm của script, thông qua một quá trình gọi là "tweaking". Điều này đảm bảo đầu ra trông giống như một khóa công khai tiêu chuẩn, khiến nó khó phân biệt với các giao dịch khác trên blockchain.
-
Tiêu dùng Bitcoin
Khi người dùng muốn tiêu dùng Bitcoin, họ có thể sử dụng khóa công khai đơn lẻ của mình (nếu điều kiện tiêu dùng được đáp ứng), hoặc tiết lộ script gốc và cung cấp chữ ký hoặc dữ liệu cần thiết để đáp ứng điều kiện tiêu dùng. Điều này được thực hiện thông qua việc sử dụng Tapscript, cho phép thực thi điều kiện tiêu dùng một cách hiệu quả và linh hoạt hơn.
-
Xác minh giao dịch
Các thợ đào và nút sau đó xác minh giao dịch bằng cách kiểm tra chữ ký Schnorr và dữ liệu được cung cấp so với điều kiện tiêu dùng. Nếu điều kiện được đáp ứng, giao dịch được coi là hợp lệ và Bitcoin có thể được tiêu dùng.
-
Tăng cường riêng tư và linh hoạt
Vì giao dịch P2TR chỉ tiết lộ điều kiện tiêu dùng cần thiết khi tiêu dùng Bitcoin, nên chúng duy trì mức độ riêng tư cao. Ngoài ra, việc sử dụng MAST và chữ ký Schnorr cho phép mã hóa hiệu quả nhiều điều kiện tiêu dùng, cho phép các giao dịch phức tạp và linh hoạt hơn mà không làm tăng kích thước tổng thể của giao dịch.
Trên đây là cách cơ chế commit-reveal được áp dụng trong P2TR, chúng ta sẽ minh họa bằng một ví dụ thực tế.
Sử dụng trình duyệt blockchain https://www.blockchain.com/ để nghiên cứu quá trình đúc một NFT hình ảnh Ordinal, bao gồm cả hai giai đoạn commit-reveal trước đó.
Đầu tiên, chúng ta thấy ID băm của giao dịch commit là (2ddf90ddf7c929c8038888fc2b7591fb999c3ba3c3c7b49d54d01f8db4af585c). Có thể thấy rằng đầu ra của giao dịch này không chứa dữ liệu khắc ghi (thực tế chứa giá trị băm của tệp hình ảnh dạng hexa), trang web cũng không hiển thị thông tin khắc ghi liên quan. Địa chỉ (bc1p4mtc.....) của đầu ra này thực chất là một địa chỉ tạm thời được tạo ra qua quá trình "tweaking" (đại diện cho khóa công khai của điều kiện giải khóa script), chia sẻ khóa riêng với địa chỉ chính Taproot (bc1pg2mp...). UTXO thứ hai trong giao dịch này thuộc về thao tác "trả lại tiền thừa". Như vậy đã thực hiện việc liên kết nội dung khắc ghi với sats chứa trong UTXO đầu tiên.

Tiếp theo, chúng ta xem bản ghi giao dịch reveal, ID băm của nó là (e7454db518ca3910d2f17f41c7b215d6cba00f29bd186ae77d4fcd7f0ba7c0e1). Tại đây, chúng ta có thể thấy thông tin Ordinals inscription. Địa chỉ input của giao dịch này chính là địa chỉ đầu ra tạm thời được tạo ra từ giao dịch trước (bc1p4mtc.....), script giải khóa của input chứa tệp hình ảnh dạng hexa gốc, còn đầu ra 0,00000546 BTC (546 sat) là việc gửi NFT này về địa chỉ chính Taproot của chính mình (bc1pg2mp...). Dựa trên nguyên tắc First in First Out và "liên kết với số thứ tự của sat đầu tiên trong output đầu tiên", mặc dù số lượng sats chứa trong hai UTXO trước và sau có thay đổi, nhưng số thứ tự sat được liên kết không đổi. Do đó, chúng ta có thể tìm thấy sat chứa khắc ghi này tại (sat 1893640468329373).
(https://ordinals.com/sat/1893640468329373)

Hai giao dịch này (thuộc cặp cha-con) khi đúc sẽ được ví tiền gửi đồng thời vào mempool, do đó chỉ cần trả một khoản phí gas, và có khả năng rất cao sẽ được các thợ đào ghi nhận và phát sóng vào cùng một khối (hai giao dịch trong ví dụ trên thực sự cùng tồn tại trong khối 790468). Các thợ đào và nút sau đó xác minh bằng cách kiểm tra chữ ký Schnorr trong input của giao dịch reveal và giá trị băm hình ảnh dạng hexa, so sánh với giá trị băm hình ảnh dạng hexa trong script khóa output của giao dịch commit. Nếu hai giá trị băm giống nhau, giao dịch được coi là hợp lệ, UTXO Bitcoin này có thể được tiêu dùng, như vậy hai giao dịch này sẽ được ghi vĩnh viễn trong cơ sở dữ liệu blockchain BTC, hình ảnh NFT cũng sẽ được lưu lại và hiển thị. Nếu hai giá trị băm khác nhau, hai giao dịch sẽ bị hủy, việc khắc ghi thất bại.
Giao thức BRC20 và Indexer
Đối với giao thức Ordinal, chúng ta khắc ghi một đoạn văn bản, nó sẽ là NFT văn bản (tương ứng với Loot trên Ethereum), khắc ghi một bức ảnh, nó sẽ là NFT hình ảnh (tương ứng với PFP trên Ethereum), khắc ghi một đoạn nhạc, nó sẽ là NFT âm thanh. Vậy nếu chúng ta khắc ghi một đoạn mã, và đoạn mã đó là mã "phát hành token FT đồng nhất" thì sao?
BRC20 chính là tận dụng giao thức Ordinal để thiết lập inscriptions (khắc ghi) dưới dạng dữ liệu JSON nhằm triển khai, đúc và chuyển nhượng Token. JSON chứa một số đoạn mã, mô tả các thuộc tính của Token như lượng cung, đơn vị đúc tối đa và mã duy nhất. Trong bài viết trước, chúng ta đã nói rằng bản chất của token BRC20 là token bán đồng nhất (SFT), nghĩa là trong một số trường hợp nó có thể được giao dịch như NFT, trong một số trường hợp khác có thể được giao dịch như FT. Làm thế nào để kiểm soát "các trường hợp khác nhau" này? Câu trả lời là indexer (bộ chỉ mục).
Indexer thực chất là một người ghi sổ, dùng để phân loại và ghi chép thông tin nhận được vào cơ sở dữ liệu. Trong giao thức Ordinal, indexer theo dõi input và output để xác định sự thay đổi của các sat đã được sắp xếp thứ tự tại các địa chỉ khác nhau. Trong giao thức BRC-20, indexer có thêm một chức năng: ghi lại sự thay đổi số dư token trong các khắc ghi tại các địa chỉ khác nhau.
Do đó, chúng ta có thể nhìn thấy các hình thức tồn tại khác nhau của token từ góc nhìn của người ghi sổ: token giao thức BRC20 thực chất tồn tại trong một cơ sở dữ liệu ba tầng. Tầng thứ nhất Layer1, người ghi sổ là thợ đào BTC, loại cơ sở dữ liệu là "cơ sở dữ liệu dạng chuỗi", BTC tạo ra là tài sản FT. Tầng thứ hai layer2, người ghi sổ là indexer Ordinal, loại cơ sở dữ liệu là "cơ sở dữ liệu quan hệ", các sat có số thứ tự tạo ra là tài sản NFT. Tầng thứ ba layer3, người ghi sổ là indexer BRC20, loại cơ sở dữ liệu là "cơ sở dữ liệu quan hệ", tài sản BRC20 tạo ra là tài sản FT. Khi chúng ta tính BRC20 theo "tờ", góc nhìn là indexer Ordinal (do indexer này ghi nhận), nó tự nhiên là NFT; khi chúng ta nghĩ về BRC20 theo "cái" đã được chia nhỏ (đặc biệt sau khi nạp vào sàn giao dịch tập trung), góc nhìn là indexer BRC20 (do indexer này ghi nhận hoặc do máy chủ sàn giao dịch tập trung ghi nhận), nó tự nhiên là FT. Từ đó chúng ta có thể rút ra kết luận rằng sự tồn tại của token bán đồng nhất SFT là do sự tồn tại của các người ghi sổ ở các cấp độ khác nhau.
Blockchain chẳng qua cũng chỉ là một cơ sở dữ liệu phân tán, do đó mới có nhóm người ghi sổ là thợ đào cùng nhau duy trì "cơ sở dữ liệu dạng chuỗi" này (bởi vì chỉ có cơ sở dữ liệu dạng chuỗi mới có thể thực sự phi tập trung). Nhưng cuối cùng, chúng ta vẫn quay lại con đường cũ của "cơ sở dữ liệu quan hệ" tập trung. Đây cũng là bản chất lý do tại sao gần đây người sáng lập giao thức Ordinal, người sáng lập giao thức BRC20, ví unisat tranh cãi nảy lửa về việc có nên nâng cấp indexer hay không -- vì các người ghi sổ không đồng thuận với nhau.
Tuy nhiên ngành công nghiệp đã phát triển hàng chục năm, cũng tích lũy không ít kinh nghiệm "phi tập trung", liệu indexer có thể dùng "cơ sở dữ liệu dạng chuỗi" thay thế cơ sở dữ liệu quan hệ không? Có thể sử dụng bằng chứng gian lận (fraud proof) hoặc ZKP để đảm bảo an toàn và tính phi tập trung không? Nhu cầu DA của hệ sinh thái Bitcoin có tràn ra các nền tảng DA khác không, từ đó thúc đẩy sự phát triển và hội tụ của hệ sinh thái đa chuỗi? Tôi dường như nhìn thấy nhiều khả năng hơn.
Chào mừng tham gia cộng đồng chính thức TechFlow
Nhóm Telegram:https://t.me/TechFlowDaily
Tài khoản Twitter chính thức:https://x.com/TechFlowPost
Tài khoản Twitter tiếng Anh:https://x.com/BlockFlow_News














