跳转到内容

第三方依赖

第三方依赖是受控模块与之交互的外部 模块.通常,这些外部模块存在于不同的账户下.

多 DEX 路由器积极利用第三方依赖.与其提交多笔交易分别与不同 DEX 及其 swap 路径中的各自 entry 函数交互,不如让一个模块(或 脚本)将所有独立的 DEX 调用合并为一笔原子交易.多 DEX 路由器通过引用并调用每个第三方 DEX 模块中的函数来实现这一点.

第三方依赖的可靠性和可用信息量会因其来源而异.具体来说,部分实例可能没有文档,且逻辑可能被重构.

应始终优先选择与链上已部署模块验证过的源代码,如 Git 仓库本地源代码.如果这些不可用,还可以依赖其他可用代码,如 反编译代码,字节码 和基于 ABI 手工编写的代码.

默认的 Move.toml 通过 git 仓库依赖包含了 AptosFramework:

[dependencies.AptosFramework]
git = "<https://github.com/aptos-labs/aptos-framework.git>"
rev = "mainnet"
subdir = "aptos-framework"

当运行 Aptos CLI 命令时,依赖会自动更新并编译.

第三方源代码可以直接放入 sources 目录,基本上与自定义代码同等对待.

  • 文件夹third_party_dependency_project/
    • 文件夹source/
      • {ControlledCode}.move
      • {ThirdPartyCode}.move
    • Move.toml

可以使用 Revela Compiler 对包的字节码进行反编译,重建 Move 代码:

Terminal window
aptos move decompile --package-path ./bytecode_modules

对应的 {ModuleName}.mv.move 文件会生成在 bytecode_modules 目录下.

  • 文件夹third_party_dependency_project/
    • 文件夹byte_modules/
      • {ModuleName}.mv
      • {ModuleName}.mv.move
    • Move.toml

将其文件类型改为 {ModuleName}.move 并放入工作区的 sources 目录后,即可作为本地源文件引用.

  • 文件夹third_party_dependency_project/
    • 文件夹sources/
      • {ModuleName}.move
    • Move.toml

Aptos CLI 支持下载 的字节码.

Terminal window
aptos move download --account {account_addr} --bytecode --package {package_name}

每个字节码依赖都需要独立的包,结构如下:

  • 带有预定义包地址的 Move.toml 文件.
  • build/{ModuleName}/bytecode_modules 目录,内含字节码.
  • 空的 sources 目录.

受控模块在其 Move.toml 中引用该依赖包后,即可使用.

Aptos Token 示例

受控的 invoking_code.move 模块与外部 aptos_token 模块交互:

module invoker::invoking_code {
use aptos_token_objects_addr::aptos_token;
public entry fun wrapper_add_property(): u64 {
aptos_token::add_property(...);
}
}

以下命令可从主网获取所需的 AptosTokenObjects 包 字节码.

Terminal window
aptos move download --account 0x4 \
--bytecode --package AptosTokenObjects \
--output-dir ./aptos_token_bytecode_output/
  • 文件夹invoking_code/
    • 文件夹aptos_token_bytecode_output/
      • 文件夹byte_modules/
        • aptos_token.mv
    • 文件夹sources/
      • invoking_code.move
    • Move.toml

创建的 aptos_token 依赖包结构如下:

  • 文件夹aptos_token_objects_addr/
    • 文件夹build/
      • 文件夹aptos_token/
        • 文件夹bytecode_modules/
          • aptos_token.mv
    • 文件夹sources/
    • Move.toml
  • 文件夹invoking_code/
    • 文件夹aptos_token_bytecode_output/
      • 文件夹byte_modules/
        • aptos_token.mv
        • aptos_token.mv.move
    • 文件夹sources/
      • invoking_code.move
    • Move.toml
[package]
name = "aptos_token"
version = "0.0.0"
[addresses]
aptos_token_module_addr = "0x4"

受控 invoking_code.move 模块的依赖列表会包含对字节码包的本地引用,从而支持编译.

[package]
name = "invoking_code"
[addresses]
invoker = "_"
[dependencies]
aptos_token = { local = "../aptos_token_objects_addr" }

可以通过读取包的 ABI,手工编写 Move 接口代码.需要注意的是,函数头必须完全一致,内部逻辑则无需实现.

之后,接口代码与本地源代码同等对待.

Aptos Token 示例

以下是从 Aptos Explorer 获取的部分 AptosTokenObjects ABI:

{
"address": "0x4",
"name": "aptos_token",
"friends": [],
"exposed_functions": [
{
"name": "add_property",
"visibility": "public",
"is_entry": true,
"is_view": false,
"generic_type_params": [
{
"constraints": [
"key"
]
}
],
"params": [
"&signer",
"0x1::object::Object<T0>",
"0x1::string::String",
"0x1::string::String",
"vector<u8>"
],
"return": []
},
...
]
}

可以手工编写接口 Move 文件,作为源文件使用.类似如下:

module 0x4::aptos_token {
// ...
public entry fun add_property<T: key>(
creator: &signer,
token: Object<T>,
key: String,
type: String,
value: vector<u8>,
) acquires AptosCollection, AptosToken {
abort 0
}
}
  • 文件夹third_party_dependency_project/
    • 文件夹source/
      • {ControlledCode}.move
      • aptos_token.move
    • Move.toml