#json-rpc #ethereum #simple #http-client #web3 #rpc

ethane

以简洁和简单为目标的Web3实现方案

4个版本 (稳定版)

1.0.2 2021年5月27日
1.0.1 2021年4月28日
1.0.0 2021年4月20日
0.1.1 2021年2月22日
0.1.0 2021年2月11日

#96 in #web3


用于 ethane-wasm

MIT 许可协议

155KB
3.5K 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(包括纯文本和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。开发遵循 OSS标准

依赖项

~12–28MB
~497K SLoC