4 个版本

0.10.1 2023 年 7 月 6 日
0.10.0 2023 年 4 月 12 日
0.9.1 2023 年 3 月 10 日
0.9.0 2022 年 12 月 8 日

#2835魔法豆

Download history 62/week @ 2024-03-09 21/week @ 2024-03-16 2/week @ 2024-03-23 21/week @ 2024-03-30 28/week @ 2024-04-06 54/week @ 2024-04-13 19/week @ 2024-04-20 2/week @ 2024-05-04 11/week @ 2024-05-11 33/week @ 2024-05-18 3/week @ 2024-05-25 38/week @ 2024-06-01 18/week @ 2024-06-08 16/week @ 2024-06-15 5/week @ 2024-06-22

每月 77 次下载

Apache-2.0

56KB
1K SLoC

事务管理器

eth-tx-manager 是一个用于向区块链提交事务的 Rust 库。它试图考虑事务发送到交易池可能出现的多种情况,并据此进行调整。

最显著的是,它

  • 自动管理nonce。
  • 必要时重发事务。
  • 等待指定数量的区块确认。
  • 从硬崩溃中恢复。

使用示例

此示例的代码位于 examples/send_transaction.rs。您可以使用 cargo run --example send_transaction 命令运行它。您需要有一个本地以开发模式运行的 geth 节点。

要开始发送事务,我们首先必须通过调用其构造函数来实例化一个 TransactionManager 对象。

TransactionManager::new(provider, gas_oracle, database, chain, configuration)

chain 参数是一个包含链 ID 和一个布尔值(表示目标区块链是否实现了 EIP-1559)的 Chain 对象。我们可以通过调用 Chain::newChain::legacy 函数来实例化它。

let chain = Chain::new(1337);

provider 是一个实现 ethers::providers::Middleware 特性的对象。(在我们的示例中,我们将向以开发模式运行的本地 geth 节点发送事务。)

let provider = Provider::<Http>::try_from("https://127.0.0.1:8545").unwrap();

服务提供方负责签署我们将发送的交易,因此,我们使用签署器中间件将其封装。

let wallet = LocalWallet::new(&mut thread_rng()).with_chain_id(chain.id);
let provider = SignerMiddleware::new(provider, wallet);

gas_oracledatabase 参数是注入到事务管理器中的依赖项,分别用于处理汽油价格和保证健壮性。configuration 用于微调内部等待时间。我们将在下一节中讨论这些内容,但在此期间,我们将使用它们提供的默认实现。

let gas_oracle = DefaultGasOracle::new();
let database = FileSystemDatabase::new("database.json".to_string());
let configuration = Configuration::default();

然后,我们可以实例化事务管理器

let (manager, receipt) =
    TransactionManager::new(provider, gas_oracle, database, chain, configuration)
        .await
        .unwrap();

assert!(receipt.is_none());

请注意,new 函数是异步的,并返回一个事务管理器和 Option<ethers::types::TransactionReceipt>。我们设计了事务管理器以使其健壮。如果在发送交易时管理器失败或被中断(例如硬件故障),它将尝试在其下一次实例化期间确认该交易,因此,可能的收据和异步的需要。本质上,这保证了我们始终处理挂起的交易。

有了管理器在手,我们可以通过调用名为 send_transaction 的方法来发送交易。

pub async fn send_transaction(
    mut self,
    transaction: Transaction,
    confirmations: usize,
    priority: Priority,
) -> Result<(Self, TransactionReceipt), Error<M, GO, DB>> {

send_transaction 方法接受一个 mut self 事务管理器,实际上接受管理器实例的所有权。当函数完成后,它返回该实例以及预期的交易收据。这通过类型系统强制执行(1)如果函数失败,则需要实例化一个新的管理器;(2)我们只能顺序发送交易。属性1保证了任何挂起的交易将由构造函数管理,属性2强制执行同步性(并发会导致很多不希望出现的复杂性)。

函数还接受一个 confirmations 参数。确认次数是在交易放置在区块中之后必须挖掘的区块数,以便函数成功返回。换句话说,如果确认次数为0,函数在交易被挖掘后立即返回,否则,它将等待 confirmations 更多区块被挖掘后返回。(这基本上考虑了网络重组。)

优先级级别是发送给汽油预言机的参数,用于计算适当的汽油费用。较高的优先级费用更高,但可以减少等待时间,反之亦然。

let transaction = Transaction {
    from: wallet.address(),
    to: H160::random(),
    value: Value::Number(U256::from(1e9 as u64)),
    call_data: None,
};

let result = manager
    .send_transaction(transaction, 1, Priority::Normal)
    .await;
assert!(result.is_err());

在我们的虚构示例中,我们是从一个随机钱包发送资金,所以很明显,该交易将以“资金不足”错误失败。

汽油预言机

待办事项。

数据库

待办事项。

配置

待办事项。

内部工作原理

待办事项。

依赖项

~25–45MB
~707K SLoC