如何在 web3py 中为合约创建的合约创建事件过滤器

Posted

技术标签:

【中文标题】如何在 web3py 中为合约创建的合约创建事件过滤器【英文标题】:How to create event filter for contract created by contract in web3py 【发布时间】:2018-10-23 00:05:14 【问题描述】:

我正在尝试为由我想要的合同创建的合同引发的事件创建一个过滤器。但是,我无法弄清楚。这是我现在拥有的。

MergeModule.sol

pragma 可靠性 ^0.4.23; 合约合并模块 事件合并事件(uint prID); 功能合并模块() 功能合并(uint prID)公共 发出合并事件(prID);

Handler.sol

pragma 可靠性 ^0.4.23; 导入“./merge_module.sol”; 合约处理程序 // 编译器会自动为此生成一个 getter 地址公共mergeModule; 函数处理程序()公共 合并模块 = 新合并模块(); 函数执行()公共 合并模块.merge();

test_handler.py

从 web3 导入 Web3,EthereumTesterProvider 导入单元测试 导入操作系统 从 eth_tester.exceptions 导入 TransactionFailed 将 tests.utils.utils 导入为 utils 从 web3.utils.filters 导入过滤器 类TestHandler(unittest.TestCase): PROJECT_ROOT = os.path.dirname(os.path.dirname(__file__)) CONTRACT_ROOT = os.path.join(PROJECT_ROOT, "合同") TEST_CONTRACT_ROOT = os.path.join(CONTRACT_ROOT, "test_contracts") 默认设置(自我): handler_contract_path = os.path.join(self.CONTRACT_ROOT, "handler.sol") # web3.py 实例 self.w3 = Web3(EthereumTesterProvider()) self.contract, self.contract_address, self.contract_instance = utils.create_contract(self.CONTRACT_ROOT, handler_contract_path, “处理程序”,self.w3) def test_event_emitted(self): # 这会打印出与 self.contract_address 不同的东西 打印(self.contract_instance.mergeModule()) # 这会创建对 Handler 合约的引用。我知道这一点,因为当我使用调试器检查它时,我将“执行”视为功能之一 merge_contract = self.w3.eth.contract(self.contract_instance.mergeModule()) merge_event_filter:过滤器 = merge_contract.events.MergeEvent.createFilter(fromBlock=0) # 在这里用过滤器做一些事情

utils.create_contract 或多或少做了quickstart for web3py 中显示的内容,并进行了一些修改以处理编译多个文件。我怀疑在执行merge_contract = self.w3.eth.contract(self.contract_instance.mergeModule()) 时我需要传递abimerge_contract = self.w3.eth.contract(self.contract_instance.mergeModule()),但我不确定。

我运行它时得到的错误是:AttributeError: 'ContractEvents' object has no attribute 'MergeEvent',这是有道理的,因为merge_contractHandler 合约而不是MergeModule 合约。

【问题讨论】:

【参考方案1】:

看来我是对的。将abi 传递给MergeModule 是关键。这是我编写的一个 hacky 函数,用于获取对合并模块的引用。

def get_merge_module(self): 从 solc 导入 compile_source,compile_files # 编译我所有的合约文件,其中之一是带有合并模块的solidity文件 编译溶胶 = 编译文件(utils.get_contract_file_paths(self.CONTRACT_ROOT)) contract_interface = compiled_sol[f'os.path.join(self.CONTRACT_ROOT, "merge_module.sol"):MergeModule'] abi = contract_interface["abi"] merge_contract = self.w3.eth.contract(self.contract_instance.mergeModule(), abi=abi) 返回合并合同

【讨论】:

以上是关于如何在 web3py 中为合约创建的合约创建事件过滤器的主要内容,如果未能解决你的问题,请参考以下文章

如何在 AssemblyScript 中为 NEAR 合约创建 UID?

没有明显原因的智能合约函数调用上的ValidationError(web3py)?

Uniswap的pair合约创建事件

不会为以太坊智能合约生成事件日志

持续监听智能合约事件

useState 变量在事件回调中为空