Skip to main content

Create a Move Module

A package's utility is defined by its modules. A module contains the logic for your package. You can create any number of modules per package. To add a module, create a .move file in the sources directory. For this guide, create a file called first_package.move and add the following content:

module first_package::first_package {
}

And now let's add some code:

Comments in .move files

In .move files, use double slashes (//) to denote a comment.

    public struct Sword has key, store {
id: UID,
magic: u64,
strength: u64,
}

public struct Forge has key {
id: UID,
swords_created: u64,
}

/// Module initializer to be executed when this module is published
fun init(ctx: &mut TxContext) {
let admin = Forge {
id: object::new(ctx),
swords_created: 0,
};

// transfer the forge object to the module/package publisher
transfer::transfer(admin, tx_context::sender(ctx));
}

// === Accessors ===

public fun magic(self: &Sword): u64 {
self.magic
}

public fun strength(self: &Sword): u64 {
self.strength
}

public fun swords_created(self: &Forge): u64 {
self.swords_created
}

Module Name

The first line of the module defines the module's name and the package it belongs to. In this case, first_package belongs to first_package.

Imports

Move's object model allows for code reuse. You can use types and functions declared in other modules, even if they belong to different packages.

In this example, the module imports from the object, transfer, and tx_context modules from the iota package, which was defined as a package dependency. The module does not need to import them explicitly, because the compiler provides these use statements by default.

Struct Declarations

Structs define the data structures your module can create, store, and destroy.

Abilities

You can add abilities to any struct using the has keyword.

key

The key ability allows you to store and transfer a struct.

store

The store ability allows the struct to be stored in structs with the key ability. The store ability allows the value to be wrapped in an object. A type with the key ability can be stored at top-level and be directly owned by an account or address.

copy

The copy ability allows the struct to be copied. If a type has the copy ability, it should likely have the drop ability too, as the drop ability is required to clean up resources when the instance is no longer needed.

drop

The drop ability allows the struct to be dropped or discarded. In Move, all assets must be handled with appropriate care. If you attempt to ignore or discard a struct without the drop ability, your code will not compile.

Module Initializer

A module initializer is a special function invoked exactly once when the module is published. It must have the following properties:

  • The function name must be init.
  • The parameter list must end with either &mut TxContext or &TxContext.
  • The function should have no return values.
  • It must be a private function.

Keep in mind that if you upgrade your package, the initializer will not be called again.

Entry Functions

Add the entry modifier to functions you want to call from a programmable transaction block. All parameters passed to the function must be inputs to the transaction block, not results from other transactions in the block, nor can they be modified by previous transactions in the block. These functions can only return types with the drop ability.

Public Functions

public functions can be called from a programmable transaction block or another module.

Accessor Functions

Accessor functions are public functions that allow the fields of the module's structs to be read from other modules.

Question 1/3

What is the purpose of the `key` ability in a struct declaration in Move?