コード例 #1
0
    def _verify_contract_integrity(self, address: Union[bytes, str], sol_filename: str, *,
                                   libraries: Dict = None, contract_name: str = None, is_library: bool = False,
                                   cwd=None) -> Any:
        if isinstance(address, bytes):
            address = self.w3.toChecksumAddress(address)

        if contract_name is None:
            contract_name = get_contract_names(sol_filename)[0]
        actual_byte_code = self.__normalized_hex(self.w3.eth.getCode(address))
        if not actual_byte_code:
            raise IntegrityError(f'Expected contract {contract_name} is not deployed at address {address}')

        cout = self.compile_contract(sol_filename, contract_name, libs=libraries, cwd=cwd)
        expected_byte_code = self.__normalized_hex(cout['deployed_bin'])

        if is_library:
            # https://github.com/ethereum/solidity/issues/7101
            expected_byte_code = expected_byte_code[:2] + self.__normalized_hex(address) + expected_byte_code[42:]

        if actual_byte_code != expected_byte_code:
            raise IntegrityError(f'Deployed contract at address {address} does not match local contract {sol_filename}')
        zk_print(f'Contract@{address} matches {sol_filename[sol_filename.rfind("/") + 1:]}:{contract_name}')

        return self.w3.eth.contract(
            address=address, abi=cout['abi']
        )
コード例 #2
0
    def _verify_library_integrity(self, libraries: List[Tuple[str, str]], contract_with_libs_addr: str, sol_with_libs_filename: str) -> Dict[str, str]:
        cname = get_contract_names(sol_with_libs_filename)[0]
        actual_code = self.__normalized_hex(self.w3.eth.getCode(contract_with_libs_addr))
        if not actual_code:
            raise IntegrityError(f'Expected contract {cname} is not deployed at address {contract_with_libs_addr}')
        code_with_placeholders = self.__normalized_hex(self.compile_contract(sol_with_libs_filename, cname)['deployed_bin'])

        if len(actual_code) != len(code_with_placeholders):
            raise IntegrityError(f'Local code of contract {cname} has different length than remote contract')

        addresses = {}
        for lib_name, lib_sol in libraries:
            # Compute placeholder according to
            # https://solidity.readthedocs.io/en/v0.5.13/using-the-compiler.html#using-the-commandline-compiler
            hash = self.w3.solidityKeccak(['string'], [f'{lib_sol[lib_sol.rfind("/") + 1:]}:{lib_name}'])
            placeholder = f'__${self.__normalized_hex(hash)[:34]}$__'

            # Retrieve concrete address in deployed code at placeholder offset in local code and verify library contract integrity
            lib_address_offset = code_with_placeholders.find(placeholder)
            if lib_address_offset != -1:
                lib_address = self.w3.toChecksumAddress(actual_code[lib_address_offset:lib_address_offset+40])
                with cfg.library_compilation_environment():
                    self._verify_contract_integrity(lib_address, lib_sol, contract_name=lib_name, is_library=True)
                addresses[lib_name] = lib_address
        return addresses
コード例 #3
0
 def deploy_solidity_contract(self, sol_filename: str,
                              contract_name: Optional[str],
                              sender: Union[bytes, str]) -> str:
     contract_name = get_contract_names(
         sol_filename)[0] if contract_name is None else contract_name
     contract = self._deploy_contract(
         sender, self.compile_contract(sol_filename, contract_name))
     return str(contract.address)
コード例 #4
0
ファイル: examples.py プロジェクト: nibau/zkay
 def name(self):
     names = get_contract_names(self.file_location)
     assert len(names) == 1
     return names[0]