3 个版本
0.1.2 | 2023 年 12 月 9 日 |
---|---|
0.1.1 | 2023 年 12 月 9 日 |
0.1.0 | 2023 年 12 月 6 日 |
#54 在 #starknet
在 switchboard-starknet-sdk 中使用
43KB
821 行
为 starknet-abigen-rs
的过程宏
abigen
abigen
宏旨在从智能合约的 ABI
生成 Rust 绑定。生成的绑定包含 ABI
文件中存在的所有函数、事件、结构和枚举。
一些类型直接映射到 Rust 原生类型(如整数、Result
、Option
、布尔值等),其他特定类型如 ContractAddress
、ClassHash
或 EthAddress
由 starknet-rs
管理,而 ABI
中找到的所有其他类型都根据需要生成为 struct
或 enum
。
abigen
将生成所有必要的序列化/反序列化代码,以便与纯 Rust 类型一起使用。
例如
// Cairo function like fn view_1(self: @ContractState, v: felt252, s: Span<felt252>)
// is generated in rust like:
fn view_1(v: FieldElement, s: Vec<FieldElement>);
要为您的合约生成绑定,您可以执行以下操作
use starknet::macros::abigen;
abigen!(MyContract, "/path/to/abi.json");
这将生成所有类型和两个 struct
,用于合约
-
MyContractReader
,用于调用仅读取区块链状态的view
函数。要初始化一个读取器,您需要一个合约地址和一个提供者let rpc_url = Url::parse("http://0.0.0.0:5050").unwrap(); let provider = JsonRpcClient::new(HttpTransport::new(rpc_url.clone())); let contract_address = FieldElement::from_hex_be("0x123...").unwrap(); let reader = MyContractReader::new(contract_address, &provider); let result = reader.my_view_1().await;
-
MyContract
,它反过来用于调用external
函数,其中实际上会将事务发送到区块链。这需要一个账户来签署这些事务let rpc_url = Url::parse("http://0.0.0.0:5050").unwrap(); let provider = JsonRpcClient::new(HttpTransport::new(rpc_url.clone())); let signer = LocalWallet::from(SigningKey::from_secret_scalar( FieldElement::from_hex_be("<PRIVATE_KEY_HEX>").unwrap(), )); let account_address = FieldElement::from_hex_be("<ACCOUNT_ADDRESS_HEX>").unwrap(); let account = SingleOwnerAccount::new( provider.clone(), signer, address, felt!("0x4b4154414e41"), // KATANA ExecutionEncoding::Legacy, ); let contract_address = FieldElement::from_hex_be("0x123...").unwrap(); let reader = MyContract::new(contract_address, &account); let result = reader.my_external_1().await;
abigen
宏提供的另一个功能是反序列化事件的能力。在 ABI
中,始终有一个包含在您的合约中声明的所有事件的 Event
枚举。
然后您可以执行以下操作
let even_page = provider.fetch_events(...);
for e in event_page.events {
let my_event: Event = match e.try_into() {
Ok(ev) => ev,
Err(_) => continue; // This is an event from an other contract or you may use an out-dated ABI.
};
match my_event {
Event::MyEventA(a) => // work with a, already typed and deserialized,
Event::MyEventB(b) => // work with b, already typed and deserialized,
...
};
}
依赖项
~12–27MB
~409K SLoC