有没有办法获取待处理交易的收据或日志?

huangapple go评论71阅读模式
英文:

Is there any way to get receipt or logs of pending transaction?

问题

让我们说我们可以使用下面的代码来监听待处理的交易。我们可以使用provider.call()函数模拟交易。然后,我们可以将模拟交易的结果作为字符串获取。
有一种方法可以获取模拟交易的日志。我想知道它影响了哪些合约。我该如何做到这一点?

const init = async () => {
    wsProvider.on("pending", async (tx_hash) => {
        const getTxResponse = await provider.getTransaction(tx_hash)
        if (!getTxResponse) return;

        const transaction = ethers.Transaction.from(getTxResponse);

        try {
            const call = await provider.call(transaction);

            // 这是模拟的。如何获取日志?

            console.log(call);
        } catch (e) {
            console.log(e);
        }
    });
};

我尝试使用provider.call(transaction)来模拟执行交易。我正在寻找获取模拟交易日志的方法。

英文:

Let's say we can listen for pending transaction using code below. We can simulate transactions using provider.call() function. And we can get result from simulated transaction as a string.
There should be a way to get logs of simulated transaction. I'd like to know which contracts it affected. How can I do this?

const init = async () => {
    wsProvider.on("pending", async (tx_hash) => {
        const getTxResponse = await provider.getTransaction(tx_hash)
        if (!getTxResponse) return;

        const transaction = ethers.Transaction.from(getTxResponse);

        try {
            const call = await provider.call(transaction);

            // It's simulated. How to get logs?

            console.log(call);
        } catch (e) {
            console.log(e);
        }


    });
};

I tried to simulate execution of tx using provider.call(transaction). I'm looking for a way to get logs of simulated tx.

答案1

得分: 2

Receipt is generated after the transaction is executed by a block producer (validator on PoS, miner on PoW), and published as part of the block.

Until a transaction is included in a published block, it's considered pending.

Meaning, transaction receipts (and parts of the receipt such as event logs) are not available for pending transactions.


We can simulate transactions using provider.call() function. And we can get result from simulated transaction as a string. There should be a way to get logs of simulated transaction.

This approach executes eth_call RPC method on the node that you're connected to. Logs are not generated for calls - only for transactions.


To get logs of an emulated transaction, you might need to run an emulator (Hardhat, Geth, EthereumJS, ...) that keeps access to the latest blockchain state (most likely you'll want to fork a public network) and then execute the transaction on this emulator.

英文:

> Is there any way to get receipt or logs of pending transaction?

Receipt is generated after the transaction is executed by a block producer (validator on PoS, miner on PoW), and published as part of the block.

Until a transaction is included in a published block, it's considered pending.

Meaning, transaction receipts (and parts of the receipt such as event logs) are not available for pending transactions.


> We can simulate transactions using provider.call() function. And we can get result from simulated transaction as a string. There should be a way to get logs of simulated transaction

This approach executes eth_call RPC method on the node that you're connected to. Logs are not generated for *calls - only for transactions.


To get logs of an emulated transaction, you might need to run an emulator (Hardhat, Geth, EthereumJS, ...) that keeps access to the latest blockchain state (most likely you'll want to fork a public network) and then execute the transaction on this emulator.

答案2

得分: 0

你可以通过以下方式模拟一笔交易:

  • 从区块链创建一个“主网分叉”,例如使用类似Anvil这样的测试RPC提供程序,这里有一个Python示例。
  • 在您的分叉网络上进行模拟交易广播。
  • 阅读模拟交易的收据中的日志。
英文:

You can simulate a transaction by

  • Creating a "mainnet fork" from a blockchain e.g. using a test-RPC provider like Anvil from Forge - here is a Python example
  • Doing a simulated transaction broadcast on your forked network
  • Reading the logs in the receipt of the simulated transaction

答案3

得分: 0

至于待处理的交易,它们与不包含在区块链中的任何其他交易对象没有区别,更正确的问题应该是:

如何在将交易对象包含到区块链之前获取交易对象的收据?

我们使用这种方法来模拟我们的交易,并在将它们提交到网络之前检查预期的状态和日志。您可以从内存池中选择一笔交易并执行相同的模拟。

  1. 我们使用 hardhat 来模拟交易。模拟是即时且在进程内执行的,这意味着您无需启动任何本地开发网络。
  2. 您将在latest区块上执行交易,这意味着您无需拥有archive节点 - 基本的RPC节点就足够了。
  3. 帐户:
    • 通过从内存池中选择交易,它们已经被签名,因此您可以立即执行它们。
    • 在我们的情况下,我们为其他没有私钥的帐户模拟交易。但是 hardhat 有一个名为 impersonateAccount 的特殊方法,允许您代表任何地址执行交易。

要了解它是如何工作的,这里是我们如何使用 dequanto 库 模拟交易的示例:

import { ERC20 } from '@dequanto-contracts/openzeppelin/ERC20';
import { HardhatProvider } from '@dequanto/hardhat/HardhatProvider';
import { $address } from '@dequanto/utils/$address';

const provider = new HardhatProvider();
const client = await provider.forked({ url: 'https://eth.public-rpc.com' });

const ownerImpersonated = '0x60faae176336dab62e284fe19b885b095d29fb7f';
const daiAddress = '0x6b175474e89094c44da98b954eedeac495271d0f';

await client.debug.impersonateAccount(ownerImpersonated);

const erc20 = new ERC20(daiAddress, client);
// 从帐户转账100DAI到零地址
const writer = await erc20.transfer({ address: ownerImpersonated }, $address.ZERO, 100n ** 18n);
const receipt = await writer.wait();

let transferEvents = erc20.extractLogsTransfer(receipt);
console.log(transferEvents);

使用原始的 hardhatweb3js 插件 将类似于以下方式:

import hardhat from 'hardhat';
import { Transaction  } from '@ethereumjs/tx';

// 来自内存池的交易
let tx: TransactionConfig & { v, r, s };

// 将进程内网络指向主网的最新块
await hardhat.reset('https://eth.public-rpc.com');

let hex = '0x' + new Transaction(tx).serialize().toString('hex');
let receipt = await hardhat.web3.eth.sendSignedTransaction(hex);

希望对您有所帮助。

英文:

As far as the pending transactions do not differ from any other transaction objects not included in the blockchain, the more correct question would be:

How to get the receipt for a Transaction Object before including it into the blockchain?

We use this approach to simulate our transactions and to check the expected status and logs before submitting them to the network. You can pick a transaction from the mempool and perform the same simulations.

  1. We use hardhat to simulate the transaction. The simulation is executed instantly and in-process, which means you don't need to launch any local development networks.
  2. You would execute the transaction on the latest block, which means you don't need to have the archive node - a basic RPC node is enough.
  3. Accounts:
    • By picking the transactions from the mempool, they are already signed, so you can execute them immediately.
    • In our case, we simulate transactions for other accounts whose private keys we don't have. But hardhat has a special method called impersonateAccount that allows you to execute transactions for any address.

To get a feeling for how it works, here is an example of how we simulate transactions using the dequanto library

import { ERC20 } from '@dequanto-contracts/openzeppelin/ERC20';
import { HardhatProvider } from '@dequanto/hardhat/HardhatProvider';
import { $address } from '@dequanto/utils/$address';

const provider = new HardhatProvider();
const client = await provider.forked({ url: 'https://eth.public-rpc.com' });

const ownerImpersonated = '0x60faae176336dab62e284fe19b885b095d29fb7f';
const daiAddress = '0x6b175474e89094c44da98b954eedeac495271d0f';

await client.debug.impersonateAccount(ownerImpersonated);

const erc20 = new ERC20(daiAddress, client);
// transfer 100DAI from account to zero address
const writer = await erc20.transfer({ address: ownerImpersonated }, $address.ZERO, 100n ** 18n);
const receipt = await writer.wait();

let transferEvents = erc20.extractLogsTransfer(receipt);
console.log(transferEvents);

With raw hardhat and web3js plugin it would be something like this:

import hardhat from 'hardhat'
import { Transaction  } from '@ethereumjs/tx';

// Transaction from mempool
let tx: TransactionConfig & { v, r, s };

// point the in-process network to target the mainnets latest
await hardhat.reset('https://eth.public-rpc.com');

let hex = '0x' + new Transaction(tx).serialize().toString('hex');
let receipt = await hardhat.web3.eth.sendSignedTransaction(hex);

Hope it helps.

答案4

得分: 0

谢谢大家的参与!
实际上,我提出了一个错误的问题。我需要日志的原因是为了确定哪些合同受到了交易的影响。
做这件事的方法是使用跟踪器调用提供程序,并将所有调用作为结果获取。

英文:

Thanks everybody for participating!
I actually asked a wrong question. The reason I need logs is to determine which contracts are affected with tx.
The way to do it is to call a provider with tracer and get all calls as a result.

huangapple
  • 本文由 发表于 2023年7月3日 17:15:51
  • 转载请务必保留本文链接:https://go.coder-hub.com/76603393.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定