Rust区块链开发工具fuels的使用:Fuel SDK为去中心化应用提供模块化智能合约支持

Rust区块链开发工具fuels的使用:Fuel SDK为去中心化应用提供模块化智能合约支持

fuels-rs是Fuel区块链的Rust SDK,可用于多种用途,包括但不限于:

  • 编译、部署和测试Sway合约
  • 启动本地Fuel网络
  • 手工制作脚本或合约调用并签名交易
  • 生成合约方法的类型安全Rust绑定
  • 更多功能仍在积极开发中

特性

  • [x] 启动Fuel节点
  • [x] 部署合约
  • [x] 与已部署合约交互
  • [x] 类型安全的Sway合约绑定代码生成
  • [x] 运行Sway脚本
  • [x] 常见操作的CLI
  • [x] 本地测试钱包
  • [ ] 钱包集成
  • [ ] 事件查询/监控

依赖需求

  • 最新的stable Rust工具链
  • forc和fuel-core二进制文件

使用示例

以下是使用fuels-rs SDK的完整示例demo:

use fuels::prelude::*;

// 示例合约ABI
abigen!(
    MyContract,
    r#"
        {
            "types": [],
            "functions": [
                {
                    "inputs": [],
                    "name": "counter",
                    "output": {
                        "name": "",
                        "type": "u64",
                        "components": null
                    }
                },
                {
                    "inputs": [
                        {
                            "name": "value",
                            "type": "u64",
                            "components": null
                        }
                    ],
                    "name": "increment_counter",
                    "output": {
                        "name": "",
                        "type": "()",
                        "components": null
                    }
                }
            ]
        }
    "#
);

#[tokio::test]
async fn test_contract() -> Result<()> {
    // 启动本地Fuel节点
    let wallet = launch_provider_and_get_wallet().await?;

    // 部署合约
    let contract_id = Contract::deploy(
        "./tests/contracts/counter/out/debug/counter.bin",
        &wallet,
        TxParameters::default(),
        StorageConfiguration::default(),
    )
    .await?;

    // 创建合约实例
    let instance = MyContract::new(contract_id, wallet.clone());

    // 调用合约方法
    let result = instance.methods().counter().call().await?;
    assert_eq!(result.value, 0);

    // 调用合约方法改变状态
    instance.methods().increment_counter(1).call().await?;

    // 验证状态变化
    let result = instance.methods().counter().call().await?;
    assert_eq!(result.value, 1);

    Ok(())
}

完整示例代码

use fuels::{prelude::*, tx::ContractId};

// 定义合约ABI并生成类型安全的Rust绑定
abigen!(
    CounterContract,
    r#"
        {
            "types": [],
            "functions": [
                {
                    "inputs": [],
                    "name": "get_count",
                    "output": {
                        "name": "",
                        "type": "u64",
                        "components": null
                    }
                },
                {
                    "inputs": [
                        {
                            "name": "amount",
                            "type": "u64",
                            "components": null
                        }
                    ],
                    "name": "increment_count",
                    "output": {
                        "name": "",
                        "type": "()",
                        "components": null
                    }
                }
            ]
        }
    "#
);

#[tokio::main]
async fn main() -> Result<()> {
    // 1. 设置测试环境
    let wallet = launch_provider_and_get_wallet().await?;

    // 2. 部署合约
    let contract_id = Contract::deploy(
        "./contracts/counter/out/debug/counter.bin",
        &wallet,
        TxParameters::default(),
        StorageConfiguration::default(),
    )
    .await?;

    println!("合约部署成功,ID: {:?}", contract_id);

    // 3. 创建合约实例
    let contract = CounterContract::new(contract_id, wallet.clone());

    // 4. 调用合约方法
    // 获取初始计数器值
    let initial_count = contract.methods().get_count().call().await?.value;
    println!("初始计数器值: {}", initial_count);

    // 增加计数器
    let increment_amount = 5u64;
    contract
        .methods()
        .increment_count(increment_amount)
        .call()
        .await?;

    // 验证新值
    let new_count = contract.methods().get_count().call().await?.value;
    println!("增加后的计数器值: {}", new_count);
    assert_eq!(new_count, initial_count + increment_amount);

    Ok(())
}

安装

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

cargo add fuels

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

fuels = "0.74.0"

测试

首先使用forc构建测试项目:

forc build --release --path e2e

然后可以运行SDK测试:

cargo test

为什么前缀是fuels而不是fuel?

为了与来自ethers.js生态系统的开发者感觉熟悉,本项目选择在末尾加s。fuels-*系列SDK受到The Ethers Project的启发。


1 回复

Rust区块链开发工具fuels的使用:Fuel SDK为去中心化应用提供模块化智能合约支持

介绍

Fuel SDK是一个专为Fuel区块链设计的Rust开发工具包,它为开发者提供了构建去中心化应用(DApps)所需的核心功能。Fuel是一个高性能模块化区块链,专注于智能合约开发和执行效率。

fuels crate是Fuel生态系统的核心Rust库,提供了:

  • 与Fuel节点交互的能力
  • 智能合约部署和调用功能
  • 交易构建和签名支持
  • 类型安全的ABI绑定

安装

在Cargo.toml中添加依赖:

[dependencies]
fuels = { version = "0.53", features = ["core"] }
tokio = { version = "1.0", features = ["full"] }

基本使用方法

1. 连接到Fuel节点

use fuels::prelude::*;

#[tokio::main]
async fn main() -> Result<()> {
    // 连接到本地测试节点
    let provider = Provider::connect("127.0.0.1:4000").await?;
    
    // 或者连接到测试网
    // let provider = Provider::connect("beta-3.fuel.network").await?;
    
    Ok(())
}

2. 创建钱包

use fuels::signers::WalletUnlocked;

let wallet = WalletUnlocked::new_random(None);
println!("钱包地址: {}", wallet.address());

3. 与智能合约交互

假设有一个简单的计数器合约:

use fuels::{
    contract::Contract,
    programs::contract::ContractCallHandler,
    types::ContractId,
};

// 部署合约
let contract_id = Contract::deploy(
    "./counter_contract/out/debug/counter_contract.bin",
    &wallet,
    TxParameters::default(),
    StorageConfiguration::default(),
)
.await?;

println!("合约部署成功,ID: {:?}", contract_id);

// 调用合约方法
let contract_methods = CounterContract::new(contract_id.clone(), wallet.clone());
let result = contract_methods.increment().call().await?;

println!("调用结果: {:?}", result.value);

4. 发送交易

use fuels::types::Address;

let recipient = Address::from_str("0x...")?;
let amount = 100;

let tx = wallet
    .transfer(recipient, amount, AssetId::default(), TxParameters::default())
    .await?;

println!("交易ID: {:?}", tx.tx_id());

高级功能

类型安全的合约绑定

使用fuels-abigen生成类型安全的合约绑定:

// 在build.rs中
use fuels_abigen_macro::abigen;

abigen!(
    CounterContract,
    "path/to/contract-abi.json"
);

事件监听

use fuels::programs::event::Event;

let events = provider.get_events(contract_id).await?;

for event in events {
    println!("收到事件: {:?}", event);
}

示例项目结构

典型的Fuel项目结构:

my_fuel_dapp/
├── Cargo.toml
├── contracts/
│   └── counter_contract/  # Sway智能合约
│       ├── Forc.toml
│       └── src/main.sw
└── src/
    └── main.rs           # Rust前端代码

最佳实践

  1. 始终在生产环境使用TxParameters设置适当的gas限制和价格
  2. 使用fuels-abigen生成类型安全的合约绑定以避免手动ABI编码错误
  3. 在测试环境中使用fuels::test_helpers提供的实用工具
  4. 考虑使用fuels::accounts::predicate进行更高级的账户管理

完整示例代码

下面是一个完整的Fuel SDK使用示例,包含合约部署、调用和事件监听:

// src/main.rs
use fuels::prelude::*;
use fuels::types::transaction::TxPolicies;

// 使用abigen生成的合约绑定
abigen!(Contract(
    name = "CounterContract",
    abi = "counter_contract/out/debug/counter_contract-abi.json"
));

#[tokio::main]
async fn main() -> Result<()> {
    // 1. 连接到本地测试节点
    let provider = Provider::connect("127.0.0.1:4000").await?;
    
    // 2. 创建钱包
    let wallet = WalletUnlocked::new_random(None);
    println!("钱包地址: {}", wallet.address());
    
    // 3. 部署合约
    let contract_id = Contract::deploy(
        "./counter_contract/out/debug/counter_contract.bin",
        &wallet,
        TxPolicies::default(),
        StorageConfiguration::default(),
    )
    .await?;
    println!("合约部署成功,ID: {:?}", contract_id);
    
    // 4. 调用合约方法
    let contract_methods = CounterContract::new(contract_id.clone(), wallet.clone());
    let result = contract_methods.increment().call().await?;
    println!("调用结果: {:?}", result.value);
    
    // 5. 监听合约事件
    let events = provider.get_events(contract_id).await?;
    for event in events {
        println!("收到事件: {:?}", event);
    }
    
    Ok(())
}
// build.rs
use fuels_abigen_macro::abigen;

fn main() {
    // 生成合约绑定
    abigen!(
        CounterContract,
        "counter_contract/out/debug/counter_contract-abi.json"
    );
}

Fuel SDK为Rust开发者提供了强大而灵活的工具集,用于构建高性能的去中心化应用程序。通过其模块化设计和类型安全接口,可以显著提高开发效率和代码可靠性。

回到顶部