DEV Community 👩‍💻👨‍💻

Cover image for Những kiến thức cơ bản về Thẻ (vé)
Marigold
Marigold

Posted on

Những kiến thức cơ bản về Thẻ (vé)

Thẻ Tezos (Tezos tickets) là một loại kiểu dữ liệu chung được tích hơp sẵn, với các bất biến mạnh được thực thi bởi hệ thống kiểu. Vậy thẻ là gì? tại sao? như thế nào? và những điều làm cho thẻ được đánh dấu là gì?

Những phần trong bài viết này sẽ giúp bạn hiểu được về thẻ mà không yêu cầu có bất cứ kiến thức chuyên môn về các loại kiểu tuyến tính (linear types), Michelson, hoặc về giao thức Edo (the Edo protocol). Trước khi bắt đầu chúng ta hãy cùng nhau tìm hiểu một số khái niệm dưới đây.

Token là gì?

Đơn vị tiền mã hoá trong Tezos được ký hiệu là: XTZ. Bạn có thể sở hữu nó, gửi nó cho một người khác, sử dụng nó trong các hợp đồng, v.v. Nó giúp thúc đẩy mọi giao dịch, thực thi các hợp đồng thông minh (smart contract). Để giúp dễ hiểu, bạn chỉ cần xem nó như một loại Token cũng được.

Bạn có thể hiểu các Token một cách trừu tượng: Chúng không phải là một thứ cụ thể trong ví của bạn mà chúng được quy định bởi hợp đồng thông minh.. Chúng ta có thể kể đến các loại Token như FA1.2, FA2 hoặc ERC-xxx. Trên thực tế Token là các tiêu chuẩn hợp đồng có các tính chất sau:

  1. có một giao diện chung,
  2. có một tiêu chuẩn siêu dữ liệu,
  3. có một số hướng dẫn không thay đổi khi thực thi.

Về cơ bản, Token là một hàng trong sổ cái (ledger) của một hợp đồng cụ thể, với các đầu vào (entrypoint) được tiêu chuẩn hóa, và với một hy vọng là chúng sẽ hoạt động tốt. Chúng ta sẽ gọi chúng là các Token hợp đồng (token contract).

Nếu bạn muốn giao dịch với các Token, bạn cần phải tương tác với các hợp đồng thông minh chứa các Token đấy. Điều này cũng xảy ra ở các sàn giao dịch, các thị trường, các ứng dụng (dapps), v.v. tất cả chúng đều cần tương tác với Token hợp đồng. Khái niệm mà bạn cần hiểu vể việc tiêu chuẩn hóa Token hợp đồng đó là: Các hợp đồng thông minh khác tương tác với hợp đồng thông minh chưa token dựa vào giao diện đã định sẵn. Mặt khác, các sàn giao dịch cần tạo các cầu nối (bridges) cho những Token mới; nghĩa là phải viết các Token hợp đồng mới. Điều này không phải là không khả thi, nhưng nó không hiệu quả.

Bạn chỉ sở hữu một Token chỉ khi một hợp đồng cụ thể của bạn được lưu trữ trong sổ cái. Token không nằm ở trong ví, mà ví của bạn sẽ tìm xem trong Token hợp đồng bạn có Token nào. Trong trường hợp bạn muốn gửi Token cho một người khác. Bạn không gửi Token trực tiếp, mà bạn sẽ yêu cầu Token hợp đồng làm điều đó bằng cách thay đổi vào những hàng cần thiết trong sổ cái (vì Token được lưu trữ thành từng hàng trong sổ cái). Các thuộc tính của Token bắt nguồn từ việc triển khai hợp đồng: chúng không phải là thuộc tính nội tại của Token, mà chúng phụ thuộc vào mã (code) trong hợp đồng, và cách mà hợp đồng được thực thi. Token không thể bị sao chép, bị đánh cắp, hoặc bị mất chỉ vì Token hợp đồng thực thi các thuộc tính đó.

Gai góc

Việc lập Token bằng một Token hợp đồng duy nhất, để làm được điều này, cần yêu cầu tất cả các hành động trên Token phải được chuyển bởi Token hợp đồng. Hãy lấy một số ví dụ sau:

Token hợp đồng là một ví dụ của một thất bại. Điều này không ảnh hưởng trực tiếp đến vấn đề bảo mật, vì hợp đồng được công khai và mọi người có thể kiểm tra các Token là không có lỗi (no bugs), không thể thay đổi. Bản chất của "không thay đổi" có thể là một vấn đề nếu ban đầu Token hợp đồng không hoàn hảo. Để khắc phục điều đó, chúng ta có thể thêm vào các trình bao bọc (wrappers), và cần có sự tin cậy hoặc một mô hình quản trị nào đó (điều này sẽ làm tăng thêm độ phức tạp của Token hợp đồng).

Vì mọi thứ được thực hiện với Token điều phải thông qua Token hợp đồng, điều này làm Token được tập trung (centralize) cao trong hệ sinh thái (ecosystem). Một giao dịch đơn giản như trao đổi Token thực sự liên quan đến nhiều giao dịch giữa cả người dùng và Token hợp đồng như: kiểm tra, chuyển nhượng, những giao dịch giữa những người dùng, xử lý lỗi, v.v. Có một trường hợp ứng dụng trong thực tế phức tạp hơn nhiều so với một loạt các giao dịch trực tiếp vì nó liên qua đến các ứng dụng (dapps). Ngoài sự phức tạp của trải nghiệm người dùng (User Experience - UX), nó còn có thêm chi phí tiêu thụ gas trực tiếp vốn tồn tại trong quá trình tập trung hóa. Những vấn đề này hoàn toàn bị che đi bởi sự đơn giản hóa về "Token trong ví của bạn".

So sánh Token XTZ và các loại Token khác

Để có một cái nhìn tổng quát, chúng ta sẽ so sánh một số điểm quan trọng giữa Token dựa trên hợp đồng thông minh với Token XTZ có sẵn trong hệ thống.

Token Bộ lưu trữ Giá trị Quyền sở hữu Gas OH Tích hợp có sẵn
XTZ Phi tập trung Protocol Protocol Không
FAxxx Tập trung Token hợp đồng Token hợp đồng Cao Không

Chúng ta lần lượt giải thích về những đặc tính trên: Bộ lưu trữ và Gas Overhead (Gas OH) có thể giải thích như sau:

Yêu cầu gọi (call) một hợp đồng sẽ luôn tốn kém hơn về không gian và thời gian so với một giao dịch trao đổi các mã XTZ với nhau.

Tích hợp có sẵn nghĩa là được hỗ trợ riêng trong giao thức (protocol): nó được lập trình sẵn, có hướng sử dụng chuyên biệt, v.v.

Về tính tin tưởng chúng ta có hai thành phần:

  • Quyền sở hữu, ví dụ như mức tối thiểu chúng ta cần tin tưởng/kiểm tra/xác minh để thuyết phục bản thân rằng Token không thể bị đánh cắp (điều này cũng tương tự như việc tin tưởng vào một hợp đồng thông minh cũng đòi hỏi phải có sự tin tưởng vào giao thức).
  • Giá trị của Token, ví dụ chúng ta có thể thuyết phục bản thân rằng không ai có thể đột nhiên tạo ra một lượng lớn Token có thể thay thế được từ một nguồn nào đó.

Thẻ là gì?

Vậy thẻ là gì? có thể hiểu tóm tắt, thẻ là Token trong ví của bạn, nó là một first-class trong hợp đồng thông minh. Nó cần phải được tạo ra bởi hợp đồng, và cần có một ứng dụng (dapps) để có thể được sử dụng hiệu quả, nhưng nó có thể được lưu trữ bên ngoài hợp đồng tạo ra nó, nó có thể được đính kèm vào bất kỳ tài khoản (account) nào và được trao đổi một cách đáng tin cậy giống như khi trao đổi Token XTZ.

Cụ thể về thẻ

Trước hết về mặt lập trình, có thể hiểu thẻ là giá trị (value) của ngôn ngữ hỗ trợ viết các hợp đồng thông minh, ví dụ như: thẻ 'a ticket trong ngôn ngữ CameLIGO, hoặc ticket cty trong Michelson một loại dữ liệu được tích hợp sẵn với các hàm tạo cụ thể. Giá trị của thẻ kiểu t cho bất kỳ kiểu type t có thể so sánh bao gồm:

  • giá trị t là giá trị được kiểm soát trực tiếp bởi hợp đồng,
  • chúng có thể được gửi đến các hợp đồng khác ,
  • và có thể mang thông tin.

Thẻ có các giá trị bất biến mạnh mẽ được thực thi bởi kiểu hệ thống (type system) được thực thi bởi bất kỳ thẻ nào gắn với một ngữ nghĩa (semantic) và một giá trị được chia sẻ bởi toàn bộ hệ thống chuỗi khối. Những giá trị đó là:

  • nó không thể được sao chép,
  • nó không thể bị thay đổi,
  • nó không thể bị giả mạo.

Một hợp đồng nào vi phạm những giá trị trên sẽ bị kiểu hệ thống (type system) loại bỏ. Thẻ là một loại kiểu tuyến tính (linear types) và thẻ có thể là bất kỳ kiểu nào. Ví dụ, trong LIGO, một giá trị biến có thể chứa thẻ có thể sử dụng một lần, những khái niệm mở rộng về những tính chất này sẽ được đề cập thêm vào phần sau của bài viết.

Trong phần này để đơn giản chúng ta giả sử rằng kiểu hệ thống của chúng ta không cho phép sao chép, nghĩa là nếu một hợp đồng gửi một thẻ đến bất kỳ nơi nào, thẻ này sẽ không thể bị sao chép bởi bất cứ ai, người sử dụng hay các hợp đồng thông minh. Điều đó có nghĩa là đây là một thẻ duy nhất: người tạo ban đầu của thẻ (chủ sở hữu) có thể tạo ra bất kỳ số lượng thẻ nào người đó muốn, nhưng chỉ có người đó mới có thể làm được điều đó, những người khác không thể làm được.

Thẻ không thể bị làm giả, nghĩa là không thể tạo hoặc thay đổi thẻ. Tóm lại, tính chất tin cậy của thẻ là có thể biết thẻ này đến từ đâu và tin tưởng rằng không ai có thể can thiệp vào thẻ này cả. Những thuộc tính này làm cho thẻ trở thành một trong những lựa chọn tự nhiên để triển khai Token:

  • có thể gửi + nhưng không thể sao chép = có thể chuyển giao quyền sở hữu.
  • có thể chia sẽ ngữ nghĩa (semantics) + có thể mang bất kỳ giá trị nào = Token.

Hơn thế nữa, chúng ta có thể thay đổi cách thực hiện các giao dịch với Token. Ví dụ: không bao giờ cần kiểm tra xem người dùng có sỡ hữu Token hay không, vì nó được cung cấp trực tiếp và có thể được thao tác trực tiếp.

Những biện pháp bảo vệ đó được cũng cố bằng thuộc tính Ticket hardening trong đề xuất của Itaca2Jakarata2.

Thẻ autopsy

Các loại thông tin được lưu trữ trong thẻ bao gồm:

  • Người bán thẻ (ticketer): chỉ địa chỉ của hợp đồng đã tạo ra thẻ,
  • khối hàng (payload): về mặt lập trình đó có thể là bất kỳ giá trị của bất kỳ kiểu (type) nào có thể so sánh được.
  • một số lượng (amount): đó là một số tự nhiên, thể hiện "khối lượng" (volume) và "trọng lượng" (weight) của một thẻ. Ví dụ: khi bạn muốn kết hợp (join) hai thẻ tương thích với số lượng x và y, bạn sẽ nhận được một thẻ với tổng số lượng "x + y". Khi bạn cần chia (split) một thẻ có tổng khối lượng/trọng lượng "x + y", bạn sẽ nhận được hai thẻ, lần lượt với số lượng là x và y.

Ticketer và payload là cố định và không thể thay đổi một khi thẻ đã được tạo. Số lượng sẽ không thay đổi, nhưng với tính chất này có một số ý kiến muốn nó có thể thay đổi. Vì tính phức tạp của ngôn ngữ lập trình, hiện tại tính chất của số lượng chỉ cho phép kết hợp (join) và chia (split).

Payload cung cấp về loại kiểu (type) của thẻ, ví dụ: một thẻ với một payload 1n là một thẻ có kiểu số tự nhiên, và payload 2n cũng vậy. Kiểu payload không bị ràng buộc vào số tự nhiên, mà nó có thể là bất kỳ một kiểu nào, và kiểu đó phải là kiểu có thể so sánh được (comparable). Một trong những kiểu so sánh được có thể đề cập đến là kiểu address và số tự nhiên nat.

Các kiểu so sánh được trong Michelson: trong Michelson kiểu có thể so sánh được là COMPARE, nó được định nghĩa là một kiểu cơ bản (int, string, bytes nhưng nó cũng có thể là các kiểu address, signature, ...) và kết hợp với (option <comparable type> hoặc kiểu <pair>, v.v.).

Kiểu và Khóa

Một kiểu chung của thẻ là 'a ticket trong đó 'a là loại kiểu được định nghĩa trong payload. Thẻ của cùng một kiểu có thể kết hợp (join) nếu nó có cùng ticketer và cùng một kiểu trong payload. Ví dụ: kiểu payload là string ticket, các thẻ: TICKET(bob, "toto", 42), TICKET(jim, "toto", 42), TICKEt(bob, "otto", 42) là có cùng một loại kiều payload (string ticket), nhưng chúng không thể tương thích với nhau vì chúng có các ticketer khác nhau (bob, jim) hoặc khác kiểu payload.

Một số ví dụ cụ thể:

  • TICKET(bob, "toto", 42) + TICKET (bob, "toto", 69) -> TICKET(bob,"toto", 111)
  • TICKET(jim, "toto", 42) + TICKET (bob, "toto", 69) -> ERROR
  • TICKET(bob, "otto", 42) + TICKET (bob, "toto", 69) -> ERROR

Tóm lại, một ticket key: một khóa (key) là một ticketer và có giá trị payload. string ticket có một số khóa (string là kiểu của payload): string của ticketer và string của kiểu payload, ví dụ như các thẻ (bob, "toto"), hoặc (bob, "otto"), hoặc (jim, "toto"). Các thẻ có cùng khóa có tính chất kết hợp (join) và chia (split). Tuy nhiên, có một số trường hợp đặc biệt, các thẻ có cùng một kiểu nhưng không thể kết hợp được với nhau, muốn kết hợp các thẻ với nhau chúng phải có cùng ticketer và giá trị payload.

Chúng ta nhắc lại một tính chất của thẻ đó là không thể thay đổi ticketer và cũng không thể thay đổi payload. Vì hai tính chất này, thẻ khóa là không thể thay đổi.

Vì thẻ không thể thay đổi, chúng chỉ có thể kết hợp hoặc chia, một hợp đồng có quyền kiểm soát rõ ràng đối với thẻ của tất cả các khóa được gán cho nó; và người nhận thẻ điều biết được thẻ này đến từ đâu. Ví dụ: để tạo một Token có thể thay thế (fungible token), người ta có thể mint một hợp đồng, và tạo ra các thẻ với payload cố định. Những thẻ này có thể được gửi cho người dùng mà không mất đi dấu của tổng số lượng, và bảo đảm rằng không ai có thể chỉnh sử thẻ này (ví dụ: tạo ra thẻ mới mà không biết ticketer chẳng hạn).

Linear type

Các giá trị bất biết có thể bắt nguồn từ nhiều nguồn. Ví dụ, các đoạn mã lập trình (code) của một số ngôn ngữ lập trình hỗ trợ strong typed. Trong phần này, chúng ta sẽ xem xét một số hệ quả thực tế của nó. Biến số (variable): sử dụng chúng hoặc bị mất.

Để hiểu kiểu bất biến (linear type), chúng ta có thể hình dung biến số (varible) khi được tạo ra được sử dụng chỉ duy nhất một lần. Và khi đã được sử dụng, chúng sẽ mất đi (không thể sử dụng lại được nữa). Ví dụ:

let ticket = ... in
let copy = ticket in 
ticket, copy
Enter fullscreen mode Exit fullscreen mode

Đoạn mã lập trình trong ví dụ trên sẽ báo lỗi trong:

  • LIGO: warning: variable "ticket" cannot be used more than once (cảnh báo: biến số "ticket" không thể được sử dụng nhiều hơn một lần.)
  • Michelson:
Ill typed contract: type ticket nat cannot be used here because it is not duplicable. Only duplicable types can be used with the DUP instruction and as view inputs and outputs
Enter fullscreen mode Exit fullscreen mode

(Kiểu hợp đồng yếu: kiểu thẻ nat không thể được sử dụng bởi vì chúng không thể bị sao chép. Chỉ có loại kiểu được sao chép mới có được sử dụng với DUP và với view đăng nhập và đăng xuất)

Điều đó có nghĩa là các hàm khai báo có thể khai báo thẻ là một đối số (argument) và hàm này cần phải có giá trị trả về nếu không nó sẽ bị mất đi. Lấy ví dụ của hàm read_ticket sau đây là không thể áp dụng:

let ticketer, payload, amount = read_ticket ticket in 
...
Enter fullscreen mode Exit fullscreen mode

Nếu không, một khi thẻ đã được đọc nó sẽ bị mất/đốt cháy (burned) vĩnh viễn. Trong thực tế, hàm read_ticket được sử dụng như sau:

let (ticketer, (payload, amount)), new_ticket = Tezos.read_ticket ticket in 
...
Enter fullscreen mode Exit fullscreen mode

Constructors

Để tạo ra thẻ mới, có thể sử dụng constructors: create_ticket, split_ticketjoin_ticket.

Trong LIGO, các hàm này như sau:

val create_ticket: 'value -> nat -> 'value ticket
val split_ticket : 'value ticket -> nat * nat -> ('value ticket * 'value ticket) option
val join_tickets : 'value ticket * 'value ticket -> ('value ticket) option
Enter fullscreen mode Exit fullscreen mode
  • create_ticket: hàm này sẽ tạo mới thẻ (trong ví dụ dưới đây, kiểu của thẻ có thể được suy ra, và chúng được đưa ra để phân biệt giữa kiểu và khóa)
let new_ticket : string ticket = Tesoz.create_ticket "some payload" 42n in
...
Enter fullscreen mode Exit fullscreen mode
  • split_ticket: chia một thẻ thành các thẻ mới có cùng khóa
let old_ticket  = Tesoz.create_ticket "some payload" 42n in
let opt  = Tesoz.split_ticket old_ticket (12n,30n) in
let ticket_12, ticket_30   = Option.unopt opt in
    ...
Enter fullscreen mode Exit fullscreen mode
  • join_ticket: kết hợp hai thẻ có cùng khóa vào làm một thẻ
let ticket_12  = Tesoz.create_ticket "some payload" 12n in
let ticket_30  = Tesoz.create_ticket "some payload" 30n in
let opt  = Tesoz.join_tickets (ticket_12,ticket_30) in
let ticket_42 = Option.unopt opt in
    ...
Enter fullscreen mode Exit fullscreen mode

Tìm kiếm bộ lưu trữ

Nếu thẻ có kiểu là map, thì không thể tìm thẻ và để nó ở trong map. Nếu bạn muốn truy suất thẻ, trước tiên bạn phải xóa thẻ từ trong map. Đó là lý do tại sao chúng ta sử dụng hàm get_and_update, với kiểu None được xem như giá trị mới:

let ticket,store_without_ticket = 
    Map.get_and_update addr (None : silly option) store in 
    ...
Enter fullscreen mode Exit fullscreen mode

Cập nhật bộ lưu trữ

Trong khi cập nhật, hàm get_and_update, nếu có giá trị mới nó sẽ trả về giá trị Some ticket cho thẻ là None. Ngược lại, nó sẽ bị trùng lặp:

let _ticket,store = Map.get_and_update addr (Some silly) store in 
    ...
Enter fullscreen mode Exit fullscreen mode

Giá trị _ticket có giá trị trả về là None.

Views

Onchain views (chế độ xem onchain) là một cơ chế tích hợp để cung cấp quyền truy cập đồng bộ, cho phép thuộc tính chỉ đọc vào hợp đồng thông minh. Chế độ xem (views) hơi giống endpoint ở chỗ chúng lấy giá trị của (parameter * storage), nhưng thay vì trả về operation list * storage, views có thể trả về bất kỳ giá trị nào mà không làm ảnh hưởng đến bộ lưu trữ.

let main (action,store : sc_parameter * storage) : operation list * storage = ... 

[@view] let view_1 (parameter,store : view_parameter * storage) : view_return_value = ...
Enter fullscreen mode Exit fullscreen mode

Parameter (view_parameter) và giá trị trả về view_return_value có thể có bất kỳ kiểu nào ngoài các kiểu sau: big_map, sapling_state, operation, ticket

So sánh lần nữa giữa: XTZ, Token và thẻ

Token Bộ lưu trữ Chủ sở hữu Giá trị Có sẵn Gas OH
XTZ Phi tập trung Protocol Protocol Không
FAxxx Tập trung Mã hợp đồng Mã hợp đồng Không Cao
Thẻ Phi tập trung Protocol, hợp đồng Hợp đồng Tùy

Bộ lưu trữ của thẻ có thể là phi tập trung, và thẻ có thể được trao đổi giữa các hợp đồng. Hơn thế nữa, việc tạo ra các thẻ là hoàn toàn tập trung, và có thể lưu trữ các thẻ với một khóa ở một chỗ: chỉ không phân tán và được lưu trữ trong sổ cái.

Về tính chất tin tưởng, nếu chúng ta chọn chủ sỡ hữu và giá trị để so sánh:

  • Tin tưởng chủ sở hữu trong trường hợp này đơn giản hơn, nó có một hợp đồng lưu trữ thẻ cần được tin tưởng.
  • Tin tưởng vào giá trị tùy thuộc vào sự sử dụng của thẻ, nhưng trong mọi trường hợp, nó sẽ phụ thuộc vào tính đúng đắn của các hợp đồng sử dụng thẻ.

Gas overhead (Gas OH) một lần nữa phụ thuộc vào kiến trúc đã chọn cho một trường hợp sử dụng cụ thể. Càng ít tập trung, thì chi phí gas càng ít. Sẽ có một số Michelson được thực thi để thao túng thẻ, vì vậy sẽ có mức tiêu thụ gas, nhưng có thể ít hơn. Một lần nữa, nó tùy thuộc vào việc triển khai và kiến trúc.

Hạn chế: Kể từ tháng 5 năm 2022, thẻ có thể được giữ bởi các địa chỉ ban đầu (địa chỉ của các hợp đồng thông minh) nhưng hạn chế này sẽ được loại bỏ trong một đề xuất trong tương lai. Layer 2 Tezos như TORUs, SCORUs, DEKU hoặc Chusai (sắp ra mắt) đã có thể giữ vé cho các tài khoản ẩn (implicit account) (tz1xxx, tz2xxx, tz4xxx).

Thẻ trong Tezos Layer 2

Hệ sinh thái tầng 2 (Layer 2 ecosystem) của một số chuỗi khối, bạn sẽ nhanh chóng nhận ra có một khó khăn đó là khó khăn khi phải kết nối các cầu nối (bridge) với Token với các token của tầng 2. Chuyển giao các nội dung giữa các tầng là một điều khó khăn.

Khi thẻ là một first-class trong tầng 2 của Tezos, điều này sẽ mang lại rất nhiều sự đơn giản và tránh được nhiều khoảng phí vô ích cho việc khóa/mở khóa trong chuỗi chính (main chain). Nó cho phép tất cả các tầng 2 trở thành "bất khả thi về Token" và thao túng các thẻ bất kể nguồn gốc cũa chúng, miễn là các Token được triên bằng thẻ, nó được hỗ trợ bởi tất cả tầng 2, miễn phí mà không cần bất kỳ cơ sở hạ tầng chuyên dụng nào. Nếu không, chỉ cần một hợp đồng cung cấp thẻ cho Token (lưu trữ trong kho (vault)) là đủ.

Chúng ta hãy tưởng tượng:

  1. Bạn có một hợp đồng cần được mint một thẻ cTez, kho CTez là một kho lưu trữ của hợp đồng với thẻ này.
  2. Bạn có thể gửi thẻ này vào TORU rollup.
  3. Sau đó thực hiện một giao dịch với một số lượng cụ thể.
  4. Sau đó rút số lượng còn lại của thẻ vào Tezos.
  5. Sau đó gửi tiền vào DEKU sidechain.
  6. Sau đó, sử dụng thẻ với một hợp đồng thông minh.
  7. Rồi, rút về Tezos và cuối cùng đốt thẻ đó từ ticketer ban đầu với cTez còn lại.

Bạn có thể sử dụng Tezos, optimistic rollup và sidechain cho cùng một thẻ!

Cách suy nghĩ về thẻ

Để kết luận, có một số ví dụ hữu ích để suy nghĩ về thẻ: nó là một suy luận về ngữ nghĩa của một hợp đồng, nó là một thử nghiệm các cách mới để triển khai các chức năng hiện có, nó truyền đạt các khái niệm.

  • Một phần dữ liệu không thể giả mạo và có thể theo dõi
  • Tiền mặt, nó ở trong túi của bạn nhưng nó không thể làm giả được
  • Chìa khóa để mở các chức năng
  • Một phương thức cho chuỗi khối hỗ trợ bất kỳ Token tùy chỉnh nào
  • Token hoạt động như dự định
  • Một vật phẩm đồng bộ hóa để xử lý đồng thời
  • Một công cụ để ghi dữ liệu vào sổ cái toàn cầu: nơi dữ liệu được lưu trữ không làm thay đổi ý nghĩa/giá trị của thẻ
  • Dữ liệu có thể được lập luận ở cấp độ của toàn bộ chuỗi khối, không chỉ ở cấp độ của hợp đồng
  • Loại dữ liệu hợp đồng thông minh với các bất biến rất mạnh

Đã đến lúc bạn sử dụng thẻ trong Tezos ngay bây giờ.

Source: https://www.marigold.dev/post/tickets-for-dummies

Translation by Ly Kim Quyen, Software developer at Marigold

Top comments (0)

Here is a post you might want to check out:

Regex for lazy developers

regex for lazy devs

Sorry for the callout 😆