external-crates/move/documentation/book/src/modules.md
Modules are the core program unit that define types along with functions that operate on these
types. Struct types define the schema of Move's storage, and module functions
define the rules interacting with values of those types. While modules themselves are also stored in
storage, they are not accessible from within a Move program. In a blockchain environment, the
modules are stored on chain in a process typically referred to as "publishing". After being
published, entry and public
functions can be invoked according to the rules of that particular Move instance.
A module has the following syntax:
module <address>::<identifier> {
(<use> | <type> | <function> | <constant>)*
}
where <address> is a valid address specifying the module's
package.
For example:
module 0x42::test {
public struct Example has copy, drop { i: u64 }
use std::debug;
const ONE: u64 = 1;
public fun print(x: u64) {
let sum = x + ONE;
let example = Example { i: sum };
debug::print(&sum)
}
}
The module test_addr::test part specifies that the module test will be published under the
numerical address value assigned for the name test_addr in the
package settings.
Modules should normally be declared using named addresses (as opposed to using the numerical value directly). For example:
module test_addr::test {
public struct Example has copy, drop { a: address }
friend test_addr::another_test;
public fun print() {
let example = Example { a: @test_addr };
debug::print(&example)
}
}
These named addresses commonly match the name of the package.
Because named addresses only exist at the source language level and during compilation, named addresses will be fully substituted for their value at the bytecode level. For example if we had the following code:
fun example() {
my_addr::m::foo(@my_addr);
}
and we compiled it with my_addr set to 0xC0FFEE, then it would be operationally equivalent to
the following:
fun example() {
0xC0FFEE::m::foo(@0xC0FFEE);
}
While at the source level these two different accesses are equivalent, it is a best practice to always use the named address and not the numerical value assigned to that address.
Module names can start with a lowercase letter from a to z or an uppercase letter from A to
Z. After the first character, module names can contain underscores _, letters a to z,
letters A to Z, or digits 0 to 9.
module a::my_module {}
module a::foo_bar_42 {}
Typically, module names start with a lowercase letter. A module named my_module should be stored
in a source file named my_module.move.
All members inside a module block can appear in any order. Fundamentally, a module is a collection
of types and functions. The use keyword refers
to members from other modules. The const keyword defines constants that can be
used in the functions of a module.
The friend syntax is a deprecated concept for specifying a list of trusted
modules. The concept has been superceded by public(package)