2021-06-28 07:48:36 +02:00
# SPDX-License-Identifier: GPL-3.0-or-later
# standard imports
import io
import sys
import os
import json
import argparse
import logging
import urllib
# external imports
from hexathon import (
add_0x ,
strip_0x ,
)
2022-05-12 15:53:33 +02:00
from chainlib . settings import ChainSettings
2021-06-28 07:48:36 +02:00
from chainlib . jsonrpc import (
JSONRPCRequest ,
IntSequenceGenerator ,
)
2022-05-12 15:53:33 +02:00
from chainlib . chain import ChainSpec
# local imports
from chainlib . eth . address import to_checksum_address
from chainlib . eth . connection import EthHTTPConnection
2021-08-21 09:27:40 +02:00
from chainlib . eth . gas import Gas
2021-06-28 07:48:36 +02:00
from chainlib . eth . gas import balance as gas_balance
from chainlib . eth . runnable . util import decode_for_puny_humans
2021-10-30 16:49:36 +02:00
from chainlib . eth . address import (
is_same_address ,
is_checksum_address ,
)
2021-08-21 09:27:40 +02:00
import chainlib . eth . cli
2022-05-12 11:29:10 +02:00
from chainlib . eth . cli . arg import (
Arg ,
ArgFlag ,
process_args ,
)
from chainlib . eth . cli . config import (
Config ,
process_config ,
)
from chainlib . eth . cli . log import process_log
2022-05-12 16:08:36 +02:00
from chainlib . eth . settings import process_settings
2021-06-28 07:48:36 +02:00
logg = logging . getLogger ( )
2022-05-12 11:29:10 +02:00
def process_config_local ( config , arg , args , flags ) :
config . add ( args . data , ' _DATA ' , False )
2022-05-12 20:05:13 +02:00
config . add ( args . amount , ' _VALUE ' , False )
2022-05-12 11:29:10 +02:00
return config
arg_flags = ArgFlag ( )
arg = Arg ( arg_flags )
flags = arg_flags . STD_WRITE | arg_flags . WALLET
argparser = chainlib . eth . cli . ArgumentParser ( )
argparser = process_args ( argparser , arg , flags )
2021-08-21 09:27:40 +02:00
argparser . add_argument ( ' --data ' , type = str , help = ' Transaction data ' )
2022-05-12 20:05:13 +02:00
argparser . add_argument ( ' amount ' , type = str , help = ' Token amount to send ' )
2021-06-28 07:48:36 +02:00
args = argparser . parse_args ( )
2022-05-12 11:29:10 +02:00
logg = process_log ( args , logg )
config = Config ( )
config = process_config ( config , arg , args , flags )
config = process_config_local ( config , arg , args , flags )
logg . debug ( ' config loaded: \n {} ' . format ( config ) )
2021-06-28 07:48:36 +02:00
2022-05-12 15:53:33 +02:00
settings = ChainSettings ( )
2022-05-12 16:08:36 +02:00
settings = process_settings ( settings , config )
logg . debug ( ' settings loaded: \n {} ' . format ( settings ) )
2021-06-28 07:48:36 +02:00
2022-05-12 16:08:36 +02:00
def balance ( conn , address , id_generator ) :
2021-06-28 07:48:36 +02:00
o = gas_balance ( address , id_generator = id_generator )
r = conn . do ( o )
2021-10-28 12:17:32 +02:00
try :
balance = int ( r )
except ValueError :
balance = strip_0x ( r )
balance = int ( balance , 16 )
return balance
2021-06-28 07:48:36 +02:00
def main ( ) :
2022-05-12 15:53:33 +02:00
g = Gas (
settings . get ( ' CHAIN_SPEC ' ) ,
2022-05-12 16:08:36 +02:00
signer = settings . get ( ' SIGNER ' ) ,
gas_oracle = settings . get ( ' GAS_ORACLE ' ) ,
nonce_oracle = settings . get ( ' NONCE_ORACLE ' ) ,
)
2021-08-21 09:27:40 +02:00
recipient = to_checksum_address ( config . get ( ' _RECIPIENT ' ) )
2021-12-10 02:35:38 +01:00
if not config . true ( ' _UNSAFE ' ) and not is_checksum_address ( recipient ) :
2021-06-28 07:48:36 +02:00
raise ValueError ( ' invalid checksum address ' )
if logg . isEnabledFor ( logging . DEBUG ) :
try :
2022-05-12 16:08:36 +02:00
sender_balance = balance (
settings . get ( ' CONN ' ) ,
settings . get ( ' SENDER_ADDRESS ' ) ,
settings . get ( ' RPC_ID_GENERATOR ' ) ,
)
recipient_balance = balance (
settings . get ( ' CONN ' ) ,
settings . get ( ' RECIPIENT ' ) ,
settings . get ( ' RPC_ID_GENERATOR ' ) ,
)
logg . debug ( ' sender {} balance before: {} ' . format ( settings . get ( ' SENDER_ADDRESS ' ) , sender_balance ) )
logg . debug ( ' recipient {} balance before: {} ' . format ( settings . get ( ' RECIPIENT ' ) , recipient_balance ) )
2021-06-28 07:48:36 +02:00
except urllib . error . URLError :
pass
2022-05-12 16:08:36 +02:00
( tx_hash_hex , o ) = g . create (
settings . get ( ' SENDER_ADDRESS ' ) ,
settings . get ( ' RECIPIENT ' ) ,
2022-05-12 20:05:13 +02:00
settings . get ( ' VALUE ' ) ,
2022-05-12 16:08:36 +02:00
data = config . get ( ' _DATA ' ) ,
id_generator = settings . get ( ' RPC_ID_GENERATOR ' ) ,
)
2022-05-14 18:36:21 +02:00
logg . info ( ' gas transfer from {} to {} value {} hash {} ' . format ( settings . get ( ' SENDER_ADDRESS ' ) , settings . get ( ' RECIPIENT ' ) , settings . get ( ' VALUE ' ) , tx_hash_hex ) )
2022-05-13 09:49:15 +02:00
2022-05-12 16:08:36 +02:00
if settings . get ( ' RPC_SEND ' ) :
settings . get ( ' CONN ' ) . do ( o )
2022-05-12 11:29:10 +02:00
if config . true ( ' _WAIT ' ) :
2022-05-12 16:08:36 +02:00
r = settings . get ( ' CONN ' ) . wait ( tx_hash_hex )
2021-06-28 07:48:36 +02:00
if logg . isEnabledFor ( logging . DEBUG ) :
2022-05-12 16:08:36 +02:00
sender_balance = balance (
settings . get ( ' CONN ' ) ,
settings . get ( ' SENDER_ADDRESS ' ) ,
settings . get ( ' RPC_ID_GENERATOR ' ) ,
)
recipient_balance = balance (
settings . get ( ' CONN ' ) ,
settings . get ( ' RECIPIENT ' ) ,
settings . get ( ' RPC_ID_GENERATOR ' ) ,
)
logg . debug ( ' sender {} balance before: {} ' . format ( settings . get ( ' SENDER_ADDRESS ' ) , sender_balance ) )
logg . debug ( ' recipient {} balance before: {} ' . format ( settings . get ( ' RECIPIENT ' ) , recipient_balance ) )
2021-06-28 07:48:36 +02:00
if r [ ' status ' ] == 0 :
2022-01-09 13:09:23 +01:00
logg . critical ( ' VM revert for {} . Wish I could tell you more ' . format ( tx_hash_hex ) )
2021-06-28 07:48:36 +02:00
sys . exit ( 1 )
print ( tx_hash_hex )
else :
2021-08-21 09:27:40 +02:00
if config . true ( ' _RAW ' ) :
print ( o [ ' params ' ] [ 0 ] )
else :
2021-06-28 07:48:36 +02:00
io_str = io . StringIO ( )
2022-05-12 16:08:36 +02:00
decode_for_puny_humans ( o [ ' params ' ] [ 0 ] , settings . get ( ' CHAIN_SPEC ' ) , io_str )
2021-06-28 07:48:36 +02:00
print ( io_str . getvalue ( ) )
if __name__ == ' __main__ ' :
main ( )