Aptos

2025年09月19日更新 4 人订阅
原价: ¥ 2.2 限时优惠
专栏简介 Aptos 开发实战:从环境搭建到第一个 Hello World Aptos 开发指南:在 JetBrains 编辑器中配置运行、编译、测试与发布部署,实现更高效开发 Aptos 区块链智能合约入门:使用 Move 实现消息存储与检索 Aptos Move 语言中的变量管理与内存所有权机制详解 Aptos Move 编程语言中的四大基础类型解析:UINT、STRING、BOOL 与 ADDRESS 深入解读 APTOS-MOVE 中的 Vector 向量核心特性与操作 深入理解APTOS-MOVE中的函数修饰符:核心概念与应用 深入解读 Aptos Move 的 Struct 特性与四大能力 Aptos Move 控制流解析:IF、WHILE与LOOP的深入解读 Aptos Move 模块的特性与实操指南:模块引用与作用域管理 Aptos Move 模块的发布与交互:完整指南 深入理解 Aptos Move 中的 Object 创建与管理 深入探索 Aptos Move:Object 配置与实操指南 使用 Aptos Move 实现随机数生成:从 AIP-41 到实战操作 Aptos Move 实践指南:构建并部署同质化代币水龙头 (FA Faucet) Aptos Move NFT 项目实操指南:从开发到部署全流程解析 Aptos Move 开发入门:从环境搭建到合约部署全流程实录 Aptos Move 入门:从零到一的合约开发与测试实战 Move 语言核心:布尔逻辑与地址类型的实战精解 深入 Aptos Move:从public到friend,函数可见性详解 Aptos Move 编程:for、while 与 loop 循环的实战详解 Aptos Move 安全编程:abort 与 assert! 错误处理实战 Aptos Move 实战:基础运算与比较逻辑的实现与测试 Aptos Move 性能优化:位运算与移位操作实战 Aptos Move 实战:as 关键字与整数类型转换技巧 Aptos Move DeFi 实战:从零构建流动性池兑换逻辑 Aptos Move 实战:用 signer 实现合约所有权与访问控制 Aptos Move 核心安全:& 与 &mut 引用机制详解 Aptos Move 实战:全面掌握 SimpleMap 的增删改查 Aptos Move 入门:掌握链上资源(Resource)的增删改查 Aptos Move 深度实践:用嵌套数据结构构建链上金银储备系统 Aptos Move 实操:如何用 Tables 构建一个链上房产管理系统 Aptos Move 实操:如何用 Tables 构建一个链上房产管理系统 Aptos Move实战:5分钟掌握链上向量(Vector)核心操作 Aptos Move 实战:从零构建一个链上价格预言机 (含源码和测试) Aptos Move 全栈实战:构建链上价格预言机与客户端交互 Move 智能合约实战:在 Aptos 上构建你的首个 Web3 应用

Move 智能合约实战:在 Aptos 上构建你的首个 Web3 应用

Move智能合约实战:在Aptos上构建你的首个Web3应用Aptos作为一条高性能、高可扩展性的公链,正迅速成为Web3开发者的热门选择。其核心语言Move以其安全、高效的特性,为链上资产管理和智能合约开发提供了强大保障。但对于初学者而言,如何从零开始,编写并部署第一个Mo

Move 智能合约实战:在 Aptos 上构建你的首个 Web3 应用

Aptos 作为一条高性能、高可扩展性的公链,正迅速成为 Web3 开发者的热门选择。其核心语言 Move 以其安全、高效的特性,为链上资产管理和智能合约开发提供了强大保障。但对于初学者而言,如何从零开始,编写并部署第一个 Move 智能合约,往往是一个巨大的挑战。本文将通过一个简单的“链上留言板”实战项目,为你提供一个清晰、完整的实践路径,让你真正理解 Move 语言的魅力,并迈出成为 Aptos 开发者坚实的第一步。

实操

创建项目

mcd message_board # mkdir message_board & cd message_board

初始化

aptos move init --name message_board
{
  "Result": "Success"
}

aptos init
Configuring for profile default
Choose network from [devnet, testnet, mainnet, local, custom | defaults to devnet]
testnet
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...

---
Aptos CLI is now set up for account 0xf416c7c5f004503fd9aca140ec17ad421b874537075f87616600404d413f138a as profile default!
---

The account has not been funded on chain yet. To fund the account and get APT on testnet you must visit https://aptos.dev/network/faucet?address=0xf416c7c5f004503fd9aca140ec17ad421b874537075f87616600404d413f138a
Press [Enter] to go there now > 
{
  "Result": "Success"
}

项目目录

➜ tree . -L 6 -I "docs|target|node_modules|build"
.
├── Move.toml
├── scripts
├── sources
│   └── message.move
└── tests
    └── message_tests.move

4 directories, 3 files

实现合约 message.move

module message_board::message {
    use std::string::{String, utf8};
    use std::signer;
    use std::debug::print;

    /// Error message not found
    const ERR_MESSAGE_NOT_FOUND: u64 = 0;

    struct MessageHolder has key, store, drop {
        message: String
    }

    public entry fun set_message(account: &signer, message: String) acquires MessageHolder {
        let account_address = signer::address_of(account);
        print(&message);

        if (exists<MessageHolder>(account_address)) {
            print(&utf8(b"Updating existing message"));
            move_from<MessageHolder>(account_address);
        } else {
            print(&utf8(b"Creating new message"));
        };

        move_to(account, MessageHolder { message });
    }

    #[view]
    public fun get_message(account_address: address): String acquires MessageHolder {
        assert!(exists<MessageHolder>(account_address), ERR_MESSAGE_NOT_FOUND);

        let message_holder = borrow_global<MessageHolder>(account_address);
        print(&message_holder.message);
        message_holder.message
    }
}

这段 Aptos Move 代码定义了一个名为 message 的模块,其核心功能是允许 Aptos 账户在链上存储和查询一条文本消息。它通过 MessageHolder 结构体实现,该结构体包含一个 message 字段,并被声明为具有 key 属性,使其可以作为资源存储在账户下。set_message 是一个 entry 函数,用于将消息写入或更新到调用者的账户上,它会先检查是否已存在消息,若有则移除旧消息再存入新消息,确保每个账户只保留一条最新消息。get_message 是一个 view 函数,允许任何人在不发起交易的情况下免费查询特定账户上存储的消息。该函数通过 exists 检查确保消息存在,然后使用 borrow_global 安全地读取并返回消息内容。这整个模块展示了 Aptos Move 中资源管理、状态读写和只读查询的基本模式。

编译

➜ aptos move compile --named-addresses message_board=default
Compiling, may take a little while to download git dependencies...
UPDATING GIT DEPENDENCY https://github.com/aptos-labs/aptos-framework.git
INCLUDING DEPENDENCY AptosFramework
INCLUDING DEPENDENCY AptosStdlib
INCLUDING DEPENDENCY MoveStdlib
BUILDING message_board
{
  "Result": [
    "f416c7c5f004503fd9aca140ec17ad421b874537075f87616600404d413f138a::message"
  ]
}

测试文件 message_tests.move

#[test_only]
module message_board::message_tests {
    use std::string::utf8;
    use std::signer;
    use message_board::message;

    #[test(sender = @message_board)]
    fun test_set_and_get_message(sender: &signer) {
        // Test setting a message
        message::set_message(sender, utf8(b"Hello World"));

        // Verify the message was set correctly
        let stored_message = message::get_message(signer::address_of(sender));
        assert!(stored_message == utf8(b"Hello World"), 0)
    }

    #[test(sender = @message_board)]
    fun test_update_message(sender: &signer) {
        // Test setting a message
        message::set_message(sender, utf8(b"Hello World"));
        // Test updating a message
        message::set_message(sender, utf8(b"Goodbye World"));

        // Verify the message was updated correctly
        let stored_message = message::get_message(signer::address_of(sender));
        assert!(stored_message == utf8(b"Goodbye World"), 0);
    }
}

这段 Aptos Move 代码是一个名为 message_tests 的测试模块,它用于验证 message 模块的功能是否按预期工作。它被 #[test_only] 标记,意味着这段代码只在测试时编译和运行,不会被部署到链上。该模块包含两个测试函数,每个函数都被 #[test] 属性标记,并模拟一个名为 sender 的账户来执行操作。test_set_and_get_message 函数首先调用 set_message 存储一条“Hello World”消息,然后调用 get_message 检索该消息,并使用 assert 验证其内容是否正确。test_update_message 函数则测试了更新功能,它先设置一条消息,再用另一条新消息覆盖它,最后断言链上的消息已被成功更新为“Goodbye World”。这段代码通过在本地虚拟机中运行,高效且安全地验证了 message 模块的核心功能。

测试

➜ aptos move test --named-addresses message_board=default                                                    
INCLUDING DEPENDENCY AptosFramework
INCLUDING DEPENDENCY AptosStdlib
INCLUDING DEPENDENCY MoveStdlib
BUILDING message_board
Running Move unit tests
[debug] "Hello World"
[debug] "Creating new message"
[debug] "Hello World"
[ PASS    ] 0xf416c7c5f004503fd9aca140ec17ad421b874537075f87616600404d413f138a::message_tests::test_set_and_get_message
[debug] "Hello World"
[debug] "Creating new message"
[debug] "Goodbye World"
[debug] "Updating existing message"
[debug] "Goodbye World"
[ PASS    ] 0xf416c7c5f004503fd9aca140ec17ad421b874537075f87616600404d413f138a::message_tests::test_update_message
Test result: OK. Total tests: 2; passed: 2; failed: 0
{
  "Result": "Success"
}

部署发布

➜ aptos move publish --named-addresses message_board=default   
Compiling, may take a little while to download git dependencies...
UPDATING GIT DEPENDENCY https://github.com/aptos-labs/aptos-framework.git
INCLUDING DEPENDENCY AptosFramework
INCLUDING DEPENDENCY AptosStdlib
INCLUDING DEPENDENCY MoveStdlib
BUILDING message_board
package size 1479 bytes
Do you want to submit a transaction for a range of [200100 - 300100] Octas at a gas unit price of 100 Octas? [yes/no] >
yes
Transaction submitted: https://explorer.aptoslabs.com/txn/0x497798403b3367786a6fdc49006ba484f9d54582951e9d57999993922dd96a1b?network=testnet
{
  "Result": {
    "transaction_hash": "0x497798403b3367786a6fdc49006ba484f9d54582951e9d57999993922dd96a1b",
    "gas_used": 2001,
    "gas_unit_price": 100,
    "sender": "f416c7c5f004503fd9aca140ec17ad421b874537075f87616600404d413f138a",
    "sequence_number": 0,
    "replay_protector": {
      "SequenceNumber": 0
    },
    "success": true,
    "timestamp_us": 1758187652429622,
    "version": 6869435942,
    "vm_status": "Executed successfully"
  }
}

➜ aptos move publish --named-addresses message_board=default
Compiling, may take a little while to download git dependencies...
UPDATING GIT DEPENDENCY https://github.com/aptos-labs/aptos-framework.git
INCLUDING DEPENDENCY AptosFramework
INCLUDING DEPENDENCY AptosStdlib
INCLUDING DEPENDENCY MoveStdlib
BUILDING message_board
package size 1504 bytes
Do you want to submit a transaction for a range of [9200 - 13800] Octas at a gas unit price of 100 Octas? [yes/no] >
yes
Transaction submitted: https://explorer.aptoslabs.com/txn/0x1237b094654964277b45d4d54e8a57ab48ee976e4807053529780f5e795c5788?network=testnet
{
  "Result": {
    "transaction_hash": "0x1237b094654964277b45d4d54e8a57ab48ee976e4807053529780f5e795c5788",
    "gas_used": 92,
    "gas_unit_price": 100,
    "sender": "f416c7c5f004503fd9aca140ec17ad421b874537075f87616600404d413f138a",
    "sequence_number": 2,
    "replay_protector": {
      "SequenceNumber": 2
    },
    "success": true,
    "timestamp_us": 1758189020411917,
    "version": 6869459428,
    "vm_status": "Executed successfully"
  }
}

0x497798403b3367786a6fdc49006ba484f9d54582951e9d57999993922dd96a1b

https://explorer.aptoslabs.com/txn/0x497798403b3367786a6fdc49006ba484f9d54582951e9d57999993922dd96a1b?network=testnet

调用 set_message

➜ aptos move run --function-id 'default::message::set_message' --args 'string:Hello, Aptos!'
Do you want to submit a transaction for a range of [44500 - 66700] Octas at a gas unit price of 100 Octas? [yes/no] >
yes
Transaction submitted: https://explorer.aptoslabs.com/txn/0x75dbc551e642f6ed210ff1ed845e6bd07879af3b1b357d4de1b8f4a9653c8e05?network=testnet
{
  "Result": {
    "transaction_hash": "0x75dbc551e642f6ed210ff1ed845e6bd07879af3b1b357d4de1b8f4a9653c8e05",
    "gas_used": 445,
    "gas_unit_price": 100,
    "sender": "f416c7c5f004503fd9aca140ec17ad421b874537075f87616600404d413f138a",
    "sequence_number": 1,
    "replay_protector": {
      "SequenceNumber": 1
    },
    "success": true,
    "timestamp_us": 1758188642390049,
    "version": 6869453126,
    "vm_status": "Executed successfully"
  }
}

调用 get_message

➜ aptos move view --function-id 'default::message::get_message' --args 'address:0xf416c7c5f004503fd9aca140ec17ad421b874537075f87616600404d413f138a'
{
  "Result": [
    "Hello, Aptos!"
  ]
}

总结

通过本次实战,我们成功地完成了 Aptos Move 智能合约的整个开发闭环。从项目的初始化开始,我们定义了一个名为 message_board 的模块,并创建了核心数据结构 MessageHolder,它以资源的形式存储在用户账户下。我们编写了 set_message 作为入口函数来修改链上状态,实现了留言的创建和更新;同时,通过 get_message 这个只读函数,我们掌握了如何免费、高效地查询链上数据。单元测试环节确保了合约的逻辑正确性,最终的部署与调用验证了所有功能在真实链上运行无误。通过这个简单的项目,你不仅理解了 Aptos Move 的基本语法和核心概念,还掌握了完整的开发流程和常用的 CLI 命令,为未来构建更复杂的链上应用打下了坚实基础。

参考

点赞 0
收藏 0
分享
本文参与登链社区写作激励计划 ,好文好收益,欢迎正在阅读的你也加入。

0 条评论

请先 登录 后评论