Hướng dẫn phát triển dự án TON (Phần 1): Xem từ góc độ mã nguồn làm thế nào để tạo một NFT trên TON Chain

Tác giả gốc: @Web3 Mario(_mario)

Tiếp tục từ bài viết trước về giới thiệu về công nghệ TON, trong thời gian này tôi đã nghiên cứu sâu hơn về tài liệu phát triển chính thức của TON và cảm thấy việc học có một số khó khăn. Nội dung tài liệu hiện tại dường như chỉ là một tài liệu phát triển nội bộ, không thân thiện với những nhà phát triển mới, do đó tôi đã cố gắng tổ chức một loạt bài viết về phát triển dự án TON Chain dựa trên quá trình học của riêng mình, hy vọng có thể giúp mọi người nhanh chóng làm quen với việc phát triển TON DApp. Nếu có sai sót trong bài viết, xin vui lòng chỉ ra để cùng nhau học tập.

Phát triển NFT trên EVM và phát triển NFT trên chuỗi TON có những điểm khác biệt nào

Phát hành một FT hoặc NFT là yêu cầu cơ bản nhất đối với nhà phát triển DApp. Do đó, tôi cũng chọn nó làm điểm khởi đầu để học hỏi. Đầu tiên, hãy tìm hiểu sự khác biệt giữa việc phát triển một NFT trên EVM và trên TON Chain. NFT dựa trên EVM thường sẽ chọn kế thừa tiêu chuẩn ERC-721. NFT, có nghĩa là loại tài sản mã hóa không thể chia tách và mỗi tài sản có tính duy nhất, tức là có những đặc tính độc quyền. Và ERC-721 chính là một mô hình phát triển thông dụng cho loại tài sản này. Hãy xem xét các hàm và thông tin cần phải ghi nhận trong một hợp đồng ERC 721 thường gặp. Hình bên dưới là một giao diện ERC 721. Như bạn có thể thấy, khác với FT, trong giao diện chuyển tiền, bạn cần nhập tokenId cần chuyển thay vì số lượng. TokenId này cũng là cách thể hiện tính duy nhất của tài sản NFT cơ bản nhất, tuy nhiên để chứa nhiều thuộc tính hơn, thường sẽ ghi nhận một metadata cho mỗi tokenId, metadata này là một liên kết bên ngoài, lưu trữ dữ liệu mở rộng khác của NFT, chẳng hạn như liên kết hình ảnh PFP, tên thuộc tính và nhiều hơn nữa.

TON项目开发教程(一):源码角度看如何在TON Chain上创建一个NFT

Đối với những nhà phát triển đã quen với Solidity hoặc hướng đối tượng, việc triển khai một hợp đồng thông minh như vậy là dễ dàng, chỉ cần định nghĩa các loại dữ liệu cần thiết trong hợp đồng, ví dụ như một số mối quan hệ ánh xạ quan trọng và phát triển các logic sửa đổi dữ liệu tương ứng cho chúng theo các chức năng cần thiết, là có thể triển khai một NFT.

Tuy nhiên, điều này không còn như vậy trên TON Chain, có hai nguyên nhân chính dẫn đến sự khác biệt:

  • Trong TON, việc lưu trữ dữ liệu dựa trên Cell, và Cell của cùng một tài khoản được triển khai thông qua đồ thị có định hướng không tuần hoàn. Điều này dẫn đến việc dữ liệu cần lưu trữ không thể tăng lên vô hạn, vì chi phí truy vấn được quyết định bởi độ sâu của đồ thị có định hướng, khi mà độ sâu mở rộng vô hạn, có thể dẫn đến chi phí truy vấn quá cao, từ đó gây ra vấn đề bế tắc cho hợp đồng.
  • Để đạt được hiệu suất đồng thời cao, TON đã từ bỏ kiến trúc thực thi tuần tự và chuyển sang một mô hình phát triển được tạo ra đặc biệt cho đồng thời, mô hình Actor, để xây dựng môi trường thực thi. Điều này dẫn đến một tác động, các hợp đồng thông minh chỉ có thể gọi bất đồng bộ thông qua việc gửi tin nhắn nội bộ, lưu ý rằng cả cuộc gọi kiểu thay đổi trạng thái và chỉ đọc đều phải tuân theo nguyên tắc này, ngoài ra, cần xem xét kỹ càng cách xử lý việc quay lại dữ liệu nếu cuộc gọi bất đồng bộ thất bại.

Tất nhiên, về các khác biệt kỹ thuật khác, đã có bài viết trước đó trình bày chi tiết, bài viết này mong muốn tập trung vào phát triển hợp đồng thông minh trên TON, do đó sẽ không mở rộng thảo luận. Hai nguyên tắc thiết kế trên đã tạo ra sự khác biệt lớn giữa phát triển hợp đồng thông minh trên TON và EVM. Trong những bài đề cập đầu tiên, chúng ta đã biết rằng một hợp đồng NFT cần định nghĩa một số quan hệ ánh xạ, nghĩa là ánh xạ, để lưu trữ dữ liệu liên quan đến NFT. Trong đó, quan trọng nhất là owners, ánh xạ này lưu trữ quan hệ ánh xạ giữa địa chỉ chủ sở hữu của NFT tương ứng với tokenID nào, quyết định sở hữu của NFT, và chuyển tiền là thay đổi quyền sở hữu đó. Vì lý thuyết đây là một cấu trúc dữ liệu có thể vô hạn, nên cần tránh nó càng nhiều càng tốt. Do đó, các ứng dụng cần lưu trữ dữ liệu tương tự sẽ được thay thế bằng mô hình hợp đồng chủ từ, quản lý dữ liệu tương ứng với mỗi khóa thông qua tạo hợp đồng con. Và thông qua hợp đồng chủ quản lý thông số toàn cục, hoặc giúp giải quyết thông tin giao tiếp trong các hợp đồng con.

Điều này cũng có nghĩa là NFT trong TON cần được thiết kế theo một kiến trúc tương tự, mỗi NFT là một hợp đồng con độc lập, lưu trữ dữ liệu riêng như địa chỉ chủ sở hữu, siêu dữ liệu và quản lý dữ liệu toàn cầu thông qua một hợp đồng chính, như tên NFT, biểu tượng, tổng cung và nhiều hơn nữa.

Sau khi xác định cấu trúc, tiếp theo cần giải quyết các yêu cầu chức năng cốt lõi. Do sử dụng cách tiếp cận hợp đồng chính-phụ này, cần xác định rõ ràng chức năng nào được chịu trách nhiệm bởi hợp đồng chính, chức năng nào được chịu trách nhiệm bởi hợp đồng phụ, và cách họ giao tiếp thông tin nội bộ với nhau. Đồng thời, khi xảy ra lỗi thực thi, cần xem xét cách quay lại dữ liệu trước đó. Thông thường, trước khi phát triển một dự án lớn phức tạp, việc vẽ một biểu đồ lớp và xác định luồng thông tin giữa các phần tử và cân nhắc kỹ lưỡng về logic quay lại khi gọi nội bộ thất bại là cần thiết. Tất nhiên, mặc dù phát triển NFT như đã nói khá đơn giản, nhưng cũng có thể thực hiện kiểm tra tương tự.

TON项目开发教程(一):源码角度看如何在TON Chain上创建一个NFT

Từ nguồn học phát triển hợp đồng thông minh TON

TON đã chọn thiết kế một ngôn ngữ tĩnh giống như ngôn ngữ C, được gọi là Func, làm ngôn ngữ phát triển hợp đồng thông minh. Tiếp theo, chúng ta sẽ học cách phát triển hợp đồng thông minh TON từ mã nguồn, tôi chọn ví dụ NFT từ tài liệu chính thức của TON để giới thiệu, những người quan tâm có thể tự tìm hiểu. Trong trường hợp này, một ví dụ NFT TON đơn giản đã được thực hiện. Hãy xem cấu trúc hợp đồng, bao gồm hai hợp đồng chức năng và ba thư viện cần thiết.

TON项目开发教程(一):源码角度看如何在TON Chain上创建一个NFT

Các hợp đồng chức năng chính này được thiết kế theo nguyên tắc đã nêu ở trên, trước tiên hãy xem mã nguồn của hợp đồng chính nft-collection:

TON项目开发教程(一):源码角度看如何在TON Chain上创建一个NFT

Điều này đã giới thiệu một điểm kiến thức đầu tiên, đó là làm thế nào để lưu trữ dữ liệu một cách bền vững trong hợp đồng thông minh TON, chúng ta biết rằng việc lưu trữ dữ liệu một cách bền vững trong Solidity được xử lý tự động bởi EVM dựa trên loại tham số, thông thường, biến trạng thái của hợp đồng thông minh sẽ được lưu trữ một cách tự động dựa trên giá trị mới nhất sau khi thực thi kết thúc, các nhà phát triển không cần phải quan tâm đến quá trình này. Nhưng trong trường hợp của Func thì không phải như vậy, các nhà phát triển cần phải tự mình triển khai logic xử lý tương ứng, tình huống này hơi giống như khi sử dụng C và C++ cần phải quan tâm đến quá trình GC, nhưng các ngôn ngữ lập trình mới khác thường sẽ tự động xử lý phần này. Hãy xem mã nguồn, trước hết, chúng ta sẽ giới thiệu một số thư viện cần thiết, sau đó xem hàm đầu tiên load_data được sử dụng để đọc dữ liệu đã được lưu trữ bền vững, logic của nó là trả về cell lưu trữ hợp đồng bền vững thông qua get_data, lưu ý rằng điều này được thực hiện bởi thư viện chuẩn stdlib.fc, thông thường có thể coi một số hàm trong đó như là hàm hệ thống để sử dụng.

Hàm này trả về kiểu cell, đây là kiểu cell trong TVM. Trong phần giới thiệu trước đó, chúng ta đã biết rằng tất cả dữ liệu lưu trữ vĩnh viễn trong blockchain TON đều được lưu trữ trong cây cell. Mỗi cell có tối đa 1023 bit dữ liệu tuỳ ý và tối đa bốn tham chiếu đến cell khác. cell được sử dụng như bộ nhớ trong TVM dựa trên ngăn xếp. Cell chứa dữ liệu được mã hóa chặt chẽ, để có thể lấy dữ liệu văn bản cụ thể từ đó, cần chuyển cell thành kiểu được gọi là slice. Cell có thể được chuyển đổi thành kiểu slice thông qua hàm begin_parse, sau đó có thể tải dữ liệu và tham chiếu đến cell khác từ slice để lấy dữ liệu trong cell. Lưu ý rằng cách gọi này trong dòng 15 là cú pháp trong func, có thể gọi trực tiếp hàm trả về của hàm thứ nhất. Và cuối cùng, tải tuần tự dữ liệu tương ứng theo thứ tự lưu trữ. Lưu ý rằng quá trình này khác với solidity và không phải là dựa trên hashmap, vì vậy thứ tự gọi này không được phép bị lẫn lộn.

Trong hàm save_data, quy trình logic tương tự, chỉ khác là quá trình này là quá trình đảo ngược, điều này đưa vào một điểm kiến thức tiếp theo, một loại builder mới, đó là loại builder của cell. Dữ liệu bit và tham chiếu đến các cell khác có thể được lưu trữ trong builder, sau đó builder có thể được hoàn thiện thành cell mới. Đầu tiên, tạo một builder bằng hàm tiêu chuẩn begin_cell, sau đó lưu trữ các hàm liên quan thông qua các hàm lưu trữ tương ứng, chú ý thứ tự gọi trong văn bản trước và thứ tự lưu trữ ở đây cần phải giữ nguyên. Cuối cùng, hoàn thành việc xây dựng cell mới thông qua end_cell, lúc này cell đó được quản lý trong bộ nhớ, cuối cùng thông qua set_data ở cấp độ bên ngoài, ta có thể hoàn thành việc lưu trữ lâu dài cho cell đó.

TON项目开发教程(一):源码角度看如何在TON Chain上创建一个NFT

Tiếp theo, chúng ta hãy xem xét các hàm liên quan đến kinh doanh, đầu tiên cần giới thiệu một điểm kiến thức, đó là cách tạo ra một hợp đồng mới thông qua hợp đồng, điều này sẽ thường xuyên được sử dụng trong kiến trúc chủ từ vừa giới thiệu. Chúng ta biết rằng trong TON, việc gọi hợp đồng thông minh giữa chúng ta được thực hiện thông qua việc gửi tin nhắn nội bộ. Điều này được thực hiện thông qua một chức năng gọi là send_raw_message, lưu ý rằng tham số đầu tiên là cell đã mã hóa của tin nhắn, tham số thứ hai là cờ, được sử dụng để chỉ ra sự khác biệt trong cách thực hiện giao dịch, TON đã thiết lập các cách thức thực hiện tin nhắn nội bộ khác nhau, hiện tại có 3 chế độ tin nhắn và 3 cờ tin nhắn. Bạn có thể kết hợp một Chế độ duy nhất với nhiều (có thể không có) cờ để có được chế độ mong muốn. Kết hợp chỉ đơn giản là cộng các giá trị của chúng và điền vào đó.

TON项目开发教程(一):源码角度看如何在TON Chain上创建一个NFT

Vậy hãy xem hàm chính đầu tiên, deploy_nft_item, theo như tên gọi, đây là một hàm dùng để tạo ra hoặc đúc một phiên bản NFT mới, sau khi mã hóa một tin nhắn, gửi nội dung hợp đồng bằng cách sử dụng send_raw_message và chọn cờ gửi với flag 1, chỉ sử dụng phí được chỉ định trong mã hóa làm phí gas cho lần thực thi này. Sau khi đọc qua phần trước, chúng ta dễ dàng nhận ra rằng quy tắc mã hóa này có lẽ là cách tạo ra một hợp đồng thông minh mới. Vậy hãy xem cụ thể làm thế nào để thực hiện.

Hãy nhìn vào dòng 51 trực tiếp, hai hàm trên là các hàm trợ giúp để tạo ra thông tin cần thiết cho tin nhắn, vì vậy chúng ta sẽ xem sau, đây là quá trình mã hóa một tin nhắn nội bộ để tạo ra một hợp đồng thông minh, một số con số ở giữa thực tế là các cờ chỉ dẫn cho yêu cầu của tin nhắn nội bộ, ở đây cần đưa ra một điểm kiến thức mới, TON đã chọn một ngôn ngữ nhị phân gọi là TL-B để mô tả cách thực thi tin nhắn và thực hiện một số chức năng cụ thể của tin nhắn nội bộ bằng cách đặt các cờ chỉ dẫn khác nhau, hai tình huống sử dụng dễ nhất để nghĩ đến là tạo mới hợp đồng và gọi hàm của hợp đồng đã triển khai. Phần sau của dòng 51 tương ứng với việc tạo ra một hợp đồng mục nft mới, điều này chủ yếu được chỉ định bởi dòng 55, 56, 57. Đầu tiên, chuỗi con số dài dòng 55 là một chuỗi các cờ chỉ dẫn, lưu ý rằng đối số đầu tiên của store_uint là giá trị, đối số thứ hai là độ dài bit, trong đó xác định rằng tin nhắn nội bộ này là tạo mới hợp đồng, với ba cờ chỉ dẫn cuối cùng, và giá trị nhị phân tương ứng là 111 (tức là 4 + 2 + 1), trong đó hai giá trị đầu tiên biểu thị tin nhắn này sẽ đi kèm với dữ liệu StateInit, đây là mã nguồn của hợp đồng mới và dữ liệu khởi tạo cần thiết. Còn cờ chỉ dẫn cuối cùng biểu thị tin nhắn nội bộ mang theo, tức là hy vọng thực hiện các logic liên quan và các tham số cần thiết. Do đó, bạn sẽ thấy trong đoạn mã ở dòng 66 không có ba giá trị này được thiết lập, điều này cho biết đó là một lần gọi hàm của hợp đồng đã triển khai. Xem quy tắc mã hóa cụ thể tại đây.

Vì vậy, quy tắc mã hóa của StateInit tương ứng với 49 dòng mã, được tính toán thông qua calculate_nft_item_state_init. Lưu ý rằng việc mã hóa dữ liệu stateinit cũng tuân theo một quy tắc mã hóa TL-B đã được thiết lập, ngoại trừ một số bit đánh dấu, chủ yếu liên quan đến hai phần mã hợp đồng mới và dữ liệu khởi tạo. Thứ tự mã hóa của dữ liệu cần phải giữ nguyên thứ tự lưu trữ của cell bền vững được chỉ định bởi hợp đồng mới. Ở dòng 36, dữ liệu khởi tạo có item_index, tương tự như tokenId trong ERC 721, cũng như địa chỉ hợp đồng hiện tại được trả về bởi hàm tiêu chuẩn my_address, tức là collection_address, thứ tự dữ liệu này giữ nguyên với khai báo trong nft-item.

Tiếp theo một điểm kiến thức là trong TON, tất cả các hợp đồng thông minh chưa được tạo ra có thể được tính toán trước địa chỉ sau khi tạo ra, điều này tương tự như hàm create 2 trong Solidity, ở TON việc tạo ra địa chỉ mới được tạo thành từ hai phần, bao gồm workchain và ghép nối giá trị băm của stateinit, phần đầu tiên chúng ta đã biết từ các phần trước đó là cần phải được chỉ định cho kiến trúc phân mảnh vô hạn của TON và hiện tại là một giá trị thống nhất. Được lấy từ hàm chuẩn workchain. Phần sau được lấy từ hàm chuẩn cell_hash. Vì vậy quay lại ví dụ này, calculate_nft_item_address chính là hàm tính toán trước địa chỉ hợp đồng mới. Và giá trị được tạo ra được mã hóa vào thông điệp ở dòng 53, làm địa chỉ nhận của thông điệp nội bộ đó. Còn nft_content tương ứng với cuộc gọi khởi tạo cho hợp đồng được tạo ra, cụ thể việc thực hiện sẽ được giới thiệu trong bài viết tiếp theo.

Đối với send_royalty_params, nó cần phản hồi cho một tin nhắn nội bộ của một yêu cầu chỉ đọc, trong phần giới thiệu trước đó, chúng tôi đã nhấn mạnh rằng trong TON, tin nhắn nội bộ không chỉ chứa các hoạt động có thể thay đổi dữ liệu, mà còn cần thực hiện các hoạt động chỉ đọc thông qua cách này, do đó hợp đồng này chính là loại hoạt động này, đầu tiên cần chú ý là dòng 67 đại diện cho cờ gọi lại hàm của người yêu cầu sau khi phản hồi yêu cầu, sau đó là dữ liệu trả về, lần lượt là chỉ số mục của yêu cầu và dữ liệu royalty tương ứng.

Tiếp theo, chúng ta hãy giới thiệu một điểm kiến thức mới, trong TON, hợp đồng thông minh chỉ có hai điểm nhập cửa thống nhất, được gọi là recv_internal và recv_external, trong đó recv_internal là điểm gọi thống nhất cho tất cả các tin nhắn nội bộ, và recv_external là điểm gọi thống nhất cho tất cả các tin nhắn bên ngoài. Nhà phát triển cần phản ứng theo yêu cầu bên trong hàm, sử dụng cách tương tự như cấu trúc switch dựa trên các bit đánh dấu khác nhau được chỉ định bởi message, trong đó bit đánh dấu ở đây chính là bit đánh dấu trong hàm pullback ở dòng 67 như đã nêu ở trên. Trong ví dụ này, trước tiên kiểm tra xem message có trống không, nếu có thì tiến hành phân tích thông tin trong message. Đầu tiên, ở dòng 83, phân tích và lấy sender_address từ message, tham số này sẽ được sử dụng cho việc kiểm tra quyền hạn sau này. Chú ý đến toán tử ~ ở đây, đây là một cú pháp khác. Chúng ta sẽ không mở rộng vấn đề này ở đây. Tiếp theo, phân tích bit đánh dấu op, sau đó xử lý các yêu cầu tương ứng dựa trên các bit đánh dấu khác nhau. Trong đó, có việc gọi các hàm như đã nêu ở trên tùy theo logic. Ví dụ, phản ứng với yêu cầu về tham số royalty, hoặc đúc ra nft mới, và tăng chỉ số toàn cầu.

Tiếp theo, một điểm kiến thức tương ứng với dòng 108, chúng ta có thể đoán được logic xử lý của hàm này thông qua tên hàm. Tương tự như hàm require trong Solidity, trong hàm Func, chúng ta sử dụng hàm throw_unless tiêu chuẩn để ném ra ngoại lệ. Đối số đầu tiên là mã lỗi, đối số thứ hai là giá trị boolean của bit kiểm tra, nếu bit là false thì ném ra ngoại lệ và kèm theo mã lỗi đó. Trong dòng này, chúng ta sử dụng equal_slices để kiểm tra xem sender_address đã giải mã ở trên có bằng owner_address được lưu trữ lâu dài của hợp đồng hay không, để thực hiện kiểm tra quyền hạn.

TON项目开发教程(一):源码角度看如何在TON Chain上创建一个NFT

Cuối cùng, để làm cho cấu trúc mã nguồn trở nên rõ ràng hơn, bắt đầu với một loạt các hàm trợ giúp để lấy thông tin bền vững, tôi sẽ không mở rộng giới thiệu ở đây, nhà phát triển có thể tham khảo cấu trúc này để phát triển hợp đồng thông minh của riêng mình.

TON项目开发教程(一):源码角度看如何在TON Chain上创建一个NFT

Việc phát triển DApp trên hệ sinh thái TON thực sự là một việc thú vị, có nhiều khác biệt so với mô hình phát triển EVM, vì vậy tôi sẽ giới thiệu qua một loạt bài viết về cách phát triển DApp trên TON Chain. Hãy cùng nhau học hỏi và tận dụng cơ hội này. Tôi cũng rất hoan nghênh mọi người tương tác với tôi trên twitter, cùng đề xuất những ý tưởng DApp thú vị mới và phát triển chúng cùng nhau.

TON2,93%
Xem bản gốc
Trang này có thể chứa nội dung của bên thứ ba, được cung cấp chỉ nhằm mục đích thông tin (không phải là tuyên bố/bảo đảm) và không được coi là sự chứng thực cho quan điểm của Gate hoặc là lời khuyên về tài chính hoặc chuyên môn. Xem Tuyên bố từ chối trách nhiệm để biết chi tiết.
  • Phần thưởng
  • Bình luận
  • Đăng lại
  • Retweed
Bình luận
0/400
Không có bình luận
  • Ghim