def add(self, path, source, replace=False): if path in self._source and not replace: raise ContractExists( f"Contract with path '{path}' already exists in this project.") data = _get_contract_data(source) for name, values in data.items(): if name in self._contracts and not replace: raise ContractExists( f"Contract '{name}' already exists in this project.") values['path'] = path self._source[path] = source self._contracts.update(data)
def add(self, path: Union["Path", str], source: Any, replace: bool = False) -> None: if path in self._source and not replace: raise ContractExists( f"Contract with path '{path}' already exists in this project.") data = _get_contract_data(source) for name, values in data.items(): if name in self._contracts and not replace: raise ContractExists( f"Contract '{name}' already exists in this project.") values["path"] = path self._source[path] = source self._contracts.update(data)
def at( self, address: str, owner: Optional[AccountsType] = None, tx: Optional[TransactionReceiptType] = None, ) -> "ProjectContract": """Returns a contract address. Raises ValueError if no bytecode exists at the address. Args: address: Address string of the contract. owner: Default Account instance to send contract transactions from. tx: Transaction ID of the contract creation.""" contract = _find_contract(address) if isinstance(contract, ProjectContract): if contract._name == self._name and contract._project == self._project: return contract raise ContractExists( f"'{contract._name}' declared at {address} in project '{contract._project._name}'" ) build = self._build contract = ProjectContract(self._project, build, address, owner, tx) if not _verify_deployed_code(address, build["deployedBytecode"], build["language"]): # prevent trace attempts when the bytecode doesn't match del contract._build["pcMap"] contract._save_deployment() _add_contract(contract) _add_deployment(contract) self._contracts.append(contract) return contract
def _get_contract_data(full_source, path): minified_source, offset_map = minify(full_source) contracts = re.findall( r"((?:contract|library|interface)[^;{]*{[\s\S]*?})\s*(?=contract|library|interface|$)", minified_source) data = {} for source in contracts: type_, name, inherited = re.findall( r"\s*(contract|library|interface)\s{1,}(\S*)\s*(?:is\s{1,}(.*?)|)(?:{)", source)[0] offset = minified_source.index(source) if name in _contracts and not _contracts[name]['path'].startswith( '<string-'): raise ContractExists( f"Contract '{name}' already exists in the active project.") data[name] = { 'path': str(path), 'offset_map': offset_map, 'minified': minified_source, 'offset': (offset + next(i[1] for i in offset_map if i[0] <= offset), offset + len(source) + next(i[1] for i in offset_map if i[0] <= offset + len(source))) } return data
def __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: raise NotImplementedError("ethPM manifests are not yet supported") elif not address: raise TypeError( "Address cannot be None unless creating object from manifest") _ContractBase.__init__(self, None, None, name, abi) # type: ignore _DeployedContractBase.__init__(self, address, owner, None) contract = _find_contract(address) if not contract: return if isinstance(contract, ProjectContract): raise ContractExists( f"'{contract._name}' declared at {address} in project '{contract._project._name}'" ) if contract.bytecode != self.bytecode: contract._reverted = True
def at( self, address: str, owner: Optional[AccountsType] = None, tx: Optional[TransactionReceiptType] = None, ) -> "ProjectContract": """Returns a contract address. Raises ValueError if no bytecode exists at the address. Args: address: Address string of the contract. owner: Default Account instance to send contract transactions from. tx: Transaction ID of the contract creation.""" contract = _find_contract(address) if contract: if contract._name == self._name and contract._project == self._project: return contract raise ContractExists( f"'{contract._name}' declared at {address} in project '{contract._project._name}'" ) contract = ProjectContract(self._project, self._build, address, owner, tx) self._contracts.append(contract) return contract
def __init__(self, address, name, abi, owner=None): _ContractBase.__init__(self, None, None, name, abi) _DeployedContractBase.__init__(self, address, owner, None) contract = history.find_contract(address) if not contract: return if isinstance(contract, ProjectContract): raise ContractExists( f"'{contract._name}' declared at {address} in project '{contract._project._name}'" ) if contract.bytecode != self.bytecode: contract._reverted = True
def __init__(self, address: Any, name: str, abi: Any, owner: AccountsType = None) -> None: _ContractBase.__init__(self, None, None, name, abi) _DeployedContractBase.__init__(self, address, owner, None) contract = find_contract(address) if not contract: return if isinstance(contract, ProjectContract): raise ContractExists( f"'{contract._name}' declared at {address} in project '{contract._project._name}'" ) if contract.bytecode != self.bytecode: contract._reverted = True
def at(self, address, owner=None, tx=None): '''Returns a contract address. Raises ValueError if no bytecode exists at the address. Args: address: Address string of the contract. owner: Default Account instance to send contract transactions from. tx: Transaction ID of the contract creation.''' contract = history.find_contract(address) if contract: if contract._name == self._name and contract._project == self._project: return contract raise ContractExists( f"'{contract._name}' declared at {address} in project '{contract._project._name}'" ) contract = ProjectContract(self._project, self._build, address, owner, tx) self._contracts.append(contract) return contract