Rust宏编程库fuels-macros的使用:Fuel框架中的过程宏与代码生成工具

Rust宏编程库fuels-macros的使用:Fuel框架中的过程宏与代码生成工具

安装

在项目目录中运行以下Cargo命令:

cargo add fuels-macros

或者在Cargo.toml中添加以下行:

fuels-macros = "0.74.0"

示例代码

以下是一个使用fuels-macros的完整示例:

use fuels_macros::{Parameterize, Tokenize};

// 定义一个结构体并使用Parameterize和Tokenize宏
#[derive(Parameterize, Tokenize)]
struct MyStruct {
    field1: u32,
    field2: String,
    field3: [u8; 32],
}

// 使用生成的代码
fn main() {
    let my_instance = MyStruct {
        field1: 42,
        field2: "Fuel".to_string(),
        field3: [0; 32],
    };

    // 使用Parameterize宏生成的方法
    let param_types = my_instance.param_types();
    println!("Parameter types: {:?}", param_types);

    // 使用Tokenize宏生成的方法
    let tokens = my_instance.into_tokens();
    println!("Tokens: {:?}", tokens);
}

主要功能

fuels-macros是Fuel框架的一部分,提供以下主要功能:

  1. 过程宏:如ParameterizeTokenize,用于自动生成与Fuel区块链交互所需的代码
  2. 代码生成:简化与Fuel区块链合约交互的开发工作
  3. 类型转换:自动将Rust类型转换为Fuel合约兼容的类型

完整示例代码

以下是一个更完整的示例,展示了fuels-macros的典型用法:

use fuels_macros::{Parameterize, Tokenize};
use fuels_core::types::{ParamType, Token};

// 定义一个更复杂的结构体
#[derive(Parameterize, Tokenize, Debug)]
struct UserProfile {
    id: u64,
    name: String,
    active: bool,
    permissions: Vec<String>,
    balance: [u8; 32],
}

// 合约交互示例
fn main() {
    // 创建结构体实例
    let user = UserProfile {
        id: 12345,
        name: "Alice".to_string(),
        active: true,
        permissions: vec!["admin".to_string(), "user".to_string()],
        balance: [0; 32],
    };

    // 使用Parameterize宏生成的方法获取参数类型
    let types = user.param_types();
    println!("Generated parameter types: {:?}", types);

    // 使用Tokenize宏生成的方法转换为Token
    let tokens = user.into_tokens();
    println!("Generated tokens: {:?}", tokens);

    // 模拟合约调用
    simulate_contract_call(&user);
}

fn simulate_contract_call<T: Parameterize + Tokenize>(data: &T) {
    println!("Simulating contract call with data:");
    println!("Parameter types: {:?}", data.param_types());
    println!("Tokens: {:?}", data.into_tokens());
}

工作原理

fuels-macros通过过程宏自动为结构体实现以下特性:

  1. Parameterize trait - 生成与Fuel合约交互所需的类型信息
  2. Tokenize trait - 将Rust数据结构转换为Fuel合约能理解的Token格式

注意事项

  1. 确保所有字段类型都是Fuel合约支持的类型
  2. 复杂嵌套结构可能需要手动实现某些trait
  3. 数组和向量有特殊处理,需注意大小限制

许可证

Apache-2.0许可证


1 回复

根据提供的内容,我将整理fuels-macros库的使用信息和示例代码。

主要功能

  1. 自动生成合约ABI绑定
  2. 类型转换和序列化/反序列化支持
  3. 简化合约接口定义
  4. 生成类型安全的Rust绑定

基本安装

在Cargo.toml中添加依赖:

[dependencies]
fuels-macros = "0.40"

主要宏示例

1. abigen! 宏示例

use fuels_macros::abigen;

// 生成合约绑定
abigen!(
    MyContract,  // 生成的模块名
    "path/to/contract-abi.json"  // ABI文件路径
);

2. setup_program_test! 宏示例

use fuels_macros::setup_program_test;

// 设置测试环境
setup_program_test!(
    Wallets("wallet1", "wallet2"),  // 创建测试钱包
    Abigen(Contract(
        name = "MyContract",  // 合约名称
        project = "path/to/contract"  // 合约项目路径
    )),
    Deploy(
        name = "contract_instance",  // 部署实例名称
        contract = "MyContract",  // 合约名称
        wallet = "wallet1"  // 使用的钱包
    )
);

3. 派生宏示例

use fuels_macros::{Parameterize, Tokenizable};

// 自定义结构体,支持参数化和令牌化
#[derive(Parameterize, Tokenizable)]
struct MyStruct {
    field1: u64,
    field2: bool,
}

完整示例代码

use fuels_macros::{abigen, setup_program_test};

// 1. 生成合约绑定
abigen!(
    MyCounterContract,  // 生成的合约模块名
    "examples/contracts/counter/out/debug/counter-abi.json"  // 计数器合约ABI路径
);

// 2. 测试用例
#[tokio::test]
async fn test_counter() {
    // 设置测试环境
    setup_program_test!(
        Wallets("wallet"),  // 创建测试钱包
        Abigen(Contract(  // 生成合约绑定
            name = "MyCounterContract",  // 合约名称
            project = "examples/contracts/counter"  // 合约项目路径
        )),
        Deploy(  // 部署合约
            name = "contract_instance",  // 合约实例名
            contract = "MyCounterContract",  // 合约名称
            wallet = "wallet"  // 使用的钱包
        )
    );

    // 调用合约方法
    let result = contract_instance
        .methods()
        .increment_counter(10)  // 调用increment_counter方法
        .call()
        .await
        .unwrap();

    // 验证结果
    assert_eq!(result.value, 10);
}

高级用法示例

1. 自定义类型映射

abigen!(
    MyContract,
    "path/to/abi.json",
    type_mappings = {
        "SomeCustomType" => "my_module::MyType"  // 自定义类型映射
    }
);

2. 生成多个合约

abigen!(
    Contract1(  // 第一个合约
        name = "FirstContract",
        abi = "path/to/first.json"
    ),
    Contract2(  // 第二个合约
        name = "SecondContract",
        abi = "path/to/second.json"
    )
);

注意事项

  1. 确保使用最新的Rust工具链
  2. 注意生成代码的作用域
  3. 大型合约可能会增加编译时间
  4. 使用cargo expand可以查看宏展开后的代码
回到顶部