Sui.

Bài viết

Chia sẻ kiến thức của bạn.

article banner.
harry phan.
Apr 13, 2025
Bài Viết

Cơ chế kiểm soát và nhận truy cập đối tượng

Đây là phần 2 của loạt “Đối tượng cha mẹ-con trong Sui Move”. Bạn có thể đọc phần 1 tại đây

Chuyển giao kiểm soát truy cập đối tượng: :nhận Cơ chế

Vì vậy, bạn đã đặt một đối tượngXbên trongPcha mẹ (bằng cách chuyển X sang ID của P) - làm thế nào để bạn lấy nó ra hoặc sử dụng nó? 🤔 Đó là nơi cơ chế nhận đặc biệt của Sui xuất hiện.

Khi một đối tượng được chuyển đến cha mẹ, nó không tự động bật ra. Nó nằm ở đó, thuộc sở hữu củaP. Để * sử dụng* hoặc* hoặc* đối tượng con đó trong một giao dịch, bạn phảinhậnnó. Sui cung cấp một cách có cấu trúc để thực hiện việc này bằng cách sử dụng **Nhận vé và chức năng chuyển: :nhận.

##Vé nhận tiên

Hãy nghĩ về Nhận như một phiếu yêu cầu cho một đối tượng con thuộc loại T. Trong một giao dịch, thay vì chuyển trực tiếp đối tượng con (mà bạn chưa sở hữu) cho một hàm, bạn chuyển một Receiving - về cơ bản là tham chiếu đến “đối tượng có ID Y thuộc sở hữu của cha mẹ X”. Nhận này là một cấu trúc Move đặc biệt mang ID, phiên bản và bản phân tích của đối tượng được nhận. Nó chỉ có khả năng thả, nghĩa là nó có thể tồn tại phù du nhưng không thể được lưu trữ liên tục. Nói cách khác, đó là một vé sử dụng một lần trong một giao dịch.

Làm thế nào để bạn nhận được một nhận? Thông thường, bằng cách thực hiện chuyển nhượng. Trong khối giao dịch có thể lập trình (PTB), một bước có thể chuyển đối tượngCsangPcha mẹ, tạo ra phiếu nhận mà bước tiếp theo có thể sử dụng. Nếu đứa trẻ đã ngồi trong vai cha mẹ từ một giao dịch trước đó, bạn có thể cung cấp Thông tin nhận làm đầu vào cho một giao dịch mới (Sui SDK/CLI cho phép bạn chỉ định đối tượng con bằng ID và cha mẹ của nó để tạo vé).

Quan trọng: Bản thân việc tiếp nhận không phải là đối tượng - nó chưa cho bạn quyền sở hữu. Nó chỉ báo hiệu rằng “đối tượng loại T với ID này thuộc sở hữu của cha mẹ đó, và tôi dự định lấy nó.” Để thực sự lấy đối tượng, bạn phải gọi transfer: :receiver:


module example::toy_box {
    use sui::transfer::{Self, Receiving};

    struct Toy has key { id: UID, name: vector<u8> }
    struct Box has key { id: UID }

    /// Remove a Toy child from a Box, returning the Toy to the caller.
    public entry fun take_toy(box: &mut Box, toy_ticket: Receiving<Toy>): Toy {
        // Use the parent's UID and the Receiving ticket to get the Toy
        let toy = transfer::receive(&mut box.id, toy_ticket);
        // Now `toy` is an owned value we can return (or transfer to someone).
        toy
    }
}

Trong take_toy, toy_ticket: Receiving đại diện cho Toy thuộc về hộp. Bằng cách gọi transfer: :receiver (&mut box.id, toy_ticket), chúng ta gọi logic gốc của Sui để thực sự lấy đối tượng Toy ra khỏi hộp. Điều này làm một số điều quan trọng:

  • Nó** xác nhận**khi chạy rằng toy_ticket thực sự tham chiếu đến một đối tượng hiện thuộc sở hữu của hộp (sử dụng UID của cha mẹ). Nếu một cái gì đó không khớp (nhầm cha mẹ hoặc đối tượng không thực sự ở đó), nó sẽ bị hủy bỏ.
  • Sau đó, nó trả về đối tượng Toy thực tế dưới dạng giá trị sở hữu trong giao dịch, nghĩa là bây giờ Đồ chơi nằm trong tầm kiểm soát của hàm của chúng tôi.

Lưu ý rằng chúng tôi phải chuyển qua &mut box.id. Sui thực thi rằng chúng tôi có một tham chiếu có thể thay đổi đến UID của phụ huynh**để nhận cuộc gọi.

Đây là một điều khiển truy cập thông minh: chỉ mô-đun có thể tạo ra & mut UID của cha mẹ mới có thể cho phép nhận. Thông thường, mô-đun định nghĩa của kiểu cha mẹ sẽ hiển thị một hàm như take_toy mà các cuộc gọi nội bộ nhận được. Nếu mô-đun cha không hiển thị bất kỳ hàm nào cung cấp UID & mut (trực tiếp hoặc gián tiếp), thì không mã bên ngoài nào có thể lấy con của nó. Bằng cách này, mô-đun của phụ huynh kiểm soát cách thức và thời điểm trẻ em có thể được truy cập.

Trong ví dụ, Box có trường id: UID. Vì take_toy nằm trong cùng một mô-đun, nó có thể mượn &mut box.id. Các mô-đun hoặc giao dịch bên ngoài có thể gọi take_toy (box_obj, ticket) nhưng chúng không thể tự gọi transfer: :receiver trên Box vì box.id là riêng tư.

**Mẫu này đảm bảo chỉ mã được ủy quyền mới có thể truy xuất trẻ em.**✅

Còn đối tượng lồng nhau thì sao? Nếu Toy theo nghĩa đen là một cánh đồng bên trong Hộp (ví dụ Box {id, toy: Toy}), chúng tôi sẽ không cần bất kỳ nhận nào - đồ chơi sẽ có thể truy cập bất cứ khi nào bạn có & mut Box. Nhưng điều đó cũng có nghĩa là loại bỏ nó hoặc xử lý nó một cách riêng biệt khó hơn (nó giống như một phần của hộp). Với các đồ vật trẻ em, chúng tôi tách bộ lưu trữ: đồ chơi tách biệt và phải được lấy ra một cách rõ ràng. Sự rõ ràng này là lý do tại sao Sui yêu cầu vé nhận và nhận cuộc gọi - điều này khiến việc lấy trẻ trở thành một hành động được ủy quyền.

Yêu cầu tham chiếu có thể thay đổi: Bạn có thể tự hỏi, tại sao &mut UID chứ không chỉ &UID? Có thể thay đổi đảm bảo cha mẹ bị khóa trong quá trình nhận, ngăn chặn sửa đổi đồng thời và đảm bảo người gọi thực sự có quyền sửa đổi cha mẹ đó (thường ngụ ý rằng họ là chủ sở hữu). Đó là một phần của kiểm tra quyền sở hữu năng động của Sui - bằng cách nhận một khoản vay có thể thay đổi từ UID của cha mẹ, Sui đảm bảo không có giao dịch hoặc hành động song song nào khác có thể can thiệp trong khi bạn rút đứa trẻ ra. Nó giống như khóa cửa của cha mẹ trước khi loại bỏ nội dung.

Ví dụ sử dụng trong khối giao dịch: Giả sử một đối tượng Box thuộc sở hữu của Alice, và cô ấy có một đối tượng Toy mà cô ấy muốn đặt vào hộp và sau đó có thể xảy ra Hãy lấy nó ra sau. Đây là cách nó có thể lặn k:

-Đính kèm đồ chơi vào hộp: Alice gọi chuyển: :public_transfer (toy, @); trong PTB. Điều này chuyển đồ chơi dưới hộp (chúng tôi sử dụng public_transfer ở đây vì đó là bối cảnh giao dịch - sẽ sớm biết thêm về điều đó). Bây giờ đồ chơi là một đứa trẻ của hộp. -Trong cùng một giao dịch hoặc một giao dịch khác, truy xuất đồ chơi: Alice gọi example: :toy_box: :take_toy (box_obj,) trong đó Receiving đề cập đến đồ chơi. Dưới mui xe, take_toy gọi nhận, xác minh mối quan hệ và trả về Toy. Bây giờ Toy sẽ là đầu ra của giao dịch, thường kết thúc trở lại dưới địa chỉ của Alice (vì chúng tôi trả về nó từ một hàm nhập).

Những điểm rút ra chính:

  • Các đối tượng con không thể truy cập được theo mặc định; bạn cần vé nhận và chức năng thích hợp để đưa chúng ra.
  • Mô-đun của cha mẹ quyết định cách bạn có thể truy xuất (bằng cách cung cấp một hàm với & mut UID).
  • transfer: :receiver được sử dụng * trong mô-đun xác định của cha đẹ* cho các đối tượng của mô-đun đó hoặc bạn bè của nó. Nếu loại của đứa trẻ được định nghĩa ở nơi khác, bạn sẽ cần một cách tiếp cận khác (nhập public_receiver...).

Trước khi tiếp tục, một chi tiết nữa: nếu một đối tượng loại T chỉ có khả năng khóa (không có cửa hàng), Sui coi nó như bị hạn chế hơn một chút. Các đối tượng như đó* không thể nhận được bằng mã chung bên ngoài mô-đun của chúng. Trong thực tế, điều này có nghĩa là nếu T chỉ có khóa và trở thành con, bạn sẽ cần xử lý việc truy xuất nó trong mô-đun riêng của nó hoặc mô-đun của cha mẹ bằng một quy tắc tùy chỉnh. Nếu T cũng có cửa hàng, chúng tôi có tính linh hoạt hơn thông qua public_receiver. Chúng ta hãy khám phá điều đó tiếp theo.

  • Sui
3
Chia sẻ
Bình luận
.

Sui is a Layer 1 protocol blockchain designed as the first internet-scale programmable blockchain platform.

368Bài viết503Câu trả lời
Sui.X.Peera.

Kiếm phần của bạn từ 1000 Sui

Tích lũy điểm danh tiếng và nhận phần thưởng khi giúp cộng đồng Sui phát triển.

Chiến dịch phần thưởngTháng Bảy