def generate_data(dataset_address, key, price, timestamp): V, R, S = [], [], [] for pk in PROVIDER_PKS.split(","): v, r, s = sign_aggregate( dataset_address, str.encode(key), price, timestamp, 1, pk ) V.append(v) R.append(r) S.append(s) return ( "0x" + ( function_signature_to_4byte_selector( "report(bytes,uint256,uint64,uint8,uint8[],bytes32[],bytes32[])" ) + encode_abi( [ "bytes", "uint256", "uint64", "uint8", "uint8[]", "bytes32[]", "bytes32[]", ], [str.encode(key), price, timestamp, 1, V, R, S], ) ).hex() )
def __init__(self, signature): self.signature = signature self.parts = parse_signature(signature) self.input_types = self.parts[1] self.output_types = self.parts[2] self.function = ''.join(self.parts[:2]) self.fourbyte = function_signature_to_4byte_selector(self.function)
def play(contract_address, data): NONCE = web3.eth.getTransactionCount(RESOLVER_ADDRESS, "pending") gas_price = requests.get("https://ethgasstation.info/json/ethgasAPI.json").json()[ "fast" ] last_data = bytes.fromhex(data[2:]) func_sig = function_signature_to_4byte_selector("buy(uint64,bool,bytes)") signed = web3.eth.account.signTransaction( { "to": contract_address, "data": func_sig + encode_abi( ["uint64", "bool", "bytes"], [int(time.time()) + 345, random.randint(0, 1) == 0, last_data], ), "nonce": NONCE, "gasPrice": web3.toWei(str(gas_price / 10 + 5), "gwei"), "value": web3.toWei("0.104", "ether"), "gas": 350000, }, RESOLVER_PK, ) txhash = web3.eth.sendRawTransaction(signed.rawTransaction).hex() return txhash
def transaction(simple_contract_address): function_selector = function_signature_to_4byte_selector('getMeaningOfLife()') return { 'from': '0x' + 'ff' * 20, # unfunded address 'to': to_hex(simple_contract_address), 'gasPrice': to_hex(0), 'data': to_hex(function_selector), }
def encode_function_call(abi: str, params: list) -> str: abi = abi.replace(' ', '') if '(' not in abi or ')' not in abi: raise ValueError( f'Function signature must contain "(" and ")": {abi}') signature = function_signature_to_4byte_selector(abi) inputs = abi[abi.index('('):] params = encode_single(inputs, params) return encode_hex(signature + params)
def create_transfer_and_call(sender, to, value, sig, *params): data_to_call = create_params_data(*params) return create_transaction_data( "transferAndCall(address,address,uint256,bytes4,bytes)", ("address", sender), ("address", to), ("uint256", value), ("bytes4", function_signature_to_4byte_selector(sig)), ("bytes", data_to_call), )
def testjson(): with open("AddrTableWorker.abi", 'r') as load_f: load_dict = json.load(load_f) for item in load_dict: if item["type"] != "constructor": print(item["name"], " is a ", item["type"]) hash4 = function_signature_to_4byte_selector(item["name"] + '()') print("function hash4:", encode_hex(hash4)) with open("abi_1.json", "w") as dump_f: json.dump(load_dict, dump_f)
def test_get_transaction_result(chain, simple_contract_address, signature, gas_price, expected): function_selector = function_signature_to_4byte_selector(signature) call_txn = new_transaction( chain.get_vm(), b'\xff' * 20, simple_contract_address, gas_price=gas_price, data=function_selector, ) result_bytes = chain.get_transaction_result(call_txn, chain.get_canonical_head()) assert result_bytes == expected
def test_get_transaction_result_revert(vm, chain_from_vm, simple_contract_address, signature, expected): chain = chain_from_vm(vm) function_selector = function_signature_to_4byte_selector(signature) call_txn = new_transaction( chain.get_vm(), b'\xff' * 20, simple_contract_address, data=function_selector, ) with pytest.raises(expected): chain.get_transaction_result(call_txn, chain.get_canonical_head())
async def test_eth_call_with_contract_on_ipc(chain, jsonrpc_ipc_pipe_path, simple_contract_address, signature, gas_price, event_loop, ipc_server, expected): function_selector = function_signature_to_4byte_selector(signature) transaction = { 'from': '0x' + 'ff' * 20, # unfunded address 'to': to_hex(simple_contract_address), 'gasPrice': to_hex(gas_price), 'data': to_hex(function_selector), } request_msg = build_request('eth_call', params=[transaction, 'latest']) result = await get_ipc_response(jsonrpc_ipc_pipe_path, request_msg, event_loop) assert result == expected
def eth_call(to, sig, data="0x"): if not is_0x_prefixed(sig): sig = to_hex(function_signature_to_4byte_selector(sig)) if isinstance(data, bytes): data = to_hex(data) return requests.post( BASE_URL, json={ "jsonrpc": "2.0", "method": "eth_call", "params": [{ "to": to, "data": sig + data[2:] }, "latest"], "id": 12, }, ).json()["result"]
def parse_abi(self): '''for item in self.contract_abi: if (item["type"] != "constructor"): print(item["name"], " is a ", item["type"]) hash4 = function_signature_to_4byte_selector(item["name"] + '()') print("function hash4:", encode_hex(hash4))''' funclist = filter_by_type("function", self.contract_abi) for func in funclist: signature = abi_to_signature(func) selector = function_signature_to_4byte_selector(signature) # print(func) # print(signature) # print(encode_hex(selector) ) self.func_abi_map_by_selector[encode_hex(selector)] = func self.func_abi_map_by_name[func['name']] = func eventlist = filter_by_type("event", self.contract_abi) for event in eventlist: topic = event_abi_to_log_topic(event) # print(event) # print(encode_hex(topic) ) self.event_abi_map[encode_hex(topic)] = event
def resolve_bet(contract_address, px, id): global NONCE NONCE = max(web3.eth.getTransactionCount(RESOLVER_ADDRESS, "pending"), NONCE) gas_price = requests.get("https://ethgasstation.info/json/ethgasAPI.json").json()[ "fast" ] last_data = bytes.fromhex(px["data"][2:]) func_sig = function_signature_to_4byte_selector("resolve(uint256,bytes)") signed = web3.eth.account.signTransaction( { "to": contract_address, "data": func_sig + encode_abi(["uint256", "bytes"], [id, last_data]), "nonce": NONCE, "gasPrice": web3.toWei(str(gas_price / 10 + 5), "gwei"), "gas": 250000, }, RESOLVER_PK, ) NONCE += 1 txhash = web3.eth.sendRawTransaction(signed.rawTransaction).hex() return txhash
validate_address, ) from .exceptions import ( SdkConfigurationError, SdkNotConfiguredError, ) from .provider import RetryHTTPProvider from .utils import load_keyfile import logging logger = logging.getLogger(__name__) # ERC20 contract consts. ERC20_TRANSFER_ABI_PREFIX = encode_hex( function_signature_to_4byte_selector('transfer(address, uint256)')) # default gas configuration. DEFAULT_GAS_PER_TX = 60000 DEFAULT_GAS_PRICE = 10 * 10**9 # 10 Gwei # default request retry configuration (linear backoff). RETRY_ATTEMPTS = 3 RETRY_DELAY = 0.3 class TransactionStatus: """Transaction status enumerator.""" UNKNOWN = 0 PENDING = 1 SUCCESS = 2
def get_function_sighash(signature): return '0x' + function_signature_to_4byte_selector(signature).hex()
validate_abi, validate_address, ) from .exceptions import ( SdkConfigurationError, SdkNotConfiguredError, ) from .provider import RetryHTTPProvider from .utils import load_keyfile import logging logger = logging.getLogger(__name__) # ERC20 contract consts. ERC20_TRANSFER_ABI_PREFIX = encode_hex(function_signature_to_4byte_selector('transfer(address, uint256)')) # default gas configuration. DEFAULT_GAS_PER_TX = 60000 DEFAULT_GAS_PRICE = 10 * 10 ** 9 # 10 Gwei # default request retry configuration (linear backoff). RETRY_ATTEMPTS = 3 RETRY_DELAY = 0.3 class TransactionStatus: """Transaction status enumerator.""" UNKNOWN = 0 PENDING = 1 SUCCESS = 2
def func_topic(func): ''' Convert function signature to ds-note log topic. ''' return encode_hex( encode_single('bytes32', function_signature_to_4byte_selector(func)))
validate_abi, validate_address, ) from .exceptions import ( SdkConfigurationError, SdkNotConfiguredError, ) from .provider import RetryHTTPProvider from .utils import load_keyfile import logging logger = logging.getLogger(__name__) # ERC20 contract consts. ERC20_TRANSFER_ABI_PREFIX = encode_hex(function_signature_to_4byte_selector('transfer(address, uint256)')) # default gas configuration. DEFAULT_GAS_PER_TX = 60000 DEFAULT_GAS_PRICE = 1 * 10 ** 9 # 1 Gwei # default request retry configuration (linear backoff). RETRY_ATTEMPTS = 3 RETRY_DELAY = 0.3 class TransactionStatus: """Transaction status enumerator.""" UNKNOWN = 0 PENDING = 1 SUCCESS = 2
def __init__(self, signature: str) -> None: self.signature = signature self.function, self.input_types, self.output_types = parse_signature(signature) self.fourbyte = function_signature_to_4byte_selector(self.function)
def test_auction_bid_from_gnosis_multisig( web3, owner, wallet_address, gnosis_multisig_wallet, get_bidders, auction_contract_fast_decline, token_contract, event_handler): eth = web3.eth auction = auction_contract_fast_decline (A, B, C) = get_bidders(3) # Initialize token token = token_contract(auction.address) auction.transact({'from': owner}).setup(token.address) auction.transact({'from': owner}).startAuction() gnosis_wallet1 = gnosis_multisig_wallet([A, B, C], 1) gnosis_wallet2 = gnosis_multisig_wallet([A, B, C], 2) gnosis_wallet1_balance = 100000 gnosis_wallet2_balance = 200000 web3.eth.sendTransaction({ 'from': B, 'to': gnosis_wallet1.address, 'value': gnosis_wallet1_balance }) web3.eth.sendTransaction({ 'from': B, 'to': gnosis_wallet2.address, 'value': gnosis_wallet2_balance }) # Test gnosis wallet with 2 owners and 1 confirmation # Using Auction's fallback function pre_balance_wallet = web3.eth.getBalance(wallet_address) gnosis_wallet1.transact({'from': A}).submitTransaction(auction.address, 1000, bytearray()) gnosis_wallet1_balance -= 1000 assert web3.eth.getBalance(gnosis_wallet1.address) == gnosis_wallet1_balance assert auction.call().bids(gnosis_wallet1.address) == 1000 assert web3.eth.getBalance(wallet_address) == pre_balance_wallet + 1000 # Test gnosis wallet with 2 owners and 1 confirmation # Using Auction's bid() function pre_balance_wallet = web3.eth.getBalance(wallet_address) data = function_signature_to_4byte_selector('bid()') gnosis_wallet1.transact({'from': A}).submitTransaction(auction.address, 1000, data) gnosis_wallet1_balance -= 1000 assert web3.eth.getBalance(gnosis_wallet1.address) == gnosis_wallet1_balance assert auction.call().bids(gnosis_wallet1.address) == 2000 assert web3.eth.getBalance(wallet_address) == pre_balance_wallet + 1000 transaction_id_keeper = TransactionIdKeeper() # Test gnosis wallet with 3 owners and 2 confirmations # Using Auction's fallback function pre_balance_wallet = web3.eth.getBalance(wallet_address) txhash = gnosis_wallet2.transact({'from': A}).submitTransaction(auction.address, 3000, bytearray()) assert web3.eth.getBalance(gnosis_wallet2.address) == gnosis_wallet2_balance assert auction.call().bids(gnosis_wallet2.address) == 0 assert web3.eth.getBalance(wallet_address) == pre_balance_wallet # Wait for transactionId from the Confirmation event ev_handler = event_handler(gnosis_wallet2) ev_handler.add(txhash, 'Confirmation', transaction_id_keeper.add) ev_handler.check() # Second owner confirms the transaction transaction_id = transaction_id_keeper.transaction_id gnosis_wallet2.transact({'from': B}).confirmTransaction(transaction_id) gnosis_wallet2_balance -= 3000 assert web3.eth.getBalance(gnosis_wallet2.address) == gnosis_wallet2_balance assert auction.call().bids(gnosis_wallet2.address) == 3000 assert web3.eth.getBalance(wallet_address) == pre_balance_wallet + 3000 # Test gnosis wallet with 3 owners and 2 confirmations # Using Auction's bid() function pre_balance_wallet = web3.eth.getBalance(wallet_address) data = function_signature_to_4byte_selector('bid()') txhash1 = gnosis_wallet2.transact({'from': A}).submitTransaction(auction.address, 3000, data) # Second owner confirms the transaction ev_handler.add(txhash1, 'Confirmation', transaction_id_keeper.add) ev_handler.check() transaction_id = transaction_id_keeper.transaction_id gnosis_wallet2.transact({'from': B}).confirmTransaction(transaction_id) gnosis_wallet2_balance -= 3000 assert web3.eth.getBalance(gnosis_wallet2.address) == gnosis_wallet2_balance assert auction.call().bids(gnosis_wallet2.address) == 6000 assert web3.eth.getBalance(wallet_address) == pre_balance_wallet + 3000
def create_transaction_data(sig, *params): if not is_0x_prefixed(sig): sig = to_hex(function_signature_to_4byte_selector(sig)) raw_param = create_params_data(*params) return sig + remove_0x_prefix(to_hex(raw_param))