Tác giả: @Web3Mario
Tóm tắt: Tiếp nối bài viết trước về giới thiệu công nghệ TON, tôi đã nghiên cứu sâu các tài liệu phát triển TON chính thức trong giai đoạn này. học tập Nội dung tài liệu hiện tại Nó có vẻ giống một tài liệu phát triển nội bộ hơn, không thân thiện lắm với các nhà phát triển mới. Vì vậy, tôi cố gắng sắp xếp một loạt bài viết về phát triển dự án TON Chain dựa trên quỹ đạo học tập của riêng mình. có thể giúp mọi người nhanh chóng bắt đầu phát triển TON DApp. Có một số trợ giúp. Nếu có sai sót gì trong bài viết, các bạn có thể sửa và cùng nhau học hỏi.
Sự khác biệt giữa phát triển NFT trong EVM và phát triển NFT trên TON Chain
Phát hành FT hoặc NFT thường là nhu cầu cơ bản nhất đối với các nhà phát triển DApp. Vì vậy, tôi cũng sử dụng điều này như một điểm khởi đầu cho việc học. Trước tiên, hãy cùng chúng tôi hiểu những điểm khác biệt sau đây giữa việc phát triển NFT trong nhóm công nghệ EVM và Chuỗi TON. NFT dựa trên EVM thường chọn kế thừa tiêu chuẩn ERC-721. Cái gọi là NFT đề cập đến một loại tài sản được mã hóa không thể phân chia và mỗi tài sản là duy nhất, nghĩa là nó có một số đặc điểm độc quyền nhất định. ERC-721 là mô hình phát triển chung cho loại tài sản này. Chúng ta hãy xem một hợp đồng ERC721 thông thường cần thực hiện những chức năng gì và những thông tin nào cần được ghi lại. Hình ảnh bên dưới là giao diện ERC721. Có thể thấy, không giống như FT, thứ cần nhập vào giao diện chuyển là tokenId cần chuyển chứ không phải số tiền. TokenId này cũng là biểu hiện cơ bản nhất về tính duy nhất của nội dung NFT. Tất nhiên, để mang nhiều thuộc tính hơn, siêu dữ liệu thường được ghi lại cho mỗi tokenId. Siêu dữ liệu này là một liên kết bên ngoài lưu trữ dữ liệu có thể mở rộng khác của NFT, chẳng hạn như. dưới dạng Liên kết tới hình ảnh PFP, tên của một số thuộc tính nhất định, v.v.
Dành cho những ai đã quen với Solidity hoặc quen thuộc Với sự phát triển hướng đối tượng Đối với các nhà đầu tư, thật dễ dàng để thực hiện một hợp đồng thông minh như vậy. Bạn chỉ cần xác định các loại dữ liệu được yêu cầu trong hợp đồng, chẳng hạn như một số mối quan hệ ánh xạ chính và phát triển logic sửa đổi tương ứng cho các dữ liệu này theo yêu cầu. thực hiện một NFT.
Tuy nhiên, mọi thứ đều khác nhau trong TON Chain. Có hai lý do cốt lõi dẫn đến sự khác biệt:
Việc lưu trữ. dữ liệu trong TON được triển khai dựa trên Ô và Ô của cùng một tài khoản được triển khai thông qua biểu đồ chu kỳ có hướng. Điều này có nghĩa là dữ liệu cần lưu trữ không thể phát triển không có ranh giới, vì đối với biểu đồ chu kỳ có hướng, chi phí truy vấn được xác định bởi độ sâu của dữ liệu. Khi độ sâu mở rộng vô hạn, chi phí truy vấn có thể quá cao, dẫn đến. Hợp đồng đang mắc kẹt trong vấn đề bế tắc.
Để theo đuổi hiệu suất xử lý đồng thời cao, TON đã từ bỏ kiến trúc thực thi nối tiếp và thay vào đó áp dụng mô hình phát triển được thiết kế đặc biệt cho tính song song, mô hình Actor, để tái cấu trúc môi trường thực thi. Điều này có tác động. Hợp đồng thông minh chỉ có thể được gọi không đồng bộ bằng cách gửi cái gọi là tin nhắn nội bộ. Lưu ý rằng dù đó là loại sửa đổi trạng thái hay loại cuộc gọi chỉ đọc thì nguyên tắc này cũng cần phải được tuân theo. cần được xem xét cẩn thận Cách xử lý khôi phục dữ liệu nếu cuộc gọi không đồng bộ không thành công.
Tất nhiên, những khác biệt kỹ thuật khác đã được thảo luận chi tiết trong bài viết trước. để tập trung phát triển hợp đồng thông minh nên sẽ không bàn tới. Hai nguyên tắc thiết kế trên tạo nên sự khác biệt lớn giữa việc phát triển hợp đồng thông minh trong TON và EVM. Trong cuộc thảo luận ban đầu, chúng tôi biết rằng hợp đồng NFT cần xác định một số mối quan hệ ánh xạ, tức là ánh xạ, để lưu dữ liệu liên quan đến NFT. Điều quan trọng nhất là chủ sở hữu. Ánh xạ này lưu trữ mối quan hệ ánh xạ của địa chỉ chủ sở hữu NFT tương ứng với một tokenID nhất định, xác định quyền sở hữu NFT. Việc chuyển giao là một sửa đổi về quyền sở hữu. Vì đây là cấu trúc dữ liệu có thể là vô biên về mặt lý thuyết nên cần phải tránh càng nhiều càng tốt. Do đó, chúng tôi chính thức khuyến nghị sử dụng sự tồn tại của cấu trúc dữ liệu không giới hạn làm tiêu chuẩn cho sharding. Nghĩa là, khi có các yêu cầu lưu trữ dữ liệu tương tự, mô hình hợp đồng chủ-nô lệ sẽ được sử dụng thay thế và dữ liệu tương ứng với từng khóa được quản lý bằng cách tạo các hợp đồng phụ. Và quản lý các tham số toàn cầu thông qua hợp đồng chính hoặc giúp xử lý tương tác thông tin nội bộ giữa các hợp đồng phụ.
Điều này có nghĩa là NFT trong TON cũng cần được thiết kế bằng kiến trúc tương tự. Mỗi NFT là một hợp đồng phụ độc lập, giúp lưu dữ liệu độc quyền như địa chỉ chủ sở hữu, siêu dữ liệu, v.v. và dữ liệu toàn cầu. chẳng hạn như tên NFT, ký hiệu, tổng nguồn cung, v.v., được quản lý thông qua hợp đồng chính.
Sau khi làm rõ kiến trúc, bước tiếp theo là giải quyết các yêu cầu chức năng cốt lõi. Vì phương thức hợp đồng chủ-nô này được áp dụng, cần phải làm rõ hợp đồng chính thực hiện chức năng nào và chức năng nào được thực hiện. được thực hiện bởi các hợp đồng phụ và thông tin nội bộ nào được truyền đạt giữa hai bên cũng như cách khôi phục dữ liệu trước đó khi xảy ra lỗi thực thi. Thông thường, trước khi phát triển một dự án quy mô lớn phức tạp, cần phải thông qua sơ đồ lớp và làm rõ luồng thông tin giữa nhau, đồng thời suy nghĩ cẩn thận về logic khôi phục sau khi cuộc gọi nội bộ không thành công. , nhưng nó cũng có thể thực hiện xác minh tương tự.
Tìm hiểu và phát triển hợp đồng thông minh TON từ mã nguồn
TON đã chọn thiết kế ngôn ngữ gõ tĩnh, giống C có tên Func làm ngôn ngữ phát triển hợp đồng thông minh, sau đó bước tiếp theo là Hãy cùng chúng tôi tìm hiểu cách phát triển hợp đồng thông minh TON từ mã nguồn. Tôi đã chọn ví dụ NFT trong tài liệu chính thức của TON để giới thiệu. Các bạn quan tâm có thể tự mình kiểm tra. Trong trường hợp này, một ví dụ TON NFT đơn giản sẽ được triển khai. Chúng ta hãy xem cấu trúc hợp đồng, được chia thành hai hợp đồng chức năng và ba thư viện cần thiết.
Hai hợp đồng chức năng chính này dựa trên Thiết kế dựa trên các nguyên tắc trên, trước tiên chúng ta hãy xem mã của hợp đồng chính nft-collection:
Phần này giới thiệu điểm kiến thức đầu tiên, cách lưu trữ dữ liệu liên tục trong hợp đồng thông minh TON. Chúng tôi biết rằng việc lưu trữ dữ liệu liên tục trong Solidity được EVM tự động xử lý theo loại tham số Trong trường hợp bình thường, các biến trạng thái của hợp đồng thông minh sẽ tự động được duy trì và lưu trữ theo giá trị mới nhất sau khi thực thi và các nhà phát triển không cần phải xem xét quá trình này. Nhưng điều này không xảy ra trong Func. Các nhà phát triển cần phải tự triển khai logic xử lý tương ứng. Tình huống này hơi giống với cách C và C++ cần xem xét quy trình GC, nhưng các ngôn ngữ phát triển mới khác thường tự động hóa phần logic này. . Chúng ta hãy xem mã. Đầu tiên, chúng tôi giới thiệu một số thư viện cần thiết và sau đó chúng tôi thấy rằng hàm đầu tiên Load_data được sử dụng để đọc dữ liệu được lưu trữ liên tục. Logic của nó trước tiên là trả về ô lưu trữ hợp đồng liên tục thông qua get_data. việc này được thực hiện theo tiêu chuẩn Được triển khai bởi thư viện stdlib.fc, một số hàm này thường có thể được sử dụng làm hàm hệ thống.
Loại giá trị trả về của hàm này là ô, là loại ô trong TVM. Trong phần giới thiệu trước, chúng ta đã biết rằng tất cả dữ liệu liên tục trong chuỗi khối TON được lưu trữ trong cây ô. Mỗi ô có tối đa 1023 bit dữ liệu tùy ý và tối đa bốn tham chiếu đến các ô khác. Các ô được sử dụng làm bộ nhớ trong TVM dựa trên ngăn xếp. Những gì được lưu trữ trong ô là dữ liệu được mã hóa nhỏ gọn. Để có được dữ liệu văn bản gốc cụ thể, ô cần được chuyển đổi thành một loại gọi là lát cắt. Ô có thể được chuyển đổi thành loại lát thông qua hàm Begin_parse và sau đó có thể lấy dữ liệu trong ô bằng cách tải các bit dữ liệu và tham chiếu đến các ô khác từ lát cắt. Lưu ý rằng phương thức gọi ở dòng 15 là cú pháp trong một func gọi trực tiếp hàm thứ hai trên giá trị trả về của hàm đầu tiên. Và cuối cùng tải dữ liệu tương ứng theo thứ tự lưu giữ dữ liệu. Lưu ý rằng quy trình này khác với quy trình vững chắc và không được gọi dựa trên hashmap, do đó thứ tự các cuộc gọi không thể bị xáo trộn.
Trong hàm save_data, logic tương tự, ngoại trừ việc đây là một quá trình ngược lại, giới thiệu điểm kiến thức tiếp theo, trình tạo kiểu mới, là loại trình tạo ô. Các bit dữ liệu và tham chiếu đến các ô khác có thể được lưu trữ trong các trình tạo, sau đó có thể được hoàn thiện thành các ô mới. Trước tiên, hãy tạo trình tạo thông qua hàm tiêu chuẩn Begin_cell và lần lượt lưu trữ các hàm liên quan thông qua các hàm liên quan đến cửa hàng. Lưu ý rằng thứ tự gọi ở trên cần phải nhất quán với thứ tự lưu trữ ở đây. Cuối cùng, end_cell được sử dụng để hoàn thành việc xây dựng ô mới. Tại thời điểm này, ô được quản lý trong bộ nhớ. Cuối cùng, thông qua set_data ngoài cùng, việc lưu trữ liên tục của ô có thể được hoàn thành.
Tiếp theo, hãy xem Chức năng liên quan đến kinh doanh, Trước tiên chúng ta cần giới thiệu điểm kiến thức tiếp theo, cách tạo hợp đồng mới thông qua hợp đồng, điểm kiến thức này sẽ được sử dụng thường xuyên trong kiến trúc chủ-nô vừa được giới thiệu. Chúng tôi biết rằng trong TON, các cuộc gọi giữa các hợp đồng thông minh được thực hiện bằng cách gửi tin nhắn nội bộ. Điều này đạt được thông qua thông báo có tên send_raw_message. Lưu ý rằng tham số đầu tiên là ô được mã hóa thông báo và tham số thứ hai là bit nhận dạng, được sử dụng để chỉ ra sự khác biệt trong phương thức thực hiện giao dịch. trong TON. Hiện tại có 3 Chế độ tin nhắn và 3 Cờ tin nhắn cho chế độ thực hiện gửi tin nhắn. Một Chế độ duy nhất có thể được kết hợp với nhiều cờ (có thể không có) để có được chế độ mong muốn. Kết hợp chỉ có nghĩa là điền vào tổng các giá trị của chúng. Bảng mô tả về Chế độ và Cờ được đưa ra dưới đây:
< p>Vì vậy, hãy xem hàm chính đầu tiên, triển khai_nft_item. Như tên cho thấy, đây là hàm được sử dụng để tạo hoặc truyền một phiên bản NFT mới. Sau khi mã hóa một tin nhắn, hãy gửi hợp đồng nội bộ thông qua send_raw_message và chọn Bit cờ gửi của. cờ 1 bị xóa và chỉ phí được chỉ định trong mã hóa mới được sử dụng làm phí gas cho việc thực hiện này. Sau phần giới thiệu ở trên, chúng ta có thể dễ dàng nhận ra rằng quy tắc mã hóa này phải tương ứng với cách tạo hợp đồng thông minh mới. Vì vậy, chúng ta hãy xem nó được thực hiện như thế nào.
Chúng ta xét trực tiếp dòng 51. Hai hàm trên là các hàm phụ dùng để tạo ra thông tin cần thiết cho tin nhắn nên chúng ta sẽ xem xét sau. Đây là quá trình mã hóa để tạo các tin nhắn nội bộ của Smart. hợp đồng, một số số ở giữa thực chất là một số bit nhận dạng, được sử dụng để giải thích các yêu cầu của thông báo nội bộ. Điểm kiến thức tiếp theo được giới thiệu ở đây. và theo Đặt các bit cờ khác nhau để triển khai các thông báo nội bộ cho một số chức năng cụ thể. Hai tình huống sử dụng dễ dàng nhất có thể nghĩ đến là tạo hợp đồng mới và các lệnh gọi hàm hợp đồng được triển khai. Phương thức trên dòng 51 tương ứng với phương thức trước, tạo ra một hợp đồng mục nft mới, chủ yếu được chỉ định thông qua các dòng 55, 56 và 57. Trước hết, dãy số lớn ở dòng 55 là một chuỗi các bit nhận dạng. Lưu ý rằng tham số đầu vào đầu tiên của store_uint là giá trị và tham số thứ hai là độ dài bit, xác định xem thông báo nội bộ có được tạo bởi hợp đồng hay không. , ba bit đánh dấu cuối cùng và các bit giá trị nhị phân tương ứng là 111 (4+2+1 ở dạng thập phân), hai bit đầu tiên cho biết rằng thông báo sẽ đi kèm với dữ liệu StateInit. Dữ liệu này là mã nguồn của dữ liệu. hợp đồng mới và dữ liệu cần thiết để khởi tạo. Bit cờ sau cho biết phần đính kèm thông báo nội bộ, nghĩa là logic liên quan và các tham số bắt buộc dự kiến sẽ được thực thi. Do đó, bạn sẽ thấy dữ liệu ba chữ số không được đặt ở dòng 66 của mã, cho biết lệnh gọi hàm đến hợp đồng đã triển khai. Quy tắc mã hóa chi tiết có thể được tìm thấy ở đây.
Sau đó, 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 quy tắc mã hóa TL-B đã được thiết lập. Ngoài một số bit cờ, nó chủ yếu tuân theo. liên quan đến hai phần của mã hợp đồng mới và dữ liệu khởi tạo. Thứ tự mã hóa dữ liệu cần phải nhất quán với thứ tự lưu trữ của các ô lưu trữ được chỉ định bởi hợp đồng mới. Như bạn có thể thấy ở dòng 36, dữ liệu khởi tạo bao gồm item_index, tương tự như tokenId trong ERC721 và địa chỉ hợp đồng hiện tại được trả về bởi hàm tiêu chuẩn my_address, là Collection_address. Thứ tự của dữ liệu này nhất quán với khai báo trong. mục nft.
Điểm kiến thức tiếp theo là trong TON, tất cả các hợp đồng thông minh chưa được tạo đều có thể tính toán trước các địa chỉ được tạo của chúng. Điều này tương tự như hàm create2 trong Solidity. Việc tạo địa chỉ mới trong TON bao gồm hai phần. Bit nhận dạng chuỗi công việc và giá trị băm của stateinit được ghép với nhau trong phần giới thiệu trước, chúng ta đã biết rằng giá trị trước cần phải được chỉ định để tương ứng với kiến trúc phân chia vô hạn TON. Nó hiện là một giá trị thống nhất. Thu được từ chuỗi công việc chức năng tiêu chuẩn. Cái sau thu được bằng hàm tiêu chuẩn cell_hash. Vì vậy, quay lại ví dụ này, Calculate_nft_item_address là một hàm tính toán trước địa chỉ hợp đồng mới. Và mã hóa giá trị được tạo thành tin nhắn trên dòng 53 làm địa chỉ nhận tin nhắn nội bộ. nft_content tương ứng với lệnh gọi khởi tạo cho hợp đồng đã tạo. Cách triển khai cụ thể sẽ được giới thiệu trong bài viết tiếp theo.
Đối với send_royalty_params, nó cần phải là phản hồi cho thông báo nội bộ của yêu cầu chỉ đọc trong phần giới thiệu trước, chúng tôi đã đặc biệt nhấn mạnh rằng thông báo nội bộ trong TON không chỉ chứa các thao tác có thể sửa đổi dữ liệu. , mà còn ở chế độ chỉ đọc. Thao tác cũng cần được thực hiện theo cách này, vì vậy hợp đồng là một thao tác như vậy. Trước hết, cần lưu ý rằng dòng 67 thể hiện dấu hiệu chức năng gọi lại của người yêu cầu sau khi phản hồi yêu cầu. Viết nó ra dưới dạng dữ liệu được trả về tương ứng là chỉ mục mục và dữ liệu tiền bản quyền tương ứng.
Hãy để chúng tôi giới thiệu điểm kiến thức tiếp theo. Chỉ có hai lối vào hợp nhất cho hợp đồng thông minh trong TON, được đặt tên là recv_internal và recv_external. Một lối vào gọi thống nhất cho tất cả các tin nhắn bên ngoài cần sử dụng phương thức giống như chuyển đổi để đáp ứng các yêu cầu khác nhau dựa trên các bit đánh dấu khác nhau được chỉ định bởi thông báo trong hàm theo yêu cầu. bên trên. Quay lại ví dụ này, trước tiên hãy thực hiện kiểm tra chỗ trống trên tin nhắn, sau đó phân tích thông tin trong tin nhắn tương ứng. Đầu tiên, phân tích cú pháp trên dòng 83 để lấy thông số sender_address. ở đây thuộc về một cú pháp khác. Tôi sẽ không mở rộng về nó ở đây. Tiếp theo, các bit cờ hoạt động được phân tích cú pháp và sau đó các yêu cầu tương ứng được xử lý theo các bit cờ khác nhau. Trong số đó, các hàm trên được gọi lần lượt theo logic nhất định. Ví dụ: phản hồi yêu cầu về tham số tiền bản quyền hoặc tạo một nft mới và tăng chỉ mục chung.
Điểm kiến thức tiếp theo tương ứng với dòng 108. Tôi tin rằng bạn cũng có thể biết logic xử lý của hàm này bằng cách đặt tên cho nó. Tương tự như hàm require trong Solidity, các ngoại lệ được đưa vào Func thông qua tiêu chuẩn. function Throw_unless. , tham số đầu vào đầu tiên là mã lỗi và tham số thứ hai là kiểm tra giá trị Boolean của bit. Nếu bit sai, một ngoại lệ sẽ được đưa ra cùng với mã lỗi. Trong dòng này, Equal_slices được sử dụng để xác định xem sender_address được phân tích ở trên có bằng owner_address của bộ lưu trữ liên tục của hợp đồng hay không và đưa ra phán quyết về quyền.
Cuối cùng, để tạo cấu trúc mã rõ ràng hơn, bắt đầu Có một loạt các chức năng phụ trợ giúp có được thông tin liên tục, sẽ không được giới thiệu ở đây. Các 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.
Việc phát triển DApp trong hệ sinh thái TON thực sự rất thú vị Mọi thứ rất khác so với mô hình phát triển của EVM, vì vậy tôi sẽ giới thiệu cách phát triển DApp trong TON Chain thông qua một loạt bài viết.