Tác giả | @Web3Mario
Tóm tắt: Tiếp theo 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, tôi cảm thấy vẫn còn một số rào cản trong việc học tập. Nội dung tài liệu hiện tại có vẻ giống sự phát triển nội bộ hơn. tài liệu, dành cho sự phát triển ở cấp độ mới bắt đầu. Nó không thân thiện lắm với người đọc, 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 tôi. bắt đầu với việc phát triển TON DApp. 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 Chuỗi TON là gì?
Phát hành FT hoặc NFT thường là nhu cầu cơ bản đố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 những chức năng mà một hợp đồng ERC721 thông thường cần thực hiện 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.
Đối với các nhà phát triển đã quen thuộc với Solidity hoặc quen với hướng đối tượng, có thể dễ dàng triển khai hợp đồng thông minh như vậy 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 tương ứng theo yêu cầu. logic sửa đổi của những dữ liệu này có thể nhận ra NFT.
Tuy nhiên, điều này không giống nhau ở 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 bằng TON được triển khai dựa trên Ô và các Ô 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 đồ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 tạo lại 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, hy vọng sẽ tập trung vào phát triển hợp đồng thông minh nên sẽ không được thảo luận. 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 trong số đó 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ế với 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à quản lý tình hình chung thông qua hợp đồng chính. chẳng hạn như tên NFT, ký hiệu, tổng nguồn cung, v.v.
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õ chức năng nào được thực hiện bởi hợp đồng chính và chức năng nào được thực hiện bởi hợp đồng phụ. và cả hai đều được chuyển qua Thông tin nội bộ nào được truyền đạt và 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. Tất nhiên, việc phát triển NFT ở trên rất đơn giản. , nhưng nó cũng có thể thực hiện xác minh tương tự.
Tìm hiểu cách phát triển hợp đồng thông minh TON từ mã nguồn
TON đã chọn thiết kế một 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 đó, chúng ta hãy 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. Bạn bè 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 được thiết kế theo các nguyên tắc trên. Đầu tiên, chúng ta hãy xem mã của nft-collection hợp đồng chính:
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 xử lý tự động theo loại tham số. Thông thường, các biến trạng thái của hợp đồng thông minh sẽ là. tự động tồn tại và lưu trữ dựa trên giá trị mới nhất sau khi thực thi và 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 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.
Kiểu giá trị trả về của hàm này là ô, là kiểu ô 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, chúng ta hãy xem xét các chức năng liên quan đến nghiệp vụ. Đầu tiên, chúng ta cần giới thiệu điểm kiến thức tiếp theo, cách tạo một hợp đồng mới thông qua một hợp đồng, điều này sẽ được sử dụng thường xuyên trong kiến trúc master-slave 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. Các cài đặt nội bộ khác nhau được thiết lập. 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ả các Chế độ và Cờ được đưa ra dưới đây:
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ợp đồng nội bộ sẽ được gửi qua send_raw_message và cờ gửi được chọn. bit cờ 1 chỉ sử dụng mức phí được chỉ định trong mã hóa 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 hãy nhìn thẳng vào dòng 51. Hai hàm trên là các hàm phụ trợ dùng để tạo ra thông tin cần thiết cho tin nhắn, vì vậy chúng ta sẽ xem xét nó sau. Đây là quá trình mã hóa để tạo các tin nhắn nội bộ của một số hợp đồng thông minh. ở giữa thực tế là một số bit nhận dạng được sử dụng để mô tả 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. TON đã chọn ngôn ngữ nhị phân có tên TL-B để mô tả phương thức thực thi thông báo và triển khai nó bằng cách đặt cờ khác. bit. Để biết thông tin nội bộ về các chức năng cụ thể nhất định, 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 chức năng 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 bởi 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à bit giá trị nhị phân tương ứng là 111 (thập phân là 4+2+1), 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 liên quan đến hai phần của hợp đồng mới. mã và Và khởi tạo dữ liệu. 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 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à hàm băm của stateinit. giá trị được ghép lại 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 vào tin nhắ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 cả các thao tác chỉ đọc. cần phải được thực hiện theo cách này. Thực hiện, vì vậy hợp đồng này là một hoạt động như vậy. Trước hết, điều đáng chú ý là dòng 67 thể hiện dấu hiệu của 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. dữ liệu được trả về, là chỉ mục mặt hàng được yêu cầu và dữ liệu tiền bản quyền tương ứng.
Tiếp theo, chúng tôi xin 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. phát triển Người dùng 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. 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 nghĩ 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 hàm tiêu chuẩn Throw_unless. mã lỗi, 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, bằng_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, để làm cho cấu trúc mã rõ ràng hơn, một loạt chức năng phụ trợ đã được phát triển để giúp lấy thông tin về tính bền vững, những thông tin này 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ị và rất khác 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. Cùng học hỏi với mọi người và nắm bắt làn sóng cơ hội này. Bạn cũng có thể tương tác với tôi trên twitter để tìm hiểu một số ý tưởng dapp mới và thú vị và cùng nhau phát triển chúng.