예제 #1
0
    def __enter__(self) -> "Multicall":
        """Enter the Context Manager and substitute `ContractCall.__call__`"""
        # we set the code objects on ContractCall class so we can grab them later

        active_network = CONFIG.active_network

        if "multicall2" in active_network:
            self.address = active_network["multicall2"]
        elif "cmd" in active_network:
            deployment = self.deploy({"from": accounts[0]})
            self.address = deployment.address  # type: ignore
            self.block_number = deployment.tx.block_number  # type: ignore

        self.block_number = self.block_number or web3.eth.get_block_number()

        if self.address is None:
            raise ContractNotFound(
                "Must set Multicall address via `brownie.multicall(address=...)`"
            )
        elif not web3.eth.get_code(self.address,
                                   block_identifier=self.block_number):
            raise ContractNotFound(
                f"Multicall at address {self.address} does not exist at block {self.block_number}"
            )

        self._contract = Contract.from_abi("Multicall", self.address,
                                           MULTICALL2_ABI)
        getattr(ContractCall, "__multicall")[get_ident()] = self
예제 #2
0
    def _deprecated_init(
        self,
        name: str,
        address: Optional[str] = None,
        abi: Optional[List] = None,
        manifest_uri: Optional[str] = None,
        owner: Optional[AccountsType] = None,
    ) -> None:
        if manifest_uri and abi:
            raise ValueError(
                "Contract requires either abi or manifest_uri, but not both")
        if manifest_uri is not None:
            manifest = ethpm.get_manifest(manifest_uri)
            abi = manifest["contract_types"][name]["abi"]
            if address is None:
                address_list = ethpm.get_deployment_addresses(manifest, name)
                if not address_list:
                    raise ContractNotFound(
                        f"'{manifest['package_name']}' manifest does not contain"
                        f" a deployment of '{name}' on this chain")
                if len(address_list) > 1:
                    raise ValueError(
                        f"'{manifest['package_name']}' manifest contains more than one "
                        f"deployment of '{name}' on this chain, you must specify an address:"
                        f" {', '.join(address_list)}")
                address = address_list[0]
            name = manifest["contract_types"][name]["contract_name"]
        elif not address:
            raise TypeError(
                "Address cannot be None unless creating object from manifest")

        build = {"abi": abi, "contractName": name, "type": "contract"}
        _ContractBase.__init__(self, None, build, {})  # type: ignore
        _DeployedContractBase.__init__(self, address, owner, None)
예제 #3
0
    def __init__(self,
                 address: str,
                 owner: Optional[AccountsType] = None,
                 tx: TransactionReceiptType = None) -> None:
        address = _resolve_address(address)
        self.bytecode = web3.eth.getCode(address).hex()[2:]
        if not self.bytecode:
            raise ContractNotFound(f"No contract deployed at {address}")
        self._owner = owner
        self.tx = tx
        self.address = address
        _add_deployment_topics(address, self.abi)

        fn_names = [i["name"] for i in self.abi if i["type"] == "function"]
        for abi in [i for i in self.abi if i["type"] == "function"]:
            name = f"{self._name}.{abi['name']}"
            sig = build_function_signature(abi)
            natspec: Dict = {}
            if self._build.get("natspec"):
                natspec = self._build["natspec"]["methods"].get(sig, {})

            if fn_names.count(abi["name"]) == 1:
                fn = _get_method_object(address, abi, name, owner, natspec)
                self._check_and_set(abi["name"], fn)
                continue

            # special logic to handle function overloading
            if not hasattr(self, abi["name"]):
                overloaded = OverloadedMethod(address, name, owner)
                self._check_and_set(abi["name"], overloaded)
            getattr(self, abi["name"])._add_fn(abi, natspec)
예제 #4
0
 def __getattribute__(self, name: str) -> Any:
     if super().__getattribute__("_reverted"):
         raise ContractNotFound("This contract no longer exists.")
     try:
         return super().__getattribute__(name)
     except AttributeError:
         raise AttributeError(f"Contract '{self._name}' object has no attribute '{name}'")
예제 #5
0
    def from_ethpm(
        cls,
        name: str,
        manifest_uri: str,
        address: Optional[str] = None,
        owner: Optional[AccountsType] = None,
    ) -> "Contract":
        """
        Create a new `Contract` object from an ethPM manifest.

        Arguments
        ---------
        name : str
            Name of the contract.
        manifest_uri : str
            erc1319 registry URI where the manifest is located
        address : str optional
            Address where the contract is deployed. Only required if the
            manifest contains more than one deployment with the given name
            on the active chain.
        owner : Account, optional
            Contract owner. If set, transactions without a `from` field
            will be performed using this account.
        """
        manifest = ethpm.get_manifest(manifest_uri)

        if address is None:
            address_list = ethpm.get_deployment_addresses(manifest, name)
            if not address_list:
                raise ContractNotFound(
                    f"'{manifest['package_name']}' manifest does not contain"
                    f" a deployment of '{name}' on this chain"
                )
            if len(address_list) > 1:
                raise ValueError(
                    f"'{manifest['package_name']}' manifest contains more than one "
                    f"deployment of '{name}' on this chain, you must specify an address:"
                    f" {', '.join(address_list)}"
                )
            address = address_list[0]

        manifest["contract_types"][name]["contract_name"]
        build = {
            "abi": manifest["contract_types"][name]["abi"],
            "contractName": name,
            "natspec": manifest["contract_types"][name]["natspec"],
            "type": "contract",
        }

        self = cls.__new__(cls)
        _ContractBase.__init__(self, None, build, manifest["sources"])  # type: ignore
        _DeployedContractBase.__init__(self, address, owner)
        _add_deployment(self)
        return self
예제 #6
0
 def __init__(
     self, address: str, owner: Optional[AccountsType] = None, tx: TransactionReceiptType = None
 ) -> None:
     address = _resolve_address(address)
     self.bytecode = web3.eth.getCode(address).hex()[2:]
     if not self.bytecode:
         raise ContractNotFound(f"No contract deployed at {address}")
     self._owner = owner
     self.tx = tx
     self.address = address
     fn_names = [i["name"] for i in self.abi if i["type"] == "function"]
     for abi in [i for i in self.abi if i["type"] == "function"]:
         name = f"{self._name}.{abi['name']}"
         if fn_names.count(abi["name"]) == 1:
             self._check_and_set(abi["name"], _get_method_object(address, abi, name, owner))
             continue
         if not hasattr(self, abi["name"]):
             self._check_and_set(abi["name"], OverloadedMethod(address, name, owner))
         key = ",".join(i["type"] for i in abi["inputs"]).replace("256", "")
         getattr(self, abi["name"]).methods[key] = _get_method_object(address, abi, name, owner)
예제 #7
0
 def __init__(self, address, owner=None, tx=None):
     address = to_address(address)
     self.bytecode = web3.eth.getCode(address).hex()[2:]
     if not self.bytecode:
         raise ContractNotFound(f"No contract deployed at {address}")
     self._owner = owner
     self.tx = tx
     self.address = address
     fn_names = [i['name'] for i in self.abi if i['type'] == "function"]
     for abi in [i for i in self.abi if i['type'] == "function"]:
         name = f"{self._name}.{abi['name']}"
         if fn_names.count(abi['name']) == 1:
             self._check_and_set(
                 abi['name'], _get_method_object(address, abi, name, owner))
             continue
         if not hasattr(self, abi['name']):
             self._check_and_set(abi['name'],
                                 OverloadedMethod(address, name, owner))
         key = ",".join(i['type'] for i in abi['inputs']).replace('256', '')
         getattr(self, abi['name']).methods[key] = _get_method_object(
             address, abi, name, owner)
예제 #8
0
 def __getattribute__(self, name: str) -> Any:
     if super().__getattribute__("_reverted"):
         raise ContractNotFound("This contract no longer exists.")
     return super().__getattribute__(name)
예제 #9
0
 def __getattribute__(self, name):
     if super().__getattribute__('_reverted'):
         raise ContractNotFound("This contract no longer exists.")
     return super().__getattribute__(name)