With the release of Sui 0.13.0, we will be replacing the concept of Child Objects with Dynamic Fields. This is a breaking change, with the Move APIs for interacting with Child Objects in sui::transfer (transfer_to_object and transfer_to_object_id) being removed and replaced with sui::dynamic_field and sui::dynamic_object_field for working with Dynamic Fields.

To avoid errors in applications that use child objects, please follow the migration guide below and be ready to land changes when Devnet updates to 0.13.0 (watch #devnet-updates on Discord for the announcement) . To minimize downtime for your application, please wait to land changes until after the Devnet update as the new APIs for interacting with Dynamic Fields will not be available until then.

What are Dynamic Fields?

Dynamic Fields are a generalization of Child Objects. They allow Move developers on Sui to extend their structs with new data, on-the-fly.

They address the main frustration with Child Objects which require passing their ancestor ownership chain (its parent, its parent's parent, and so on up to the root object owned by the sender) via the entry function. This restriction made working with deeply nested child objects painful, and didn't support uses where the ancestor chain couldn't be known at the start of the transaction (i.e. loading child objects dynamically). With Dynamic Fields, only the root object is passed into the entry function, and its dynamic fields can be accessed on-the-fly during transaction execution. (In fact, passing a dynamic field value as an input to an entry function will now fail).

They also come with a few other improvements:

  • Holding any store value, not just objects.
  • Labeling and looking up fields by name (where a name can be any copy, drop, store value).
  • Powering new on-chain key-value stores like Table (homogeneous keys and values) and Bag (heterogeneous keys and values).

Go crazy with them! We have heard a lot of frustration around missing data structures and then being unable to implement them in Move. You should be able to efficiently implement all sorts of data structures in Move now! Whether it be a linked hash-map or a prefix trie or just a simple linked list. Dynamic fields do require reading/writing objects to storage. We still expect simple vectors to be more efficient than complex data structures for very small numbers of items.

Current Limitations

We are still actively working on some parts of Dynamic Fields, but we couldn’t wait to share this feature with you to see what you could build with it, and to get your feedback. While you are using this feature, watch out for the following known issues, which will be addressed in a future release:

  • remove for dynamic fields is currently unoptimized and will not give a full storage refund. Under the hood, the dynamic_field (and dynamic_object_field) creates Field objects to store its key-value pairs.
  • There is currently no exists_ function for dynamic_fields to check whether a field with a given name is already defined on the object.
  • There are some potential durability/consistency issues with dynamic field objects: If a validator goes down and comes back up while processing a transaction with dynamic fields, it might be unable to further process transactions with those objects. We are actively working on a solution for this.

Migration Guide

The suggestions below will work to convert any existing use of Child Objects to using Dynamic Fields, but note that in many cases, you may want to rethink your usage of the APIs. In many cases, the code can be made simpler or more end-user friendly. The examples below are designed to help with drop-in replacements to help get things running.

Replace calls to transfer_to_object with add

// Old, Child Object API
use sui::transfer;
transfer::transfer_to_object(&mut parent, child)

// New, Dynamic Field API
use sui::dynamic_object_field as ofield;
let id = object::id(&child);
ofield::add(&mut parent.id, id, child);

The new API adds a field to parent with child's ID as the name, and child as the value.

Replace ownership ancestor chains in entry funs with calls borrow, borrow_mut, or remove

(Note: this suggestion assumes that you have followed the earlier suggestion to migrate from transfer_to_object to ofield::add using the child's ID as the field name).

// Child, Parent, GrandParent are all Objects
struct Child has key, store { id: UID, /* ... */ }
struct Parent has key, store { id: UID, /* ... */ }
struct GrandParent has key, store { id: UID, /* ... */ }

// Old, Child Object API
entry fun read_child(gp: &GrandParent, p: &Parent, c: &Child) {
/* ... */
}
entry fun write_child(gp: &mut GrandParent, p: &mut Parent, c: &mut Child) {
/* ... */
}

entry fun take_child(gp: &mut GrandParent, p: &mut Parent, c: Child) {
/* ... */
}

// New, Dynamic Field API
use sui::dynamic_object_field as ofield;

entry fun read_child(gp: &GrandParent, pid: ID, cid: ID) {
let p = ofield::borrow<ID, Parent>(&gp.id, pid);
let c = ofield::borrow<ID, Child>(&p.id, cid);
/* ... */
}

entry fun write_child(gp: &mut GrandParent, pid: ID, cid: ID) {
let p = ofield::borrow_mut<ID, Parent>(&mut gp.id, pid);
let c = ofield::borrow_mut<ID, Child>(&mut p.id, cid);
/* ... */
}

entry fun take_child(gp: &mut GrandParent, pid: ID, cid: ID) {
let p = ofield::borrow_mut<ID, Parent>(&mut gp.id, pid);
let c = ofield::remove<ID, Child>(&mut p.id, cid);
/* ... */
}

Learn More about Dynamic Fields

Author

Sam Blackshear

Co-Founder, CTO, Mysten Labs, Creator of Move Language

CTO of Mysten Labs and inventor of Move language. Former Principal Engineer at Meta.

Read more like this

Sui Mainnet Outage Resolution

Sui engineers quickly diagnosed and issued a fix, subsequently deployed by validators, minimizing the network outage.

2min read
Sui Foundation

How Gorae is Making EV Chargers More Investable with Sui and Walrus

Onchain settlement turns EV charger revenue into something operators can prove and investors can readily finance, creating a flywheel for EV growth.

3min read
Sui Foundation

Artfi Brings Blue-chip Art Investing to Sui

By fractionalizing artworks and using Sui’s dynamic NFT technology, Artfi is making it possible for more people to invest in world-class art.

5min read
Sui Foundation

Sui Stack Messaging SDK: Programmable Communication for Web3

Build private, programmable communication directly into your app with the new Sui Stack Messaging SDK.

3min read
Sui Foundation

All About SuiNS

Human-readable identifiers not only dramatically simplify user interactions with blockchains but also provide powerful ownership benefits.

3min read
Sui Foundation

Enhancing Blockchain Security with Multi-Signature Wallets

Desig Labs multi-signature technology makes it possible to create blockchain wallets requiring any number of keys to open.

8min read
Sui Foundation