def deploy_code(self, file_path, params, addresses): if addresses: addresses = dict([(k, self.replace_address(v)) for k, v in addresses.iteritems()]) language = "solidity" if file_path.endswith(".sol") else "serpent" code = self.pp.process(file_path, add_dev_code=self.add_dev_code, contract_dir=self.contract_dir, addresses=addresses) # compile code bytecode, abi = self.compile_code(code, language) # replace library placeholders bytecode = self.replace_library_placeholders(bytecode, addresses) if params: translator = ContractTranslator(abi) # replace constructor placeholders params = [self.replace_address(p) for p in params] bytecode += translator.encode_constructor_arguments(params).encode( "hex") logging.info( 'Try to create contract with length {} based on code in file: {}'. format(len(bytecode), file_path)) if self.private_key: raw_tx = self.get_raw_transaction(bytecode) tx_response = self.json_rpc.eth_sendRawTransaction("0x" + raw_tx) while "error" in tx_response: logging.info('Deploy failed with error {}. Retry!'.format( tx_response['error'])) time.sleep(5) tx_response = self.json_rpc.eth_sendRawTransaction("0x" + raw_tx) else: tx_response = self.json_rpc.eth_sendTransaction( self.user_address, data=bytecode, gas=self.gas, gas_price=self.gas_price) while "error" in tx_response: logging.info('Deploy failed with error {}. Retry!'.format( tx_response['error'])) time.sleep(5) tx_response = self.json_rpc.eth_sendTransaction( self.user_address, data=bytecode, gas=self.gas, gas_price=self.gas_price) transaction_hash = tx_response['result'] self.wait_for_transaction_receipt(transaction_hash) contract_address = self.json_rpc.eth_getTransactionReceipt( transaction_hash)["result"]["contractAddress"] # Verify deployed code with locally deployed code if self.verify_code and not self.code_is_valid(contract_address, bytecode): logging.info('Deploy of {} failed. Retry!'.format(file_path)) self.deploy_code(file_path, params, addresses) contract_name = file_path.split("/")[-1].split(".")[0] self.contract_addresses[contract_name] = contract_address self.contract_abis[contract_name] = abi logging.info('Contract {} was created at address {}.'.format( file_path, contract_address))
def contract(self, sourcecode, args=[], sender=k0, value=0, language=None, l=None, startgas=STARTGAS, gasprice=GASPRICE): assert not (l and language) language = l or language if language == 'evm': assert len(args) == 0 return self.tx(sender=sender, to=b'', value=value, data=sourcecode, startgas=startgas, gasprice=gasprice) else: compiler = languages[language] interface = compiler.mk_full_signature(sourcecode) ct = ContractTranslator(interface) code = compiler.compile(sourcecode) + ( ct.encode_constructor_arguments(args) if args else b'') addr = self.tx(sender=sender, to=b'', value=value, data=code, startgas=startgas, gasprice=gasprice) return ABIContract(self, ct, addr)
def upload(self, relativeFilePath, lookupKey=None, signatureKey=None, constructorArgs=[]): resolvedPath = resolveRelativePath(relativeFilePath) lookupKey = lookupKey if lookupKey else path.splitext( path.basename(resolvedPath))[0] signatureKey = signatureKey if signatureKey else lookupKey if lookupKey in self.contracts: return (self.contracts[lookupKey]) compiledCode = ContractsFixture.getCompiledCode(resolvedPath) # abstract contracts have a 0-length array for bytecode if len(compiledCode) == 0: print "Skipping upload of " + lookupKey + " because it had no bytecode (likely a abstract class/interface)." return None if signatureKey not in ContractsFixture.signatures: ContractsFixture.signatures[ signatureKey] = ContractsFixture.generateSignature( resolvedPath) signature = ContractsFixture.signatures[signatureKey] contractTranslator = ContractTranslator(signature) if len(constructorArgs) > 0: compiledCode += contractTranslator.encode_constructor_arguments( constructorArgs) contractAddress = bytesToHexString( self.chain.contract(compiledCode, language='evm', startgas=long(6.7 * 10**6))) contract = ABIContract(self.chain, contractTranslator, contractAddress) self.contracts[lookupKey] = contract return (contract)
def upload(self, relativeFilePath, lookupKey = None, signatureKey = None, constructorArgs=[]): resolvedPath = resolveRelativePath(relativeFilePath) if self.coverageMode: resolvedPath = resolvedPath.replace("tests", "coverageEnv").replace("source/", "coverageEnv/") lookupKey = lookupKey if lookupKey else path.splitext(path.basename(resolvedPath))[0] signatureKey = signatureKey if signatureKey else lookupKey if lookupKey in self.contracts: return(self.contracts[lookupKey]) compiledCode = self.getCompiledCode(resolvedPath) # abstract contracts have a 0-length array for bytecode if len(compiledCode) == 0: if ("libraries" in relativeFilePath or lookupKey.startswith("I") or lookupKey.startswith("Base") or lookupKey.startswith("DS")): pass#print "Skipping upload of " + lookupKey + " because it had no bytecode (likely a abstract class/interface)." else: raise Exception("Contract: " + lookupKey + " has no bytecode, but this is not expected. It probably doesn't implement all its abstract methods") return None if signatureKey not in ContractsFixture.signatures: ContractsFixture.signatures[signatureKey] = self.generateSignature(resolvedPath) signature = ContractsFixture.signatures[signatureKey] contractTranslator = ContractTranslator(signature) if len(constructorArgs) > 0: compiledCode += contractTranslator.encode_constructor_arguments(constructorArgs) contractAddress = bytesToHexString(self.chain.contract(compiledCode, language='evm')) contract = ABIContract(self.chain, contractTranslator, contractAddress) self.contracts[lookupKey] = contract return(contract)
def upload(self, relativeFilePath, lookupKey = None, signatureKey = None, constructorArgs=[]): resolvedPath = resolveRelativePath(relativeFilePath) if self.coverageMode: resolvedPath = resolvedPath.replace("tests", "coverageEnv").replace("source/", "coverageEnv/") lookupKey = lookupKey if lookupKey else path.splitext(path.basename(resolvedPath))[0] signatureKey = signatureKey if signatureKey else lookupKey if lookupKey in self.contracts: return(self.contracts[lookupKey]) compiledCode = self.getCompiledCode(resolvedPath) # abstract contracts have a 0-length array for bytecode if len(compiledCode) == 0: if ("libraries" in relativeFilePath or lookupKey.startswith("I") or lookupKey.startswith("Base")): pass#print "Skipping upload of " + lookupKey + " because it had no bytecode (likely a abstract class/interface)." else: raise Exception("Contract: " + lookupKey + " has no bytecode, but this is not expected. It probably doesn't implement all its abstract methods") return None if signatureKey not in ContractsFixture.signatures: ContractsFixture.signatures[signatureKey] = self.generateSignature(resolvedPath) signature = ContractsFixture.signatures[signatureKey] contractTranslator = ContractTranslator(signature) if len(constructorArgs) > 0: compiledCode += contractTranslator.encode_constructor_arguments(constructorArgs) contractAddress = bytesToHexString(self.chain.contract(compiledCode, language='evm')) contract = ABIContract(self.chain, contractTranslator, contractAddress) self.contracts[lookupKey] = contract return(contract)
def deploy_solidity_contract_with_args(chain, solc_config_sources, allow_paths, contract_file, contract_name, startgas, args=[]): compiled = compile_standard( { 'language': 'Solidity', 'sources': solc_config_sources, 'settings': { 'evmVersion': 'byzantium', 'outputSelection': { '*': { '*': ['abi', 'evm.bytecode'] } }, }, }, allow_paths=allow_paths) abi = compiled['contracts'][contract_file][contract_name]['abi'] binary = compiled['contracts'][contract_file][contract_name]['evm'][ 'bytecode']['object'] ct = ContractTranslator(abi) address = chain.contract( (utils.decode_hex(binary) + ct.encode_constructor_arguments(args) if args else b''), language='evm', value=0, startgas=startgas, sender=tester.k0) contract = tester.ABIContract(chain, ct, address) return contract
def abi_contract(self, sourcecode, sender=DEFAULT_KEY, endowment=0, # pylint: disable=too-many-arguments language='serpent', log_listener=None, listen=True, libraries=None, path=None, constructor_parameters=None, **kwargs): # pylint: disable=too-many-locals compiler = languages[language] contract_interface = compiler.mk_full_signature(sourcecode, path=path, **kwargs) translator = ContractTranslator(contract_interface) encoded_parameters = None if constructor_parameters is not None: encoded_parameters = translator.encode_constructor_arguments(constructor_parameters) address = self.contract( sourcecode, sender, endowment, language, libraries, path, constructor_call=encoded_parameters, **kwargs ) return ABIContract( self, translator, address, listen=listen, log_listener=log_listener, )
def create_contract(path, args=(), sender=t.k0): abi, hexcode, _ = Deployer().compile_contract(path, args) bytecode = u.decode_hex(hexcode) ct = ContractTranslator(abi) code = bytecode + (ct.encode_constructor_arguments(args) if args else b'') address = t.chain.tx(sender=sender, to=b'', startgas=(4 * 10 ** 6), value=0, data=code) return t.ABIContract(t.chain, abi, address)
def deploy_solidity_contract(contract_path, contract_name, chain, sender=k0, value=0, startgas=STARTGAS, gasprice=GASPRICE, *args): output = subprocess.check_output( ["solc", "--combined-json", "bin,abi", contract_path]) result = solc_parse_output(output) data = solidity_get_contract_data(result, contract_path, contract_name) interface = data['abi'] ct = ContractTranslator(interface) code = data['bin'] \ + (ct.encode_constructor_arguments(args) if args else b'') addr = chain.tx(sender=sender, to=b'', value=value, data=code, startgas=startgas, gasprice=gasprice) return ABIContract(chain, ct, addr)
def deploy(self, _from, file_path, bytecode, sourcecode, libraries, value, params, label, abi): # replace library placeholders if libraries: for library_name, library_address in libraries.iteritems(): self.references[library_name] = self.replace_references( self.strip_0x(library_address)) if file_path: if self.contract_dir: file_path = '{}/{}'.format(self.contract_dir, file_path) bytecode, abi = self.compile_code(path=file_path) if not label: label = file_path.split("/")[-1].split(".")[0] if sourcecode: # compile code bytecode, abi = self.compile_code(code=sourcecode) if params: translator = ContractTranslator(abi) # replace constructor placeholders params = [self.replace_references(p) for p in params] bytecode += translator.encode_constructor_arguments(params).hex() # deploy contract self.log('Deployment transaction for {} sent'.format( label if label else 'unknown')) tx_response = None tx = { 'from': self._from, 'value': value, 'data': self.add_0x(bytecode), 'gas': self.gas, 'gas_price': self.gas_price } if self.private_key: tx = Transaction(tx) nonce = self.web3.eth.getTransactionCount(self._from) tx['nonce'] = nonce tx.sign(self.private_key) raw_tx = rlp.encode(tx) while tx_response is None or 'error' in tx_response: if tx_response and 'error' in tx_response: self.log('Deploy failed with error {}'.format( tx_response['error']['message'])) time.sleep(5) self.web3.eth.sendRawTransaction(raw_tx) tx_response = self.web3.eth.sendRawTransaction(raw_tx) else: while tx_response is None or 'error' in tx_response: if tx_response and 'error' in tx_response: self.log('Deploy failed with error {}'.format( tx_response['error']['message'])) time.sleep(5) tx_response = self.web3.eth.sendTransaction(tx) transaction_receipt = self.web3.eth.getTransactionReceipt(tx_response) contract_address = transaction_receipt['contractAddress'] self.references[label] = contract_address self.abis[contract_address] = abi self.log('Contract {} created at address {}'.format( label if label else 'unknown', self.add_0x(contract_address))) self.log_transaction_receipt(transaction_receipt)
def deploy(self, _from, file_path, bytecode, sourcecode, libraries, value, params, label, abi): # replace library placeholders if libraries: for library_name, library_address in libraries.iteritems(): self.references[library_name] = self.replace_references( self.strip_0x(library_address)) if file_path: if self.contract_dir: file_path = '{}/{}'.format(self.contract_dir, file_path) bytecode, abi = self.compile_code(path=file_path) if not label: label = file_path.split("/")[-1].split(".")[0] if sourcecode: # compile code bytecode, abi = self.compile_code(code=sourcecode) if params: translator = ContractTranslator(abi) # replace constructor placeholders params = [self.replace_references(p) for p in params] bytecode += translator.encode_constructor_arguments(params).encode( 'hex') # deploy contract self.log('Deployment transaction for {} sent'.format( label if label else 'unknown')) tx_response = None if self.private_key: raw_tx = self.get_raw_transaction(value=value, data=bytecode) while tx_response is None or 'error' in tx_response: if tx_response and 'error' in tx_response: self.log('Deploy failed with error {}'.format( tx_response['error']['message'])) time.sleep(5) tx_response = self.json_rpc.eth_sendRawTransaction(raw_tx) else: while tx_response is None or 'error' in tx_response: if tx_response and 'error' in tx_response: self.log('Deploy failed with error {}'.format( tx_response['error']['message'])) time.sleep(5) tx_response = self.json_rpc.eth_sendTransaction( self.add_0x(_from if _from else self._from), value=value, data=self.add_0x(bytecode), gas=self.gas, gas_price=self.gas_price) transaction_receipt = self.wait_for_transaction_receipt( self.add_0x(tx_response['result'])) contract_address = self.strip_0x( transaction_receipt['contractAddress']) self.references[label] = contract_address self.abis[contract_address] = abi self.log('Contract {} created at address {}'.format( label if label else 'unknown', self.add_0x(contract_address))) self.log_transaction_receipt(transaction_receipt)
def init_permission_contracts(self): ncinfo = self.contracts_list['NormalContracts'] pcinfo = self.contracts_list['PermissionContracts'] path = os.path.join(self.contracts_dir, pcinfo['file']) data = self.compile_to_data('Permission', path) self.write_docs('Permission', data) for name, info in pcinfo['basic'].items(): addr = info['address'] conts = [addr] funcs = [binascii.unhexlify('00000000')] ctt = ContractTranslator(data['abi']) extra = ctt.encode_constructor_arguments([name, conts, funcs]) self.mine_contract_on_chain_tester(addr, data['bin'] + extra) for name, info in pcinfo['contracts'].items(): addr = info['address'] conts = [ncinfo[cont]['address'] for cont in info['contracts']] funcs = [function_encode(func) for func in info['functions']] ctt = ContractTranslator(data['abi']) extra = ctt.encode_constructor_arguments([name, conts, funcs]) self.mine_contract_on_chain_tester(addr, data['bin'] + extra)
def init_contracts(nodes): result = dict() tester_state = Chain() for address, contract in CONTRACTS.iteritems(): contract_path = path.join(CONTRACTS_DIR, contract['file']) simple_compiled = compile_file(contract_path) simple_data = solidity_get_contract_data( simple_compiled, contract_path, contract['name'], ) ct = ContractTranslator(simple_data['abi']) if (address == '0x00000000000000000000000000000000013241a3'): extra = (ct.encode_constructor_arguments([nodes[address]]) if nodes[address] else b'') else: extra = (ct.encode_constructor_arguments([nodes[address][0], nodes[address][1]]) if nodes[address] else b'') print(binascii.hexlify(simple_data['bin'] + extra)) abi_address = tester_state.contract(simple_data['bin'] + extra) tester_state.mine() account = tester_state.chain.state.account_to_dict(abi_address) result[address] = {'code': account['code'], 'storage': account['storage'], 'nonce': account['nonce']} return result
def init_normal_contracts(self): """Compile normal contracts from files and construct by arguments. """ ncinfo = self.contracts_list['NormalContracts'] for name, info in ncinfo.items(): addr = info['address'] path = os.path.join(self.contracts_dir, info['file']) data = self.compile_to_data(name, path) self.write_docs(name, data) ctt = ContractTranslator(data['abi']) args = self.contracts_args.get(name) extra = b'' if not args else ctt.encode_constructor_arguments( [arg for arg in args.values()]) self.mine_contract_on_chain_tester(addr, data['bin'] + extra)
async def test_deploy_contract(self, *, node): client = JsonRPCClient(node.dsn()['url']) sourcecode = b"contract greeter{string greeting;function greeter(string _greeting) public{greeting=_greeting;}function greet() constant returns (string){return greeting;}}" #source_fn = os.path.join(node.get_data_directory(), 'greeting.sol') #with open(source_fn, 'wb') as wf: # wf.write(sourcecode) source_fn = '<stdin>' contract_name = 'greeter' constructor_args = [b'hello world!'] args = ['solc', '--combined-json', 'bin,abi', '--add-std'] # , source_fn] #output = subprocess.check_output(args, stderr=subprocess.PIPE) process = subprocess.Popen(args, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE) output, stderrdata = process.communicate(input=sourcecode) output = json_decode(output) contract = output['contracts']['{}:{}'.format(source_fn, contract_name)] bytecode = data_decoder(contract['bin']) contract_interface = json_decode(contract['abi']) translator = ContractTranslator(contract_interface) constructor_call = translator.encode_constructor_arguments( constructor_args) bytecode += constructor_call tx_hash, contract_address = await self.deploy_contract(bytecode) tx_receipt = await client.eth_getTransactionReceipt(tx_hash) self.assertIsNotNone(tx_receipt) code = await client.eth_getCode(contract_address) self.assertIsNotNone(code) self.assertNotEqual(data_decoder(code), b'') # call the contract and check the result res = await client.eth_call( from_address='0x39bf9e501e61440b4b268d7b2e9aa2458dd201bb', to_address=contract_address, data=sha3('greet()')) result = translator.decode_function_result('greet', data_decoder(res)) self.assertEqual(result[0], constructor_args[0])
def get_contract_data(contract_name, ctor_args): bin_file = open(contract_name + ".bin", "rb") bin = h2b(bin_file.read()) # print bin bin_file.close() bin = h2b("6060604052341561000c57fe5b5b5b5b6103b08061001e6000396000f300606060405263ffffffff60e060020a6000350416631e5e2d8f81146100425780637789139314610069578063d40f1da21461007e578063de9702a4146100a5575bfe5b341561004a57fe5b610067600435602435600160a060020a03604435166064356100ef565b005b341561007157fe5b610067600435610162565b005b341561008657fe5b6100916004356101f8565b604080519115158252519081900360200190f35b34156100ad57fe5b6100b8600435610276565b60408051600160a060020a039687168152949095166020850152838501929092526060830152608082015290519081900360a00190f35b600060008281548110151561010057fe5b906000526020600020906005020160005b50805490915033600160a060020a0390811691161461012f57610000565b600181018054600160a060020a031916600160a060020a03851617905560028101859055600381018490555b5050505050565b61016a6102c3565b600160a060020a033316815260808101829052600080546001810161018f8382610305565b916000526020600020906005020160005b5082518154600160a060020a03918216600160a060020a0319918216178355602085015160018401805491909316911617905560408301516002820155606083015160038201556080830151600490910155505b5050565b6000600060008381548110151561020b57fe5b906000526020600020906005020160005b50600181015490915033600160a060020a039081169116146102415760009150610270565b80600201544210156102565760009150610270565b806003015442111561026b5760009150610270565b600191505b50919050565b600080548290811061028457fe5b906000526020600020906005020160005b508054600182015460028301546003840154600490940154600160a060020a03938416955091909216929085565b60a0604051908101604052806000600160a060020a031681526020016000600160a060020a031681526020016000815260200160008152602001600081525090565b815481835581811511610331576005028160050283600052602060002091820191016103319190610337565b5b505050565b61038191905b8082111561037d578054600160a060020a03199081168255600182018054909116905560006002820181905560038201819055600482015560050161033d565b5090565b905600a165627a7a72305820c2389efff0fcf3752969acca63721798524aa30be1bcda35155b682da37f83b20029") abi_file = open(contract_name + ".abi", "r") abi = abi_file.read() abi_file.close() translator = ContractTranslator(abi) ctor_call = translator.encode_constructor_arguments(ctor_args) #print "ctor" #print b2h(ctor_call) return (bin + ctor_call, abi)
def create_contract(path, args=None, sender=t.k0): t.s.mine() contract_name = path.split('/')[1] contract_name += ':' + contract_name.split('.')[0] path, extra_args = get_dirs(path) if args: args = [ x.address if isinstance(x, t.ABIContract) else x for x in args ] compiler = t.languages['solidity'] combined = _solidity.compile_file(path, combined='bin,abi', optimize=True, extra_args=extra_args) abi = combined[contract_name]['abi'] ct = ContractTranslator(abi) code = combined[contract_name]['bin'] + ( ct.encode_constructor_arguments(args) if args else b'') address = t.s.tx(sender=sender, to=b'', value=0, data=code) return t.ABIContract(t.s, abi, address)
def abi_contract( self, sourcecode, sender=DEFAULT_KEY, endowment=0, # pylint: disable=too-many-arguments language='serpent', log_listener=None, listen=True, libraries=None, path=None, constructor_parameters=None, **kwargs): # pylint: disable=too-many-locals compiler = languages[language] contract_interface = compiler.mk_full_signature(sourcecode, path=path, **kwargs) translator = ContractTranslator(contract_interface) encoded_parameters = None if constructor_parameters is not None: encoded_parameters = translator.encode_constructor_arguments( constructor_parameters) address = self.contract(sourcecode, sender, endowment, language, libraries, path, constructor_call=encoded_parameters, **kwargs) return ABIContract( self, translator, address, listen=listen, log_listener=log_listener, )
class Repo(object): def __init__(self, account, infura, bin_path, abi_path): self.account = account self.infura = infura with open(bin_path, 'rb') as contract_file: contract_bin = contract_file.read().replace(b"\n", b"") self.contract_bin = binascii.unhexlify(contract_bin) with open(abi_path, 'r') as abi_file: self.contract = ContractTranslator(json.load(abi_file)) def create(self, ref_head, gasprice, startgas): constructor_args = self.contract.encode_constructor_arguments([ref_head]) tx, response = self.account.send_transaction(gasprice, startgas, self.contract_bin + constructor_args) contract_address = '0x' + encode_hex(tx.creates) return contract_address, response.json() def transact(self, contract_address, function, args, value=0, gasprice=15000000000, gaslimit=140000): txdata = self.contract.encode_function_call(function, args) tx, response = self.account.send_transaction(gasprice, gaslimit, txdata, to=contract_address, value=value) return response.json() def call(self, contract_address, function, args): txdata = self.contract.encode_function_call(function, args) params = { "params": json.dumps([{ "to": contract_address, "data": "0x" + encode_hex(txdata) }, 'latest']) } response = self.infura.get('eth_call', params).json() if 'result' in response and response['result'] == '0x': response['result'] = [] elif 'result' in response: response['result'] = self.contract.decode_function_result(function, binascii.unhexlify(response['result'][2:])) return response
def init_normal_contracts(self): """Compile normal contracts from files and construct by arguments. """ flags = [ 'checkCallPermission', 'checkSendTxPermission', 'checkCreateContractPermission', 'checkQuota', 'checkFeeBackPlatform', 'autoExec' ] ncinfo = self.contracts_list['NormalContracts'] for name, info in ncinfo.items(): addr = info['address'] path = os.path.join(self.contracts_dir, info['file']) data = self.compile_to_data(name, path) self.write_docs(name, data) ctt = ContractTranslator(data['abi']) args = self.contracts_args.get(name) if name == 'SysConfig': args['flags'] = [] for flag in flags: args['flags'].append(args[flag]) args.pop(flag) extra = b'' if not args else ctt.encode_constructor_arguments( [arg for arg in args.values()]) self.mine_contract_on_chain_tester(addr, data['bin'] + extra)
def tester_deploy_contract( tester_state, private_key, contract_name, contract_file, constructor_parameters=None): contract_path = get_contract_path(contract_file) all_contracts = _solidity.compile_file(contract_path, libraries=dict()) contract_key = solidity_get_contract_key(all_contracts, contract_path, contract_name) contract = all_contracts[contract_key] contract_interface = contract['abi'] log.info('Deploying "{}" contract'.format(contract_file)) dependencies = deploy_dependencies_symbols(all_contracts) deployment_order = dependencies_order_of_build(contract_key, dependencies) log.info('Deploying dependencies: {}'.format(str(deployment_order))) deployment_order.pop() # remove `contract_name` from the list libraries = dict() for deploy_contract in deployment_order: dependency_contract = all_contracts[deploy_contract] hex_bytecode = _solidity.solidity_resolve_symbols( dependency_contract['bin_hex'], libraries, ) bytecode = decode_hex(hex_bytecode) dependency_contract['bin_hex'] = hex_bytecode dependency_contract['bin'] = bytecode log.info('Creating contract {}'.format(deploy_contract)) contract_address = tester_state.evm( bytecode, private_key, endowment=0, ) tester_state.mine(number_of_blocks=1) if len(tester_state.block.get_code(contract_address)) == 0: raise Exception('Contract code empty') libraries[deploy_contract] = encode_hex(contract_address) hex_bytecode = _solidity.solidity_resolve_symbols(contract['bin_hex'], libraries) bytecode = hex_bytecode.decode('hex') contract['bin_hex'] = hex_bytecode contract['bin'] = bytecode if constructor_parameters: translator = ContractTranslator(contract_interface) parameters = translator.encode_constructor_arguments(constructor_parameters) bytecode = contract['bin'] + parameters else: bytecode = contract['bin'] log.info('Creating contract {}'.format(contract_name)) contract_address = tester_state.evm( bytecode, private_key, endowment=0, ) tester_state.mine(number_of_blocks=1) if len(tester_state.block.get_code(contract_address)) == 0: raise Exception('Contract code empty') return contract_address
def deploy_solidity_contract( self, # pylint: disable=too-many-locals sender, contract_name, all_contracts, libraries, constructor_parameters, contract_path=None, timeout=None, gasprice=GAS_PRICE): """ Deploy a solidity contract. Args: sender (address): the sender address contract_name (str): the name of the contract to compile all_contracts (dict): the json dictionary containing the result of compiling a file libraries (list): A list of libraries to use in deployment constructor_parameters (tuple): A tuple of arguments to pass to the constructor contract_path (str): If we are dealing with solc >= v0.4.9 then the path to the contract is a required argument to extract the contract data from the `all_contracts` dict. timeout (int): Amount of time to poll the chain to confirm deployment gasprice: The gasprice to provide for the transaction """ if contract_name in all_contracts: contract_key = contract_name elif contract_path is not None: _, filename = os.path.split(contract_path) contract_key = filename + ':' + contract_name if contract_key not in all_contracts: raise ValueError('Unknown contract {}'.format(contract_name)) else: raise ValueError( 'Unknown contract {} and no contract_path given'.format( contract_name)) libraries = dict(libraries) contract = all_contracts[contract_key] contract_interface = contract['abi'] symbols = solidity_unresolved_symbols(contract['bin_hex']) if symbols: available_symbols = map(solidity_library_symbol, all_contracts.keys()) unknown_symbols = set(symbols) - set(available_symbols) if unknown_symbols: msg = 'Cannot deploy contract, known symbols {}, unresolved symbols {}.'.format( available_symbols, unknown_symbols, ) raise Exception(msg) dependencies = deploy_dependencies_symbols(all_contracts) deployment_order = dependencies_order_of_build( contract_key, dependencies) deployment_order.pop() # remove `contract_name` from the list log.debug('Deploying dependencies: {}'.format( str(deployment_order))) for deploy_contract in deployment_order: dependency_contract = all_contracts[deploy_contract] hex_bytecode = solidity_resolve_symbols( dependency_contract['bin_hex'], libraries) bytecode = unhexlify(hex_bytecode) dependency_contract['bin_hex'] = hex_bytecode dependency_contract['bin'] = bytecode transaction_hash_hex = self.send_transaction( sender, to='', data=bytecode, gasprice=gasprice, ) transaction_hash = unhexlify(transaction_hash_hex) self.poll(transaction_hash, timeout=timeout) receipt = self.eth_getTransactionReceipt(transaction_hash) contract_address = receipt['contractAddress'] # remove the hexadecimal prefix 0x from the address contract_address = contract_address[2:] libraries[deploy_contract] = contract_address deployed_code = self.eth_getCode(unhexlify(contract_address)) if deployed_code == '0x': raise RuntimeError( 'Contract address has no code, check gas usage.') hex_bytecode = solidity_resolve_symbols(contract['bin_hex'], libraries) bytecode = unhexlify(hex_bytecode) contract['bin_hex'] = hex_bytecode contract['bin'] = bytecode if constructor_parameters: translator = ContractTranslator(contract_interface) parameters = translator.encode_constructor_arguments( constructor_parameters) bytecode = contract['bin'] + parameters else: bytecode = contract['bin'] transaction_hash_hex = self.send_transaction( sender, to='', data=bytecode, gasprice=gasprice, ) transaction_hash = unhexlify(transaction_hash_hex) self.poll(transaction_hash, timeout=timeout) receipt = self.eth_getTransactionReceipt(transaction_hash) contract_address = receipt['contractAddress'] deployed_code = self.eth_getCode(unhexlify(contract_address[2:])) if deployed_code == '0x': raise RuntimeError( 'Deployment of {} failed. Contract address has no code, check gas usage.' .format(contract_name, )) return self.new_contract_proxy( contract_interface, contract_address, )
def deploy_solidity_contract( self, # pylint: disable=too-many-locals sender, contract_name, all_contracts, libraries, constructor_parameters, contract_path=None, timeout=None, gasprice=GAS_PRICE): """ Deploy a solidity contract. Args: sender (address): the sender address contract_name (str): the name of the contract to compile all_contracts (dict): the json dictionary containing the result of compiling a file libraries (list): A list of libraries to use in deployment constructor_parameters (tuple): A tuple of arguments to pass to the constructor contract_path (str): If we are dealing with solc >= v0.4.9 then the path to the contract is a required argument to extract the contract data from the `all_contracts` dict. timeout (int): Amount of time to poll the chain to confirm deployment gasprice: The gasprice to provide for the transaction """ if contract_name in all_contracts: contract_key = contract_name elif contract_path is not None: _, filename = os.path.split(contract_path) contract_key = filename + ':' + contract_name if contract_key not in all_contracts: raise ValueError('Unknown contract {}'.format(contract_name)) else: raise ValueError( 'Unknown contract {} and no contract_path given'.format(contract_name) ) libraries = dict(libraries) contract = all_contracts[contract_key] contract_interface = contract['abi'] symbols = solidity_unresolved_symbols(contract['bin_hex']) if symbols: available_symbols = list(map(solidity_library_symbol, all_contracts.keys())) unknown_symbols = set(symbols) - set(available_symbols) if unknown_symbols: msg = 'Cannot deploy contract, known symbols {}, unresolved symbols {}.'.format( available_symbols, unknown_symbols, ) raise Exception(msg) dependencies = deploy_dependencies_symbols(all_contracts) deployment_order = dependencies_order_of_build(contract_key, dependencies) deployment_order.pop() # remove `contract_name` from the list log.debug('Deploying dependencies: {}'.format(str(deployment_order))) for deploy_contract in deployment_order: dependency_contract = all_contracts[deploy_contract] hex_bytecode = solidity_resolve_symbols(dependency_contract['bin_hex'], libraries) bytecode = unhexlify(hex_bytecode) dependency_contract['bin_hex'] = hex_bytecode dependency_contract['bin'] = bytecode transaction_hash_hex = self.send_transaction( sender, to=b'', data=bytecode, gasprice=gasprice, ) transaction_hash = unhexlify(transaction_hash_hex) self.poll(transaction_hash, timeout=timeout) receipt = self.eth_getTransactionReceipt(transaction_hash) contract_address = receipt['contractAddress'] # remove the hexadecimal prefix 0x from the address contract_address = contract_address[2:] libraries[deploy_contract] = contract_address deployed_code = self.eth_getCode(address_decoder(contract_address)) if len(deployed_code) == 0: raise RuntimeError('Contract address has no code, check gas usage.') hex_bytecode = solidity_resolve_symbols(contract['bin_hex'], libraries) bytecode = unhexlify(hex_bytecode) contract['bin_hex'] = hex_bytecode contract['bin'] = bytecode if constructor_parameters: translator = ContractTranslator(contract_interface) parameters = translator.encode_constructor_arguments(constructor_parameters) bytecode = contract['bin'] + parameters else: bytecode = contract['bin'] transaction_hash_hex = self.send_transaction( sender, to=b'', data=bytecode, gasprice=gasprice, ) transaction_hash = unhexlify(transaction_hash_hex) self.poll(transaction_hash, timeout=timeout) receipt = self.eth_getTransactionReceipt(transaction_hash) contract_address = receipt['contractAddress'] deployed_code = self.eth_getCode(address_decoder(contract_address)) if len(deployed_code) == 0: raise RuntimeError( 'Deployment of {} failed. Contract address has no code, check gas usage.'.format( contract_name, ) ) return self.new_contract_proxy( contract_interface, contract_address, )
def tester_deploy_contract(tester_state, private_key, contract_name, contract_file, constructor_parameters=None): contract_path = get_contract_path(contract_file) all_contracts = _solidity.compile_file(contract_path, libraries=dict()) contract = all_contracts[contract_name] contract_interface = contract['abi'] log.info('Deploying "{}" contract'.format(contract_file)) dependencies = deploy_dependencies_symbols(all_contracts) deployment_order = dependencies_order_of_build(contract_name, dependencies) log.info('Deploing dependencies: {}'.format(str(deployment_order))) deployment_order.pop() # remove `contract_name` from the list libraries = dict() for deploy_contract in deployment_order: dependency_contract = all_contracts[deploy_contract] hex_bytecode = _solidity.solidity_resolve_symbols( dependency_contract['bin_hex'], libraries, ) bytecode = decode_hex(hex_bytecode) dependency_contract['bin_hex'] = hex_bytecode dependency_contract['bin'] = bytecode log.info('Creating contract {}'.format(deploy_contract)) contract_address = tester_state.evm( bytecode, private_key, endowment=0, ) tester_state.mine(number_of_blocks=1) if len(tester_state.block.get_code(contract_address)) == 0: raise Exception('Contract code empty') libraries[deploy_contract] = encode_hex(contract_address) hex_bytecode = _solidity.solidity_resolve_symbols(contract['bin_hex'], libraries) bytecode = hex_bytecode.decode('hex') contract['bin_hex'] = hex_bytecode contract['bin'] = bytecode if constructor_parameters: translator = ContractTranslator(contract_interface) parameters = translator.encode_constructor_arguments(constructor_parameters) bytecode = contract['bin'] + parameters else: bytecode = contract['bin'] log.info('Creating contract {}'.format(contract_name)) contract_address = tester_state.evm( bytecode, private_key, endowment=0, ) tester_state.mine(number_of_blocks=1) if len(tester_state.block.get_code(contract_address)) == 0: raise Exception('Contract code empty') return contract_address
GOLEM_FACTORY = '0x7da82C7AB4771ff031b66538D2fB9b0B047f6CF9' MIGRATION_MASTER = '0x7da82C7AB4771ff031b66538D2fB9b0B047f6CF9' START_BLOCK = 2607800 END_BLOCK = 2734100 version_info = subprocess.check_output(['solc', '--version']) print(version_info) contract = compile_contract('contracts/Token.sol', 'GolemNetworkToken') init = contract['bin_hex'] abi = contract['abi'] translator = ContractTranslator(abi) args = translator.encode_constructor_arguments( (GOLEM_FACTORY, MIGRATION_MASTER, START_BLOCK, END_BLOCK) ).encode('hex') print('\nGolem Network Token') print('- Factory: ' + GOLEM_FACTORY) print('- Migration Master: ' + MIGRATION_MASTER) print('- Start: ', START_BLOCK) print('- End: ', END_BLOCK) print() print('Deploy:') print(init + args) print() print('Args:') print(args) print() print('ABI:')
async def from_source_code(cls, sourcecode, contract_name, constructor_data=None, *, address=None, deployer_private_key=None, import_mappings=None, libraries=None, optimize=False, deploy=True, cwd=None): if deploy: ethurl = os.environ.get('ETHEREUM_NODE_URL') if not ethurl: raise Exception( "requires 'ETHEREUM_NODE_URL' environment variable to be set" ) if address is None and deployer_private_key is None: raise TypeError( "requires either address or deployer_private_key") if address is None and not isinstance(constructor_data, (list, type(None))): raise TypeError( "must supply constructor_data as a list (hint: use [] if args should be empty)" ) args = ['solc', '--combined-json', 'bin,abi', '--add-std'] if libraries: args.extend([ '--libraries', ','.join(['{}:{}'.format(*library) for library in libraries]) ]) if optimize: args.append('--optimize') if import_mappings: args.extend([ "{}={}".format(path, mapping) for path, mapping in import_mappings ]) # check if sourcecode is actually a filename if cwd: filename = os.path.join(cwd, sourcecode) else: filename = sourcecode if os.path.exists(filename): args.append(filename) sourcecode = None else: filename = '<stdin>' process = subprocess.Popen(args, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, cwd=cwd) output, stderrdata = process.communicate(input=sourcecode) try: output = json_decode(output) except json.JSONDecodeError: if output and stderrdata: output += b'\n' + stderrdata elif stderrdata: output = stderrdata raise Exception("Failed to compile source: {}\n{}\n{}".format( filename, ' '.join(args), output.decode('utf-8'))) try: contract = output['contracts']['{}:{}'.format( filename, contract_name)] except KeyError: print(output) raise abi = json_decode(contract['abi']) # deploy contract translator = ContractTranslator(abi) if not deploy: return Contract(abi=abi, address=address, translator=translator) ethclient = JsonRPCClient(ethurl) if address is not None: # verify there is code at the given address for i in range(10): code = await ethclient.eth_getCode(address) if code == "0x": await asyncio.sleep(1) continue break else: raise Exception("No code found at given address") return Contract(abi=abi, address=address, translator=translator) try: bytecode = data_decoder(contract['bin']) except binascii.Error: print(contract['bin']) raise if constructor_data is not None: constructor_call = translator.encode_constructor_arguments( constructor_data) bytecode += constructor_call if isinstance(deployer_private_key, str): deployer_private_key = data_decoder(deployer_private_key) deployer_address = private_key_to_address(deployer_private_key) nonce = await ethclient.eth_getTransactionCount(deployer_address) balance = await ethclient.eth_getBalance(deployer_address) gasprice = 20000000000 value = 0 startgas = await ethclient.eth_estimateGas(deployer_address, '', data=bytecode, nonce=nonce, value=0, gasprice=gasprice) if balance < (startgas * gasprice): raise Exception("Given account doesn't have enough funds") tx = Transaction(nonce, gasprice, startgas, '', value, bytecode, 0, 0, 0) tx.sign(deployer_private_key) tx_encoded = data_encoder(rlp.encode(tx, Transaction)) contract_address = data_encoder(tx.creates) tx_hash = await ethclient.eth_sendRawTransaction(tx_encoded) # wait for the contract to be deployed while True: resp = await ethclient.eth_getTransactionByHash(tx_hash) if resp is None or resp['blockNumber'] is None: await asyncio.sleep(0.1) else: code = await ethclient.eth_getCode(contract_address) if code == '0x': raise Exception( "Failed to deploy contract: resulting address '{}' has no code" .format(contract_address)) break return Contract(abi=abi, address=contract_address, translator=translator)
def deploy_solidity_contract( self, sender, contract_name, all_contracts, # pylint: disable=too-many-locals libraries, constructor_parameters, timeout=None, gasprice=denoms.wei): if contract_name not in all_contracts: raise ValueError('Unkonwn contract {}'.format(contract_name)) libraries = dict(libraries) contract = all_contracts[contract_name] contract_interface = contract['abi'] symbols = solidity_unresolved_symbols(contract['bin_hex']) if symbols: available_symbols = map(solidity_library_symbol, all_contracts.keys()) # pylint: disable=bad-builtin unknown_symbols = set(symbols) - set(available_symbols) if unknown_symbols: msg = 'Cannot deploy contract, known symbols {}, unresolved symbols {}.'.format( available_symbols, unknown_symbols, ) raise Exception(msg) dependencies = deploy_dependencies_symbols(all_contracts) deployment_order = dependencies_order_of_build( contract_name, dependencies) deployment_order.pop() # remove `contract_name` from the list log.debug('Deploing dependencies: {}'.format( str(deployment_order))) for deploy_contract in deployment_order: dependency_contract = all_contracts[deploy_contract] hex_bytecode = solidity_resolve_symbols( dependency_contract['bin_hex'], libraries) bytecode = hex_bytecode.decode('hex') dependency_contract['bin_hex'] = hex_bytecode dependency_contract['bin'] = bytecode transaction_hash = self.send_transaction( sender, to='', data=bytecode, gasprice=gasprice, ) self.poll(transaction_hash.decode('hex'), timeout=timeout) receipt = self.call('eth_getTransactionReceipt', '0x' + transaction_hash) contract_address = receipt['contractAddress'] contract_address = contract_address[ 2:] # remove the hexadecimal prefix 0x from the address libraries[deploy_contract] = contract_address deployed_code = self.call('eth_getCode', contract_address, 'latest') if deployed_code == '0x': raise RuntimeError( "Contract address has no code, check gas usage.") hex_bytecode = solidity_resolve_symbols(contract['bin_hex'], libraries) bytecode = hex_bytecode.decode('hex') contract['bin_hex'] = hex_bytecode contract['bin'] = bytecode if constructor_parameters: translator = ContractTranslator(contract_interface) parameters = translator.encode_constructor_arguments( constructor_parameters) bytecode = contract['bin'] + parameters else: bytecode = contract['bin'] transaction_hash = self.send_transaction( sender, to='', data=bytecode, gasprice=gasprice, ) self.poll(transaction_hash.decode('hex'), timeout=timeout) receipt = self.call('eth_getTransactionReceipt', '0x' + transaction_hash) contract_address = receipt['contractAddress'] deployed_code = self.call('eth_getCode', contract_address, 'latest') if deployed_code == '0x': raise RuntimeError( "Deployment of {} failed. Contract address has no code, check gas usage." .format(contract_name)) return ContractProxy( sender, contract_interface, contract_address, self.eth_call, self.send_transaction, )
def deploy_code(json_rpc, coinbase, file_path, constructor_params, contract_addresses, add_dev_code, contract_dir, gas, gas_price, private_key): if file_path not in addresses.keys(): if contract_addresses: a_copy = addresses.copy() a_copy.update(contract_addresses) contract_addresses = a_copy else: contract_addresses = addresses language = "solidity" if file_path.endswith(".sol") else "serpent" code = pp.process(file_path, add_dev_code=add_dev_code, contract_dir=contract_dir, addresses=contract_addresses) # compile code combined = languages[language].combined(code) compiled_code = combined[-1][1]["bin_hex"] abi = combined[-1][1]["abi"] # replace library placeholders for library_name, library_address in contract_addresses.iteritems(): compiled_code = compiled_code.replace( "__{}{}".format(library_name, "_" * (38 - len(library_name))), library_address[2:]) if constructor_params: translator = ContractTranslator(abi) compiled_code += translator.encode_constructor_arguments( constructor_params).encode("hex") print 'Try to create contract with length {} based on code in file: {}'.format( len(compiled_code), file_path) if private_key: address = privtoaddr(private_key.decode('hex')) nonce = int( json_rpc.eth_getTransactionCount('0x' + address.encode('hex')) ["result"][2:], 16) tx = Transaction(nonce, gas_price, gas, '', 0, compiled_code.decode('hex')) tx.sign(private_key.decode('hex')) raw_tx = rlp.encode(tx).encode('hex') tx_response = json_rpc.eth_sendRawTransaction("0x" + raw_tx) # transaction_hash = json_rpc.eth_sendRawTransaction("0x" + raw_tx)["result"] while "error" in tx_response: print 'Deploy failed with error {}. Retry!'.format( tx_response['error']) time.sleep(5) tx_response = json_rpc.eth_sendRawTransaction("0x" + raw_tx) else: tx_response = json_rpc.eth_sendTransaction(coinbase, data=compiled_code, gas=gas, gas_price=gas_price) # transaction_hash = json_rpc.eth_sendTransaction(coinbase, data=compiled_code, gas=gas, gas_price=gas_price)["result"] while "error" in tx_response: print 'Deploy failed with error {}. Retry!'.format( tx_response['error']) time.sleep(5) tx_response = json_rpc.eth_sendTransaction(coinbase, data=compiled_code, gas=gas, gas_price=gas_price) transaction_hash = tx_response['result'] wait_for_transaction_receipt(json_rpc, transaction_hash) contract_address = json_rpc.eth_getTransactionReceipt( transaction_hash)["result"]["contractAddress"] locally_deployed_code_address = s.evm( compiled_code.decode("hex")).encode("hex") locally_deployed_code = s.block.get_code( locally_deployed_code_address).encode("hex") deployed_code = json_rpc.eth_getCode(contract_address)["result"] if deployed_code != "0x" + locally_deployed_code: print 'Deploy of {} failed. Retry!'.format(file_path) deploy_code(json_rpc, coinbase, file_path, constructor_params, contract_addresses, add_dev_code, contract_dir, gas, gas_price, private_key) contract_name = file_path.split("/")[-1].split(".")[0] addresses[contract_name] = contract_address abis[contract_name] = abi print 'Contract {} was created at address {}.'.format( file_path, contract_address)
def tester_deploy_contract( tester_chain, private_key, contract_name, contract_path, constructor_parameters=None): all_contracts = _solidity.compile_file(contract_path, libraries=dict()) contract_key = solidity_get_contract_key(all_contracts, contract_path, contract_name) contract = all_contracts[contract_key] contract_interface = contract['abi'] log.info('Deploying "{}" contract'.format(os.path.basename(contract_path))) dependencies = deploy_dependencies_symbols(all_contracts) deployment_order = dependencies_order_of_build(contract_key, dependencies) log.info('Deploying dependencies: {}'.format(str(deployment_order))) deployment_order.pop() # remove `contract_name` from the list libraries = dict() for deploy_contract in deployment_order: dependency_contract = all_contracts[deploy_contract] hex_bytecode = _solidity.solidity_resolve_symbols( dependency_contract['bin_hex'], libraries, ) bytecode = unhexlify(hex_bytecode) dependency_contract['bin_hex'] = hex_bytecode dependency_contract['bin'] = bytecode log.info('Creating contract {}'.format(deploy_contract)) contract_address = tester_chain.contract(bytecode, language='evm', sender=private_key) tester_chain.mine(number_of_blocks=1) if len(tester_chain.head_state.get_code(contract_address)) == 0: raise Exception('Contract code empty') libraries[deploy_contract] = encode_hex(contract_address) hex_bytecode = _solidity.solidity_resolve_symbols(contract['bin_hex'], libraries) bytecode = unhexlify(hex_bytecode) contract['bin_hex'] = hex_bytecode contract['bin'] = bytecode if constructor_parameters: translator = ContractTranslator(contract_interface) parameters = translator.encode_constructor_arguments(constructor_parameters) bytecode = contract['bin'] + parameters else: bytecode = contract['bin'] log.info('Creating contract {}'.format(contract_name)) contract_address = tester_chain.contract(bytecode, language='evm', sender=private_key) tester_chain.mine(number_of_blocks=1) if len(tester_chain.head_state.get_code(contract_address)) == 0: raise Exception('Contract code empty') return contract_address