diff --git a/docs/content/concepts/sui-move-concepts.mdx b/docs/content/concepts/sui-move-concepts.mdx
index 1f5e237a1833f..c1ebfdee206c2 100644
--- a/docs/content/concepts/sui-move-concepts.mdx
+++ b/docs/content/concepts/sui-move-concepts.mdx
@@ -1,6 +1,6 @@
---
title: Move Concepts
-description: Move is an open source language for writing safe packages to manipulate on-chain objects
+description: Move is an open-source language for writing safe packages to manipulate on-chain objects
---
{@include: ../snippets/move-summary.mdx}
@@ -9,9 +9,7 @@ You can use Move to define, create, and manage programmable Sui objects represen
## Move on Sui
-
-Move on Sui contains some important differences from Move on other blockchains. Sui takes advantage of Move's security and flexibility and enhances it with the features described in the following sections to vastly improve throughput, reduce delays in finality, and make Move programming more approachable. For full details, see the [Sui Smart Contracts Platform](/doc/sui.pdf) white paper.
-
+Move on Sui contains some important differences from Move on other blockchains. Sui takes advantage of Move's security and flexibility and enhances it with the features to vastly improve throughput, reduce delays in finality, and make Move programming more approachable. For full details, see the [Sui Smart Contracts Platform](/doc/sui.pdf) whitepaper.
:::tip
@@ -19,11 +17,6 @@ Where the Sui documentation refers to the Move language, the content is document
:::
-In general, Move on Diem code written for other systems works in Sui with these exceptions:
-
-- [Global storage operators](https://move-language.github.io/move/global-storage-operators.html)
-- [Key abilities](https://github.com/move-language/move/blob/main/language/documentation/book/src/abilities.md)
-
## Key differences {#differences}
Key differences with Move on Sui include:
@@ -40,13 +33,15 @@ In Move on Diem, global storage is part of the programming model. Resources and
This approach introduces a scaling issue, as it is not possible to statically determine which transactions are contending over the same resource and which are not. This is similar to the scaling issues faced by other blockchains where smart contracts typically store account information in large, internal mappings, which limit throughput.
-Move on Sui addresses the scaling issue by not having global storage, or its related operations. When objects (in contrast to resources) and packages (sets of modules) are stored on Sui, they are each given unique identifiers. All a transaction's inputs are explicitly specified up-front using these unique identifiers, to allow the chain to schedule transactions with non-overlapping inputs in parallel.
+Move on Sui addresses the scaling issue by not having global storage, or its related operations. When objects (in contrast to resources) and packages (sets of modules) are stored on Sui, they are each given unique identifiers. All a transaction's inputs are explicitly specified up-front using these unique identifiers, to allow the chain to schedule transactions with non-overlapping inputs in parallel.
### Addresses represent Object IDs {#object-ids}
In Move on Diem, there is a 16-byte `address` type used to represent account addresses in global storage. A 16 byte address is sufficient for the Move on Diem security model.
-Sui doesn't have global storage, so `address` is re-purposed as a 32-byte identifier used for both objects and accounts. Each transaction is signed by an account (the "sender") that is accessible from the transaction context, and each object stores its `address` wrapped in its `id: UID` field. (Refer to [object.move](https://github.com/MystenLabs/sui/tree/main/crates/sui-framework/packages/sui-framework/sources/object.move) in the Sui framework for details).
+Sui doesn't have global storage, so `address` is re-purposed as a 32-byte identifier used for both objects and accounts. Each transaction is signed by an account (the "sender") that is accessible from the transaction context, and each object stores its `address` wrapped in its `id: UID` field.
+
+See [Address](https://move-book.com/reference/primitive-types/address.html) in The Move Book for an overview on addresses and refer to object.move in the Sui Framework for implementation details.
### Object with key ability, globally unique IDs {#global-unique}
@@ -56,31 +51,17 @@ On Sui, the `key` ability indicates that a struct is an object type and comes wi
### Module initializers {#module-initializers}
-As described in [Object-centric global storage](#global-storage), you publish Move modules into Sui storage. The Sui runtime executes a special [initializer function](./sui-move-concepts/init.mdx) you optionally define in a module only once at the time of module publication to pre-initialize module-specific data (for example, creating singleton objects).
+As described in [Object-centric global storage](#global-storage), you publish Move modules into Sui storage. The Sui runtime executes a special initializer function you optionally define in a module only once at the time of module publication to pre-initialize module-specific data (for example, creating singleton objects). See [Module Initializer](https://move-book.com/programmability/module-initializer.html) in The Move Book for more information.
### Entry points take object references as input {#entry-points}
You can call public functions from Sui transactions (called programmable transaction blocks). These functions can take objects by value, by immutable reference, or by mutable reference. If taken by value, you can destroy the object, wrap it (in another object), or transfer it (to a Sui ID specified by an address). If taken by mutable reference, the modified version of the object saves to storage without any change in ownership. In any case, the Sui network authenticates the object and declares it's usage as a part of the transaction.
-In addition to calling public functions, you can call a function that is marked [entry](./sui-move-concepts/entry-functions.mdx) even if it is private as long as other non-`entry` functions have not used its inputs.
-
-
-## Explore concepts
-
-Some of the features of Move are defined in this section using commented code examples.
-
-### Init
-
-The `init` function is a special function that executes only once - when you publish the associated module. See [Init](./sui-move-concepts/init.mdx) for details.
-
-### Entry functions
-
-The `entry` modifier for functions enables safe and direct invocation of module functions, much like scripts. See [Entry](./sui-move-concepts/entry-functions.mdx) for details.
-
-### Strings
+In addition to calling public functions, you can call a function that is marked `entry`, even if it is private, as long as other non-`entry` functions have not used its inputs. See [entry modifier](https://move-book.com/reference/functions.html#entry-modifier) in The Move Reference for more information.
-Move does not have a native type for strings, but it has a useful wrapper. See [Strings](./sui-move-concepts/strings.mdx) for examples.
+## Related links
-### One-time witness
+To learn more about using Move on Sui, see the following sites:
-A one-time witness (OTW) is a special instance of a type created in the module initializer and guaranteed to be unique with only one instance. See [One-Time Witness](./sui-move-concepts/one-time-witness.mdx) for an example.
+- [The Move Book](https://move-book.com): A comprehensive guide to the Move programming language on the Sui blockchain.
+- [The Move Reference](https://move-book.com/reference): Language reference for Move on Sui.
diff --git a/docs/content/concepts/sui-move-concepts/collections.mdx b/docs/content/concepts/sui-move-concepts/collections.mdx
deleted file mode 100644
index f1c5d63ca0348..0000000000000
--- a/docs/content/concepts/sui-move-concepts/collections.mdx
+++ /dev/null
@@ -1,74 +0,0 @@
----
-title: Collections
-description: The Sui framework provides several modules you can use to work with groups of data.
----
-
-Collections provide a convenient way to work with groups of data. The Sui framework provides several modules that provide collection logic:
-
-## bag
-
-A bag is a heterogeneous map-like collection. The collection is similar to `sui::table` in that its keys and values are not stored within the Bag value, but instead are stored using Sui's object system. The Bag struct acts only as a handle into the object system to retrieve those keys and values. This means that Bag values with exactly the same key-value mapping will not be equal, with ==, at runtime.
-
-To learn more, see [Table and Bag](../dynamic-fields/tables-bags.mdx) or the [framework definition](https://github.com/MystenLabs/sui/blob/main/crates/sui-framework/docs/sui-framework/bag.md) on GitHub.
-
-## dynamic_field
-
-In addition to the fields declared in its type definition, a Sui object can have dynamic fields that can be added after the object has been constructed. Unlike ordinary field names (which are always statically declared identifiers) a dynamic field name can be any value with the copy, drop, and store abilities (for example, an integer, a boolean, or a string). This gives Sui programmers the flexibility to extend objects on-the-fly, and it also serves as a building block for core collection types.
-
-To learn more, see [Dynamic Fields](../dynamic-fields.mdx) or the [framework definition](https://github.com/MystenLabs/sui/blob/main/crates/sui-framework/docs/sui-framework/dynamic_field.md) on GitHub.
-
-## dynamic_object_field
-
-Similar to `sui::dynamic_field`, this module allows for the access of dynamic fields. But unlike, `sui::dynamic_field` the values bound to these dynamic fields must be objects themselves. This allows for the objects to still exist within storage, which may be important for external tools. The difference is otherwise not observable from within Move.
-
-To learn more, see [Dynamic Fields](../dynamic-fields.mdx) or the [framework definition](https://github.com/MystenLabs/sui/blob/main/crates/sui-framework/docs/sui-framework/dynamic_object_field.md) on GitHub.
-
-## linked_table
-
-Similar to `sui::table` but the values are linked together, allowing for ordered insertion and removal.
-
-To learn more, see the [framework definition](https://github.com/MystenLabs/sui/blob/main/crates/sui-framework/docs/sui-framework/linked_table.md) on GitHub.
-
-## object_bag
-
-Similar to `sui::bag`, an `ObjectBag` is a heterogeneous map-like collection. But unlike `sui::bag`, the values bound to these dynamic fields must be objects themselves. This allows for the objects to still exist in storage, which might be important for external tools. The difference is otherwise not observable from within Move.
-
-To learn more, see [Table and Bag](../dynamic-fields/tables-bags.mdx) or the [framework definition](https://github.com/MystenLabs/sui/blob/main/crates/sui-framework/docs/sui-framework/object_bag.md) on GitHub.
-
-## object_table
-
-Similar to `sui::table`, an `ObjectTable` is a map-like collection. But unlike `sui::table`, the values bound to these dynamic fields must be objects themselves. This allows for the objects to still exist within in storage, which may be important for external tools. The difference is otherwise not observable from within Move.
-
-To learn more, see [Table and Bag](../dynamic-fields/tables-bags.mdx) or the [framework definition](https://github.com/MystenLabs/sui/blob/main/crates/sui-framework/docs/sui-framework/object_table.md) on GitHub.
-
-## priority_queue
-
-Priority queue implemented using a max heap.
-
-To learn more, see the [framework definition](https://github.com/MystenLabs/sui/blob/main/crates/sui-framework/docs/sui-framework/priority_queue.md) on GitHub.
-
-## table
-
-A table is a map-like collection. But unlike a traditional collection, its keys and values are not stored within the Table value, but instead are stored using Sui's object system. The Table struct acts only as a handle into the object system to retrieve those keys and values. Note that this means that Table values with exactly the same key-value mapping will not be equal, with ==, at runtime.
-
-To learn more, see [Table and Bag](../dynamic-fields/tables-bags.mdx) or the [framework definition](https://github.com/MystenLabs/sui/blob/main/crates/sui-framework/docs/sui-framework/table.md) on GitHub.
-
-## table_vec
-
-A basic scalable vector library implemented using Table.
-
-To learn more, see the [framework definition](https://github.com/MystenLabs/sui/blob/main/crates/sui-framework/docs/sui-framework/table_vec.md) on GitHub.
-
-## vec_map
-
-A map data structure backed by a vector. The map is guaranteed not to contain duplicate keys, but entries are not sorted by key--entries are included in insertion order. All operations are O(N) in the size of the map--the intention of this data structure is only to provide the convenience of programming against a map API. Large maps should use handwritten parent/child relationships instead. Maps that need sorted iteration rather than insertion order iteration should also be handwritten.
-
-To learn more, see the [framework definition](https://github.com/MystenLabs/sui/blob/main/crates/sui-framework/docs/sui-framework/vec_map.md) on GitHub.
-
-## vec_set
-
-The main object for `vec_set` is a set data structure backed by a vector. The set is guaranteed not to contain duplicate keys. All operations are O(N) in the size of the set. The intention of this data structure is only to provide the convenience of programming against a set API. Sets that need sorted iteration rather than insertion order iteration should be handwritten.
-
-To learn more, see the [framework definition](https://github.com/MystenLabs/sui/blob/main/crates/sui-framework/docs/sui-framework/vec_set.md) on GitHub.
-
-
diff --git a/docs/content/concepts/sui-move-concepts/entry-functions.mdx b/docs/content/concepts/sui-move-concepts/entry-functions.mdx
deleted file mode 100644
index ffbc83b781ff9..0000000000000
--- a/docs/content/concepts/sui-move-concepts/entry-functions.mdx
+++ /dev/null
@@ -1,60 +0,0 @@
----
-title: Entry Functions
----
-
-The `entry` modifier allows a function to be called directly from a programmable transaction block, as an "entrypoint" to the module.
-
-When called this way, parameters passed to `entry` functions must be inputs to the transaction block, not the results of previous transactions in that block, and not modified by previous transactions in that block. Entry functions are also only allowed to return types that have `drop`.
-
-These restrictions prevent third parties using the scriptable nature of programmable transaction blocks to bypass the fact that `entry` functions are not otherwise allowed to be called from other modules.
-
-## `public` vs `entry` functions
-
-The `public` modifier also allows a function to be called from a programmable transaction block. It additionally allows the function to be called from other modules, and does not impose the same restrictions on where the function's parameters can come from and what it can return, so in many cases `public` is the right way to expose your function to the outside world. `entry` is useful if:
-
-- You want strong guarantees that your function is not being combined with third-party module functions, in programmable transaction blocks. The canonical example of this is a swap protocol that does not want to interact with a flash loan provider: If the swap protocol exposes only `entry` functions to perform swaps, it will not be possible to pass in a flash loaned `Coin`, because that coin will be the output of some previous transaction.
-- You do not want the function's signature to appear in your module's ABI. `public` function signatures must be maintained by upgrades while `entry` function signatures do not.
-
-It is also possible to create a `public entry` function, which can be called by other modules and by programmable transaction blocks but is restricted like an `entry` function in the latter case. This is rarely useful -- you probably only want one of `public` or `entry`.
-
-## Example
-
-```move
-module entry_functions::example {
- use sui::object::{Self, UID};
- use sui::transfer;
- use sui::tx_context::{Self, TxContext};
-
- struct Foo has key {
- id: UID,
- bar: u64,
- }
-
- /// Entry functions can accept a reference to the `TxContext`
- /// (mutable or immutable) as their last parameter.
- entry fun share(bar: u64, ctx: &mut TxContext) {
- transfer::share_object(Foo {
- id: object::new(ctx),
- bar,
- })
- }
-
- /// Parameters passed to entry functions called in a programmable
- /// transaction block (like `foo`, below) must be inputs to the
- /// transaction block, and not results of previous transactions.
- entry fun update(foo: &mut Foo, ctx: &TxContext) {
- foo.bar = tx_context::epoch(ctx);
- }
-
- /// Entry functions can return types that have `drop`.
- entry fun bar(foo: &Foo): u64 {
- foo.bar
- }
-
- /// This function cannot be `entry` because it returns a value
- /// that does not have `drop`.
- public fun foo(ctx: &mut TxContext): Foo {
- Foo { id: object::new(ctx), bar: 0 }
- }
-}
-```
diff --git a/docs/content/concepts/sui-move-concepts/init.mdx b/docs/content/concepts/sui-move-concepts/init.mdx
deleted file mode 100644
index b144068b9a2cc..0000000000000
--- a/docs/content/concepts/sui-move-concepts/init.mdx
+++ /dev/null
@@ -1,45 +0,0 @@
----
-title: Module Initializers
----
-
-The module initializer function, `init`, is special in that it executes only once - when you publish the associated module - and must have the following properties:
-
-- Function name must be `init`
-- The parameter list must end with either a `&mut TxContext` or a `&TxContext` type
-- No return values
-- Private visibility
-- Optionally, the parameter list starts by accepting the module's one-time witness by value
-
-For example, the following `init` functions are all valid:
-
-- `fun init(ctx: &TxContext)`
-- `fun init(ctx: &mut TxContext)`
-- `fun init(otw: EXAMPLE, ctx: &TxContext)`
-- `fun init(otw: EXAMPLE, ctx: &mut TxContext)`
-
-Every function that fits this criteria will be run when the package is first published, and at no other time, including when the package is upgraded. This means that an `init` function that was introduced during an upgrade (to a new or existing module) will never run.
-
-The following example demonstrates a valid `init` function in a module:
-
-```move
-module examples::one_timer {
- use sui::transfer;
- use sui::object::{Self, UID};
- use sui::tx_context::{Self, TxContext};
-
- /// The one of a kind - created in the module initializer.
- struct CreatorCapability has key {
- id: UID
- }
-
- /// This function is only called once on module publish.
- /// Use it to make sure something has happened only once, like
- /// here - only module author will own a version of a
- /// `CreatorCapability` struct.
- fun init(ctx: &mut TxContext) {
- transfer::transfer(CreatorCapability {
- id: object::new(ctx),
- }, tx_context::sender(ctx))
- }
-}
-```
diff --git a/docs/content/concepts/sui-move-concepts/move-on-sui.mdx b/docs/content/concepts/sui-move-concepts/move-on-sui.mdx
deleted file mode 100644
index b73c78cba9fde..0000000000000
--- a/docs/content/concepts/sui-move-concepts/move-on-sui.mdx
+++ /dev/null
@@ -1,8 +0,0 @@
----
-title: Move on Sui
-description: The Move language has additional benefits on the Sui blockchain that take advantage of the object-centric nature of Sui.
-draft: true
----
-
-Content moved to sui-move-concepts
-
diff --git a/docs/content/concepts/sui-move-concepts/one-time-witness.mdx b/docs/content/concepts/sui-move-concepts/one-time-witness.mdx
deleted file mode 100644
index 4a5461b1bf44f..0000000000000
--- a/docs/content/concepts/sui-move-concepts/one-time-witness.mdx
+++ /dev/null
@@ -1,99 +0,0 @@
----
-title: One-Time Witness
-description: A one-time witness is a special type that is guaranteed to have at most one instance.
----
-
-A one-time witness (OTW) is a special type that is guaranteed to have at most one instance. It is useful for limiting certain actions to only happen once (for example, creating a coin). In Move, a type is considered a OTW if:
-
-- Its name is the same as its module's names, all uppercased.
-- It has the `drop` ability and only the `drop` ability.
-- It has no fields, or a single `bool` field.
-
-The only instance of this type is passed to its module's `init` function when the package containing it is published.
-
-To check whether a type could be used as a OTW, pass an instance of it to `sui::types::is_one_time_witness`.
-
-```move
-module examples::mycoin {
-
- /// Name matches the module name
- struct MYCOIN has drop {}
-
- /// The instance is received as the first argument
- fun init(witness: MYCOIN, ctx: &mut TxContext) {
- /* ... */
- }
-}
-```
-
-The following example illustrates how you could use a OTW:
-
-```move
-/// This example illustrates how One Time Witness works.
-///
-/// One Time Witness (OTW) is an instance of a type which is guaranteed to
-/// be unique across the system. It has the following properties:
-///
-/// - created only in module initializer
-/// - named after the module (uppercased)
-/// - cannot be packed manually
-/// - has a `drop` ability
-module examples::one_time_witness_registry {
- use sui::tx_context::TxContext;
- use sui::object::{Self, UID};
- use std::string::String;
- use sui::transfer;
-
- // This dependency allows us to check whether type
- // is a one-time witness (OTW)
- use sui::types;
-
- /// For when someone tries to send a non OTW struct
- const ENotOneTimeWitness: u64 = 0;
-
- /// An object of this type will mark that there's a type,
- /// and there can be only one record per type.
- struct UniqueTypeRecord has key {
- id: UID,
- name: String
- }
-
- /// Expose a public function to allow registering new types with
- /// custom names. With a `is_one_time_witness` call we make sure
- /// that for a single `T` this function can be called only once.
- public fun add_record(
- witness: T,
- name: String,
- ctx: &mut TxContext
- ) {
- // This call allows us to check whether type is an OTW;
- assert!(types::is_one_time_witness(&witness), ENotOneTimeWitness);
-
- // Share the record for the world to see. :)
- transfer::share_object(UniqueTypeRecord {
- id: object::new(ctx),
- name
- });
- }
-}
-
-/// Example of spawning an OTW.
-module examples::my_otw {
- use std::string;
- use sui::tx_context::TxContext;
- use examples::one_time_witness_registry as registry;
-
- /// Type is named after the module but uppercased
- struct MY_OTW has drop {}
-
- /// To get it, use the first argument of the module initializer.
- /// It is a full instance and not a reference type.
- fun init(witness: MY_OTW, ctx: &mut TxContext) {
- registry::add_record(
- witness, // here it goes
- string::utf8(b"My awesome record"),
- ctx
- )
- }
-}
-```
diff --git a/docs/content/concepts/sui-move-concepts/packages/upgrade.mdx b/docs/content/concepts/sui-move-concepts/packages/upgrade.mdx
index a2024027eb0bb..fd19bd42799ed 100644
--- a/docs/content/concepts/sui-move-concepts/packages/upgrade.mdx
+++ b/docs/content/concepts/sui-move-concepts/packages/upgrade.mdx
@@ -11,7 +11,7 @@ The inability to change package objects, however, becomes a problem when conside
There are some details of the process that you should consider before upgrading your packages.
-For example, [module initializers](../init.mdx) do not re-run with package upgrades. When you publish your initial package, Move runs the `init` function you define for the package once (and only once) at the time of the publish event. Any `init` functions you might include in subsequent versions of your package are ignored.
+For example, module initializers do not re-run with package upgrades. When you publish your initial package, Move runs the `init` function you define for the package once (and only once) at the time of the publish event. Any `init` functions you might include in subsequent versions of your package are ignored. See [Module Initializer](https://move-book.com/programmability/module-initializer.html) in The Move Book for more information.
As alluded to previously, all packages on the Sui network are immutable. Because of this fact, you cannot delete old packages from the chain. As a result, there is nothing that prevents other packages from accessing the methods and types defined in the old versions of your upgraded packages. By default, users can choose to keep using the old version of a package, as well. As a package developer, you must be aware of and account for this possibility.
diff --git a/docs/content/concepts/sui-move-concepts/strings.mdx b/docs/content/concepts/sui-move-concepts/strings.mdx
deleted file mode 100644
index fa897e7bce601..0000000000000
--- a/docs/content/concepts/sui-move-concepts/strings.mdx
+++ /dev/null
@@ -1,50 +0,0 @@
----
-title: Strings
----
-
-Move does not have a native type for strings, but it has a useful wrapper.
-
-```move
-module examples::strings {
- use sui::object::{Self, UID};
- use sui::tx_context::TxContext;
-
- // Use this dependency to get a type wrapper for UTF-8 strings
- use std::string::{Self, String};
-
- /// A dummy Object that holds a String type
- struct Name has key, store {
- id: UID,
-
- /// Here it is - the String type
- name: String
- }
-
- /// Create a name Object by passing raw bytes
- public fun issue_name_nft(
- name_bytes: vector, ctx: &mut TxContext
- ): Name {
- Name {
- id: object::new(ctx),
- name: string::utf8(name_bytes)
- }
- }
-}
-```
-
-## String literals
-
-Define string literals in Move as byte strings. To do so, prepend `b` to your string.
-
-```move
-const IMAGE_URL: vector = b"https://api.capy.art/capys/";
-
-let keys = vector[
- utf8(b"name"),
- utf8(b"link"),
- utf8(b"image_url"),
- utf8(b"description"),
- utf8(b"project_url"),
- utf8(b"creator"),
- ];
-```
diff --git a/docs/content/guides/developer/app-examples/coin-flip.mdx b/docs/content/guides/developer/app-examples/coin-flip.mdx
index 56a2ca19480ac..2e5d67488556a 100644
--- a/docs/content/guides/developer/app-examples/coin-flip.mdx
+++ b/docs/content/guides/developer/app-examples/coin-flip.mdx
@@ -110,7 +110,7 @@ Next, add some more code to this module:
- The first struct, `HouseData`, stores the most essential information pertaining to the game.
- The second struct, `HouseCap`, is a capability that initializes the house data.
- The third struct, `HOUSE_DATA`, is a one-time witness that ensures only a single instance of this `HouseData` ever exists.
-- The [`init` function](concepts/sui-move-concepts/init.mdx) creates and sends the `Publisher` and `HouseCap` objects to the sender.
+- The `init` function creates and sends the `Publisher` and `HouseCap` objects to the sender. See [Module Initializer](https://move-book.com/programmability/module-initializer.html) in The Move Book for more information.
So far, you've set up the data structures within the module. Now, create a function that initializes the house data and shares the `HouseData` object:
diff --git a/docs/content/guides/developer/app-examples/reviews-rating.mdx b/docs/content/guides/developer/app-examples/reviews-rating.mdx
index 1167c02312211..a5c4057d30512 100644
--- a/docs/content/guides/developer/app-examples/reviews-rating.mdx
+++ b/docs/content/guides/developer/app-examples/reviews-rating.mdx
@@ -173,7 +173,8 @@ The pool of `SUI` tokens to be distributed to reviewers is stored in the `reward
#### Storage for reviews
-Because anyone can submit a review for a service, `Service` is defined as a shared object. All the reviews are stored in the `reviews` field, which has [ObjectTable](../../../concepts/sui-move-concepts/collections.mdx#object_table)`` type. The `reviews` are stored as children of the shared object, but they are still accessible by their `ID`.
+Because anyone can submit a review for a service, `Service` is defined as a shared object. All the reviews are stored in the `reviews` field, which has `ObjectTable` type. The `reviews` are stored as children of the shared object, but they are still accessible by their `ID`. See [Dynamic Collections](https://move-book.com/programmability/dynamic-collections.html#objecttable) in The Move Book for more information on `ObjectTables`.
+
In other words, anyone can go to a transaction explorer and find a review object by its object ID, but they won't be able to use a review as an input to a transaction by its object ID.
:::info
diff --git a/docs/content/guides/developer/app-examples/weather-oracle.mdx b/docs/content/guides/developer/app-examples/weather-oracle.mdx
index ec39547a6fdf5..0ae821b671231 100644
--- a/docs/content/guides/developer/app-examples/weather-oracle.mdx
+++ b/docs/content/guides/developer/app-examples/weather-oracle.mdx
@@ -95,9 +95,9 @@ fun init(otw: WEATHER, ctx: &mut TxContext) {
```
- The first struct, `AdminCap`, is a capability.
-- The second struct, `WEATHER`, is a [one-time witness](concepts/sui-move-concepts/one-time-witness.mdx) that ensures only a single instance of this `Weather` ever exists.
+- The second struct, `WEATHER`, is a one-time witness that ensures only a single instance of this `Weather` ever exists. See [One Time Witness](https://move-book.com/programmability/one-time-witness.html) in The Move Book for more information.
- The `WeatherOracle` struct works as a registry and stores the `geoname_id`s of the `CityWeatherOracle`s as [dynamic fields](concepts/dynamic-fields.mdx).
-- The [`init` function](concepts/sui-move-concepts/init.mdx) creates and sends the `Publisher` and `AdminCap` objects to the sender. Also, it creates a [shared object](concepts/object-ownership/shared.mdx) for all the `CityWeatherOracle`s.
+- The `init` function creates and sends the `Publisher` and `AdminCap` objects to the sender. Also, it creates a [shared object](concepts/object-ownership/shared.mdx) for all the `CityWeatherOracle`s. See [Module Initializer](https://move-book.com/programmability/module-initializer.html) in The Move Book for more information.
So far, you've set up the data structures within the module.
Now, create a function that initializes a `CityWeatherOracle` and adds it as [dynamic fields](concepts/dynamic-fields.mdx) to the `WeatherOracle` object:
diff --git a/docs/content/guides/developer/first-app/build-test.mdx b/docs/content/guides/developer/first-app/build-test.mdx
index 845289e685d40..5fd5c21ca12ab 100644
--- a/docs/content/guides/developer/first-app/build-test.mdx
+++ b/docs/content/guides/developer/first-app/build-test.mdx
@@ -172,11 +172,11 @@ Test result: OK. Total tests: 2; passed: 2; failed: 0
Each module in a package can include a special initializer function that runs at publication time. The goal of an initializer function is to pre-initialize module-specific data (for example, to create singleton objects). The initializer function must have the following properties for it to execute at publication:
-- Function name must be `init`
-- The parameter list must end with either a `&mut TxContext` or a `&TxContext` type
-- No return values
-- Private visibility
-- Optionally, the parameter list starts by accepting the module's [one-time witness by value](../../../concepts/sui-move-concepts/one-time-witness.mdx)
+- Function name must be `init`.
+- The parameter list must end with either a `&mut TxContext` or a `&TxContext` type.
+- No return values.
+- Private visibility.
+- Optionally, the parameter list starts by accepting the module's one-time witness by value. See [One Time Witness](https://move-book.com/programmability/one-time-witness.html) in The Move Book for more information.
For example, the following `init` functions are all valid:
diff --git a/docs/content/guides/developer/nft/asset-tokenization.mdx b/docs/content/guides/developer/nft/asset-tokenization.mdx
index bdb7953f2c0af..edbbd3fcd995b 100644
--- a/docs/content/guides/developer/nft/asset-tokenization.mdx
+++ b/docs/content/guides/developer/nft/asset-tokenization.mdx
@@ -57,7 +57,7 @@ Select a module to view its details:
The `tokenized_asset` module operates in a manner similar to the `coin` library.
-When it receives a new [one-time witness](concepts/sui-move-concepts/one-time-witness.mdx) type, it creates a unique representation of a fractional asset. This module employs similar implementations to some methods found in the `Coin` module. It encompasses functionalities pertinent to asset tokenization, including new asset creation, minting, splitting, joining, and burning.
+When it receives a new one-time witness type, it creates a unique representation of a fractional asset. This module employs similar implementations to some methods found in the `Coin` module. It encompasses functionalities pertinent to asset tokenization, including new asset creation, minting, splitting, joining, and burning. See [One Time Witness](https://move-book.com/programmability/one-time-witness.html) in The Move Book for more information.
**Structs**
diff --git a/docs/content/sidebars/concepts.js b/docs/content/sidebars/concepts.js
index e9420eeea9a32..341195c2e19cb 100644
--- a/docs/content/sidebars/concepts.js
+++ b/docs/content/sidebars/concepts.js
@@ -63,11 +63,6 @@ const concepts = [
id: 'concepts/sui-move-concepts',
},
items: [
- 'concepts/sui-move-concepts/strings',
- 'concepts/sui-move-concepts/collections',
- 'concepts/sui-move-concepts/init',
- 'concepts/sui-move-concepts/entry-functions',
- 'concepts/sui-move-concepts/one-time-witness',
{
type: 'category',
label: 'Packages',
diff --git a/docs/site/vercel.json b/docs/site/vercel.json
index ec0aa1defa7ef..9c1fb4c03c619 100644
--- a/docs/site/vercel.json
+++ b/docs/site/vercel.json
@@ -112,6 +112,11 @@
{ "source": "/concepts/tokenomics/sui-coin", "destination": "/concepts/tokenomics#sui-coin", "permanent": true },
{ "source": "/concepts/tokenomics/storage-fund", "destination": "/concepts/tokenomics#storage-fund", "permanent": true },
{ "source": "/concepts/tokenomics/proof-of-stake", "destination": "/concepts/tokenomics#proof-of-stake", "permanent": true },
- { "source": "/concepts/tokenomics/validators-staking", "destination": "/concepts/tokenomics#validators-and-staking-pools", "permanent": true }
+ { "source": "/concepts/tokenomics/validators-staking", "destination": "/concepts/tokenomics#validators-and-staking-pools", "permanent": true },
+ { "source": "/concepts/sui-move-concepts/strings", "destination": "/concepts/sui-move-concepts", "permanent": true },
+ { "source": "/concepts/sui-move-concepts/collections", "destination": "/concepts/sui-move-concepts", "permanent": true },
+ { "source": "/concepts/sui-move-concepts/init", "destination": "/concepts/sui-move-concepts", "permanent": true },
+ { "source": "/concepts/sui-move-concepts/entry-functions", "destination": "/concepts/sui-move-concepts", "permanent": true },
+ { "source": "/concepts/sui-move-concepts/one-time-witness", "destination": "/concepts/sui-move-concepts", "permanent": true }
]
}