Skip to content
🎉 Welcome to the new Aptos Docs! Click here to submit an issue.

地址(Address)

address 是 Move 语言的内置类型,用于表示全局存储中的位置(有时称为账户)。一个 address 值是一个 256 位(32 字节)的标识符。在给定地址下可以存储两种内容:模块资源

虽然 address 底层实现是 256 位整数,但 Move 地址被设计为不透明的——它们不能从整数创建,不支持算术运算,也不可修改。尽管某些场景可能需要这类特性(例如 C 语言中的指针算术就有类似用途),但 Move 出于支持静态验证的设计目标,不允许这种动态行为。

你可以在运行时使用地址值(address 类型)来访问该地址下的资源,但_无法_通过地址值在运行时访问模块。

地址及其语法

地址有两种形式:命名地址和数值地址。命名地址的语法遵循 Move 中命名标识符的通用规则。数值地址的语法不限于十六进制值,任何有效的 u256 数值都可以作为地址值,例如 420xCAFE2021 都是有效的数值地址字面量。

为区分地址是否在表达式上下文中使用,其语法会根据使用场景有所不同:

  • 当地址在表达式中使用时,必须以 @ 字符作为前缀,即 @<数值>@<命名地址标识符>
  • 在非表达式上下文中,地址可以不带 @ 前缀书写,即 <数值><命名地址标识符>

通常可以将 @ 视为一个运算符,它将地址从命名空间项转换为表达式项。

命名地址

命名地址允许在任何使用地址的地方用标识符替代数值,而不仅限于值层面。命名地址在 Move 包中作为顶层元素(模块和脚本之外)声明和绑定,或作为参数传递给 Move 编译器。

命名地址仅存在于源代码层面,在字节码层面会被完全替换为其对应的数值。因此,模块和模块成员_必须_通过模块的命名地址访问,而不能通过编译时分配给命名地址的数值访问。例如,即使 Move 程序编译时将 my_addr 设为 0x2use my_addr::foo 也_不等同_于 use 0x2::foo。这个区别在模块与脚本章节有更详细的讨论。

示例

script {
  fun example() {
    let a1: address = @0x1; // 0x0000000000000000000000000000000000000000000000000000000000000001 的简写
    let a2: address = @0x42; // 0x0000000000000000000000000000000000000000000000000000000000000042 的简写
    let a3: address = @0xDEADBEEF; // 0x00000000000000000000000000000000000000000000000000000000DEADBEEF 的简写
    let a4: address = @0x000000000000000000000000000000000000000000000000000000000000000A;
    let a5: address = @std; // 将命名地址 `std` 的值赋给 `a5`
    let a6: address = @66;
    let a7: address = @0x42;
  }
}
 
module 66::some_module {   // 非表达式上下文,无需 @ 前缀
    use 0x1::other_module; // 非表达式上下文,无需 @ 前缀
    use std::vector;       // 引用其他模块时可将命名地址作为命名空间项使用
    ...
}
 
module std::other_module {  // 声明模块时可将命名地址作为命名空间项使用
    ...
}

全局存储操作

address 值的主要用途是与全局存储操作进行交互。

address 值会与 existsborrow_globalborrow_global_mutmove_from 操作 一起使用。

唯一 使用 address 的全局存储操作是 move_to,该操作使用 signer

所有权

与语言中内置的其他标量值一样,address 值是隐式可复制的,这意味着它们无需显式指令(如 copy)即可被复制。