vend.py (5114B)
1 # standard imports 2 import logging 3 import os 4 import enum 5 6 # external imports 7 from chainlib.eth.constant import ZERO_ADDRESS 8 from chainlib.eth.contract import ( 9 ABIContractEncoder, 10 ABIContractDecoder, 11 ABIContractType, 12 abi_decode_single, 13 ) 14 from chainlib.eth.jsonrpc import to_blockheight_param 15 from chainlib.eth.error import RequestMismatchException 16 from chainlib.eth.tx import ( 17 TxFactory, 18 TxFormat, 19 ) 20 from chainlib.jsonrpc import JSONRPCRequest 21 from chainlib.block import BlockSpec 22 from hexathon import ( 23 add_0x, 24 strip_0x, 25 ) 26 from chainlib.eth.cli.encode import CLIEncoder 27 28 # local imports 29 from erc20_vend.data import data_dir 30 31 logg = logging.getLogger() 32 33 34 35 class Vend(TxFactory): 36 37 __abi = None 38 __bytecode = None 39 40 def constructor(self, sender_address, token_address, decimals=0, mint=False, tx_format=TxFormat.JSONRPC, version=None): 41 code = self.cargs(token_address, decimals=decimals, mint=mint, version=version) 42 tx = self.template(sender_address, None, use_nonce=True) 43 tx = self.set_code(tx, code) 44 return self.finalize(tx, tx_format) 45 46 47 @staticmethod 48 def cargs(token_address, decimals=0, mint=False, version=None): 49 code = Vend.bytecode(version=version) 50 enc = ABIContractEncoder() 51 enc.address(token_address) 52 enc.uintn(decimals, 8) 53 enc.bool(mint) 54 args = enc.get() 55 code += args 56 logg.debug('constructor code: ' + args) 57 return code 58 59 60 @staticmethod 61 def gas(code=None): 62 return 4000000 63 64 65 66 @staticmethod 67 def abi(): 68 if Vend.__abi == None: 69 f = open(os.path.join(data_dir, 'Vend.json'), 'r') 70 Vend.__abi = json.load(f) 71 f.close() 72 return Vend.__abi 73 74 75 @staticmethod 76 def bytecode(version=None): 77 if Vend.__bytecode == None: 78 f = open(os.path.join(data_dir, 'Vend.bin')) 79 Vend.__bytecode = f.read() 80 f.close() 81 return Vend.__bytecode 82 83 84 def create(self, contract_address, sender_address, name, symbol, tx_format=TxFormat.JSONRPC, id_generator=None): 85 enc = ABIContractEncoder() 86 enc.method('create') 87 enc.typ(ABIContractType.STRING) 88 enc.typ(ABIContractType.STRING) 89 enc.string(name) 90 enc.string(symbol) 91 data = add_0x(enc.get()) 92 tx = self.template(sender_address, contract_address, use_nonce=True) 93 tx = self.set_code(tx, data) 94 tx = self.finalize(tx, tx_format, id_generator=id_generator) 95 return tx 96 97 98 def deposit(self, contract_address, sender_address, token_address, tx_format=TxFormat.JSONRPC, id_generator=None): 99 enc = ABIContractEncoder() 100 enc.method('deposit') 101 enc.typ(ABIContractType.ADDRESS) 102 enc.typ(ABIContractType.UINT256) 103 enc.address(token_address) 104 enc.uint256(0) 105 data = add_0x(enc.get()) 106 tx = self.template(sender_address, contract_address, use_nonce=True) 107 tx = self.set_code(tx, data) 108 tx = self.finalize(tx, tx_format, id_generator=id_generator) 109 return tx 110 111 112 def withdraw(self, contract_address, sender_address, token_address, tx_format=TxFormat.JSONRPC, id_generator=None): 113 enc = ABIContractEncoder() 114 enc.method('withdraw') 115 enc.typ(ABIContractType.ADDRESS) 116 enc.typ(ABIContractType.UINT256) 117 enc.address(token_address) 118 enc.uint256(0) 119 data = add_0x(enc.get()) 120 tx = self.template(sender_address, contract_address, use_nonce=True) 121 tx = self.set_code(tx, data) 122 tx = self.finalize(tx, tx_format, id_generator=id_generator) 123 return tx 124 125 126 def get_token(self, contract_address, token_idx, sender_address=ZERO_ADDRESS, id_generator=None): 127 j = JSONRPCRequest(id_generator) 128 o = j.template() 129 o['method'] = 'eth_call' 130 enc = ABIContractEncoder() 131 enc.method('getTokenByIndex') 132 enc.typ(ABIContractType.UINT256) 133 enc.uint256(token_idx) 134 data = add_0x(enc.get()) 135 tx = self.template(sender_address, contract_address) 136 tx = self.set_code(tx, data) 137 o['params'].append(self.normalize(tx)) 138 o['params'].append('latest') 139 o = j.finalize(o) 140 return o 141 142 143 def parse_token(self, v): 144 dec = ABIContractDecoder() 145 dec.typ(ABIContractType.ADDRESS) 146 dec.val(v) 147 r = dec.get() 148 return r[0] 149 150 151 def bytecode(**kwargs): 152 return Vend.bytecode(version=kwargs.get('version')) 153 154 155 def create(**kwargs): 156 enc = CLIEncoder() 157 (typ, token_address) = enc.translate('a', strip_0x(kwargs['token_address'])) 158 decimals = kwargs.get('decimals', 0) 159 if decimals != None: 160 (typ, decimals) = enc.translate('u', decimals) 161 return Vend.cargs(token_address, decimals=decimals, mint=kwargs.get('mint'), version=kwargs.get('version')) 162 163 164 def args(v): 165 if v == 'create': 166 return (['token_address'], ['decimals', 'mint'],) 167 elif v == 'default' or v == 'bytecode': 168 return ([], ['version'],) 169 raise ValueError('unknown command: ' + v)