def create_contract(self, path, params=None, libraries=None, sender=None): path, extra_args = self.get_dirs(path) if params: params = [ x.address if isinstance(x, t.ABIContract) else x for x in params ] if libraries: for name, address in libraries.items(): if type(address) == str: if self.is_hex(address): libraries[name] = address else: libraries[ name] = ContractTranslator.encode_function_call( address, 'hex') elif isinstance(address, t.ABIContract): libraries[name] = ContractTranslator.encode_function_call( address.address, 'hex') else: raise ValueError return self.s.abi_contract(None, path=path, constructor_parameters=params, libraries=libraries, language='solidity', extra_args=extra_args, sender=keys[sender if sender else 0])
def call_const_function( self, priv_key, value, contract_hash, contract_abi, function_name, eth_args ): # src_address = b2h(utils.privtoaddr(priv_key)) translator = ContractTranslator(json.loads(contract_abi)) call = translator.encode_function_call(function_name, eth_args) # nonce = get_num_transactions(src_address) # gas_price = get_gas_price_in_wei() # start_gas = eval_startgas( # src_address, contract_hash, value, b2h(call), gas_price) # nonce = int(nonce, base=16) # gas_price = int(gas_price, base=16) # start_gas = int(start_gas, base=16) + 100000 # start_gas = 7612288 params = { # "from": "0x" + src_address, "to": "0x" + contract_hash, # "gas": "0x" + "%x" % start_gas, # "gasPrice": "0x" + "%x" % gas_price, # "value": "0x" + str(value), "data": "0x" + b2h(call), } return_value = self._json_call("eth_call", [params, "latest"]) # print return_value return_value = h2b(return_value[2:]) # remove 0x return translator.decode_function_result(function_name, return_value)
def call_const_function(priv_key, value, contract_hash, contract_abi, function_name, args): src_address = b2h(utils.privtoaddr(priv_key)) translator = ContractTranslator(contract_abi) call = translator.encode_function_call(function_name, args) nonce = get_num_transactions(src_address) gas_price = get_gas_price_in_wei() start_gas = eval_startgas(src_address, contract_hash, value, b2h(call), gas_price) nonce = int(nonce, 16) gas_price = int(gas_price, 16) start_gas = int(start_gas, 16) + 100000 params = { "from": "0x" + src_address, "to": "0x" + contract_hash, "gas": "0x" + str(start_gas), "gasPrice": "0x" + str(gas_price), "value": str(value), "data": "0x" + b2h(call) } return_value = json_call("eth_call", [params]) return_value = h2b(return_value[2:]) # remove 0x return translator.decode(function_name, return_value)
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 call_function( self, priv_key, value, contract_hash, contract_abi, function_name, eth_args, use_increased_gas_price=False, ): translator = ContractTranslator(json.loads(contract_abi)) call = translator.encode_function_call(function_name, eth_args) return self._make_transaction( src_priv_key=priv_key, dst_address=contract_hash, value=value, data=call, use_increased_gas_price=use_increased_gas_price, )
def call_const_function( priv_key, value, contract_hash, contract_abi, function_name, args ): src_address = b2h( utils.privtoaddr(priv_key) ) translator = ContractTranslator(contract_abi) call = translator.encode_function_call(function_name, args) nonce = get_num_transactions( src_address ) gas_price = get_gas_price_in_wei() start_gas = eval_startgas( src_address, contract_hash, value, b2h(call), gas_price ) nonce = int( nonce, 16 ) gas_price = int( gas_price, 16 ) start_gas = int( start_gas, 16 ) + 100000 params = { "from" : "0x" + src_address, "to" : "0x" + contract_hash, "gas" : "0x" + str(start_gas), "gasPrice" : "0x" + str(gas_price), "value" : str(value), "data" : "0x" + b2h(call) } return_value = json_call( "eth_call", [params]) return_value = h2b(return_value[2:]) # remove 0x return translator.decode(function_name, return_value)
ContractFactoryClass=ConciseContract) # check bumber of tokens # tokens = contract_instance.tokensOfOwner(badge_owner); # print('Tokens: {}'.format(tokens)) # Contract creates new badge transact = {"gas": gas, "from": sender_address} # Sending transaction # contract_instance.create(donation_tx, badge_title, badge_owner, transact=transact) # Send raw transaction ct = ContractTranslator(abi['abi']) txHash = Web3.toInt(hexstr=donation_tx) txdata = ct.encode_function_call("create", [txHash, challenge, badge_owner]) # Load data with configuration and nonce # data = json.load(open('data.txt', 'r')) # if 'nonce' not in data: # data['nonce'] = w3.eth.getTransactionCount(sender_address) # else: # nonce = data["nonce"] + 1 # nonce = max(nonce, w3.eth.getTransactionCount(sender_address)) nonce = w3.eth.getTransactionCount(sender_address, block_identifier="pending") tx = Transaction( nonce=nonce, gasprice=20000000000, startgas=6638084,
def encode_transfer_data(recipient_address, amount: EthereumTokenAmount): translator = ContractTranslator(EIP20_ABI) encoded_data = translator.encode_function_call( "transfer", (recipient_address, amount.as_wei)) return f"0x{encoded_data.hex()}"
def call_function(priv_key, value, contract_hash, contract_abi, function_name, args): translator = ContractTranslator(contract_abi) call = translator.encode_function_call(function_name, args) return make_transaction(priv_key, contract_hash, value, call)
def call_function( priv_key, value, contract_hash, contract_abi, function_name, args ): translator = ContractTranslator(contract_abi) call = translator.encode_function_call(function_name, args) return make_transaction(priv_key, contract_hash, value, call)
class Contract(object): """A class for interacting with Ethereum contracts.""" def __init__(self, address: str, interface: Sequence[Mapping], rpc_address: str, sender: str = None, gas: int = MAX_GAS): """Create a new Contract instance. Batch requests not supported! Arguments: address -- The address of the smart contract you want to use. interface -- The full signature of the smart contract. rpc_address -- The address of the RPC server for your Ethereum node. sender -- The address to send from. If None, the default sender for your node is used. gas -- The maximum amount of gas to use per transaction/call. """ err_fmt = 'Invalid {} address, must be 40 digit hex starting with \'0x\': {!r}' if not ETH_ADDR.match(address): raise ContractError(err_fmt.format('contract', address)) self.translator = ContractTranslator(interface) self.rpc_client = rpc_factory(rpc_address, False) self.common_params = {'to': address, 'gas': hex(gas)} if sender is None: pass elif ETH_ADDR.match(sender): self.common_params['from'] = sender else: raise ContractError(err_fmt.format('sender', sender)) def proxy_factory(name): # Generates proxy functions that use rpc methods under the hood. pyname = name.split('(')[0] # a python compatible name def proxy(*args, **kwds): """Calls function {} in contract {}. If the optional `call` keyword is True, then the result of the function call is decoded into a Python object and returned, otherwise the transaction hash is returned. """ tx = self.common_params.copy() data = self.translator.encode_function_call(pyname, args) tx['data'] = '0x{}'.format(data.encode('hex')) if kwds.get('call', False): return self._call(pyname, tx) else: return self._send(tx) proxy.__name__ = pyname proxy.__doc__ = proxy.__doc__.format(name, address) return proxy for item in interface: if item['type'] == 'function': proxy = proxy_factory(item['name']) if hasattr(self, proxy.__name__): raise ContractError('Polymorphism not supported!') setattr(self, proxy.__name__, proxy) def _call(self, func_name, tx): # Uses call to interact with a contract. response = self.rpc_client.eth_call(tx, 'latest') self._check_response(response) raw_result = response['result'].lstrip('0x').decode('hex') return self.translator.decode(func_name, raw_result) def _send(self, tx): response = self.rpc_client.eth_sendTransaction(tx) return response['result']