event_filter = w3.eth.filter({
'address': contract_address,
'fromBlock':4916476,
'toBlock':4916576
# 'topics':[topic]
})
for event in event_filter.get_all_entries():
print(event)
我部署了一个合约并想使用 w3 扫描事件。返回的结果是一堆包含“地址、主题、..”等的“attributesDict”。 问题是信息存储在“数据”中,如下所示:
'
data
': '0x0000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000046164616d00000000000000000000000000000000000000000000000000000000
',
这些来自区块链事件的“数据”包含什么?我应该如何解码才能获得我想要的信息?
我正在使用 web3 5.22.0 顺便说一句
问题解决了。我想分享一些我发现的东西,希望对其他人有帮助。
基本上,w3.eth.get_new/all_entries 检索到的 attributeDict 中的“数据”正是存储在区块上智能合约的“事件”中的信息。 例如,我写了这个样本合同
struct UserInfo{
address userAddr;
uint userId;
}
UserInfo[] public userInfo;
event setUserEvent(address addrs, uint ids);
function setUser(address addr_, uint id_) public {
userInfo.push(UserInfo(addr_, id_));
emit setUserEvent(addr_, id_);
}
SetUser 函数将记录事件“setUserEvent”中的地址和 id。如果我正确调用该函数,检索到的“数据”将如下所示:
'0x00000000000000000000000057384071e06f31aaaa039da92907a0000017691d20000000000000000000000000000000000000000000000000000000 00000000001'
这个十六进制字节有 2 个部分(每个部分有 64 个十六进制字节,所以我这里总共有 128 个)包含 2 条信息(地址和我通过调用 setUser 函数存储的 Id)。显然地址是
‘0x00000000000000000000000057384071e06f31aaaa039da92907a0000017691d2’
这是前 64 个十六进制字节(0x 不算)
而 ID 实际上是
'0000000000000000000000000000000000000000000000000000000000000001'
一个。这是“数据”的第二部分,64 十六进制。
我现在要做的就是把地址中多余的0去掉,把开头的0x还回去,把ID号变成普通的数字。
顺便说一句,如果您遇到一些奇怪的情况,例如数据包含额外的“64”和更多信息,例如单个数字,这不是您在事件中存储的数字,可能是因为它并不真正支持您在事件中存储字符,例如用户名等(字符串)。不过,它可以被扫描,当你尝试解码它时,它看起来会很奇怪。该单个数字应与您存储在事件中的字符串的字符数相匹配。