faucet.py (2725B)
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 11 # external imports 12 from chainlib.eth.tx import TxFactory 13 from chainlib.eth.constant import ZERO_ADDRESS 14 from chainlib.eth.contract import ( 15 abi_decode_single, 16 ABIContractEncoder, 17 ABIContractType, 18 ) 19 from hexathon import add_0x 20 21 # local imports 22 from .interface import Faucet 23 24 logg = logging.getLogger().getChild(__name__) 25 26 moddir = os.path.dirname(__file__) 27 datadir = os.path.join(moddir, 'data') 28 29 30 class SingleShotFaucet(Faucet): 31 32 __abi = None 33 __bytecode = None 34 __address = None 35 36 @staticmethod 37 def abi(part=None): 38 if SingleShotFaucet.__abi == None: 39 f = open(os.path.join(datadir, 'ERC20Faucet.json'), 'r') 40 SingleShotFaucet.__abi = json.load(f) 41 f.close() 42 if part == 'storage': 43 f = open(os.path.join(datadir, 'ERC20FaucetStorage.json')) 44 abi = f.read() 45 f.close() 46 return abi 47 elif part != None: 48 raise ValueError('unknown abi identifier "{}"'.format(part)) 49 return SingleShotFaucet.__abi 50 51 52 @staticmethod 53 def bytecode(part=None): 54 if SingleShotFaucet.__bytecode == None: 55 f = open(os.path.join(datadir, 'ERC20Faucet.bin')) 56 SingleShotFaucet.__bytecode = f.read() 57 f.close() 58 if part == 'storage': 59 f = open(os.path.join(datadir, 'ERC20FaucetStorage.bin')) 60 bytecode = f.read() 61 f.close() 62 return bytecode 63 elif part != None: 64 raise ValueError('unknown bytecode identifier "{}"'.format(part)) 65 66 return SingleShotFaucet.__bytecode 67 68 69 @staticmethod 70 def gas(code=None): 71 return 2000000 72 73 74 def store_constructor(self, sender_address): 75 code = SingleShotFaucet.bytecode(part='storage') 76 tx = self.template(sender_address, None, use_nonce=True) 77 tx = self.set_code(tx, code) 78 return self.build(tx) 79 80 81 # TODO: allow multiple overriders 82 def constructor(self, sender_address, token, store, accounts_index): 83 if accounts_index == None: 84 accounts_index = ZERO_ADDRESS 85 code = SingleShotFaucet.bytecode() 86 enc = ABIContractEncoder() 87 enc.address(token) 88 enc.address(store) 89 enc.address(accounts_index) 90 code += enc.get() 91 tx = self.template(sender_address, None, use_nonce=True) 92 tx = self.set_code(tx, code) 93 return self.build(tx)