def cli(ctx, config_path, broadcast: bool): config = parse_config(ctx, config_path, Config) config.contract_bin = StrictStr( file_validator(config.contract_bin, config_path)) constructor_data = "" if config.constructor_types and config.constructor_values: constructor_types = yaml.full_load(config.constructor_types) constructor_values = yaml.full_load(config.constructor_values) constructor_data = eth_abi.encode_data(constructor_types, constructor_values)[2:] if ctx.obj.get("config"): # noinspection PyUnresolvedReferences print_json(config.dict() | {"constructor_data": constructor_data}) exit(0) tx_params: Any = pydash.omit(config.dict(), "node", "contract_bin", "constructor_types", "constructor_values") tx_params["data"] = config.contract_bin + constructor_data if tx_params["nonce"] is None: tx_params["nonce"] = get_nonce_or_exit( config.node, eth_account.private_to_address(config.private_key)) signed_tx = eth_tx.sign_tx(**tx_params) if broadcast: res = eth_rpc.eth_send_raw_transaction(config.node, signed_tx.raw_tx) print_json({"result": res.ok_or_error}) else: decoded = eth_utils.to_human_readable_tx( eth_tx.decode_raw_tx(signed_tx.raw_tx)) print_json(signed_tx.dict() | {"decoded": decoded})
def cli(ctx, config_path, broadcast: bool): config = parse_config(ctx, config_path, Config) res = eth_rpc.eth_get_transaction_by_hash(config.node, config.tx_hash) if res.is_error(): return print_json({"error": res.error}) tx = res.ok new_tx = eth_tx.sign_tx( nonce=tx.nonce, gas_price=config.gas_price, gas=21_000, private_key=config.private_key, chain_id=config.chain_id, data=None, value=0, to=tx.from_, ) if broadcast: res = eth_rpc.eth_send_raw_transaction(config.node, new_tx.raw_tx) print_json({"result": res.ok_or_error}) else: decoded = eth_tx.decode_raw_tx(new_tx.raw_tx) print_json(new_tx.dict() | {"decoded": eth_utils.to_human_readable_tx(decoded)})
def cli(ctx, config_path, broadcast: bool): config = parse_config(ctx, config_path, Config) config.abi = file_validator(config.abi, config_path) print_config_and_exit(ctx, config) function_args = yaml.full_load( config.function_args) if config.function_args else [] data = eth_abi.encode_function_input(yaml.full_load(config.abi), config.function_name, function_args) if config.nonce is None: config.nonce = get_nonce_or_exit( config.node, eth_account.private_to_address(config.private_key)) signed_tx = eth_tx.sign_tx( nonce=config.nonce, gas_price=config.gas_price, gas=config.gas, private_key=config.private_key, chain_id=config.chain_id, data=data, value=config.value, to=config.contract, ) if broadcast: res = eth_rpc.eth_send_raw_transaction(config.node, signed_tx.raw_tx) if res.is_ok(): print_json({"tx_hash": res.ok}) else: print_json({"error": res.error}) else: decoded = eth_utils.to_human_readable_tx( eth_tx.decode_raw_tx(signed_tx.raw_tx)) print_json({"signed": signed_tx.dict(), "decoded": decoded})
def cli(ctx, config_path, broadcast: bool): config = parse_config(ctx, config_path, Config) # address -> private_key accounts = { eth_account.private_to_address(private_key): private_key for private_key in config.private_keys } tx_fee = 21_000 * config.gas_price low_eth_balance: list[str] = [] signed_tx: list[SignedTx] = [] for address, private_key in accounts.items(): res = eth_rpc.eth_get_balance(config.random_node, address) if res.is_error(): return fatal(f"can't get balance: {res.error}") balance = res.ok if balance <= tx_fee: low_eth_balance.append(address) else: res = eth_rpc.eth_get_transaction_count(config.random_node, address) if res.is_error(): return fatal(f"can't get nonce: {res.error}") nonce = res.ok value = balance - tx_fee tx = eth_tx.sign_tx( nonce=nonce, gas_price=config.gas_price, gas=21_000, private_key=private_key, chain_id=config.chain_id, value=value, to=config.recipient, ) signed_tx.append(tx) if broadcast: result = [] for tx in signed_tx: res = eth_rpc.eth_send_raw_transaction(config.random_node, tx.raw_tx) result.append(res.ok_or_error) print_json(md(low_eth_balance, result)) else: txs = [] for tx in signed_tx: decoded = eth_tx.decode_raw_tx(tx.raw_tx) decoded = eth_utils.to_human_readable_tx(decoded) # type:ignore txs.append(tx.dict() | md(decoded)) print_json(md(low_eth_balance, signed_tx=txs))
def cli(ctx, config_path): config = parse_config(ctx, config_path, Config) print_config_and_exit(ctx, config) if not eth_account.is_valid_private_key(config.from_, config.private_key): print_json({"error": "wrong private key"}) exit(1) raw_tx = eth_tx.sign_tx(**config.dict(exclude={"from_"})) print_json( raw_tx.dict() | { "decoded": eth_utils.to_human_readable_tx(eth_tx.decode_raw_tx(raw_tx.raw_tx)) })
def cli(ctx, config_path, broadcast: bool): config = parse_config(ctx, config_path, Config) print_config_and_exit(ctx, config) txs = sign_txs(config) result: list[Any] = [] if broadcast: for tx in txs: res = eth_rpc.eth_send_raw_transaction(config.random_node, tx.raw_tx) result.append([tx.tx_hash, "ok" if res.is_ok() else res.error]) else: for tx in txs: res = eth_tx.decode_raw_tx(tx.raw_tx) result.append({ "raw": tx.raw_tx, "tx": eth_utils.to_human_readable_tx(res) }) print_json(result)
def cli(raw_tx): tx = eth_tx.decode_raw_tx(raw_tx).dict() tx = pydash.rename_keys(tx, {"from_": "from"}) tx = eth_utils.to_human_readable_tx(tx) print_json(tx)