Difference from Core Move

Summary of key differences:

  1. Sui objects have globally unique IDs

Object-centric Global Storage

In core Move, global storage is part of the programming model and can be accessed through special operations, such as move_to, move_from and many more global storage operators. Both resources and modules are stored in the core Move global storage. When you publish a module, it’s stored into a newly generated module address inside Move. When a new object (a.k.a. resource) is created, it's usually stored into some address, as well.

But on-chain storage is expensive and limited (not optimized for storage and indexing). Current blockchains cannot scale to handle storage-heavy applications such as marketplaces and social apps.

So there is no global storage in Sui Move. None of the global storage-related operations are allowed in Sui Move. (We have a bytecode verifier for this to detect violations.) Instead, storage happens exclusively within Sui. When we publish a module, the newly published module is stored in Sui storage, instead of Move storage. Similarly, newly created objects are stored in Sui storage. This also means that when we need to read an object in Move, we cannot rely on global storage operations but instead Sui must explicitly pass all objects that need to be accessed into Move.

Addresses represent Object IDs

In Move, there is a special address type. This type is used to represent addresses in core Move. Core Move needs to know the address of an account when dealing with the global storage. The address type is 16 bytes, which is sufficient for the core Move security model.

In Sui, since we don’t support global storage in Move, we don’t need the address type to represent user accounts. Instead, we use the address type to represent the Object ID. Refer to the object.move file in Sui framework for an understanding of address use.

Object with key ability, globally unique IDs

We need a way to distinguish between objects that are internal to Sui Move and objects that can be stored in Sui storage. This is important because we need to be able to serialize/deserialize objects in the Move-Sui boundary, and this process makes assumptions on the shape of the objects.

We take advantage of the key ability in Move to annotate a Sui object. In core Move, the key ability is used to tell that the type can be used as a key for global storage. Since we don’t touch global storage in Sui Move, we are able to repurpose this ability. We require that any struct with key ability must start with an id field with the ID type. The ID type contains both the ObjectID and the sequence number (a.k.a. version). We have bytecode verifiers in place to make sure that the ID field is immutable and cannot be transferred to other objects (as each object must have a unique ID).

Module initializers

As described in Object-centric global storage, Sui Move modules are published into Sui storage. A special initializer function optionally defined in a module is executed (once) at the time of module publication by the Sui runtime for the purpose of pre-initializing module-specific data (e.g., creating singleton objects). The initializer function must have the following properties in order to be executed at publication:

  • Name init

  • Single parameter of &mut TxContext type

  • No return values

  • Private

Entry points take object references as input

Sui offers entry functions that can be called directly from Sui, in addition to functions callable from other functions. See Entry functions.

Last updated