Move ra đời trong giai đoạn đầu của dự án Libra vào năm 2018 - hai nhà sáng lập Mysten (Evan và tôi) cũng chính là nhóm sáng lập Libra. Trước khi chúng tôi quyết định tạo một ngôn ngữ mới, nhóm Libra ban đầu đã nghiên cứu chuyên sâu các trường hợp và ngôn ngữ sử dụng hợp đồng thông minh hiện có để hiểu những gì các nhà phát triển muốn làm và những điểm mà các ngôn ngữ hiện tại không cung cấp được. Vấn đề chính mà chúng tôi phát hiện ra là hợp đồng thông minh đều liên quan đến tài sản và kiểm soát quyền truy cập, tuy nhiên các ngôn ngữ hợp đồng thông minh ban đầu thiếu sự thể hiện loại/giá trị cho cả hai. Giả thuyết của chúng tôi là nếu chúng tôi cung cấp những kiến thức trừu tượng hạng nhất cho các khái niệm chính này, chúng tôi có thể cải thiện đáng kể tính bảo mật của hợp đồng thông minh và năng suất của người lập trình hợp đồng thông minh - việc có vốn từ vựng phù hợp cho nhiệm vụ trong tay có thể tạo ra sự khác biệt. Trong những năm qua, nhiều người đã đóng góp vào việc thiết kế và triển khai Move khi ngôn ngữ này phát triển từ ý tưởng chính thành ngôn ngữ hợp đồng thông minh không phụ thuộc vào nền tảng với mục tiêu táo bạo là trở thành "JavaScript của web3".
Hôm nay, chúng tôi vui mừng thông báo một cột mốc quan trọng trong việc tích hợp Move và Sui. Chức năng của Sui Move hoàn chỉnh, được hỗ trợ bởi các công cụ nâng cao và có tài liệu cũng như ví dụ phong phú, bao gồm các phần sau:
Chuỗi hướng dẫn lập trình sử dụng đối tượng Sui Move. Tài liệu phát triển về kiến thức cơ bản, mẫu thiết kế và mẫu của Sui Move. Một plug-in nâng cao VSCode do nhóm Mysten Move phát triển, hỗ trợ phân tích mã và chẩn đoán lỗi và tích hợp. việc xây dựng, thử nghiệm và quản lý gói Move, tạo tài liệu và trình xác thực Move được tích hợp với sui CLI.
Điều gì khiến Move trở nên độc đáo
Move là một ngôn ngữ nhúng đa nền tảng. Bản thân cú pháp cốt lõi rất đơn giản: nó có các khái niệm phổ biến như cấu trúc, số nguyên và địa chỉ, nhưng nó không có các khái niệm dành riêng cho blockchain như tài khoản và giao dịch), thời gian, mật mã, v.v. Các chức năng này phải được cung cấp bởi nền tảng blockchain được tích hợp với Move. Điều quan trọng là các chuỗi khối này không yêu cầu các nhánh Move riêng - mỗi nền tảng sử dụng cùng một máy ảo Move, trình xác thực mã byte, trình biên dịch, trình xác thực, trình quản lý gói và CLI, nhưng bằng cách xây dựng trên Mã trên các thành phần cốt lõi này để thêm chức năng dành riêng cho chuỗi khối . Diệm là blockchain đầu tiên nhúng Move và các blockchain dựa trên Move tiếp theo (bao gồm 0L, StarCoin và Aptos) hầu hết áp dụng cách tiếp cận kiểu Diem. Mặc dù Move kiểu Diem có một số phẩm chất tuyệt vời, nhưng cả bản chất được cấp phép của Diem và các chi tiết triển khai nhất định của chuỗi khối Diem (đặc biệt là mô hình lưu trữ) khiến một số trường hợp sử dụng hợp đồng thông minh cơ bản khó thực hiện. Đặc biệt, các thiết kế ban đầu của Move and Diem có trước sự bùng nổ về mức độ phổ biến của NFT và có một số điểm kỳ quặc khiến việc triển khai các trường hợp sử dụng liên quan đến NFT trở nên đặc biệt khó khăn. Trong bài đăng này, chúng tôi sẽ trình bày các vấn đề với việc nhúng Move kiểu Diem ban đầu thông qua ba ví dụ như vậy và mô tả cách chúng tôi giải quyết vấn đề này trong Sui Move. Chúng tôi giả định có một số hiểu biết cơ bản về Move, nhưng hy vọng những điểm chính này sẽ dễ hiểu đối với bất kỳ ai có nền tảng lập trình.
Trải nghiệm mượt mà khi tạo nội dung trên quy mô lớn
Khả năng tạo và phân phối nội dung hàng loạt là rất quan trọng đối với cả người dùng web3 mới tham gia và thu hút người dùng web3. Có thể một người phát trực tiếp trên Twitch muốn phân phối NFT kỷ niệm, một người sáng tạo muốn gửi vé tham dự một sự kiện đặc biệt hoặc một nhà phát triển trò chơi muốn phát sóng các vật phẩm mới cho tất cả người chơi. Đây là một nỗ lực (không thành công) trong việc viết mã để đúc hàng loạt tài sản theo phong cách Diễm. Mã này lấy đầu vào là vectơ địa chỉ người nhận, tạo nội dung cho mỗi người nhận và cố gắng chuyển nội dung đó.
Theo động thái kiểu Diệm, kho lưu trữ toàn cầu được nhập theo cặp (địa chỉ, tên loại) - nghĩa là mỗi địa chỉ có thể lưu trữ tối đa một tài sản thuộc một loại cụ thể. Do đó, move_to(receiverient, CoolAsset { ...} cố gắng di chuyển CoolAsset bằng cách lưu trữ nó tại địa chỉ của người nhận. Tuy nhiên, mã này không biên dịch được tại dòng move_to(receiverient, ...). Câu hỏi chính là , trong Di chuyển kiểu Diem, bạn không thể gửi giá trị loại CoolAsset đến địa chỉ A, trừ khi giao dịch được gửi từ địa chỉ khác A và chủ sở hữu tài khoản được tạo trong A gửi giao dịch và chọn nhận CoolAsset một cách rõ ràng. Đây là hai giao dịch, chỉ để nhận một tài sản! Quyết định thực hiện điều này có ý nghĩa đối với Diễm, đây là một hệ thống được cấp phép cần hạn chế cẩn thận việc tạo tài khoản và ngăn chặn tài khoản bị giới hạn bởi hệ thống lưu trữ. Tuy nhiên, thay vì nắm giữ quá nhiều tài sản, đối với một hệ thống mở muốn sử dụng phân bổ tài sản làm cơ chế giới thiệu hoặc nói chung chỉ cho phép tài sản lưu chuyển tự do giữa những người dùng, giống như cách họ làm trên Ethereum và các chuỗi khối tương tự. .
Mã để thực hiện chức năng tương tự trong Sui Move như sau:
Bộ nhớ toàn cầu của Sui Move được khóa bằng ID đối tượng. Mọi cấu trúc có cặp khóa-giá trị là một "đối tượng Sui", phải có trường id duy nhất trên toàn cầu. Sui Move giới thiệu một nguyên hàm truyền có thể được sử dụng trên bất kỳ đối tượng Sui nào, thay vì sử dụng cấu trúc move_to hạn chế. Dưới lớp vỏ bọc, nguyên thủy này ánh xạ id tới CoolAsset trong bộ lưu trữ toàn cầu và thêm siêu dữ liệu để cho biết rằng giá trị đó thuộc sở hữu của người nhận. Một đặc tính thú vị của phiên bản Sui của mass_mint là nó được hoán đổi với tất cả các giao dịch khác (bao gồm cả các giao dịch khác gọi mass_mint!). Thời gian chạy Sui sẽ nhận thấy điều này và gửi các giao dịch gọi chức năng này thông qua "đường dẫn nhanh" phát sóng đồng thuận Byzantine không yêu cầu sự đồng thuận. Các giao dịch như vậy có thể được cam kết hoặc thực hiện song song. Điều này không đòi hỏi nỗ lực từ phía lập trình viên (họ chỉ viết mã ở trên và thời gian chạy xử lý phần còn lại.) Có lẽ một cách tinh tế, đây không phải là trường hợp với biến thể Diem của mã này -- mặc dù mã ở trên hoạt động, vẫn tồn tại và các cuộc gọi guid::create sẽ tạo ra các điểm tranh chấp với các giao dịch khác tạo GUID hoặc chạm vào tài nguyên tài khoản. Trong một số trường hợp, có thể viết lại mã Di chuyển kiểu Điểm để tránh tranh luận, nhưng nhiều cách viết Di chuyển kiểu Điểm thông thường đưa ra những trở ngại nhỏ cản trở việc thực hiện song song.
Quyền sở hữu và chuyển giao tài sản địa phương
Hãy mở rộng mã Move kiểu Diem bằng một giải pháp thực sự biên dịch và chạy. Cách thông thường để thực hiện điều này là "mẫu trình bao bọc": vì Bob không thể di chuyển CoolAsset trực tiếp đến địa chỉ của Alice, nên chúng tôi yêu cầu Alice "chọn tham gia" để nhận CoolAsset, trước tiên xuất bản loại trình bao bọc CoolAssetStore, chứa loại Bộ sưu tập (bàn). Alice có thể thực hiện việc này bằng cách gọi hàm opt_in. Sau đó, chúng tôi thêm mã cho phép Bob di chuyển CoolAsset từ CoolAssetStore của anh ấy sang CoolAssetStore của Alice. Trong mã này, hãy thêm một điểm bổ sung: chúng tôi sẽ chỉ cho phép chuyển CoolAssets nếu chúng được tạo cách đây ít nhất 30 ngày. Loại chính sách này rất quan trọng đối với những người sáng tạo (chẳng hạn như) muốn ngăn những kẻ đầu cơ mua/thổi phồng vé sự kiện để những người hâm mộ thực sự có thể mua được những tấm vé đó ở mức giá hợp lý dễ dàng hơn.
Mã này hợp lệ. Nhưng đây là một cách khá phức tạp để hoàn thành nhiệm vụ chuyển tài sản từ Alice sang Bob! Chúng ta hãy xem một cách triển khai khác của Sui Move
Mã này ngắn hơn nhiều. Điều quan trọng cần lưu ý ở đây là cool_transfer là một hàm nhập (có nghĩa là nó có thể được gọi trực tiếp bởi thời gian chạy Sui thông qua một giao dịch), tuy nhiên, nó có tham số loại CoolAsset làm đầu vào. Đây lại là điều kỳ diệu của Sui Runtime. Một giao dịch bao gồm một bộ ID đối tượng mà nó muốn hoạt động và khi Sui Runtime:
Phân tích ID thành một giá trị đối tượng (không cần các phần loan_global_mut và table_remove trong mã kiểu Diem ở trên). Kiểm tra xem đối tượng có thuộc quyền sở hữu của người gửi giao dịch hay không (loại bỏ sự cần thiết của phần signer::address_of và mã liên quan ở trên). Phần này đặc biệt thú vị và chúng tôi sẽ giải thích sớm: Trong Sui, kiểm tra quyền sở hữu đối tượng an toàn là một phần của thời gian chạy. Kiểm tra loại giá trị đối tượng theo loại tham số của hàm được gọi cool_transfer. để tham số cool_transfer và gọi hàm
Điều này cho phép các lập trình viên của Sui Move bỏ qua mẫu logic "Rút tiền" và chuyển thẳng sang phần thú vị: kiểm tra chính sách hết hạn 30 ngày. Tương tự, phần "gửi tiền" cũng được đơn giản hóa rất nhiều với cấu trúc chuyển Sui Move đã giải thích ở trên. Cuối cùng, không cần phải giới thiệu loại trình bao bọc với bộ sưu tập nội bộ như CoolAssetStore - cửa hàng toàn cầu Sui được lập chỉ mục id cho phép một địa chỉ lưu trữ bất kỳ số lượng giá trị nào của một loại nhất định. Một điểm khác biệt cần chỉ ra là cool_transfer kiểu Diem có 5 cách hủy (tức là không thành công và tính phí gas cho người dùng mà không hoàn tất chuyển khoản), trong khi Sui Move cool_transfer chỉ có 1 cách hủy: khi vi phạm chính sách 30 ngày. Việc giảm tải việc kiểm tra quyền sở hữu đối tượng trong thời gian chạy là một thắng lợi lớn, không chỉ về mặt công thái học mà còn về mặt bảo mật. Việc triển khai an toàn ở cấp độ thời gian chạy sẽ ngăn ngừa các lỗi khi triển khai các kiểm tra này trên cấu trúc (hoặc hoàn toàn quên chúng!). Cuối cùng, hãy lưu ý rằng chữ ký hàm điểm vào của Sui Move cool_transfer( assets: CoolAsset, ...) cung cấp cho chúng ta rất nhiều thông tin về chức năng của hàm này (nó mờ hơn chữ ký hàm kiểu Diem). Chúng ta có thể nghĩ rằng hàm này đang yêu cầu quyền chuyển CoolAsset, trong khi hàm khác f(asset: &mut CoolAsset, ...) đang yêu cầu quyền ghi (nhưng không chuyển) CoolAsset và g(asset: &CoolAsset, ..) chỉ là xin phép đọc thôi.
Vì thông tin này có sẵn trực tiếp trong chữ ký hàm (không cần thực thi hoặc phân tích tĩnh!), nên nó có thể được sử dụng trực tiếp bởi ví và các công cụ máy khách khác. Trong Sui Wallet, chúng tôi đang nghiên cứu các yêu cầu chữ ký mà con người có thể đọc được, tận dụng các chữ ký chức năng có cấu trúc này để cung cấp lời nhắc cấp quyền theo phong cách iOS/Android cho người dùng. Ví có thể nói những điều như: "Giao dịch này yêu cầu quyền đọc CoolAsset của bạn, ghi vào AssetCollection và chuyển ConcertTicket của bạn. Tiếp tục?".
Các yêu cầu chữ ký mà con người có thể đọc được giải quyết một vectơ tấn công quy mô lớn hiện có trên nhiều nền tảng hiện có, bao gồm cả những nền tảng sử dụng Move! kiểu Diem!, nơi người dùng ví phải ký các giao dịch một cách mù quáng mà không hiểu tác động mà chúng có thể gây ra. Chúng tôi tin rằng việc làm cho trải nghiệm ví ít rủi ro hơn là một bước quan trọng trong việc thúc đẩy việc áp dụng phổ biến ví tiền điện tử và đã thiết kế Sui Move để hỗ trợ mục tiêu này bằng cách kích hoạt các tính năng như yêu cầu chữ ký mà con người có thể đọc được.
Gói các tài sản khác nhau
Cuối cùng, hãy xem xét một ví dụ về việc gộp các loại nội dung khác nhau. Đây là trường hợp sử dụng khá phổ biến: các lập trình viên có thể muốn đóng gói các loại NFT khác nhau vào một bộ sưu tập, gộp các mặt hàng lại với nhau để bán trên thị trường hoặc thêm tệp đính kèm vào các mặt hàng hiện có. Giả sử chúng ta có tình huống sau:
Alice xác định đối tượng nhân vật để sử dụng trong trò chơi. Alice muốn hỗ trợ việc trang trí nhân vật của mình bằng các loại phụ kiện khác nhau của bên thứ ba được tạo ra sau này. Bất kỳ ai cũng có thể tạo phụ kiện nhưng chủ nhân của nhân vật phải quyết định xem có nên thêm phụ kiện hay không. Việc chuyển nhân vật sẽ tự động chuyển tất cả các phụ kiện của nhân vật đó.
Lần này, hãy bắt đầu với mã dành cho Sui Move. Chúng ta sẽ tận dụng một khía cạnh khác của chức năng sở hữu đối tượng được tích hợp trong thời gian chạy Sui: một đối tượng có thể được sở hữu bởi một đối tượng khác. Mỗi đối tượng có một chủ sở hữu duy nhất, nhưng một đối tượng cha có thể có số lượng đối tượng con bất kỳ. Mối quan hệ đối tượng cha/con được tạo bằng cách sử dụng hàm transfer_to_object, đây là đối tượng liên quan của hàm truyền được giới thiệu ở trên.
Trong mã này, mô-đun vai trò bao gồm chức năng truy cập cho phép chủ sở hữu vai trò thêm đối tượng phụ kiện thuộc bất kỳ loại nào làm đối tượng con. Điều này cho phép Bob và Clarissa tạo ra các loại đồ trang trí của riêng họ với các đặc tính và chức năng khác nhau mà Alice không có nhưng được xây dựng dựa trên những gì Alice đã làm. Ví dụ, áo của Bob chỉ có thể được trang bị nếu đó là màu sắc yêu thích của nhân vật và thanh kiếm của Clarissa chỉ có thể được sử dụng nếu nhân vật đủ mạnh. Sau đây là một minh chứng thực tế của chiêu Diệm, nhưng chưa có chiêu nào thành công, tức là chiêu Diệm không thể đạt được kịch bản trên.
Có thể thấy các vấn đề trong Move kiểu Diệm như sau
Chỉ các bộ sưu tập cùng loại mới được hỗ trợ (như thử nghiệm đầu tiên cho thấy), nhưng về cơ bản, các phụ kiện không phải là một loại đối tượng. Mối quan hệ giữa các đối tượng chỉ có thể đạt được thông qua "đóng gói" (tức là lưu trữ một đối tượng bên trong một đối tượng khác); tập hợp các đối tượng có thể được bao bọc phải được xác định trước (như trong lần thử thứ hai) hoặc được thêm vào theo cách tạm thời và thành phần đối tượng bổ sung không được hỗ trợ (như trong thử nghiệm thứ ba).
Tóm tắt
Sui là nền tảng đầu tiên có sự khác biệt đáng kể so với thiết kế ban đầu của Diệm trong cách sử dụng Move. Thiết kế một sự kết hợp tận dụng tối đa Move và các khả năng độc đáo của nền tảng vừa là nghệ thuật vừa là khoa học, đòi hỏi sự hiểu biết sâu sắc về ngôn ngữ Move và các khả năng của chuỗi khối cơ bản. Chúng tôi rất vui mừng về tiến độ mà Sui Move đang đạt được cũng như những trường hợp sử dụng mới mà nó sẽ mang lại! ". [1] Một lập luận khác ủng hộ chính sách Di chuyển kiểu Diệm là "bạn phải chọn tham gia trước khi có thể nhận một loại tài sản cụ thể". Đây là một cơ chế tốt để ngăn chặn thư rác. Tuy nhiên, chúng tôi nghĩ đến việc ngăn chặn thư rác Vì thuộc lớp ứng dụng, thay vì yêu cầu người dùng gửi các giao dịch tốn tiền thật để chọn tham gia nhận tài sản, thư rác có thể được xử lý dễ dàng ở (ví dụ) ở cấp ví với các chính sách phong phú do người dùng xác định và bộ lọc thư rác tự động. .


