Add tx get script
This commit is contained in:
parent
a7ed9e9ad3
commit
6e44b903ed
@ -7,7 +7,7 @@ from hexathon import (
|
|||||||
even,
|
even,
|
||||||
)
|
)
|
||||||
|
|
||||||
def block():
|
def block_latest():
|
||||||
o = jsonrpc_template()
|
o = jsonrpc_template()
|
||||||
o['method'] = 'eth_blockNumber'
|
o['method'] = 'eth_blockNumber'
|
||||||
return o
|
return o
|
||||||
|
@ -22,18 +22,6 @@ erc20_transfer_signature = keccak256_string_to_hex('transfer(address,uint256)')[
|
|||||||
|
|
||||||
class ERC20TxFactory(TxFactory):
|
class ERC20TxFactory(TxFactory):
|
||||||
|
|
||||||
def build(self, tx):
|
|
||||||
txe = EIP155Transaction(tx, tx['nonce'], tx['chainId'])
|
|
||||||
self.signer.signTransaction(txe)
|
|
||||||
tx_raw = txe.rlp_serialize()
|
|
||||||
tx_raw_hex = add_0x(tx_raw.hex())
|
|
||||||
tx_hash_hex = add_0x(keccak256_hex_to_hex(tx_raw_hex))
|
|
||||||
|
|
||||||
o = jsonrpc_template()
|
|
||||||
o['method'] = 'eth_sendRawTransaction'
|
|
||||||
o['params'].append(tx_raw_hex)
|
|
||||||
|
|
||||||
return (tx_hash_hex, o)
|
|
||||||
|
|
||||||
|
|
||||||
def erc20_balance(self, contract_address, address, sender_address=ZERO_ADDRESS):
|
def erc20_balance(self, contract_address, address, sender_address=ZERO_ADDRESS):
|
||||||
|
@ -21,10 +21,17 @@ class DefaultNonceOracle:
|
|||||||
def __init__(self, address, conn):
|
def __init__(self, address, conn):
|
||||||
self.address = address
|
self.address = address
|
||||||
self.conn = conn
|
self.conn = conn
|
||||||
|
self.nonce = self.get()
|
||||||
|
|
||||||
|
|
||||||
def next(self):
|
def get(self):
|
||||||
o = nonce(self.address)
|
o = nonce(self.address)
|
||||||
r = self.conn.do(o)
|
r = self.conn.do(o)
|
||||||
n = strip_0x(r)
|
n = strip_0x(r)
|
||||||
return int(n, 16)
|
return int(n, 16)
|
||||||
|
|
||||||
|
|
||||||
|
def next(self):
|
||||||
|
n = self.nonce
|
||||||
|
self.nonce += 1
|
||||||
|
return n
|
||||||
|
101
chainlib/eth/runnable/get.py
Normal file
101
chainlib/eth/runnable/get.py
Normal file
@ -0,0 +1,101 @@
|
|||||||
|
#!python3
|
||||||
|
|
||||||
|
"""Token balance query script
|
||||||
|
|
||||||
|
.. moduleauthor:: Louis Holbrook <dev@holbrook.no>
|
||||||
|
.. pgp:: 0826EDA1702D1E87C6E2875121D2E7BB88C2A746
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
|
# standard imports
|
||||||
|
import os
|
||||||
|
import json
|
||||||
|
import argparse
|
||||||
|
import logging
|
||||||
|
import enum
|
||||||
|
|
||||||
|
# third-party imports
|
||||||
|
from hexathon import (
|
||||||
|
add_0x,
|
||||||
|
strip_0x,
|
||||||
|
even,
|
||||||
|
)
|
||||||
|
import sha3
|
||||||
|
from eth_abi import encode_single
|
||||||
|
|
||||||
|
# local imports
|
||||||
|
from chainlib.eth.address import to_checksum
|
||||||
|
from chainlib.eth.rpc import (
|
||||||
|
jsonrpc_template,
|
||||||
|
jsonrpc_result,
|
||||||
|
)
|
||||||
|
from chainlib.eth.connection import HTTPConnection
|
||||||
|
from chainlib.eth.tx import Tx
|
||||||
|
from chainlib.eth.block import Block
|
||||||
|
|
||||||
|
logging.basicConfig(level=logging.WARNING)
|
||||||
|
logg = logging.getLogger()
|
||||||
|
|
||||||
|
default_abi_dir = os.environ.get('ETH_ABI_DIR', '/usr/share/local/cic/solidity/abi')
|
||||||
|
default_eth_provider = os.environ.get('ETH_PROVIDER', 'http://localhost:8545')
|
||||||
|
|
||||||
|
argparser = argparse.ArgumentParser()
|
||||||
|
argparser.add_argument('-p', '--provider', dest='p', default=default_eth_provider, type=str, help='Web3 provider url (http only)')
|
||||||
|
argparser.add_argument('-t', '--token-address', dest='t', type=str, help='Token address. If not set, will return gas balance')
|
||||||
|
argparser.add_argument('-u', '--unsafe', dest='u', action='store_true', help='Auto-convert address to checksum adddress')
|
||||||
|
argparser.add_argument('--abi-dir', dest='abi_dir', type=str, default=default_abi_dir, help='Directory containing bytecode and abi (default {})'.format(default_abi_dir))
|
||||||
|
argparser.add_argument('-v', action='store_true', help='Be verbose')
|
||||||
|
argparser.add_argument('tx_hash', type=str, help='Transaction hash')
|
||||||
|
args = argparser.parse_args()
|
||||||
|
|
||||||
|
|
||||||
|
if args.v:
|
||||||
|
logg.setLevel(logging.DEBUG)
|
||||||
|
|
||||||
|
conn = HTTPConnection(args.p)
|
||||||
|
|
||||||
|
tx_hash = args.tx_hash
|
||||||
|
|
||||||
|
|
||||||
|
class Status(enum.Enum):
|
||||||
|
UNCONFIRMED = -1
|
||||||
|
REVERTED = 0
|
||||||
|
SUCCESS = 1
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
o = jsonrpc_template()
|
||||||
|
o['method'] = 'eth_getTransactionByHash'
|
||||||
|
o['params'].append(tx_hash)
|
||||||
|
tx_src = conn.do(o)
|
||||||
|
|
||||||
|
tx = None
|
||||||
|
status = -1
|
||||||
|
if tx_src['blockHash'] != None:
|
||||||
|
o = jsonrpc_template()
|
||||||
|
o['method'] = 'eth_getBlockByHash'
|
||||||
|
o['params'].append(tx_src['blockHash'])
|
||||||
|
o['params'].append(True)
|
||||||
|
block_src = conn.do(o)
|
||||||
|
block = Block(block_src)
|
||||||
|
for t in block.txs:
|
||||||
|
if t['hash'] == tx_hash:
|
||||||
|
tx = Tx(t, block)
|
||||||
|
break
|
||||||
|
o = jsonrpc_template()
|
||||||
|
o['method'] = 'eth_getTransactionReceipt'
|
||||||
|
o['params'].append(tx_hash)
|
||||||
|
rcpt = conn.do(o)
|
||||||
|
status = int(strip_0x(rcpt['status']), 16)
|
||||||
|
|
||||||
|
if tx == None:
|
||||||
|
tx = Tx(tx_src)
|
||||||
|
print(tx)
|
||||||
|
status_name = Status(status).name
|
||||||
|
print('status {}'.format(status_name))
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
main()
|
@ -18,7 +18,6 @@ import logging
|
|||||||
# third-party imports
|
# third-party imports
|
||||||
from crypto_dev_signer.eth.signer import ReferenceSigner as EIP155Signer
|
from crypto_dev_signer.eth.signer import ReferenceSigner as EIP155Signer
|
||||||
from crypto_dev_signer.keystore import DictKeystore
|
from crypto_dev_signer.keystore import DictKeystore
|
||||||
from crypto_dev_signer.eth.helper import EthTxExecutor
|
|
||||||
from hexathon import (
|
from hexathon import (
|
||||||
add_0x,
|
add_0x,
|
||||||
strip_0x,
|
strip_0x,
|
||||||
|
@ -3,20 +3,26 @@ import logging
|
|||||||
|
|
||||||
# third-party imports
|
# third-party imports
|
||||||
import sha3
|
import sha3
|
||||||
from hexathon import strip_0x
|
from hexathon import (
|
||||||
|
strip_0x,
|
||||||
|
add_0x,
|
||||||
|
)
|
||||||
from eth_keys import KeyAPI
|
from eth_keys import KeyAPI
|
||||||
from eth_keys.backends import NativeECCBackend
|
from eth_keys.backends import NativeECCBackend
|
||||||
from rlp import decode as rlp_decode
|
from rlp import decode as rlp_decode
|
||||||
from rlp import encode as rlp_encode
|
from rlp import encode as rlp_encode
|
||||||
from crypto_dev_signer.eth.transaction import EIP155Transaction
|
from crypto_dev_signer.eth.transaction import EIP155Transaction
|
||||||
|
|
||||||
|
|
||||||
# local imports
|
# local imports
|
||||||
|
from chainlib.hash import keccak256_hex_to_hex
|
||||||
from .address import to_checksum
|
from .address import to_checksum
|
||||||
from .constant import (
|
from .constant import (
|
||||||
MINIMUM_FEE_UNITS,
|
MINIMUM_FEE_UNITS,
|
||||||
MINIMUM_FEE_PRICE,
|
MINIMUM_FEE_PRICE,
|
||||||
ZERO_ADDRESS,
|
ZERO_ADDRESS,
|
||||||
)
|
)
|
||||||
|
from .rpc import jsonrpc_template
|
||||||
|
|
||||||
logg = logging.getLogger(__name__)
|
logg = logging.getLogger(__name__)
|
||||||
|
|
||||||
@ -97,6 +103,20 @@ class TxFactory:
|
|||||||
self.signer = signer
|
self.signer = signer
|
||||||
|
|
||||||
|
|
||||||
|
def build(self, tx):
|
||||||
|
txe = EIP155Transaction(tx, tx['nonce'], tx['chainId'])
|
||||||
|
self.signer.signTransaction(txe)
|
||||||
|
tx_raw = txe.rlp_serialize()
|
||||||
|
tx_raw_hex = add_0x(tx_raw.hex())
|
||||||
|
tx_hash_hex = add_0x(keccak256_hex_to_hex(tx_raw_hex))
|
||||||
|
|
||||||
|
o = jsonrpc_template()
|
||||||
|
o['method'] = 'eth_sendRawTransaction'
|
||||||
|
o['params'].append(tx_raw_hex)
|
||||||
|
|
||||||
|
return (tx_hash_hex, o)
|
||||||
|
|
||||||
|
|
||||||
def template(self, sender, recipient):
|
def template(self, sender, recipient):
|
||||||
gas_price = MINIMUM_FEE_PRICE
|
gas_price = MINIMUM_FEE_PRICE
|
||||||
if self.gas_oracle != None:
|
if self.gas_oracle != None:
|
||||||
@ -121,7 +141,6 @@ class TxFactory:
|
|||||||
def normalize(self, tx):
|
def normalize(self, tx):
|
||||||
txe = EIP155Transaction(tx, tx['nonce'], tx['chainId'])
|
txe = EIP155Transaction(tx, tx['nonce'], tx['chainId'])
|
||||||
txes = txe.serialize()
|
txes = txe.serialize()
|
||||||
print(txes)
|
|
||||||
return {
|
return {
|
||||||
'from': tx['from'],
|
'from': tx['from'],
|
||||||
'to': txes['to'],
|
'to': txes['to'],
|
||||||
@ -141,12 +160,18 @@ class TxFactory:
|
|||||||
|
|
||||||
class Tx:
|
class Tx:
|
||||||
|
|
||||||
def __init__(self, src, block):
|
def __init__(self, src, block=None):
|
||||||
|
self.index = -1
|
||||||
|
self.status = -1
|
||||||
|
if block != None:
|
||||||
self.index = int(strip_0x(src['transactionIndex']), 16)
|
self.index = int(strip_0x(src['transactionIndex']), 16)
|
||||||
self.value = int(strip_0x(src['value']), 16)
|
self.value = int(strip_0x(src['value']), 16)
|
||||||
self.nonce = int(strip_0x(src['nonce']), 16)
|
self.nonce = int(strip_0x(src['nonce']), 16)
|
||||||
self.hash = strip_0x(src['hash'])
|
self.hash = strip_0x(src['hash'])
|
||||||
self.outputs = [strip_0x(src['from'])]
|
address_from = strip_0x(src['from'])
|
||||||
|
self.gasPrice = int(strip_0x(src['gasPrice']), 16)
|
||||||
|
self.gasLimit = int(strip_0x(src['gas']), 16)
|
||||||
|
self.outputs = [to_checksum(address_from)]
|
||||||
|
|
||||||
inpt = src['input']
|
inpt = src['input']
|
||||||
if inpt != '0x':
|
if inpt != '0x':
|
||||||
@ -158,7 +183,7 @@ class Tx:
|
|||||||
to = src['to']
|
to = src['to']
|
||||||
if to == None:
|
if to == None:
|
||||||
to = ZERO_ADDRESS
|
to = ZERO_ADDRESS
|
||||||
self.inputs = [strip_0x(to)]
|
self.inputs = [to_checksum(strip_0x(to))]
|
||||||
|
|
||||||
self.block = block
|
self.block = block
|
||||||
self.wire = src['raw']
|
self.wire = src['raw']
|
||||||
@ -170,4 +195,18 @@ class Tx:
|
|||||||
|
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return 'from {} to {} value {} input {}'.format(self.outputs[0], self.inputs[0], self.value, self.payload)
|
return """from {}
|
||||||
|
to {}
|
||||||
|
value {}
|
||||||
|
nonce {}
|
||||||
|
gasPrice {}
|
||||||
|
gasLimit {}
|
||||||
|
input {}""".format(
|
||||||
|
self.outputs[0],
|
||||||
|
self.inputs[0],
|
||||||
|
self.value,
|
||||||
|
self.nonce,
|
||||||
|
self.gasPrice,
|
||||||
|
self.gasLimit,
|
||||||
|
self.payload,
|
||||||
|
)
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
[metadata]
|
[metadata]
|
||||||
name = chainlib
|
name = chainlib
|
||||||
version = 0.0.1a6
|
version = 0.0.1a7
|
||||||
description = Generic blockchain access library and tooling
|
description = Generic blockchain access library and tooling
|
||||||
author = Louis Holbrook
|
author = Louis Holbrook
|
||||||
author_email = dev@holbrook.no
|
author_email = dev@holbrook.no
|
||||||
@ -37,3 +37,4 @@ console_scripts =
|
|||||||
eth-checksum = chainlib.eth.runnable.checksum:main
|
eth-checksum = chainlib.eth.runnable.checksum:main
|
||||||
eth-gas = chainlib.eth.runnable.gas:main
|
eth-gas = chainlib.eth.runnable.gas:main
|
||||||
eth-transfer = chainlib.eth.runnable.transfer:main
|
eth-transfer = chainlib.eth.runnable.transfer:main
|
||||||
|
eth-get = chainlib.eth.runnable.get:main
|
||||||
|
Loading…
Reference in New Issue
Block a user