#abi #ethereum #json-rpc #web3 #rpc

ethane-abi

一个旨在实现简洁性的替代Web3 ABI解析库

3个稳定版本

1.0.2 2021年5月27日
1.0.1 2021年4月28日
1.0.0 2021年4月20日

#abi中排名109


2个crate中使用(通过ethane

MIT许可证

93KB
2K SLoC

Ethane Logo

Stake to support us Latest Version Minimum rustc version

故事

该软件包最初由thojest创建,并由ZGEN DAO维护。旨在为用Rust编写的Web3软件包提供一个简单的替代方案。

描述

Ethane是一个旨在实现精简和简单的Web3实现。它有两个特性 blockingnon-blocking,这决定了它应使用哪种http连接类型。

阻塞http客户端不依赖于futures或任何执行器。此外,它目前支持WebSocket(包括plain和TLS)以及通过Unix域套接字(仅限Unix)进行进程间通信。对于http和WebSocket,它还支持Http Basic和Bearer身份验证。它还包含一个内置的ABI解析库。它隐藏在合约功能之下,但可以与主crate一起使用。

如果您仍然需要一个非阻塞的http客户端(例如,为了与wasm兼容),您可以在编译Ethane时使用non-blocking功能标志以启用异步http客户端。

请参阅文档。如果您只想使用此crate,它也可在crates.io上找到。 (Ethane)。如果您发现任何错误,请毫不犹豫地提出问题。

用法

使用Ethane库的指南。示例是为阻塞客户端编写的,但是非阻塞版本相当类似。主要区别在于AsyncConnection只能包装一个无类型的AsyncHttp客户端,因此目前还没有非阻塞WebSocket的实现。

连接

一切从连接开始。

use ethane::{Connection, Http, WebSocket};

fn main() {
    let conn = Connection::new(Http::new("https://127.0.0.1:8545", None));
    // or
    let conn = Connection::new(WebSocket::new("ws://127.0.0.1:8546", None));
}

方法

连接到以太坊网络后,我们可以调用几个方法。稍后详细介绍支持的方法。

use ethane::{Connection, Http};
use ethane::types::Address;

fn main() {
    let conn = Connection::new(Http::new("https://127.0.0.1:8545", None));
    
    match conn.call(rpc::eth_get_balance(Address::try_from_str(ADDRESS1).unwrap(), None)) {
        Ok(res) => res,
        Err(err) => println!("{:?}", err),
    }
}

合约调用

该库还支持通过 ethane-abi 进行合约调用。

use ethane::{Connection, Http};
use ethane::contract::{CallOpts, CallResult, Caller};
use ethane::types::{Address, U256};
use ethane_abi::Parameter;

fn main() {
    let conn = Connection::new(Http::new("https://127.0.0.1:8545", None));

    let mut caller = Caller::new_from_path(
        conn,
        "path/to/contract.abi",
        Address::try_from_str("0x141770c471a64bcde74c587e55a1ffd9a1bffd31").unwrap(),
    );

    // The call function determine the call_type based on the state_mutability.
    // This calls to function from an ERC-20 compliant token
    // eth_call
    let address = Address::try_from_str("0x141770c471a64bcde74c587e55a1ffd9a1bffd31").uwnrap();
    let result = caller.call(
        "balanceOf",
        vec![Parameter::from(address)],
        None,
    );
    match result {
        CallResult::Transaction(_) => panic!("Should be eth_call"),
        CallResult::Call(r) => match r[0] {
            Parameter::Uint(data, 256) => assert_eq!(data, H256::from_int_unchecked(1000000000_u64)),
            _ => panic!("Invalid data received!"),
        },
    }

    // eth_sendTransaction
    let to_address = Address::try_from_str("0x...").unwrap();
    let result = caller.call(
        "transfer",
        vec![
            Parameter::from(to_address),
            Parameter::from(U256::try_from_int(1000_u128).unwrap()),
        ],
        Some(CallOpts {
            force_call_type: None, // NOTE: the call_type can be forced
            from: Some(address),
        }),
    );
    match result {
        CallResult::Call(_) => panic!("Should be a transaction"),
        CallResult::Transaction(tx_hash) => println!("{}", tx_hash),
    }
}

订阅

订阅有不同的连接方法。

use ethane::{Connection, WebSocket};

fn main() {
    let conn = Connection::new(WebSocket::new("ws://127.0.0.1:8546", None));
    let mut tx_subscription = conn.subscribe(eth_subscribe_new_pending_transactions()).unwrap();

    // Get next transaction item
    let tx = tx_subscription.next_item().unwrap();
}

贡献

欢迎提交问题和PR。开发遵循开源软件标准

依赖

~0.7–1.4MB
~33K SLoC