py3port: Ethereum-related changes
This commit is contained in:
parent
53189f4469
commit
9d694488d9
2 changed files with 49 additions and 46 deletions
|
|
@ -42,10 +42,10 @@ class Token(MMGenObject): # ERC20
|
|||
def __init__(self,addr,decimals=None):
|
||||
self.addr = TokenAddr(addr)
|
||||
if decimals is None:
|
||||
ret_hex = self.do_call('decimals()')
|
||||
try: decimals = int(ret_hex,16)
|
||||
except: raise TokenNotInBlockchain("Token '{}' not in blockchain".format(addr))
|
||||
self.base_unit = Decimal(10) ** -decimals
|
||||
decimals = self.decimals()
|
||||
if not decimals:
|
||||
raise TokenNotInBlockchain("Token '{}' not in blockchain".format(addr))
|
||||
self.base_unit = Decimal('10') ** -decimals
|
||||
|
||||
def transferdata2amt(self,data): # online
|
||||
return ETHAmt(int(parse_abi(data)[-1],16) * self.base_unit)
|
||||
|
|
@ -61,10 +61,17 @@ class Token(MMGenObject): # ERC20
|
|||
return self.do_call('balanceOf(address)',acct_addr.rjust(64,'0'),toUnit=True)
|
||||
|
||||
def strip(self,s):
|
||||
return ''.join(ch for ch in s if 32 <= ord(ch) <= 127).strip()
|
||||
return ''.join([chr(b) for b in s if 32 <= b <= 127]).strip()
|
||||
|
||||
def total_supply(self): return self.do_call('totalSupply()',toUnit=True)
|
||||
def decimals(self): return int(self.do_call('decimals()'),16)
|
||||
def decimals(self):
|
||||
ret = self.do_call('decimals()')
|
||||
try:
|
||||
a,b = ret[:2],ret[2:]
|
||||
assert a == '0x' and is_hex_str_lc(b)
|
||||
except:
|
||||
"RPC call to decimals() failed (returned '{}')".format(ret)
|
||||
return int(b,16) if b else None
|
||||
def name(self): return self.strip(unhexlify(self.do_call('name()')[2:]))
|
||||
def symbol(self): return self.strip(unhexlify(self.do_call('symbol()')[2:]))
|
||||
|
||||
|
|
@ -79,12 +86,6 @@ class Token(MMGenObject): # ERC20
|
|||
def code(self):
|
||||
return g.rpch.eth_getCode('0x'+self.addr)[2:]
|
||||
|
||||
def transfer_from(self,from_addr,to_addr,amt,key,start_gas,gasPrice):
|
||||
raise NotImplementedError('method not implemented')
|
||||
return self.transfer( from_addr,to_addr,amt,key,start_gas,gasPrice,
|
||||
method_sig='transferFrom(address,address,uint256)',
|
||||
from_addr2=from_addr)
|
||||
|
||||
def create_data(self,to_addr,amt,method_sig='transfer(address,uint256)',from_addr=None):
|
||||
from_arg = from_addr.rjust(64,'0') if from_addr else ''
|
||||
to_arg = to_addr.rjust(64,'0')
|
||||
|
|
@ -118,6 +119,8 @@ class Token(MMGenObject): # ERC20
|
|||
pmsg(tx.to_dict())
|
||||
return hex_tx,coin_txid
|
||||
|
||||
# The following are used for token deployment only:
|
||||
|
||||
def txsend(self,hex_tx):
|
||||
return g.rpch.eth_sendRawTransaction('0x'+hex_tx.decode()).replace('0x','',1).encode()
|
||||
|
||||
|
|
@ -132,3 +135,9 @@ class Token(MMGenObject): # ERC20
|
|||
from_addr2=from_addr2)
|
||||
(hex_tx,coin_txid) = self.txsign(tx_in,key,from_addr)
|
||||
return self.txsend(hex_tx)
|
||||
|
||||
def transfer_from(self,from_addr,to_addr,amt,key,start_gas,gasPrice):
|
||||
raise NotImplementedError('method not implemented')
|
||||
return self.transfer( from_addr,to_addr,amt,key,start_gas,gasPrice,
|
||||
method_sig='transferFrom(address,address,uint256)',
|
||||
from_addr2=from_addr)
|
||||
|
|
|
|||
|
|
@ -151,7 +151,8 @@ class EthereumMMGenTX(MMGenTX):
|
|||
o_num = len(self.outputs)
|
||||
assert o_num in o_ok,'Transaction has invalid number of outputs!'.format(o_num)
|
||||
self.make_txobj()
|
||||
self.hex = json.dumps(dict([(k,str(v))for k,v in list(self.txobj.items())]))
|
||||
ol = [(k,v.decode() if issubclass(type(v),bytes) else str(v)) for k,v in self.txobj.items()]
|
||||
self.hex = json.dumps(dict(ol)).encode()
|
||||
self.update_txid()
|
||||
|
||||
def del_output(self,idx): pass
|
||||
|
|
@ -278,7 +279,6 @@ class EthereumMMGenTX(MMGenTX):
|
|||
return m.format(ETHAmt(chg).hl(),g.coin)
|
||||
|
||||
def do_sign(self,d,wif,tx_num_str):
|
||||
|
||||
d_in = {'to': unhexlify(d['to']),
|
||||
'startgas': d['startGas'].toWei(),
|
||||
'gasprice': d['gasPrice'].toWei(),
|
||||
|
|
@ -286,24 +286,15 @@ class EthereumMMGenTX(MMGenTX):
|
|||
'nonce': d['nonce'],
|
||||
'data': unhexlify(d['data'])}
|
||||
|
||||
msg_r('Signing transaction{}...'.format(tx_num_str))
|
||||
|
||||
try:
|
||||
from ethereum.transactions import Transaction
|
||||
etx = Transaction(**d_in)
|
||||
etx.sign(wif,d['chainId'])
|
||||
import rlp
|
||||
self.hex = hexlify(rlp.encode(etx))
|
||||
self.coin_txid = CoinTxID(hexlify(etx.hash))
|
||||
msg('OK')
|
||||
if d['data']:
|
||||
self.token_addr = TokenAddr(hexlify(etx.creates))
|
||||
except Exception as e:
|
||||
m = "{!r}: transaction signing failed!"
|
||||
msg(m.format(e.args[0]))
|
||||
return False
|
||||
|
||||
return self.check_sigs()
|
||||
from ethereum.transactions import Transaction
|
||||
etx = Transaction(**d_in)
|
||||
etx.sign(wif,d['chainId'])
|
||||
import rlp
|
||||
self.hex = hexlify(rlp.encode(etx))
|
||||
self.coin_txid = CoinTxID(hexlify(etx.hash))
|
||||
if d['data']:
|
||||
self.token_addr = TokenAddr(hexlify(etx.creates).decode())
|
||||
assert self.check_sigs(),'Signature check failed'
|
||||
|
||||
def sign(self,tx_num_str,keys): # return True or False; don't exit or raise exception
|
||||
|
||||
|
|
@ -314,10 +305,21 @@ class EthereumMMGenTX(MMGenTX):
|
|||
if not self.check_correct_chain(on_fail='return'):
|
||||
return False
|
||||
|
||||
return self.do_sign(self.txobj,keys[0].sec.wif,tx_num_str)
|
||||
msg_r('Signing transaction{}...'.format(tx_num_str))
|
||||
|
||||
try:
|
||||
self.do_sign(self.txobj,keys[0].sec.wif,tx_num_str)
|
||||
msg('OK')
|
||||
return True
|
||||
except Exception as e:
|
||||
if os.getenv('MMGEN_TRACEBACK'):
|
||||
import traceback
|
||||
ymsg('\n'+''.join(traceback.format_exception(*sys.exc_info())))
|
||||
m = "{!r}: transaction signing failed!"
|
||||
msg(m.format(e.args[0]))
|
||||
return False
|
||||
|
||||
def is_in_mempool(self):
|
||||
# pmsg(g.rpch.parity_pendingTransactions())
|
||||
return '0x'+self.coin_txid.decode() in [x['hash'] for x in g.rpch.parity_pendingTransactions()]
|
||||
|
||||
def is_in_wallet(self):
|
||||
|
|
@ -454,18 +456,10 @@ class EthereumTokenMMGenTX(EthereumMMGenTX):
|
|||
|
||||
def do_sign(self,d,wif,tx_num_str):
|
||||
d = self.txobj
|
||||
msg_r('Signing transaction{}...'.format(tx_num_str))
|
||||
try:
|
||||
t = Token(d['token_addr'],decimals=d['decimals'])
|
||||
tx_in = t.txcreate(d['from'],d['to'],d['amt'],self.start_gas,d['gasPrice'],nonce=d['nonce'])
|
||||
(self.hex,self.coin_txid) = t.txsign(tx_in,wif,d['from'],chain_id=d['chainId'])
|
||||
msg('OK')
|
||||
except Exception as e:
|
||||
m = "{!r}: transaction signing failed!"
|
||||
msg(m.format(e.args[0]))
|
||||
return False
|
||||
|
||||
return self.check_sigs()
|
||||
t = Token(d['token_addr'],decimals=d['decimals'])
|
||||
tx_in = t.txcreate(d['from'],d['to'],d['amt'],self.start_gas,d['gasPrice'],nonce=d['nonce'])
|
||||
(self.hex,self.coin_txid) = t.txsign(tx_in,wif,d['from'],chain_id=d['chainId'])
|
||||
assert self.check_sigs(),'Signature check failed'
|
||||
|
||||
class EthereumMMGenBumpTX(EthereumMMGenTX,MMGenBumpTX):
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue