Giới thiệu
Bitcoin đôi khi được gọi là tiền có thể lập trình được. Do tính chất kỹ thuật số của nó, nó cho phép người dùng có mức độ linh hoạt cao khi đặt ra các điều kiện về cách chi tiêu tiền.
Chúng tôi nói về ví và tiền xu khi thảo luận về Bitcoin. Nhưng chúng ta cũng có thể coi ví là chìa khóa, tiền xu là séc và chuỗi khối là hàng két sắt bị khóa. Mỗi chiếc két sắt đều có một khe mỏng để bất kỳ ai cũng có thể gửi séc hoặc nhìn vào để xem két có giá trị bao nhiêu. Tuy nhiên, chỉ người giữ chìa khóa mới có thể vào bên trong.
Khi người giữ chìa khóa muốn đưa tiền cho người khác, họ sẽ mở hộp của họ. Họ tạo ra một tấm séc mới có tham chiếu đến tấm séc cũ hơn (sau đó sẽ bị hủy) và khóa nó vào một chiếc hộp mà người nhận có thể mở. Để chi tiêu số tiền đó, người nhận mới sẽ lặp lại quy trình.
Trong bài viết này, chúng ta sẽ xem xét kỹ hơn về Script, ngôn ngữ lập trình được giải thích bởi các nút trên mạng Bitcoin. Kịch bản là thứ chi phối cơ chế khóa/mở khóa được đề cập cho két sắt.
Bitcoin hoạt động như thế nào?
Sử dụng phép tương tự của chúng tôi ở trên, bạn có thể nói rằng mỗi giao dịch đều có hai phần – chìa khóa (để mở khóa hộp của bạn) và ổ khóa. Bạn sử dụng chìa khóa để mở hộp chứa séc bạn muốn gửi, sau đó thêm một séc mới vào hộp mới có khóa khác. Để chi tiêu từ hộp mới, bạn cần có một chìa khóa khác.
Đủ đơn giản. Bạn cũng có thể có một chút thay đổi về loại khóa trong hệ thống. Có thể một số két yêu cầu bạn cung cấp nhiều chìa khóa và có thể một số két khác cần bạn chứng minh rằng bạn biết một bí mật. Có rất nhiều điều kiện mà mọi người có thể đặt ra.
Chìa khóa của chúng tôi là cái mà chúng tôi gọi là scriptSig. Khóa là scriptPubKey của chúng tôi. Nếu xem xét các thành phần đó chi tiết hơn một chút, chúng ta sẽ thấy rằng chúng thực sự được tạo thành từ các bit dữ liệu và khối mã. Khi kết hợp lại, chúng tạo ra một chương trình nhỏ.
Khi bạn thực hiện một giao dịch, bạn sẽ phát sóng sự kết hợp đó lên mạng. Mỗi nút nhận được nó sẽ kiểm tra chương trình để biết liệu giao dịch có hợp lệ hay không. Nếu không, nó sẽ bị loại bỏ và bạn sẽ không thể tiêu số tiền bị khóa.
Séc (đồng xu) bạn nắm giữ được gọi là đầu ra giao dịch chưa chi tiêu (UTXO). Bất kỳ ai có thể cung cấp chìa khóa phù hợp với ổ khóa đều có thể sử dụng số tiền này. Cụ thể key là scriptSig và lock là scriptPubKey.
Nếu UTXO có trong ví của bạn, họ có thể sẽ có điều kiện chỉ người có thể chứng minh quyền sở hữu khóa chung này mới có thể mở khóa số tiền này. Để mở khóa, bạn cung cấp scriptSig bao gồm chữ ký số, sử dụng khóa riêng ánh xạ tới khóa chung được chỉ định trong scriptPubKey. Tất cả điều này sẽ trở nên rõ ràng hơn trong thời gian ngắn.
Hiểu về ngăn xếp Bitcoin
Script là thứ được gọi là ngôn ngữ dựa trên ngăn xếp. Tất cả điều này có nghĩa là khi chúng ta đọc một bộ hướng dẫn, chúng ta đặt chúng vào một cột có thể được coi là cột dọc. Ví dụ: danh sách A, B, C sẽ tạo ra một ngăn xếp có A ở dưới cùng và C ở trên cùng. Khi hướng dẫn yêu cầu chúng ta làm điều gì đó, chúng ta thao tác trên một hoặc nhiều phần tử bắt đầu từ đầu ngăn xếp.

Các phần tử A, B và C được thêm vào và “bật” ra khỏi ngăn xếp.
Chúng ta có thể phân biệt giữa dữ liệu (những thứ như chữ ký, hàm băm và khóa chung) và hướng dẫn (hoặc mã hoạt động). Các hướng dẫn xóa dữ liệu và làm điều gì đó với nó. Đây là một ví dụ rất đơn giản về giao diện của một tập lệnh:
<xyz> <md5 hasher> <d16fb36f0911f878998c136191af705e> <kiểm tra xem có bằng không>
Trong màu đỏ, chúng ta có dữ liệu và trong màu xanh lam, chúng ta có các opcode. Chúng ta đọc từ trái sang phải, vì vậy trước tiên chúng ta đặt chuỗi <xyz> vào ngăn xếp. Tiếp theo là mã băm <md5> opcode. Cái này không tồn tại trong Bitcoin, nhưng giả sử nó loại bỏ phần tử trên cùng của ngăn xếp (<xyz>) và băm nó bằng thuật toán MD5. Sau đó, đầu ra sẽ được thêm trở lại ngăn xếp. Đầu ra ở đây là d16fb36f0911f878998c136191af705e.
Thật là một sự trùng hợp ngẫu nhiên! Phần tử tiếp theo cần thêm là <d16fb36f0911f878998c136191af705e>, vì vậy bây giờ ngăn xếp của chúng tôi có hai phần tử giống hệt nhau. Cuối cùng, <check if bằng> bật hai phần tử lên trên cùng và kiểm tra xem chúng có bằng nhau không. Nếu đúng như vậy, nó sẽ thêm <1> vào ngăn xếp. Nếu không, nó sẽ thêm <0>.
Chúng ta đã đi đến cuối danh sách hướng dẫn. Tập lệnh của chúng tôi có thể đã thất bại theo hai cách – nếu phần tử còn lại bằng 0 hoặc nếu một trong các toán tử khiến tập lệnh bị lỗi khi một số điều kiện không được đáp ứng. Chúng tôi không có bất kỳ toán tử nào như vậy trong ví dụ này và chúng tôi kết thúc bằng một phần tử khác 0 (<1>), vì vậy tập lệnh của chúng tôi hợp lệ. Những quy tắc này cũng đúng với các giao dịch Bitcoin thực sự.
Đó chỉ là một chương trình bịa đặt. Bây giờ chúng ta hãy xem xét một số cái thực tế.
Trả tiền cho Pubkey (P2PK)
Trả tiền cho Pubkey (P2PK) cực kỳ đơn giản. Nó liên quan đến việc khóa tiền vào một khóa công khai cụ thể. Nếu bạn muốn nhận tiền theo cách này, bạn sẽ cung cấp cho người gửi khóa công khai của mình, thay vì địa chỉ Bitcoin.
Giao dịch đầu tiên giữa Satoshi Nakamoto và Hal Finney vào năm 2009 là giao dịch P2PK. Cấu trúc này được sử dụng nhiều trong những ngày đầu của Bitcoin, nhưng ngày nay, Pay-to-Pubkey-Hash (P2PKH) đã thay thế phần lớn cấu trúc này.
Tập lệnh khóa cho giao dịch P2PK tuân theo định dạng <public key> OP_CHECKSIG. Đủ đơn giản. Bạn có thể đoán rằng OP_CHECKSIG kiểm tra chữ ký đối với khóa chung được cung cấp. Như vậy, scriptSig của chúng ta sẽ là một <signature> đơn giản. Hãy nhớ rằng scriptSig là chìa khóa của ổ khóa.

Nó không đơn giản hơn thế này nhiều. Chữ ký được thêm vào ngăn xếp, theo sau là khóa chung. OP_CHECKSIG bật cả hai và xác minh chữ ký dựa trên khóa chung. Nếu chúng khớp nhau, nó sẽ thêm <1> vào ngăn xếp. Nếu không, nó sẽ thêm <0>.
Vì những lý do chúng tôi sẽ trình bày chi tiết trong phần tiếp theo, P2PK không thực sự được sử dụng nữa.
Trả tiền cho Pubkey-Hash (P2PKH)
Pay-to-Pubkey-Hash (P2PKH) hiện là loại giao dịch phổ biến nhất. Trừ khi bạn cố gắng tải xuống phần mềm cổ xưa, ví của bạn có thể sẽ thực hiện những điều này theo mặc định.
scriptPubKey trong P2PKH như sau:
OP_DUP OP_HASH160 <băm khóa công khai> OP_EQUALVERIFY OP_CHECKSIG
Trước khi chúng tôi giới thiệu scriptSig, hãy cùng phân tích xem các opcode mới sẽ làm gì:
OP_DUP
OP_DUP bật phần tử đầu tiên và sao chép nó. Sau đó, nó thêm cả hai trở lại ngăn xếp. Thông thường, điều này được thực hiện để chúng ta có thể thực hiện thao tác trên bản sao mà không ảnh hưởng đến bản gốc.
OP_HASH160
Điều này làm bật phần tử đầu tiên và băm nó hai lần. Vòng đầu tiên sẽ băm bằng thuật toán SHA-256. Đầu ra SHA-256 sau đó được băm bằng thuật toán RIPEMD-160. Kết quả đầu ra được thêm trở lại vào ngăn xếp.
OP_EQUALXÁC MINH
OP_EQUALVERIFY kết hợp hai toán tử khác – OP_EQUAL và OP_VERIFY. OP_EQUAL hiển thị hai phần tử và kiểm tra xem chúng có giống nhau không. Nếu đúng thì nó sẽ thêm số 1 vào ngăn xếp. Nếu không, nó sẽ thêm 0. OP_VERIFY hiển thị phần tử trên cùng và kiểm tra xem nó có đúng không (tức là khác 0). Nếu không, giao dịch không thành công. Kết hợp lại, OP_EQUALVERIFY khiến giao dịch không thành công nếu hai phần tử trên cùng không khớp.
Lần này, scriptSig trông như thế này:
<signature> <khóa công khai>
Bạn cần cung cấp chữ ký và khóa chung tương ứng để mở khóa đầu ra P2PKH.

Bạn có thể thấy những gì đang diễn ra trong ảnh GIF ở trên. Nó không quá khác biệt so với tập lệnh P2PK. Chúng tôi chỉ thêm một bước nữa để kiểm tra xem khóa chung có khớp với hàm băm trong tập lệnh hay không.
Tuy nhiên, có một điều cần lưu ý. Trong tập lệnh khóa P2PKH, khóa chung không hiển thị – chúng ta chỉ có thể thấy hàm băm của nó. Nếu chúng tôi truy cập trình khám phá blockchain và xem đầu ra P2PKH chưa được sử dụng, chúng tôi không thể xác định khóa chung. Nó chỉ được tiết lộ khi người nhận quyết định chuyển tiền.
Điều này có một vài lợi ích. Đầu tiên là hàm băm khóa công khai đơn giản là dễ dàng được truyền đi hơn so với khóa chung đầy đủ. Satoshi ra mắt nó vào năm 2009 vì lý do này. Băm khóa công khai là những gì chúng ta biết như một địa chỉ Bitcoin ngày nay.
Lợi ích thứ hai là băm khóa công khai có thể cung cấp một lớp bảo mật bổ sung chống lại điện toán lượng tử. Bởi vì khóa công khai của chúng tôi không được biết cho đến khi chúng tôi chi tiền, nên việc tính toán khóa riêng của người khác càng khó khăn hơn. Họ sẽ phải đảo ngược hai vòng băm (RIPEMD-160 và SHA-256) để có được nó.
➠ Bạn đang muốn bắt đầu với tiền điện tử? Mua Bitcoin trên Binance!
Trả tiền theo tập lệnh-Hash (P2SH)
Pay-to-Script-Hash (P2SH) là một sự phát triển rất thú vị đối với Bitcoin. Nó cho phép người gửi khóa tiền vào hàm băm của tập lệnh – họ không cần biết tập lệnh thực sự làm gì. Lấy hàm băm SHA-256 sau:
e145fe9ed5c23aa71fdb443de00c7d9b4a69f8a27a2e4fbb1fe1d0dbfb6583f1
Bạn không cần biết đầu vào của hàm băm để khóa tiền vào nó. Tuy nhiên, người chi tiêu cần cung cấp tập lệnh đã được sử dụng để băm nó và cần đáp ứng các điều kiện của tập lệnh đó.
Hàm băm trên được tạo từ tập lệnh sau:
<nhân với 2> <4> <kiểm tra xem có bằng không>
Nếu bạn muốn tiêu số tiền gắn với scriptPubKey đó, bạn không chỉ cung cấp các lệnh đó. Bạn cũng cần scriptSig để đánh giá tập lệnh hoàn chỉnh là Đúng. Trong ví dụ này, đó là phần tử mà bạn <nhân với 2> để cho kết quả là <4>. Tất nhiên, điều đó có nghĩa là scriptSig của chúng tôi chỉ là <2>.
Trong thực tế, scriptPubKey cho đầu ra P2SH là:
OP_HASH160 <redeemScript băm> OP_EQUAL
Không có nhà khai thác mới ở đây. Tuy nhiên, chúng tôi có hàm băm <redeemScript> làm phần tử mới. Như tên cho thấy, đó là hàm băm của tập lệnh mà chúng tôi cần cung cấp để đổi tiền (được gọi là RedemptionScript). scriptSig sẽ thay đổi tùy thuộc vào nội dung trong RedemptionScript. Tuy nhiên, nói chung, bạn sẽ thấy rằng đó là sự kết hợp giữa chữ ký và khóa công khai đính kèm, theo sau là redScript (bắt buộc):
<signature> <khóa công khai> <redeemScript>
Đánh giá của chúng tôi hơi khác một chút so với cách thực thi ngăn xếp mà chúng tôi đã thấy cho đến nay. Nó xảy ra trong hai phần. Việc đầu tiên chỉ đơn giản là kiểm tra xem bạn đã cung cấp hàm băm chính xác chưa.

Bạn sẽ lưu ý rằng chúng tôi không làm bất kỳ điều gì với các phần tử trước RedemptionScript. Chúng không được sử dụng vào thời điểm này. Chúng ta đã đi đến phần cuối của chương trình nhỏ này và phần tử trên cùng khác 0. Điều đó có nghĩa là nó hợp lệ.
Tuy nhiên, chúng tôi vẫn chưa hoàn thành. Các nút mạng nhận ra cấu trúc này là P2SH, vì vậy chúng thực sự có các phần tử của scriptSig đang chờ trong một ngăn xếp khác. Đó là nơi chữ ký và khóa chung sẽ được sử dụng.
Cho đến nay, chúng ta đã coi buyScript như một phần tử. Nhưng bây giờ, nó sẽ được hiểu là hướng dẫn, có thể là bất cứ thứ gì. Hãy lấy ví dụ về tập lệnh khóa P2PKH mà chúng tôi phải cung cấp <signature> và <public key> khớp với hàm băm khóa <public> bên trong <redeemScript>.

Sau khi chuộcScript của bạn đã được mở rộng, bạn có thể thấy rằng chúng tôi có một tình huống giống hệt như giao dịch P2PKH thông thường. Từ đó, bạn chỉ cần chạy nó như bình thường.
Chúng tôi đã trình diễn cái được gọi là tập lệnh P2SH(P2PKH) tại đây, nhưng bạn khó có thể tìm thấy một trong số đó trong tự nhiên. Không có gì ngăn cản bạn tạo một khối, nhưng nó không mang lại cho bạn thêm lợi ích nào và cuối cùng chiếm nhiều không gian hơn trong một khối (và do đó, chi phí cao hơn).
P2SH thường có ích cho những thứ như giao dịch đa chữ ký hoặc tương thích với SegWit. Giao dịch nhiều chữ ký có thể có kích thước rất lớn vì chúng có thể yêu cầu nhiều khóa. Trước khi triển khai Pay-to-Script-Hash, người gửi sẽ phải liệt kê tất cả các khóa chung có thể có trong tập lệnh khóa của họ.
Nhưng với P2SH, điều kiện chi tiêu có phức tạp đến đâu cũng không thành vấn đề. Hàm băm của RedScript luôn có kích thước cố định. Do đó, chi phí sẽ được chuyển cho (những) người dùng muốn mở khóa tập lệnh khóa.
Khả năng tương thích SegWit là một trường hợp khác trong đó P2SH trở nên hữu ích (chúng ta sẽ tìm hiểu chi tiết về sự khác biệt của cấu trúc giao dịch trong phần tiếp theo). SegWit là một soft fork dẫn đến sự thay đổi về định dạng khối/giao dịch. Vì đây là bản nâng cấp chọn tham gia nên không phải tất cả phần mềm ví đều nhận ra những thay đổi. Sẽ không có vấn đề gì nếu khách hàng gói hàm băm tập lệnh SegWit trong P2SH. Giống như tất cả các giao dịch thuộc loại này, họ không cần biết việc mở khóa RedScript sẽ là gì.
Giao dịch SegWit (P2WPKH và P2WSH)
Để có phần giới thiệu toàn diện hơn về SegWit, hãy xem Hướng dẫn dành cho người mới bắt đầu về Segregated Witness.
Để hiểu định dạng giao dịch trong SegWit, bạn chỉ cần biết rằng chúng tôi không còn chỉ có scriptSig và scriptPubKey nữa. Bây giờ, chúng ta cũng có một trường mới gọi là nhân chứng. Dữ liệu chúng ta sử dụng để giữ trong scriptSig được chuyển đến nhân chứng, vì vậy scriptSig trống.
Nếu bạn gặp các địa chỉ bắt đầu bằng 'bc1', thì đó là những gì chúng tôi gọi là gốc SegWit (trái ngược với chỉ tương thích với SegWit, bắt đầu bằng '3' vì chúng là địa chỉ P2SH).
Trả tiền cho nhân chứng-Pubkey-Hash (P2WPKH)
Pay-to-Witness-Pubkey-Hash (P2WPKH) là phiên bản SegWit của P2PKH. Nhân chứng của chúng tôi trông như thế này:
<signature> <khóa công khai>
Bạn sẽ lưu ý rằng điều này giống với scriptSig từ P2PKH. Ở đây, scriptSig trống. Trong khi đó, scriptPubKey trông giống như sau:
<OP_0> <băm khóa công khai>
Điều đó có vẻ hơi lạ phải không? Các opcode ở đâu để chúng ta so sánh chữ ký, khóa chung và hàm băm của nó?
Chúng tôi không hiển thị các toán tử bổ sung ở đây vì các nút nhận giao dịch sẽ biết phải làm gì với giao dịch đó dựa trên độ dài của hàm băm khóa công khai <. Họ sẽ tính toán độ dài và hiểu rằng nó phải được chạy theo kiểu giống như một giao dịch P2PKH kiểu cũ.
Các nút không được nâng cấp không biết cách diễn giải giao dịch theo cách đó, nhưng điều đó không thành vấn đề. Theo quy định cũ, không có nhân chứng nên họ đọc một scriptSig trống và một số dữ liệu. Họ đánh giá điều này và đánh dấu nó là hợp lệ – theo như họ lo ngại, bất kỳ ai cũng có thể chi tiêu số tiền đầu ra. Đây là lý do tại sao SegWit được coi là một soft fork tương thích ngược.
Trả tiền cho nhân chứng-Script-Hash (P2WSH)
Băm tập lệnh trả tiền cho nhân chứng (P2WSH) là P2SH mới. Nếu bạn đã làm được đến mức này, bạn có thể hình dung ra nó sẽ trông như thế nào, nhưng dù sao thì chúng ta cũng sẽ vượt qua nó. Nhân chứng của chúng tôi là những gì chúng tôi thường đưa vào scriptSig. Ví dụ: trong P2WSH bao bọc giao dịch P2PKH, nó có thể trông giống như thế này:
<chữ ký 1> <khóa công khai>
Đây là scriptPubKey của chúng tôi:
<OP_0> <script băm>
Các quy tắc tương tự giữ. Các nút SegWit đọc độ dài của hàm băm tập lệnh và xác định rằng đó là đầu ra P2WSH, được đánh giá tương tự như P2SH. Trong khi đó, các nút cũ chỉ coi nó là đầu ra mà bất kỳ ai cũng có thể chi tiêu.
Bớt tư tưởng
Trong bài viết này, chúng ta đã tìm hiểu một chút về các khối xây dựng của Bitcoin. Hãy tóm tắt chúng một cách nhanh chóng:
Loại tập lệnh | Sự miêu tả |
|---|---|
Trả tiền cho Pubkey (P2PK) | Khóa tiền vào một khóa công khai cụ thể |
Trả tiền cho Pubkey-Hash (P2PKH) | Khóa tiền vào một hàm băm khóa công khai cụ thể (tức là một địa chỉ) |
Trả tiền theo tập lệnh-Hash (P2SH) | Khóa tiền vào hàm băm của tập lệnh mà người nhận có thể cung cấp |
Trả tiền cho nhân chứng-Pubkey-Hash (P2WPKH) | Phiên bản SegWit của P2PK |
Trả tiền cho nhân chứng-Script-Hash (P2WSH) | Phiên bản SegWit của P2SH |
Khi bạn tìm hiểu sâu hơn về Bitcoin, bạn sẽ bắt đầu hiểu tại sao nó lại có nhiều tiềm năng đến vậy. Giao dịch có thể được tạo thành từ nhiều thành phần khác nhau. Bằng cách vận dụng các khối xây dựng này, người dùng có rất nhiều sự linh hoạt khi đặt ra các điều kiện về cách thức và thời điểm có thể chi tiêu tiền.
➠ Câu hỏi về Tập lệnh? Hãy đến Học viện Hỏi!



