You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用Rust SDK在Aptos上执行指定Move脚本?

使用Aptos Rust SDK执行Move脚本

需求背景

你有一个位于sources/top_up.move的Move脚本,功能为检查目标账户的Aptos币余额,若余额低于指定的desired_balance,则从源账户转账补足差额。脚本内容如下:

script {
    use std::signer;
    use aptos_framework::aptos_account;
    use aptos_framework::aptos_coin;
    use aptos_framework::coin;

    fun main(src: &signer, dest: address, desired_balance: u64) {
        let src_addr = signer::address_of(src);

        let balance = coin::balance<aptos_coin::AptosCoin>(src_addr);
        if (balance < desired_balance) {
            aptos_account::transfer(src, dest, desired_balance - balance);
        };
    }
}

目前你已能通过CLI执行该脚本,命令如下:

# 先编译再执行
aptos move compile
aptos move run-script --compiled-script-path build/MyModule/bytecode_scripts/main.mv

# 直接执行源码脚本
aptos move run-script --script-path sources/top_up.move

你希望了解是否可以通过Aptos Rust SDK完成相同操作,答案是肯定的,以下是具体实现方案:


实现步骤

1. 添加依赖

在你的Rust项目的Cargo.toml中添加Aptos SDK依赖:

[dependencies]
aptos = { version = "~1.0", features = ["full"] }
tokio = { version = "1.0", features = ["full"] }
anyhow = "1.0"

2. 执行脚本的Rust代码实现

你可以选择直接加载脚本源码让SDK编译,或者使用预编译好的字节码,两种方式的实现如下:

方式一:加载脚本源码执行

use aptos::{
    crypto::ed25519::Ed25519PrivateKey,
    rest_client::Client,
    signer::local::LocalSigner,
    transaction_builder::TransactionBuilder,
    types::{account_address::AccountAddress, transaction::TransactionPayload},
};
use std::fs;

#[tokio::main]
async fn main() -> anyhow::Result<()> {
    // 初始化Aptos客户端(测试网地址,主网替换为https://fullnode.mainnet.aptoslabs.com/v1)
    let client = Client::new("https://fullnode.testnet.aptoslabs.com/v1");

    // 加载源账户的私钥和地址(建议从环境变量/配置文件读取,不要硬编码)
    let private_key = Ed25519PrivateKey::from_hex("你的源账户私钥")?;
    let src_address = AccountAddress::from_hex("你的源账户地址")?;
    let signer = LocalSigner::from_private_key(src_address, private_key);

    // 读取Move脚本源码
    let script_source = fs::read_to_string("sources/top_up.move")?;

    // 定义脚本参数:目标账户地址、期望余额(单位为Octa,1 Aptos = 1e8 Octa)
    let dest_address = AccountAddress::from_hex("目标账户地址")?;
    let desired_balance = 100_000_000; // 等价于100 Aptos

    // 编译脚本并构建交易Payload
    let payload = TransactionPayload::Script(
        aptos::transaction_builder::compile_script(&script_source, vec![], vec![
            dest_address.into(),
            desired_balance.into(),
        ])?,
    );

    // 获取源账户当前序列号,构建交易
    let sequence_number = client.get_account(signer.address()).await?.into_inner().sequence_number;
    let transaction = TransactionBuilder::new(payload)
        .sequence_number(sequence_number)
        .max_gas_amount(100_000)
        .gas_unit_price(100)
        .expiration_timestamp_secs(std::time::SystemTime::now().duration_since(std::time::UNIX_EPOCH)?.as_secs() + 300)
        .build();

    // 签名并提交交易
    let signed_tx = signer.sign_transaction(&transaction)?;
    let response = client.submit_transaction(&signed_tx).await?;

    println!("交易提交成功,哈希: {}", response.into_inner().hash);

    Ok(())
}

方式二:加载预编译字节码执行

如果你已经通过CLI编译好了脚本字节码,可以直接加载字节码文件执行,替换上述代码中的脚本加载和Payload构建部分:

// 替换方式一中的脚本读取和Payload构建代码
let script_bytecode = fs::read("build/MyModule/bytecode_scripts/main.mv")?;
let payload = TransactionPayload::Script(
    aptos::types::script::Script::new(
        script_bytecode,
        vec![], // 脚本无泛型类型参数,传入空向量
        vec![
            dest_address.into(),
            desired_balance.into(),
        ],
    ),
);

注意事项

  • 私钥安全:绝对不要在代码中硬编码私钥,建议通过环境变量、加密配置文件等方式加载。
  • 网络适配:根据你使用的网络(测试网/主网/本地节点)替换客户端URL。
  • Gas参数调整:max_gas_amount和gas_unit_price需要根据当前网络拥堵情况调整,避免交易失败。
  • 版本兼容性:确保Aptos SDK版本与你使用的CLI版本大致匹配,避免因版本差异导致的编译或执行错误。

内容的提问来源于stack exchange,提问作者Daniel Porteous

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.12 18:45:47