> For the complete documentation index, see [llms.txt](https://gushi10546.gitbook.io/aptos-kai-fa-zhe-wen-dang/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://gushi10546.gitbook.io/aptos-kai-fa-zhe-wen-dang/kai-fa-zhe-jiao-cheng/ni-de-di-yi-ge-move-mo-kuai.md).

# 你的第一个 Move 模块

{% hint style="info" %}
截至本翻译稿出炉，Aptos CLI 的版本为 0.3.3
{% endhint %}

本教程详细介绍了如何在 Aptos 区块链上编译、测试、发布和与 Move 模块互动。其步骤如下：

1. [从Git安装CLI](https://aptos.dev/cli-tools/aptos-cli-tool/install-aptos-cli)
2. 编译和测试一个 Move 模块
3. 将 Move 模块发布到 Aptos 区块链上
4. 与一个 Move 模块互动
5. 理解代码

###

### 准备 Aptos-CLI 环境

通过 Git 安装完 Aptos CLI 后，通过创建和资助一个账户来准备与 Aptos 互动的环境。首先启动一个新的终端：

1. 通过 `aptos init` 命令来初始化一个本地的账户，terminal 的输出如下：

   ```
   Enter your rest endpoint [Current: None | No input: <https://fullnode.devnet.aptoslabs.com/v1>]

   No rest url given, using <https://fullnode.devnet.aptoslabs.com/v1>...
   Enter your faucet endpoint [Current: None | No input: <https://faucet.devnet.aptoslabs.com> | 'skip' to not use a faucet]

   No faucet url given, using <https://faucet.devnet.aptoslabs.com>...
   Enter your private key as a hex literal (0x...) [Current: None | No input: Generate new key (or keep one if present)]

   No key given, generating key...
   Account a345dbfb0c94416589721360f207dcc92ecfe4f06d8ddc1c286f569d59721e5a doesn't exist, creating it and funding it with 10000 coins
   Aptos is now set up for account a345dbfb0c94416589721360f207dcc92ecfe4f06d8ddc1c286f569d59721e5a!  Run `aptos help` for more information about commands
   {
     "Result": "Success"
   }
   ```
2. 接下来为这个账户注资：`aptos account fund-with-faucet --account aedd72868bc24fcc42eb481b874a1aadd0a648779aaacb69498b69c5c10fc47a`

   ```
   {
     "Result": "Added 50000 coins to account aedd72868bc24fcc42eb481b874a1aadd0a648779aaacb69498b69c5c10fc47a"
   }
   ```

###

### 编译，测试模块

在 [aptos-core/aptos-move/move-examples](https://github.com/aptos-labs/aptos-core/tree/main/aptos-move/move-examples) 目录下有许多Move模块的例子。

打开终端并进入 `hello_blockchain` 目录：`cd aptos-core/aptos-move/move-examples`.

运行  `aptos move compile --named-addresses hello_blockchain=0xa345dbfb0c94416589721360f207dcc92ecfe4f06d8ddc1c286f569d59721e5a` 编译该模块。如果需要测试该模块，运行以下命令：`aptos move test --named-addresses hello_blockchain=0xa345dbfb0c94416589721360f207dcc92ecfe4f06d8ddc1c286f569d59721e5a`.

CLI 的入参中必须包含 `--named-addresses` 因为在源码的 Move.toml 文件中，该 module 的地址为空：

```
[addresses]
hello_blockchain = "_"
```

为了给上一步创建的账户准备一个模块，我们将命名地址 `hello_blockchain` 设置为我们的账户地址。

### 发布 Move 模块

现在代码可以被编译并且测试通过，让我们把模块发布到为本教程创建的账户上。 `aptos move publish --named-addresses hello_blockchain=0xa345dbfb0c94416589721360f207dcc92ecfe4f06d8ddc1c286f569d59721e5a`

```json
package size 1736 bytes
{
  "Result": {
    "transaction_hash": "0x08abc186cbc38d179712d97dc41b719b26ea98060c84cfce5b6b8b5b32849eef",
    "gas_used": 339,
    "gas_unit_price": 1,
    "sender": "aedd72868bc24fcc42eb481b874a1aadd0a648779aaacb69498b69c5c10fc47a",
    "sequence_number": 0,
    "success": true,
    "timestamp_us": 1662961280781593,
    "version": 14113515,
    "vm_status": "Executed successfully"
  }
}
```

现在，这个模块被存储到了该账户地址下。

###

### 与模块交互

移动模块暴露了访问点或 `entry functions` 。这些可以通过交易来调用。CLI允许对这些进行无缝访问。 `hello_blockchain` 暴露了一个 `set_message` 入口函数，它接收一个字符串。这可以通过 CLI 调用。

```bash
aptos move run \\
--function-id '0xaedd72868bc24fcc42eb481b874a1aadd0a648779aaacb69498b69c5c10fc47a::message::set_message' \\
--args 'string:hello, blockchain
```

在收到请求成功的响应后，CLI 的输出如下：

```json
{
  "Result": {
    "transaction_hash": "0x18f5d8623dba4d4b21921dbbfecec61a13af03097ba5014a49ed72aec425afde",
    "gas_used": 40,
    "gas_unit_price": 1,
    "sender": "aedd72868bc24fcc42eb481b874a1aadd0a648779aaacb69498b69c5c10fc47a",
    "sequence_number": 1,
    "success": true,
    "timestamp_us": 1662961337637266,
    "version": 14117578,
    "vm_status": "Executed successfully"
  }
}
```

`set_message` 函数修改了 `hello_blockchain` 指代的账户地址下 `MessageHolder` 资源。资源是

一种数据结构，存储在全局存储中。可以通过查询以下 REST API 来读取该资源，

{% embed url="<https://fullnode.devnet.aptoslabs.com/v1/accounts/6dcdbfbbb2a1f5d2cd9b8f78b9ec32feaa0170db64ccfc02442af5384f0439ac/resource/0x6dcdbfbbb2a1f5d2cd9b8f78b9ec32feaa0170db64ccfc02442af5384f0439ac::message::MessageHolder>" %}

在我们调用了创建 Move 模块的命令后，输出将会如下所示

```json
{
    "type": "0xaedd72868bc24fcc42eb481b874a1aadd0a648779aaacb69498b69c5c10fc47a::message::MessageHolder",
    "data": {
        "message": "hello, blockchain",
        "message_change_events": {
            "counter": "0",
            "guid": {
                "id": {
                    "addr": "0xaedd72868bc24fcc42eb481b874a1aadd0a648779aaacb69498b69c5c10fc47a",
                    "creation_num": "4"
                }
            }
        }
    }
}
```

注意 `message` 字段包含 `hello, blockchain` 的内容。

在第一次调用 `set_message` 后，后续每次成功的调用都会导致 `message_change_events` 的更新。一个特定账户地址下的 `message_change_events` 可以通过以下 REST API 访问：

`https://fullnode.devnet.aptoslabs.com/v1/accounts/aedd72868bc24fcc42eb481b874a1aadd0a648779aaacb69498b69c5c10fc47a/events/0xaedd72868bc24fcc42eb481b874a1aadd0a648779aaacb69498b69c5c10fc47a::message::MessageHolder/message_change_events`

在调用 `set_message` 函数将消息设置为 `hello, blockchain, again` 后，事件流将包含以下内容：

```json
[
    {
        "version": "14165058",
        "key": "0x0400000000000000aedd72868bc24fcc42eb481b874a1aadd0a648779aaacb69498b69c5c10fc47a",
        "sequence_number": "0",
        "type": "0xaedd72868bc24fcc42eb481b874a1aadd0a648779aaacb69498b69c5c10fc47a::message::MessageChangeEvent",
        "data": {
            "from_message": "hello, blockchain",
            "to_message": "hello, blockchain, again"
        }
    }
]
```

{% hint style="info" %}
请注意： 其他账户可以通过调用与本例中完全相同的函数来重复使用已发布的模块。我们把这个验证过程当成课后练习，留给读者。
{% endhint %}
