Как создать фильтр событий для контракта, созданного контрактом в web3py - PullRequest
0 голосов
/ 13 мая 2018

Я пытаюсь создать фильтр для события, вызванного контрактом, созданным моим желаемым контрактом. Однако я не могу понять это. Вот что у меня сейчас.

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

pragma solidity ^0.4.23;

import "./merge_module.sol";

contract Handler {

    // a getter for this will automatically be made by the compiler
    address public mergeModule;

    function Handler() public {
        mergeModule = new MergeModule();
    }

    function execute() public {
        mergeModule.merge();
    }
}

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 более или менее соответствует тому, что показано в быстром запуске для web3py с некоторыми изменениями для обработки компиляции нескольких файлов. Я подозреваю , что мне нужно передать abi из mergeModule при выполнении merge_contract = self.w3.eth.contract(self.contract_instance.mergeModule()), но я не уверен.

Ошибка, которую я получаю при запуске: AttributeError: 'ContractEvents' object has no attribute 'MergeEvent', что имеет смысл, поскольку merge_contract - это Handler контракт, а не MergeModule контракт.

1 Ответ

0 голосов
/ 13 мая 2018

Похоже, я был прав. Передача abi для MergeModule была ключевой. Вот хакерская функция, которую я написал, чтобы получить ссылку на модуль слияния.

    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
...