假设我有这样的代码:
private async void LaunchEventRetrievalLoop()
{
try
{
Debug.Log("Creating event filter");
Event transferEvent = web3DirectClient.Eth.GetEvent(ContractAddress);
NewFilterInput filterInput = transferEvent.CreateFilterInput();
HexBigInteger filterId = await transferEvent.CreateFilterAsync(filterInput);
Debug.Log("Starting event lifecycle");
while (gameObject)
{
Debug.Log("Testing log");
List> events = await transferEvent.GetFilterChangesAsync(filterId);
Debug.Log($"Iterating log ({events.Count})");
foreach (EventLog @event in events)
{
string eventLine = $"\n{@event.Log.BlockNumber} {@event.Log.Type} - " +
$"{@event.Event.From}->{@event.Event.To} : {@event.Event.Value}";
if (string.IsNullOrEmpty(eventsBox.text))
{
eventsBox.text = eventLine;
}
else
{
eventsBox.text += $"\n{eventLine}";
}
}
float time = 0;
while (time < 5f)
{
await Tasks.Blink();
time += Time.deltaTime;
}
}
Debug.Log("Destroying everything");
}
catch (Exception e)
{
Debug.LogException(e);
}
}大部分代码来自教程是怎么说的,用于检索几乎实时的事件。此代码在统一同步上下文中运行(此方法是异步的,但在Unity中)。
如您所见,有许多日志,但是在while循环中,有两个日志是反复出现的:
Testing log
Iterating log (0)
# these lines repeat over and over in intervals of 5 seconds - no Unity time scaling.它的意思是:我根本没有收到任何事件。
这个例程是样例UI的一部分,它实际上可以连接到示例Ganache GUI本地服务器(at http://my.local.network.address:8545/),并通过一个哑协议发出查询(调用)和事务(发送),这实际上是我创建的一个ERC-20协议,它只是为了有一个视图方法、一个非视图方法和一个要测试的事件。
除了这些事件,一切都很顺利。我拥有的Erc20TransferEvent模型如下所示:
[Event("Transfer")]
public class Erc20TransferEvent : IEventDTO
{
[Parameter("address", "_from", 1)]
public string From { get; set; }
[Parameter("address", "_to", 2)]
public string To { get; set; }
[Parameter("uint256", "_value", 3)]
public System.Numerics.BigInteger Value { get; set; }
}与教程相同(假设IEventDTO和Event是适当导入的)。
假设一个最新版本的Ganache GUI存储库,并且假设ContractAddress中的一个有效值是OpenZeppelin的ERC-20实现(它在构造函数中只有一个额外的实现来为契约的创建者创建一个默认的令牌供应),在这个实现中,我可以使用相同的Web3 web3DirectClient实例在合同的方法上发出发送和调用命令.
...What我在这里失踪了吗?为什么我不能记录任何单个事件?即使Ganache GUI对事务是即时的,我也不会看到任何日志,不管我等待了多少。
发布于 2022-06-17 05:07:46
好的,我加入了一个临时答案,这在我所需要的程度上是正确的,但不是我想要的方式。我对新的答案持开放态度,并可能在这个过程中作为其他答案的基础。
答案由两部分组成。
第一个问题是,实际上,我在DTO定义中犯了一个错误:I忘记添加索引参数的标志。索引参数非常重要,因为在事件中搜索最多3个主题是有用的(例如,在ERC-20中快速获取特定发送方、特定接收方或两者的事件),但是还需要根据事件定义在相应的DTO参数上指定they以执行查找。因此,定义必须在索引参数的Parameter定义中包含第四个参数(两个,在ERC-20's传输事件中):
[Event("Transfer")]
public class Erc20TransferEvent : IEventDTO
{
[Parameter("address", "_from", 1, true)]
public string From { get; set; }
[Parameter("address", "_to", 2, true)]
public string To { get; set; }
[Parameter("uint256", "_value", 3)]
public System.Numerics.BigInteger Value { get; set; }
}(注意true标志,在第1和第2事件参数中添加为第4个参数)
第二部分..。我不太确定。也许有些地方我不理解库或它上的bug (我使用的版本实际上是从Moralis.io SDK中提取出来的版本)。然而,我以一种我不喜欢的方式解决了这个问题:改变范式/使用另一个可用的调用:GetAllChangesAsync-based方法(而不是GetFilterChangesAsync-based方法),其中我必须显式地控制块范围:
private async void LaunchEventRetrievalLoop()
{
try
{
Debug.Log("Creating event filter");
Event transferEvent = web3DirectClient.Eth.GetEvent(ContractAddress);
BlockParameter fromBlock = null;
Debug.Log("Starting event lifecycle");
while (gameObject)
{
NewFilterInput filterInput = transferEvent.CreateFilterInput(fromBlock, null);
Debug.Log("Testing log");
List> events = await transferEvent.GetAllChangesAsync(filterInput);
Debug.Log($"Iterating log ({events.Count})");
foreach (EventLog @event in events)
{
string eventLine = $"\n{@event.Log.BlockNumber} {@event.Log.Type} - " +
$"{@event.Event.From}->{@event.Event.To} : {@event.Event.Value}";
if (string.IsNullOrEmpty(eventsBox.text))
{
eventsBox.text = eventLine;
}
else
{
eventsBox.text += $"\n{eventLine}";
}
fromBlock = new BlockParameter(new HexBigInteger(@event.Log.BlockNumber.Value + 1));
}
float time = 0;
while (time < 5f)
{
await Tasks.Blink();
time += Time.deltaTime;
}
}
Debug.Log("Destroying everything");
}
catch (Exception e)
{
Debug.LogException(e);
}
}请注意:我不确定这是否是由于我正在使用的版本(S)的错误还是什么--至少索引标志是必需的,但我不确定,如果在其他人的尝试中它恰好是对另一个代码版本中的GetFilterChangesAsync_-方法的修改或接受的话。
https://ethereum.stackexchange.com/questions/130295
复制相似问题