コード例 #1
0
 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
コード例 #2
0
ファイル: tw.py プロジェクト: totaltrader/mmgen
	async def __ainit__(self,proto,mode='r',token_addr=None):
		await super().__ainit__(proto,mode=mode)

		for v in self.data['tokens'].values():
			self.conv_types(v)

		if self.importing and token_addr:
			if not is_coin_addr(proto,token_addr):
				raise InvalidTokenAddress(f'{token_addr!r}: invalid token address')
		else:
			assert token_addr == None,'EthereumTokenTrackingWallet_chk1'
			token_addr = await self.sym2addr(proto.tokensym) # returns None on failure
			if not is_coin_addr(proto,token_addr):
				raise UnrecognizedTokenSymbol(f'Specified token {proto.tokensym!r} could not be resolved!')

		from mmgen.obj import TokenAddr
		self.token = TokenAddr(proto,token_addr)

		if self.token not in self.data['tokens']:
			if self.importing:
				await self.import_token(self.token)
			else:
				raise TokenNotInWallet(f'Specified token {self.token!r} not in wallet!')

		self.decimals = self.get_param('decimals')
		self.symbol   = self.get_param('symbol')

		proto.tokensym = self.symbol
コード例 #3
0
 async def __ainit__(self, proto, rpc, addr):
     self.proto = proto
     self.rpc = rpc
     self.addr = TokenAddr(proto, addr)
     decimals = await self.get_decimals()  # requires self.addr!
     if not decimals:
         raise TokenNotInBlockchain(f'Token {addr!r} not in blockchain')
     Token.__init__(self, proto, addr, decimals, rpc)
コード例 #4
0
 def __init__(self, addr, decimals=None):
     self.addr = TokenAddr(addr)
     if decimals is None:
         decimals = self.decimals()
         if not decimals:
             raise TokenNotInBlockchain(
                 "Token '{}' not in blockchain".format(addr))
     self.base_unit = Decimal('10')**-decimals
コード例 #5
0
 def __init__(self, proto, addr, decimals, rpc=None):
     self.proto = proto
     self.addr = TokenAddr(proto, addr)
     assert isinstance(
         decimals,
         int), f'decimals param must be int instance, not {type(decimals)}'
     self.decimals = decimals
     self.base_unit = Decimal('10')**-self.decimals
     self.rpc = rpc
コード例 #6
0
class Token(MMGenObject):  # ERC20

    # Test that token is in the blockchain by calling constructor w/o decimals arg
    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

    def transferdata2amt(self, data):  # online
        return ETHAmt(int(parse_abi(data)[-1], 16) * self.base_unit)

    def do_call(self, method_sig, method_args='', toUnit=False):
        data = create_method_id(method_sig) + method_args
        if g.debug:
            msg('{}:  {}'.format(method_sig, '\n  '.join(parse_abi(data))))
        ret = g.rpch.eth_call({'to': '0x' + self.addr, 'data': '0x' + data})
        return int(ret, 16) * self.base_unit if toUnit else ret

    def balance(self, acct_addr):
        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()

    def total_supply(self):
        return self.do_call('totalSupply()', toUnit=True)

    def decimals(self):
        return int(self.do_call('decimals()'), 16)

    def name(self):
        return self.strip(self.do_call('name()')[2:].decode('hex'))

    def symbol(self):
        return self.strip(self.do_call('symbol()')[2:].decode('hex'))

    def info(self):
        fs = '{:15}{}\n' * 5
        return fs.format('token address:', self.addr, 'token symbol:',
                         self.symbol(), 'token name:', self.name(),
                         'decimals:', self.decimals(), 'total supply:',
                         self.total_supply())

    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')
        amt_arg = '{:064x}'.format(int(amt / self.base_unit))
        return create_method_id(method_sig) + from_arg + to_arg + amt_arg

    def txcreate(self,
                 from_addr,
                 to_addr,
                 amt,
                 start_gas,
                 gasPrice,
                 nonce=None,
                 method_sig='transfer(address,uint256)',
                 from_addr2=None):
        if nonce is None:
            nonce = int(g.rpch.parity_nextNonce('0x' + from_addr), 16)
        data = self.create_data(to_addr,
                                amt,
                                method_sig=method_sig,
                                from_addr=from_addr2)
        return {
            'to': self.addr.decode('hex'),
            'startgas': start_gas.toWei(),
            'gasprice': gasPrice.toWei(),
            'value': 0,
            'nonce': nonce,
            'data': data.decode('hex')
        }

    def txsign(self, tx_in, key, from_addr, chain_id=None):
        tx = Transaction(**tx_in)
        if chain_id is None:
            chain_id = int(g.rpch.parity_chainId(), 16)
        tx.sign(key, chain_id)
        hex_tx = rlp.encode(tx).encode('hex')
        coin_txid = CoinTxID(tx.hash.encode('hex'))
        if tx.sender.encode('hex') != from_addr:
            m = "Sender address '{}' does not match address of key '{}'!"
            die(3, m.format(from_addr, tx.sender.encode('hex')))
        if g.debug:
            msg('{}'.format('\n  '.join(parse_abi(data))))
            pmsg(tx.to_dict())
        return hex_tx, coin_txid

    def txsend(self, hex_tx):
        return g.rpch.eth_sendRawTransaction('0x' + hex_tx).replace(
            '0x', '', 1)

    def transfer(self,
                 from_addr,
                 to_addr,
                 amt,
                 key,
                 start_gas,
                 gasPrice,
                 method_sig='transfer(address,uint256)',
                 from_addr2=None,
                 return_data=False):
        tx_in = self.txcreate(from_addr,
                              to_addr,
                              amt,
                              start_gas,
                              gasPrice,
                              nonce=None,
                              method_sig=method_sig,
                              from_addr2=from_addr2)
        (hex_tx, coin_txid) = self.txsign(tx_in, key, from_addr)
        return self.txsend(hex_tx)
コード例 #7
0
ファイル: contract.py プロジェクト: markt12014/mmgen
	async def __ainit__(self,addr):
		self.addr = TokenAddr(addr)
		decimals = await self.get_decimals() # requires self.addr!
		if not decimals:
			raise TokenNotInBlockchain(f'Token {addr!r} not in blockchain')
		Token.__init__(self,addr,decimals)
コード例 #8
0
ファイル: contract.py プロジェクト: markt12014/mmgen
	def __init__(self,addr,decimals):
		self.addr = TokenAddr(addr)
		assert isinstance(decimals,int),f'decimals param must be int instance, not {type(decimals)}'
		self.decimals = decimals
		self.base_unit = Decimal('10') ** -self.decimals