index.py (5933B)
1 # Author: Louis Holbrook <dev@holbrook.no> 0826EDA1702D1E87C6E2875121D2E7BB88C2A746 2 # SPDX-License-Identifier: GPL-3.0-or-later 3 # File-version: 1 4 # Description: Python interface to abi and bin files for faucet contracts 5 6 # standard imports 7 import logging 8 import json 9 import os 10 import hashlib 11 12 # external imports 13 from chainlib.eth.contract import ( 14 ABIContractEncoder, 15 ABIContractType, 16 abi_decode_single, 17 ) 18 from chainlib.eth.tx import ( 19 TxFactory, 20 TxFormat, 21 ) 22 from chainlib.jsonrpc import JSONRPCRequest 23 from chainlib.eth.constant import ZERO_ADDRESS 24 from hexathon import ( 25 add_0x, 26 ) 27 28 logg = logging.getLogger(__name__) 29 30 moddir = os.path.dirname(__file__) 31 datadir = os.path.join(moddir, 'data') 32 33 34 def to_identifier(s): 35 r = s.encode('utf-8').hex() 36 assert len(r) <= 64 37 return '{:0<64}'.format(r) 38 39 40 class TokenUniqueSymbolIndex(TxFactory): 41 42 __abi = None 43 __bytecode = None 44 45 46 @staticmethod 47 def abi(): 48 if TokenUniqueSymbolIndex.__abi == None: 49 f = open(os.path.join(datadir, 'TokenUniqueSymbolIndex.json'), 'r') 50 TokenUniqueSymbolIndex.__abi = json.load(f) 51 f.close() 52 return TokenUniqueSymbolIndex.__abi 53 54 55 @staticmethod 56 def bytecode(): 57 if TokenUniqueSymbolIndex.__bytecode == None: 58 f = open(os.path.join(datadir, 'TokenUniqueSymbolIndex.bin')) 59 TokenUniqueSymbolIndex.__bytecode = f.read() 60 f.close() 61 return TokenUniqueSymbolIndex.__bytecode 62 63 64 @staticmethod 65 def gas(code=None): 66 return 1200000 67 68 69 def constructor(self, sender_address): 70 code = TokenUniqueSymbolIndex.bytecode() 71 tx = self.template(sender_address, None, use_nonce=True) 72 tx = self.set_code(tx, code) 73 return self.build(tx) 74 75 76 def register(self, contract_address, sender_address, address, tx_format=TxFormat.JSONRPC): 77 enc = ABIContractEncoder() 78 enc.method('register') 79 enc.typ(ABIContractType.ADDRESS) 80 enc.address(address) 81 data = enc.get() 82 tx = self.template(sender_address, contract_address, use_nonce=True) 83 tx = self.set_code(tx, data) 84 tx = self.finalize(tx, tx_format) 85 return tx 86 87 88 def remove(self, contract_address, sender_address, address, tx_format=TxFormat.JSONRPC): 89 enc = ABIContractEncoder() 90 enc.method('remove') 91 enc.typ(ABIContractType.ADDRESS) 92 enc.address(address) 93 data = enc.get() 94 tx = self.template(sender_address, contract_address, use_nonce=True) 95 tx = self.set_code(tx, data) 96 tx = self.finalize(tx, tx_format) 97 return tx 98 99 100 def add_writer(self, contract_address, sender_address, address, tx_format=TxFormat.JSONRPC, id_generator=None): 101 enc = ABIContractEncoder() 102 enc.method('addWriter') 103 enc.typ(ABIContractType.ADDRESS) 104 enc.address(address) 105 data = 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) 109 return tx 110 111 112 def address_of(self, contract_address, token_symbol, sender_address=ZERO_ADDRESS, id_generator=None): 113 j = JSONRPCRequest(id_generator) 114 o = j.template() 115 o['method'] = 'eth_call' 116 enc = ABIContractEncoder() 117 enc.method('addressOf') 118 enc.typ(ABIContractType.BYTES32) 119 token_symbol_digest = to_identifier(token_symbol) 120 enc.bytes32(token_symbol_digest) 121 data = add_0x(enc.get()) 122 tx = self.template(sender_address, contract_address) 123 tx = self.set_code(tx, data) 124 o['params'].append(self.normalize(tx)) 125 o = j.finalize(o) 126 return o 127 128 129 def entry(self, contract_address, idx, sender_address=ZERO_ADDRESS, id_generator=None): 130 j = JSONRPCRequest(id_generator) 131 o = j.template() 132 o['method'] = 'eth_call' 133 enc = ABIContractEncoder() 134 enc.method('entry') 135 enc.typ(ABIContractType.UINT256) 136 enc.uint256(idx) 137 data = add_0x(enc.get()) 138 tx = self.template(sender_address, contract_address) 139 tx = self.set_code(tx, data) 140 o['params'].append(self.normalize(tx)) 141 o = j.finalize(o) 142 return o 143 144 145 def entry_count(self, contract_address, sender_address=ZERO_ADDRESS, id_generator=None): 146 j = JSONRPCRequest(id_generator) 147 o = j.template() 148 o['method'] = 'eth_call' 149 enc = ABIContractEncoder() 150 enc.method('entryCount') 151 data = add_0x(enc.get()) 152 tx = self.template(sender_address, contract_address) 153 tx = self.set_code(tx, data) 154 o['params'].append(self.normalize(tx)) 155 o = j.finalize(o) 156 return o 157 158 159 def identifier(self, contract_address, idx, sender_address=ZERO_ADDRESS, id_generator=None): 160 j = JSONRPCRequest(id_generator) 161 o = j.template() 162 o['method'] = 'eth_call' 163 enc = ABIContractEncoder() 164 enc.method('identifier') 165 enc.typ(ABIContractType.UINT256) 166 enc.uint256(idx) 167 data = add_0x(enc.encode()) 168 tx = self.template(sender_address, contract_address) 169 tx = self.set_code(tx, data) 170 o['params'].append(self.normalize(tx)) 171 o = j.finalize(o) 172 return o 173 174 175 def identifier_count(self, contract_address, sender_address=ZERO_ADDRESS, id_generator=None): 176 return self.call_noarg('identifierCount', contract_address, sender_address=sender_address, id_generator=id_generator) 177 178 179 @classmethod 180 def parse_address_of(self, v): 181 return abi_decode_single(ABIContractType.ADDRESS, v) 182 183 184 @classmethod 185 def parse_entry(self, v): 186 return abi_decode_single(ABIContractType.ADDRESS, v) 187 188 189 @classmethod 190 def parse_entry_count(self, v): 191 return abi_decode_single(ABIContractType.UINT256, v)