def _verify_deployed_contract( self, deployment_data: DeployedContracts, contract_name: str, ) -> Contract: """ Verify deployment info against the chain Verifies: - the runtime bytecode - precompiled data against the chain - information stored in deployment_*.json against the chain, except for the constructor arguments, which have to be checked separately. Returns: (onchain_instance, constructor_arguments) """ contracts = deployment_data['contracts'] contract_address = contracts[contract_name]['address'] contract_instance = self.web3.eth.contract( abi=self.contract_manager.get_contract_abi(contract_name), address=contract_address, ) # Check that the deployed bytecode matches the precompiled data blockchain_bytecode = self.web3.eth.getCode(contract_address).hex() compiled_bytecode = runtime_hexcode( contracts_manager=self.contract_manager, name=contract_name, ) assert blockchain_bytecode == compiled_bytecode print( f'{contract_name} at {contract_address} ' f'matches the compiled data from contracts.json', ) # Check blockchain transaction hash & block information receipt = self.web3.eth.getTransactionReceipt( contracts[contract_name]['transaction_hash'], ) assert receipt['blockNumber'] == contracts[contract_name][ 'block_number'], ( f'We have block_number {contracts[contract_name]["block_number"]} ' f'instead of {receipt["blockNumber"]}') assert receipt['gasUsed'] == contracts[contract_name]['gas_cost'], ( f'We have gasUsed {contracts[contract_name]["gas_cost"]} ' f'instead of {receipt["gasUsed"]}') assert receipt['contractAddress'] == contracts[contract_name][ 'address'], ( f'We have contractAddress {contracts[contract_name]["address"]} ' f'instead of {receipt["contractAddress"]}') # Check the contract version version = contract_instance.functions.contract_version().call() assert version == deployment_data['contracts_version'], \ f'got {version} expected {deployment_data["contracts_version"]}.' \ f'contract_manager has contracts_version {self.contract_manager.contracts_version}' return contract_instance, contracts[contract_name][ 'constructor_arguments']
def test_human_standard_token(human_standard_token, web3, contracts_manager): """ See human_standard_token.address contains the expected code """ blockchain_bytecode = web3.eth.getCode(human_standard_token.address).hex() compiled_bytecode = runtime_hexcode( contracts_manager, CONTRACT_HUMAN_STANDARD_TOKEN, len(blockchain_bytecode), ) assert blockchain_bytecode == compiled_bytecode
def test_custom_token(custom_token, web3, contracts_manager): """ See custom_token.address contains the expected code """ blockchain_bytecode = web3.eth.getCode(custom_token.address).hex() compiled_bytecode = runtime_hexcode( contracts_manager, CONTRACT_CUSTOM_TOKEN, len(blockchain_bytecode), ) assert blockchain_bytecode == compiled_bytecode
def verify_deployed_contract( web3: Web3, contract_manager: ContractManager, deployment_data: dict, contract_name: str, ) -> Contract: """ Verify deployment info against the chain Verifies: - the runtime bytecode - precompiled data against the chain - information stored in deployment_*.json against the chain, except for the constructor arguments, which have to be checked separately. """ contracts = deployment_data['contracts'] contract_address = contracts[contract_name]['address'] contract_instance = web3.eth.contract( abi=contract_manager.get_contract_abi(contract_name), address=contract_address, ) # Check that the deployed bytecode matches the precompiled data blockchain_bytecode = web3.eth.getCode(contract_address).hex() compiled_bytecode = runtime_hexcode(contract_manager, contract_name) assert blockchain_bytecode == compiled_bytecode # Check blockchain transaction hash & block information receipt = web3.eth.getTransactionReceipt( contracts[contract_name]['transaction_hash'], ) assert receipt['blockNumber'] == contracts[contract_name]['block_number'], ( f"We have block_number {contracts[contract_name]['block_number']} " f"instead of {receipt['blockNumber']}" ) assert receipt['gasUsed'] == contracts[contract_name]['gas_cost'], ( f"We have gasUsed {contracts[contract_name]['gas_cost']} " f"instead of {receipt['gasUsed']}" ) assert receipt['contractAddress'] == contracts[contract_name]['address'], ( f"We have contractAddress {contracts[contract_name]['address']} " f"instead of {receipt['contractAddress']}" ) # Check the contract version version = contract_instance.functions.contract_version().call() assert version == deployment_data['contracts_version'] return contract_instance
def verify_deployed_contracts(web3: Web3, contract_manager: ContractManager, deployment_data=None): chain_id = int(web3.version.network) deployment_file_path = None if deployment_data is None: deployment_data = get_contracts_deployed(chain_id, contract_manager.contracts_version) deployment_file_path = contracts_deployed_path( chain_id, contract_manager.contracts_version, ) contracts = deployment_data['contracts'] assert contract_manager.contracts_version == deployment_data['contracts_version'] assert chain_id == deployment_data['chain_id'] endpoint_registry_address = contracts[CONTRACT_ENDPOINT_REGISTRY]['address'] endpoint_registry_abi = contract_manager.get_contract_abi(CONTRACT_ENDPOINT_REGISTRY) endpoint_registry = web3.eth.contract( abi=endpoint_registry_abi, address=endpoint_registry_address, ) # Check that the deployed bytecode matches the precompiled data blockchain_bytecode = web3.eth.getCode(endpoint_registry_address).hex() compiled_bytecode = runtime_hexcode( contract_manager, CONTRACT_ENDPOINT_REGISTRY, len(blockchain_bytecode), ) assert blockchain_bytecode == compiled_bytecode # Check blockchain transaction hash & block information receipt = web3.eth.getTransactionReceipt( contracts[CONTRACT_ENDPOINT_REGISTRY]['transaction_hash'], ) assert receipt['blockNumber'] == contracts[CONTRACT_ENDPOINT_REGISTRY]['block_number'], \ f"We have block_number {contracts[CONTRACT_ENDPOINT_REGISTRY]['block_number']} " \ f"instead of {receipt['blockNumber']}" assert receipt['gasUsed'] == contracts[CONTRACT_ENDPOINT_REGISTRY]['gas_cost'], \ f"We have gasUsed {contracts[CONTRACT_ENDPOINT_REGISTRY]['gas_cost']} " \ f"instead of {receipt['gasUsed']}" assert receipt['contractAddress'] == contracts[CONTRACT_ENDPOINT_REGISTRY]['address'], \ f"We have contractAddress {contracts[CONTRACT_ENDPOINT_REGISTRY]['address']} " \ f"instead of {receipt['contractAddress']}" # Check the contract version version = endpoint_registry.functions.contract_version().call() assert version == deployment_data['contracts_version'] print( f'{CONTRACT_ENDPOINT_REGISTRY} at {endpoint_registry_address} ' f'matches the compiled data from contracts.json', ) secret_registry_address = contracts[CONTRACT_SECRET_REGISTRY]['address'] secret_registry_abi = contract_manager.get_contract_abi(CONTRACT_SECRET_REGISTRY) secret_registry = web3.eth.contract( abi=secret_registry_abi, address=secret_registry_address, ) # Check that the deployed bytecode matches the precompiled data blockchain_bytecode = web3.eth.getCode(secret_registry_address).hex() compiled_bytecode = runtime_hexcode( contract_manager, CONTRACT_SECRET_REGISTRY, len(blockchain_bytecode), ) assert blockchain_bytecode == compiled_bytecode # Check blockchain transaction hash & block information receipt = web3.eth.getTransactionReceipt( contracts[CONTRACT_SECRET_REGISTRY]['transaction_hash'], ) assert receipt['blockNumber'] == contracts[CONTRACT_SECRET_REGISTRY]['block_number'], \ f"We have block_number {contracts[CONTRACT_SECRET_REGISTRY]['block_number']} " \ f"instead of {receipt['blockNumber']}" assert receipt['gasUsed'] == contracts[CONTRACT_SECRET_REGISTRY]['gas_cost'], \ f"We have gasUsed {contracts[CONTRACT_SECRET_REGISTRY]['gas_cost']} " \ f"instead of {receipt['gasUsed']}" assert receipt['contractAddress'] == contracts[CONTRACT_SECRET_REGISTRY]['address'], \ f"We have contractAddress {contracts[CONTRACT_SECRET_REGISTRY]['address']} " \ f"instead of {receipt['contractAddress']}" # Check the contract version version = secret_registry.functions.contract_version().call() assert version == deployment_data['contracts_version'] print( f'{CONTRACT_SECRET_REGISTRY} at {secret_registry_address} ' f'matches the compiled data from contracts.json', ) token_registry_address = contracts[CONTRACT_TOKEN_NETWORK_REGISTRY]['address'] token_registry_abi = contract_manager.get_contract_abi( CONTRACT_TOKEN_NETWORK_REGISTRY, ) token_network_registry = web3.eth.contract( abi=token_registry_abi, address=token_registry_address, ) # Check that the deployed bytecode matches the precompiled data blockchain_bytecode = web3.eth.getCode(token_registry_address).hex() compiled_bytecode = runtime_hexcode( contract_manager, CONTRACT_TOKEN_NETWORK_REGISTRY, len(blockchain_bytecode), ) assert blockchain_bytecode == compiled_bytecode # Check blockchain transaction hash & block information receipt = web3.eth.getTransactionReceipt( contracts[CONTRACT_TOKEN_NETWORK_REGISTRY]['transaction_hash'], ) assert receipt['blockNumber'] == contracts[CONTRACT_TOKEN_NETWORK_REGISTRY]['block_number'], \ f"We have block_number {contracts[CONTRACT_TOKEN_NETWORK_REGISTRY]['block_number']} " \ f"instead of {receipt['blockNumber']}" assert receipt['gasUsed'] == contracts[CONTRACT_TOKEN_NETWORK_REGISTRY]['gas_cost'], \ f"We have gasUsed {contracts[CONTRACT_TOKEN_NETWORK_REGISTRY]['gas_cost']} " \ f"instead of {receipt['gasUsed']}" assert receipt['contractAddress'] == contracts[CONTRACT_TOKEN_NETWORK_REGISTRY]['address'], \ f"We have contractAddress {contracts[CONTRACT_TOKEN_NETWORK_REGISTRY]['address']} " \ f"instead of {receipt['contractAddress']}" # Check the contract version version = token_network_registry.functions.contract_version().call() assert version == deployment_data['contracts_version'] # Check constructor parameters constructor_arguments = contracts[CONTRACT_TOKEN_NETWORK_REGISTRY]['constructor_arguments'] assert to_checksum_address( token_network_registry.functions.secret_registry_address().call(), ) == secret_registry_address assert secret_registry_address == constructor_arguments[0] chain_id = token_network_registry.functions.chain_id().call() assert chain_id == constructor_arguments[1] settlement_timeout_min = token_network_registry.functions.settlement_timeout_min().call() settlement_timeout_max = token_network_registry.functions.settlement_timeout_max().call() assert settlement_timeout_min == constructor_arguments[2] assert settlement_timeout_max == constructor_arguments[3] print( f'{CONTRACT_TOKEN_NETWORK_REGISTRY} at {token_registry_address} ' f'matches the compiled data from contracts.json', ) if deployment_file_path is not None: print(f'Deployment info from {deployment_file_path} has been verified and it is CORRECT.')