Rust智能合约开发库fuel-abi-types的使用,Fuel区块链ABI类型定义与序列化工具
Rust智能合约开发库fuel-abi-types的使用,Fuel区块链ABI类型定义与序列化工具
安装
在您的项目目录中运行以下Cargo命令:
cargo add fuel-abi-types
或者在您的Cargo.toml中添加以下行:
fuel-abi-types = "0.15.0"
示例使用
以下是一个完整的示例代码,展示如何使用fuel-abi-types库进行ABI类型定义和序列化:
use fuel_abi_types::{
abi::{
full_program::FullProgramABI,
program::{ProgramABI, TypeApplication},
},
utils::{extract_custom_type_name, extract_generic_parameters},
};
use serde_json;
fn main() {
// 定义一个简单的ABI类型
let abi_type = TypeApplication {
name: "MyType".to_string(),
type_id: 1,
type_arguments: vec![],
};
// 创建程序ABI
let program_abi = ProgramABI {
types: vec![abi_type],
functions: vec![],
logged_types: vec![],
messages_types: vec![],
};
// 创建完整的程序ABI
let full_program_abi = FullProgramABI {
program_abi,
storage_slots: vec![],
};
// 序列化为JSON
let json = serde_json::to_string_pretty(&full_program_abi).unwrap();
println!("Serialized ABI:\n{}", json);
// 从JSON反序列化
let deserialized: FullProgramABI = serde_json::from_str(&json).unwrap();
println!("\nDeserialized type name: {}", deserialized.program_abi.types[0].name);
// 使用实用工具函数
let custom_type_name = extract_custom_type_name("struct MyGenericType<T, U>");
println!("\nExtracted custom type name: {}", custom_type_name);
let generic_params = extract_generic_parameters("struct MyGenericType<T, U>");
println!("Extracted generic parameters: {:?}", generic_params);
}
完整示例demo
以下是基于上述内容的完整示例扩展,展示更多fuel-abi-types库的功能:
use fuel_abi_types::{
abi::{
full_program::FullProgramABI,
program::{ProgramABI, TypeApplication, Function},
parameter::Parameter,
},
utils::{extract_custom_type_name, extract_generic_parameters},
};
use serde_json;
fn main() {
// 示例1: 基础类型定义
let simple_type = TypeApplication {
name: "u64".to_string(),
type_id: 1,
type_arguments: vec![],
};
// 示例2: 泛型类型定义
let generic_type = TypeApplication {
name: "Option".to_string(),
type_id: 2,
type_arguments: vec![
TypeApplication {
name: "T".to_string(),
type_id: 3,
type_arguments: vec![],
}
],
};
// 示例3: 定义函数参数
let param = Parameter {
name: "amount".to_string(),
type_application: TypeApplication {
name: "u64".to_string(),
type_id: 1,
type_arguments: vec![],
},
};
// 示例4: 定义函数ABI
let function = Function {
name: "transfer".to_string(),
inputs: vec![param],
output: TypeApplication {
name: "bool".to_string(),
type_id: 4,
type_arguments: vec![],
},
};
// 创建完整程序ABI
let program_abi = ProgramABI {
types: vec![simple_type, generic_type],
functions: vec![function],
logged_types: vec![],
messages_types: vec![],
};
let full_program_abi = FullProgramABI {
program_abi,
storage_slots: vec![],
};
// 序列化并打印
let json = serde_json::to_string_pretty(&full_program_abi).unwrap();
println!("完整程序ABI:\n{}", json);
// 使用工具函数示例
let complex_type_str = "enum Result<T, E> { Ok(T), Err(E) }";
println!("\n提取类型名称: {}", extract_custom_type_name(complex_type_str));
println!("提取泛型参数: {:?}", extract_generic_parameters(complex_type_str));
}
功能说明
- ABI类型定义:提供了
TypeApplication
等核心类型来表示ABI中的类型定义 - 程序ABI结构:通过
ProgramABI
和FullProgramABI
结构体完整描述智能合约的ABI - 序列化支持:支持通过serde将ABI结构序列化为JSON格式
- 实用工具:提供提取自定义类型名称和泛型参数等实用函数
许可证
Apache-2.0
1 回复
Rust智能合约开发库fuel-abi-types使用指南
简介
fuel-abi-types
是Fuel区块链生态中的一个Rust库,专门用于处理Fuel智能合约的ABI(应用程序二进制接口)类型定义和序列化。它为Fuel区块链上的智能合约开发提供了类型安全的ABI处理能力。
主要功能
- 提供Fuel区块链ABI的核心类型定义
- 实现ABI类型的序列化与反序列化
- 支持Fuel合约调用参数编码
- 提供类型转换工具
安装方法
在Cargo.toml中添加依赖:
[dependencies]
fuel-abi-types = "0.1"
基本使用方法
1. 基本类型使用
use fuel_abi_types::abi::full_program::FullTypeDeclaration;
use fuel_abi_types::utils::extract_custom_type_name;
let type_decl = FullTypeDeclaration {
type_field: "struct MyStruct".to_string(),
components: None,
type_parameters: None,
};
let custom_name = extract_custom_type_name(&type_decl.type_field);
assert_eq!(custom_name, Some("MyStruct"));
2. ABI参数编码
use fuel_abi_types::abi::program::ProgramABI;
use fuel_abi_types::traits::{Parameterize, Tokenizable};
use serde_json;
// 从JSON加载ABI定义
let abi_json = r#"
{
"types": [],
"functions": [
{
"inputs": [
{
"name": "amount",
"type": "u64",
"components": null,
"typeParameters": null
}
],
"name": "transfer",
"output": {
"name": "",
"type": "bool",
"components": null,
"typeParameters": null
}
}
]
}"#;
let abi: ProgramABI = serde_json::from_str(abi_json).unwrap();
println!("Loaded ABI with {} functions", abi.functions.len());
3. 类型转换
use fuel_abi_types::abi::full_program::FullTypeDeclaration;
use fuel_abi_types::program_bindings::utils::to_token;
let value = 42u64;
let token = to_token(&value).unwrap();
println!("Token representation: {:?}", token);
高级用法
自定义类型处理
use fuel_abi_types::abi::full_program::{FullTypeDeclaration, FullTypeApplication};
use fuel_abi_types::program_bindings::utils::transform_json_type_to_token;
let custom_type = FullTypeDeclaration {
type_field: "struct MyCustomType".to_string(),
components: Some(vec![
FullTypeApplication {
name: "field1".to_string(),
type_decl: FullTypeDeclaration {
type_field: "u32".to_string(),
components: None,
type_parameters: None,
},
},
FullTypeApplication {
name: "field2".to_string(),
type_decl: FullTypeDeclaration {
type_field: "bool".to_string(),
components: None,
type_parameters: None,
},
},
]),
type_parameters: None,
};
let json_value = serde_json::json!({
"field1": 100,
"field2": true
});
let token = transform_json_type_to_token(&json_value, &custom_type).unwrap();
println!("Custom type token: {:?}", token);
实际应用场景
- 合约调用参数编码:
use fuel_abi_types::program_bindings::ParamType;
use fuel_abi_types::traits::Tokenizable;
fn encode_transfer_call(recipient: [u8; 32], amount: u64) -> Vec<u8> {
let recipient_param = ParamType::B256;
let amount_param = ParamType::U64;
let tokens = vec![
recipient_param.encode_token(recipient).unwrap(),
amount_param.encode_token(amount).unwrap()
];
// 这里通常会使用fuel-vm或其他库进行实际编码
tokens.iter().flat_map(|t| t.to_bytes()).collect()
}
- ABI验证:
use fuel_abi_types::abi::program::ProgramABI;
use fuel_abi_types::abi::errors::AbiError;
fn validate_abi(abi: &ProgramABI) -> Result<(), AbiError> {
// 检查是否有函数定义
if abi.functions.is_empty() {
return Err(AbiError::new("ABI must contain at least one function"));
}
// 检查每个函数的输入输出类型是否有效
for func in &abi.functions {
// 验证逻辑...
}
Ok(())
}
完整示例Demo
下面是一个完整的合约调用示例,展示了如何使用fuel-abi-types库进行参数编码和ABI处理:
use fuel_abi_types::{
abi::{
full_program::{FullTypeApplication, FullTypeDeclaration},
program::ProgramABI,
},
program_bindings::{utils::transform_json_type_to_token, ParamType},
traits::{Parameterize, Tokenizable},
};
use serde_json::json;
fn main() {
// 1. 定义合约ABI
let abi_json = r#"
{
"types": [
{
"typeField": "struct TransferParams",
"components": [
{
"name": "recipient",
"type": "b256",
"components": null,
"typeParameters": null
},
{
"name": "amount",
"type": "u64",
"components": null,
"typeParameters": null
}
],
"typeParameters": null
}
],
"functions": [
{
"inputs": [
{
"name": "params",
"type": "TransferParams",
"components": null,
"typeParameters": null
}
],
"name": "transfer",
"output": {
"name": "",
"type": "bool",
"components": null,
"typeParameters": null
}
}
]
}"#;
// 2. 解析ABI
let abi: ProgramABI = serde_json::from_str(abi_json).unwrap();
// 3. 准备调用参数
let transfer_params = json!({
"recipient": "0x7d9d9e7e7d9d9e7e7d9d9e7e7d9d9e7e7d9d9e7e7d9d9e7e7d9d9e7e7d9d9e7e",
"amount": 1000
});
// 4. 查找类型定义
let transfer_type = abi.types.iter().find(|t| t.type_field == "struct TransferParams").unwrap();
// 5. 将JSON参数转换为Token
let token = transform_json_type_to_token(&transfer_params, transfer_type).unwrap();
println!("Generated token: {:?}", token);
// 6. 编码为字节
let encoded: Vec<u8> = token.to_bytes();
println!("Encoded bytes: {:?}", encoded);
// 7. 验证ABI
if let Err(e) = validate_abi(&abi) {
eprintln!("ABI validation failed: {}", e);
}
}
// ABI验证函数
fn validate_abi(abi: &ProgramABI) -> Result<(), String> {
if abi.functions.is_empty() {
return Err("ABI must contain at least one function".to_string());
}
for func in &abi.functions {
if func.name.is_empty() {
return Err("Function name cannot be empty".to_string());
}
}
Ok(())
}
注意事项
- Fuel区块链使用特定的ABI格式,与其他区块链(如Ethereum)不兼容
- 类型序列化遵循Fuel区块链的规范
- 复杂类型(如结构体、枚举)需要正确定义components字段
- 处理大整数时要注意类型范围和精度
总结
fuel-abi-types
库为Fuel区块链智能合约开发提供了强大的ABI处理能力,通过类型安全的方式简化了合约调用参数编码、返回值解码等常见任务。结合Fuel生态的其他工具如fuels-rs
,可以构建完整的区块链应用开发工作流。