2021-02-09 09:42:46 +01:00
#!python3
""" Gas transfer script
. . moduleauthor : : Louis Holbrook < dev @holbrook.no >
. . pgp : : 0826 EDA1702D1E87C6E2875121D2E7BB88C2A746
"""
# SPDX-License-Identifier: GPL-3.0-or-later
# standard imports
2021-04-04 14:55:27 +02:00
import io
2021-02-09 09:42:46 +01:00
import sys
import os
import json
import argparse
import logging
2021-04-09 16:06:19 +02:00
import urllib
2021-02-09 09:42:46 +01:00
2021-04-09 16:06:19 +02:00
# external imports
2021-02-09 09:42:46 +01:00
from crypto_dev_signer . eth . signer import ReferenceSigner as EIP155Signer
2021-04-04 14:55:27 +02:00
from crypto_dev_signer . keystore . dict import DictKeystore
2021-02-09 09:42:46 +01:00
from hexathon import (
add_0x ,
strip_0x ,
)
# local imports
2021-02-11 08:52:59 +01:00
from chainlib . eth . address import to_checksum
2021-04-04 14:55:27 +02:00
from chainlib . eth . connection import EthHTTPConnection
from chainlib . jsonrpc import jsonrpc_template
2021-02-17 21:20:21 +01:00
from chainlib . eth . nonce import (
2021-04-04 14:55:27 +02:00
RPCNonceOracle ,
2021-02-17 21:20:21 +01:00
OverrideNonceOracle ,
)
2021-02-11 08:52:59 +01:00
from chainlib . eth . gas import (
2021-04-04 14:55:27 +02:00
RPCGasOracle ,
2021-02-17 21:20:21 +01:00
OverrideGasOracle ,
2021-04-04 14:55:27 +02:00
Gas ,
2021-02-09 09:42:46 +01:00
)
2021-02-11 08:52:59 +01:00
from chainlib . eth . gas import balance as gas_balance
2021-02-19 14:57:08 +01:00
from chainlib . chain import ChainSpec
2021-04-04 14:55:27 +02:00
from chainlib . eth . runnable . util import decode_for_puny_humans
2021-02-09 09:42:46 +01:00
logging . basicConfig ( level = logging . WARNING )
logg = logging . getLogger ( )
default_eth_provider = os . environ . get ( ' ETH_PROVIDER ' , ' http://localhost:8545 ' )
argparser = argparse . ArgumentParser ( )
argparser . add_argument ( ' -p ' , ' --provider ' , dest = ' p ' , default = ' http://localhost:8545 ' , type = str , help = ' Web3 provider url (http only) ' )
argparser . add_argument ( ' -w ' , action = ' store_true ' , help = ' Wait for the last transaction to be confirmed ' )
argparser . add_argument ( ' -ww ' , action = ' store_true ' , help = ' Wait for every transaction to be confirmed ' )
2021-04-04 14:55:27 +02:00
argparser . add_argument ( ' -i ' , ' --chain-spec ' , dest = ' i ' , type = str , default = ' evm:ethereum:1 ' , help = ' Chain specification string ' )
2021-02-09 09:42:46 +01:00
argparser . add_argument ( ' -y ' , ' --key-file ' , dest = ' y ' , type = str , help = ' Ethereum keystore file to use for signing ' )
2021-02-17 21:20:21 +01:00
argparser . add_argument ( ' --env-prefix ' , default = os . environ . get ( ' CONFINI_ENV_PREFIX ' ) , dest = ' env_prefix ' , type = str , help = ' environment prefix for variables to overwrite configuration ' )
argparser . add_argument ( ' --nonce ' , type = int , help = ' override nonce ' )
2021-04-13 06:50:33 +02:00
argparser . add_argument ( ' --gas-price ' , dest = ' gas_price ' , type = int , help = ' override gas price ' )
argparser . add_argument ( ' --gas-limit ' , dest = ' gas_limit ' , type = int , help = ' override gas limit ' )
2021-02-09 09:42:46 +01:00
argparser . add_argument ( ' -u ' , ' --unsafe ' , dest = ' u ' , action = ' store_true ' , help = ' Auto-convert address to checksum adddress ' )
2021-02-09 12:12:37 +01:00
argparser . add_argument ( ' -v ' , action = ' store_true ' , help = ' Be verbose ' )
2021-02-09 09:42:46 +01:00
argparser . add_argument ( ' -vv ' , action = ' store_true ' , help = ' Be more verbose ' )
2021-04-04 14:55:27 +02:00
argparser . add_argument ( ' -s ' , ' --send ' , dest = ' s ' , action = ' store_true ' , help = ' Send to network ' )
2021-04-13 07:14:19 +02:00
argparser . add_argument ( ' recipient ' , type = str , help = ' ethereum address of recipient ' )
argparser . add_argument ( ' amount ' , type = int , help = ' gas value in wei ' )
2021-02-09 09:42:46 +01:00
args = argparser . parse_args ( )
if args . vv :
logg . setLevel ( logging . DEBUG )
elif args . v :
logg . setLevel ( logging . INFO )
block_all = args . ww
2021-02-09 15:53:58 +01:00
block_last = args . w or block_all
2021-02-09 09:42:46 +01:00
2021-02-17 21:20:21 +01:00
passphrase_env = ' ETH_PASSPHRASE '
if args . env_prefix != None :
passphrase_env = args . env_prefix + ' _ ' + passphrase_env
passphrase = os . environ . get ( passphrase_env )
if passphrase == None :
logg . warning ( ' no passphrase given ' )
passphrase = ' '
2021-02-09 09:42:46 +01:00
signer_address = None
keystore = DictKeystore ( )
if args . y != None :
logg . debug ( ' loading keystore file {} ' . format ( args . y ) )
2021-04-04 14:55:27 +02:00
signer_address = keystore . import_keystore_file ( args . y , password = passphrase )
2021-02-09 09:42:46 +01:00
logg . debug ( ' now have key for signer address {} ' . format ( signer_address ) )
signer = EIP155Signer ( keystore )
2021-04-04 14:55:27 +02:00
conn = EthHTTPConnection ( args . p )
2021-02-17 21:20:21 +01:00
nonce_oracle = None
if args . nonce != None :
nonce_oracle = OverrideNonceOracle ( signer_address , args . nonce )
else :
2021-04-04 14:55:27 +02:00
nonce_oracle = RPCNonceOracle ( signer_address , conn )
2021-02-17 21:20:21 +01:00
gas_oracle = None
2021-04-13 06:50:33 +02:00
if args . gas_price or args . gas_limit != None :
gas_oracle = OverrideGasOracle ( price = args . gas_price , limit = args . gas_limit , conn = conn )
2021-02-17 21:20:21 +01:00
else :
2021-04-04 14:55:27 +02:00
gas_oracle = RPCGasOracle ( conn )
2021-02-17 21:20:21 +01:00
2021-02-09 09:42:46 +01:00
2021-02-19 14:57:08 +01:00
chain_spec = ChainSpec . from_chain_str ( args . i )
2021-02-09 09:42:46 +01:00
2021-02-09 15:53:58 +01:00
value = args . amount
2021-04-04 14:55:27 +02:00
send = args . s
2021-02-17 21:20:21 +01:00
2021-04-04 14:55:27 +02:00
g = Gas ( chain_spec , signer = signer , gas_oracle = gas_oracle , nonce_oracle = nonce_oracle )
2021-02-09 15:53:58 +01:00
2021-02-09 09:42:46 +01:00
def balance ( address ) :
o = gas_balance ( address )
r = conn . do ( o )
hx = strip_0x ( r )
return int ( hx , 16 )
def main ( ) :
recipient = to_checksum ( args . recipient )
if not args . u and recipient != add_0x ( args . recipient ) :
raise ValueError ( ' invalid checksum address ' )
2021-02-09 15:53:58 +01:00
logg . info ( ' gas transfer from {} to {} value {} ' . format ( signer_address , recipient , value ) )
2021-04-04 14:55:27 +02:00
if logg . isEnabledFor ( logging . DEBUG ) :
2021-04-09 16:06:19 +02:00
try :
logg . debug ( ' sender {} balance before: {} ' . format ( signer_address , balance ( signer_address ) ) )
logg . debug ( ' recipient {} balance before: {} ' . format ( recipient , balance ( recipient ) ) )
except urllib . error . URLError :
pass
2021-04-04 14:55:27 +02:00
2021-02-09 09:42:46 +01:00
( tx_hash_hex , o ) = g . create ( signer_address , recipient , value )
2021-04-04 14:55:27 +02:00
2021-02-17 21:20:21 +01:00
if send :
conn . do ( o )
if block_last :
2021-04-04 14:55:27 +02:00
r = conn . wait ( tx_hash_hex )
if logg . isEnabledFor ( logging . DEBUG ) :
logg . debug ( ' sender {} balance after: {} ' . format ( signer_address , balance ( signer_address ) ) )
logg . debug ( ' recipient {} balance after: {} ' . format ( recipient , balance ( recipient ) ) )
if r [ ' status ' ] == 0 :
logg . critical ( ' VM revert. Wish I could tell you more ' )
sys . exit ( 1 )
print ( tx_hash_hex )
else :
if logg . isEnabledFor ( logging . INFO ) :
io_str = io . StringIO ( )
decode_for_puny_humans ( o [ ' params ' ] [ 0 ] , chain_spec , io_str )
print ( io_str . getvalue ( ) )
else :
print ( o [ ' params ' ] [ 0 ] )
2021-02-09 12:12:37 +01:00
2021-02-09 09:42:46 +01:00
if __name__ == ' __main__ ' :
main ( )