diff --git a/cic/ext/eth/__init__.py b/cic/ext/eth/__init__.py index 881dd09..0a84b82 100644 --- a/cic/ext/eth/__init__.py +++ b/cic/ext/eth/__init__.py @@ -9,7 +9,11 @@ from chainlib.eth.tx import ( TxFactory, ) from chainlib.eth.connection import RPCConnection -from chainlib.eth.contract import ABIContractEncoder +from chainlib.eth.contract import ( + ABIContractEncoder, + ABIContractType + ) +from chainlib.eth.address import is_address from eth_token_index import TokenUniqueSymbolIndex from eth_address_declarator import Declarator @@ -39,24 +43,88 @@ class CICEth: self.tx_format = TxFormat.RLP_SIGNED - def prepare_token(self, name, symbol, precision, code, extra={}, positions=None): + def prepare_token(self, name, symbol, precision, code, extra=[], extra_types=[], positions=None): self.token_details = { 'name': name, 'symbol': symbol, 'precision': precision, 'code': code, 'extra': extra, + 'extra_types': extra_types, 'positions': positions, } + + def __detect_arg_type(self, v): + typ = None + try: + int(v, 10) + typ = ABIContractType.UINT256 + except TypeError: + pass + + if typ == None: + try: + vv = strip_0x(v) + if is_address(vv): + typ = ABIContractType.ADDRESS + else: + typ = ABIContractType.BYTES32 + except ValueError: + pass + + if typ == None: + try: + v.encode('utf-8') + typ = ABIContractType.STRING + except ValueError: + pass + + if typ == None: + raise ValueError('cannot automatically determine type for value {}'.format(v)) + + logg.info('argument {} parsed as abi contract type {}'.format(typ.value)) + + return typ + + + def __order_args(self): + args = [ + self.token_details['name'], + self.token_details['symbol'], + self.token_details['precision'], + ] + args_types = [ + ABIContractType.STRING.value, + ABIContractType.STRING.value, + ABIContractType.UINT256.value, + ] + + for i, x in enumerate(self.token_details['extra']): + args.append(x) + typ = None + if self.token_details['extra_types'] != None: + typ = self.token_details['extra_types'][i] + else: + typ = self.__detect_arg_type(x) + arg_types.append(typ) + + positions = self.token_details['positions'] + if positions == None: + positions = list(range(len(args))) + + return (args, args_types, positions) + def process_token(self): - enc = ABIContractEncoder() - enc.string(self.token_details['name']) - enc.string(self.token_details['symbol']) - enc.uint256(self.token_details['precision']) - code = self.token_details['code'] + enc.get() + (args, args_types, positions) = self.__order_args() + enc = ABIContractEncoder() + + for i in positions: + getattr(enc, args_types[i])(args[i]) + + code = self.token_details['code'] + enc.get() signer_address = self.resources['token']['key_address'] c = TxFactory(self.chain_spec, signer=self.signer, nonce_oracle=self.nonce_oracle, gas_oracle=self.fee_oracle) @@ -76,6 +144,7 @@ class CICEth: self.outputs.append(r) return r + def process_token_index(self): c = TokenUniqueSymbolIndex(self.chain_spec, signer=self.signer)