chainlib-eth/chainlib/eth/cli/encode.py

104 lines
2.4 KiB
Python

# standard imports
import re
import logging
# external imports
from chainlib.eth.contract import (
ABIContractType,
ABIContractEncoder,
)
logg = logging.getLogger(__name__)
class CLIEncoder(ABIContractEncoder):
__re_uint = r'^([uU])[int]*([0-9]+)?$'
__re_bytes = r'^([bB])[ytes]*([0-9]+)?$'
__re_string = r'^([sS])[tring]*$'
__re_address = r'^([aA])[ddress]*?$'
__translations = [
'to_uint',
'to_bytes',
'to_string',
'to_address',
]
def __init__(self, signature=None):
super(CLIEncoder, self).__init__()
self.signature = signature
if signature != None:
self.method(signature)
def to_uint(self, typ):
s = None
a = None
m = re.match(self.__re_uint, typ)
if m == None:
return None
n = m.group(2)
if m.group(2) == None:
n = 256
s = 'UINT256'.format(m.group(2))
a = getattr(ABIContractType, s)
return (s, a)
def to_bytes(self, typ):
s = None
a = None
m = re.match(self.__re_bytes, typ)
if m == None:
return None
n = m.group(2)
if n == None:
n = 32
s = 'BYTES{}'.format(n)
a = getattr(ABIContractType, s)
return (s, a)
def to_address(self, typ):
s = None
a = None
m = re.match(self.__re_address, typ)
if m == None:
return None
s = 'ADDRESS'
a = getattr(ABIContractType, s)
return (s, a)
def to_string(self, typ):
m = re.match(self.__re_string, typ)
if m == None:
return None
s = 'STRING'
a = getattr(ABIContractType, s)
return (s, a)
def translate_type(self, typ):
r = None
for tr in self.__translations:
r = getattr(self, tr)(typ)
if r != None:
break
if r == None:
raise ValueError('no translation for type {}'.format(typ))
logg.debug('type {} translated to {}'.format(typ, r[0]))
return r[1]
def add_from(self, arg):
logg.debug('arg {}'.format(arg))
(typ, val) = arg.split(':', maxsplit=1)
real_typ = self.translate_type(typ)
if self.signature != None:
self.typ(real_typ)
fn = getattr(self, real_typ.value)
fn(val)