-
Notifications
You must be signed in to change notification settings - Fork 11.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Create sui-move-diffs.md #693
Changes from all commits
b3c17a3
8fdd63a
fa03b08
6c441f4
cfee3b8
85817d0
10caa80
d0095b9
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
|
||
--- | ||
title: How Sui Move differs from Core Move | ||
--- | ||
|
||
This document describes the Sui programming model and highlights the differences between the core (previously Diem) Move language and the Move we use in Sui. First remember, Move is a language and Sui a platform. | ||
|
||
In general, Move code written for other systems will work in Sui with these exceptions: | ||
|
||
* Global Storage operators | ||
* Key Abilities | ||
|
||
Here is a summary of key differences: | ||
|
||
1. Sui uses its own [object-centric global storage](#object-centric-global-storage) | ||
2. Addresses represent Object IDs | ||
3. Sui objects have [globally unique IDs](#addresses-represent-object-ids) | ||
4. Sui has [module initializers (init)](#module-initializers) | ||
5. Sui [entry points take object references as input](#entry-points-take-object-references-as-input) | ||
|
||
Find a detailed description of each change below. | ||
|
||
## 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](https://diem.github.io/move/global-storage-operators.html). 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 account’s 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. | ||
|
||
TODO: Review/edit the impetus above and include similar reasoning for each item below. | ||
|
||
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 account 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 [ID.move](https://github.com/MystenLabs/fastnft/blob/main/sui_programmability/framework/sources/ID.move) file in Sui framework for an understanding of address use. | ||
Comment on lines
+35
to
+37
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think this paragraph might go over much more easily once we've explained the notion of ownership. In particular, we could mention something along the lines of:
And then we can move on to how we reuse the account address type, which no longer has meaning given our data layout. ... or we could reuse any way of tying this paragraph to the previous one, because it's really a deduction of the difference in storage layouts. |
||
|
||
## Object with key ability, globally unique IDs | ||
|
||
We need a way to distinguish between objects that are internal to Move and objects that can be passed across the Move-Sui boundary (i.e. 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. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. First, could we define what "internal" object are and what they are used for? We have established in the prior paragraphs that there are "toplevel" objects in Sui, that are the basis of storage and storage access. Those "other" non-key Move objects, are they something the programmer is likely to encounter? In what cases? Then we explain we'll use the "key" ability to mark those top-level transferrable Sui objects we've been talking about. Cool. But then conversely, what's the Sui meaning of being non-key? What are the semantics of non-Sui ojbects and what might I use them for? |
||
|
||
We take advantage of the _key_ ability in Move to annotate a Sui object. In core Move, the [key ability](https://github.com/diem/move/blob/main/language/documentation/book/src/abilities.md#key) 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](#object-centric-global-storage), 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 | ||
Clay-Mysten marked this conversation as resolved.
Show resolved
Hide resolved
|
||
* 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](https://github.com/MystenLabs/fastnft/blob/main/doc/move.md#entry-functions). | ||
|
||
## Conclusion | ||
|
||
In summary, Sui takes advantage of Move’s security and flexibility and enhances it with the features described above to vastly improve throughput, reduce delays in finality, and make Move programming easier. Now see [how Sui works](how-sui-works.md). For full details, see the [Sui Smart Contracts Platform](../../paper/sui.pdf) white paper. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think the issue with this paragraph is that it speaks about data layout, and that's not really what the problem is. Instead, I think we should reformulate in terms of data access, and tie this with parallel execution & up-to-date-ness requirement on execution.
Why this doesn't quite resonate
Ethereum has a storage model that's fully account-based. Every piece of data is stored in some account storage as well:
https://ethereum.org/en/developers/docs/accounts/#an-account-examined
There is no state outside accounts, so you could say that there's no "globally-stored" data.
Now, scalability issues of blockchains are indeed in some respects due to this storage model, but that's not due to account-centric storage, it's because there's no notion of "just accessing one account" (whether that's for reads, writes, or being up-to date prior to any of those 2 ops). in other terms, you're always "touching global storage" even if the semantics of the operation you are actually performing do much less.
What this could indeed focus on
In other terms, we have parcimonious per-object access.
Then we can explain to storage layout, i.e. flat objects, which is now a deduction from the above difference in approaches.
Does this help?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sure. Do you want to send a suggested change to the text? Or work with Xun to refactor this material, since he drafted it?
I'm still working on drafting How Sui Works based upon our meeting Tuesday...