def _deploy( contract_name: str, args: Any, transaction: Dict[str, Any], package: Package ) -> Tuple[Package, Address]: # Deploy new instance factory = package.get_contract_factory(contract_name) if not factory.linked_references and factory.unlinked_references: raise LinkerError( f"Contract factory: {contract_name} is missing runtime link references, which are " "necessary to populate manifest deployments that have a link reference. If using the " "builder tool, use `contract_type(..., runtime_bytecode=True)`." ) tx_hash = factory.constructor(*args).transact(transaction) tx_receipt = package.w3.eth.waitForTransactionReceipt(tx_hash) # Create manifest copy with new deployment instance latest_block_uri = create_latest_block_uri(package.w3, 0) deployment_data = create_deployment_data( contract_name, to_checksum_address(tx_receipt.contractAddress), tx_receipt, factory.linked_references, ) manifest = insert_deployment( package, contract_name, deployment_data, latest_block_uri ) logger.info("%s deployed." % contract_name) return Package(manifest, package.w3)
def get_deployment_address(linked_type: str, package: Package) -> Address: """ Return the address of a linked_type found in a package's manifest deployments. """ try: deployment_address = package.deployments.get(linked_type)["address"] except KeyError: raise LinkerError( f"Package data does not contain a valid deployment of {linked_type} on the " "current w3-connected chain.") return deployment_address
def pluck_matching_uri(deployment_data: Dict[URI, Dict[str, str]], w3: Web3) -> URI: """ Return any blockchain uri that matches w3-connected chain, if one is present in the deployment data keys. """ for uri in deployment_data.keys(): if check_if_chain_matches_chain_uri(w3, uri): return uri raise LinkerError( f"No matching blockchain URI found in deployment_data: {list(deployment_data.keys())}, " "for w3 instance: {w3.__repr__()}.")
def link(contract: str, linked_type: str, package: Package) -> Package: """ Return a new package, created with a new manifest after applying the linked type reference to the contract factory. """ deployment_address = get_deployment_address(linked_type, package) unlinked_factory = package.get_contract_factory(contract) if not unlinked_factory.needs_bytecode_linking: raise LinkerError( f"Contract factory: {unlinked_factory.__repr__()} does not need bytecode linking, " "so it is not a valid contract type for link()") linked_factory = unlinked_factory.link_bytecode( {linked_type: deployment_address}) # todo replace runtime_bytecode in manifest manifest = assoc_in( package.manifest, ("contract_types", contract, "deployment_bytecode", "bytecode"), to_hex(linked_factory.bytecode), ) logger.info( "%s linked to %s at address %s." % (contract, linked_type, to_checksum_address(deployment_address))) return Package(manifest, package.w3)