Beitrag
Teile dein Wissen.
Objektzugriffskontrolle und Empfangsmechanik
Dies ist Teil 2 der Serie „Eltern-Kind-Objekte in Sui Move“. Teil 1 können Sie hier lesen
Übertragung der Objektzugriffskontrolle: :receive Mechanics
Sie haben also ein ObjektXin ein übergeordnetesPgesteckt (indem Sie X auf die ID von P übertragen haben) — wie holen Sie es wieder heraus oder verwenden es? 🤔 An dieser Stelle kommt Suis spezieller Empfangsmechanismus ins Spiel.
Wenn ein Objekt an ein übergeordnetes Objekt übertragen wird, springt es nicht automatisch heraus. Es befindet sich dort und gehörtP. Um dieses untergeordnete Objekt in einer Transaktion verwenden oder entfernen zu können, müssen Sie esempfangen.
Stellen Sie sich Wareneingang
Wie bekommt man eine Quittung
Wichtig: Eine Empfangsfunktion
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
}
}
In take_toy
- Esüberprüftzur Laufzeit, ob das toy_ticket tatsächlich auf ein Objekt verweist, das derzeit der Box gehört (unter Verwendung der UID des übergeordneten Objekts). Wenn etwas nicht passt (falsches übergeordnetes Objekt oder Objekt, das nicht wirklich vorhanden ist), wird der Vorgang abgebrochen.
- Es gibt dann das eigentliche Toy-Objekt als eigenen Wert in der Transaktion zurück, was bedeutet, dass das Spielzeug jetzt unter der Kontrolle unserer Funktion steht.
Beachten Sie, dass wir &mut box.id übergeben mussten. Sui erzwingt, dass wir eineveränderbare Referenz auf die UIDdes Elternteils haben, um den Empfang aufzurufen.
Das ist eine clevere Zugriffskontrolle: Nur das Modul, das eine &mut-UID des Elternteils erzeugen kann, kann den Empfang zulassen. Normalerweise stellt das Definitionsmodul des übergeordneten Typs eine Funktion wie take_toy bereit, die interne Aufrufe empfangen. Wenn das übergeordnete Modul keine Funktion bereitstellt, die eine &mut-UID ausgibt (direkt oder indirekt), kann kein externer Code seine untergeordneten Elemente abrufen. Auf diese Weise steuert das Modul der Eltern, wie und wann auf Kinder zugegriffen werden kann.
Im Beispiel hat Box ein Feld id: UID. Da sich take_toy im selben Modul befindet, kann es &mut box.id ausleihen. Externe Module oder Transaktionen können take_toy (box_obj, ticket) aufrufen, aber sie können nicht selbst transfer: :receive auf Box aufrufen, da box.id privat ist.
**Dieses Muster stellt sicher, dass nur autorisierter Code Kinder abrufen kann.**✅
Was ist mit verschachtelten Objekten? Wenn Toy buchstäblich ein Feld in der Box wäre (sagen wir Box {id, toy: Toy}), bräuchten wir keinen Empfang — das Spielzeug wäre immer zugänglich, wenn Sie &mut Box haben. Das bedeutet aber auch, dass es schwieriger ist, es zu entfernen oder es separat zu behandeln (es ist wie ein Teil der Box). Bei Objekten für Kinder entkoppeln wir den Stauraum: Das Spielzeug ist separat und muss explizit herausgenommen werden. Diese Deutlichkeit ist der Grund, warum Sui die Option „Ticket annehmen“ und „Anruf annehmen“ verlangt — so wird das Abrufen von Kindern zu einer autorisierten Aktion.
Veränderbare Referenzanforderung: Sie fragen sich vielleicht, warum &mut UID und nicht nur &UID? Mutable stellt sicher, dass das übergeordnete Objekt während des Empfangsvorgangs gesperrt ist, wodurch gleichzeitige Änderungen verhindert werden und sichergestellt wird, dass der Anrufer tatsächlich das Recht hat, dieses übergeordnete Objekt zu ändern (was normalerweise bedeutet, dass er der Eigentümer ist). Das ist Teil der dynamischen Eigentumsüberprüfung von Sui. Indem Sui die UID des Elternteils veränderbar ausnutzt, garantiert Sui, dass keine andere Transaktion oder parallele Aktion stören kann, während Sie das Kind herausziehen. Es ist ein bisschen so, als würde man die Tür der Eltern verriegeln, bevor man den Inhalt herausnimmt.
Beispiel für die Verwendung in einem Transaktionsblock: Angenommen, ein Box-Objekt gehört Alice, und sie hat ein Toy-Objekt, das sie in die Box legen möchte und dann vielleicht Also nimm es später heraus. So könnte es aussehen, okay:
-Spielzeug an der Kiste befestigen: Alice ruft transfer: :public_transfer (toy, @
Wichtige Erkenntnisse:
- Auf untergeordnete Objekte kann standardmäßig nicht zugegriffen werden. Sie benötigen ein
Empfangsticket und eine entsprechende Funktion, um sie herauszuholen. — Das übergeordnete Modul entscheidet, wie Sie Daten abrufen können (indem Sie eine Funktion mit &mut UID bereitstellen). - transfer: :receive wird innerhalb des Definitionsmoduls des übergeordneten Moduls für Objekte dieses Moduls oder seiner Freunde verwendet. Wenn der Typ des Kindes an anderer Stelle definiert ist, benötigen Sie einen anderen Ansatz (geben Sie public_receive... ein).
Bevor wir weitermachen, noch ein Detail: Wenn ein Objekttyp T nur die Schlüsselfähigkeit hat (kein Speichern), behandelt Sui sie etwas eingeschränkter. Solche Objekte können nicht mit generischem Code außerhalb ihres Moduls empfangen werden. In der Praxis bedeutet das, wenn T nur einen Schlüssel hat und ein untergeordnetes Objekt wird, müssen Sie den Abruf in einem eigenen Modul oder im Modul des Elternteils mit einer benutzerdefinierten Regel durchführen. Wenn T auch Speicher hat, haben wir über public_receive mehr Flexibilität. Lassen Sie uns das als Nächstes untersuchen.
- Sui
Sui is a Layer 1 protocol blockchain designed as the first internet-scale programmable blockchain platform.
Verdiene deinen Anteil an 1000 Sui
Sammle Reputationspunkte und erhalte Belohnungen für deine Hilfe beim Wachstum der Sui-Community.
- Warum benötigt BCS eine genaue Feldreihenfolge für die Deserialisierung, wenn Move-Strukturen benannte Felder haben?53
- Fehler bei der Überprüfung mehrerer Quellen“ in den Veröffentlichungen des Sui Move-Moduls — Automatisierte Fehlerbehebung42
- Sui-Transaktion schlägt fehl: Objekte sind für eine andere Transaktion reserviert24
- Wie interagieren Fähigkeitsbeschränkungen mit dynamischen Feldern in heterogenen Sammlungen?04