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

2024-03-29 14:07:16 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在尝试为由我想要的契约创建的契约引发的事件创建筛选器。但是,我想不通。这是我现在所拥有的。在

MergeModule.sol

pragma solidity ^0.4.23;

contract MergeModule {
    event MergeEvent(uint prID);

    function MergeModule(){

    }

    function merge(uint prID) public {
        emit MergeEvent(prID);
    }
}

Handler.sol

^{pr2}$

test_handler.py

from web3 import Web3, EthereumTesterProvider
import unittest
import os
from eth_tester.exceptions import TransactionFailed
import tests.utils.utils as utils
from web3.utils.filters import Filter


class TestHandler(unittest.TestCase):
    PROJECT_ROOT = os.path.dirname(os.path.dirname(__file__))
    CONTRACT_ROOT = os.path.join(PROJECT_ROOT, "contracts")
    TEST_CONTRACT_ROOT = os.path.join(CONTRACT_ROOT, "test_contracts")

    def setUp(self):
        handler_contract_path = os.path.join(self.CONTRACT_ROOT, "handler.sol")

        # web3.py instance
        self.w3 = Web3(EthereumTesterProvider())

        self.contract, self.contract_address, self.contract_instance = utils.create_contract(self.CONTRACT_ROOT,
                                                                                             handler_contract_path,
                                                                                             "Handler", self.w3)


    def test_event_emitted(self):
        # this prints something different from self.contract_address
        print(self.contract_instance.mergeModule())

        # this creates a reference to the Handler contract. I know this because when I inspect it with the debugger I see `execute` as one of the functions
        merge_contract = self.w3.eth.contract(self.contract_instance.mergeModule())
        merge_event_filter: Filter = merge_contract.events.MergeEvent.createFilter(fromBlock=0)

        # do stuff here with the filter

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

当我运行这个时得到的错误是:AttributeError: 'ContractEvents' object has no attribute 'MergeEvent',这是有意义的,因为merge_contract是一个Handler契约,而不是MergeModule契约。在


Tags: pathinstancefromimportselfosutilsroot
1条回答
网友
1楼 · 发布于 2024-03-29 14:07:16

看来我是对的。为MergeModule传递abi是关键。这是我写的一个hacky函数,用来获取对merge模块的引用。在

    def get_merge_module(self):
        from solc import compile_source, compile_files

        # compile all of my contract files, one of which is the solidity file with the merge module
        compiled_sol = compile_files(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)

        return merge_contract

相关问题 更多 >