eth-contract-registry/python/eth_contract_registry/registry.py

129 lines
3.4 KiB
Python
Raw Normal View History

# standard imports
import os
import logging
import json
2021-03-22 18:37:00 +01:00
import hashlib
# third-party imports
from chainlib.eth.contract import (
ABIContractEncoder,
ABIContractType,
abi_decode_single,
)
from chainlib.chain import ChainSpec
from chainlib.eth.constant import (
ZERO_ADDRESS,
)
2021-06-28 09:29:37 +02:00
from chainlib.jsonrpc import JSONRPCRequest
from hexathon import (
even,
add_0x,
)
from chainlib.eth.tx import TxFactory
# local imports
2021-03-25 09:27:31 +01:00
from .encoding import (
to_identifier,
from_identifier_hex,
)
2021-04-30 13:11:22 +02:00
from .interface import Registry
logg = logging.getLogger(__name__)
moddir = os.path.dirname(__file__)
datadir = os.path.join(moddir, 'data')
2021-04-30 13:11:22 +02:00
class ContractRegistry(Registry):
default_chain_spec = None
__chains_registry = {}
__abi = None
__bytecode = None
@staticmethod
def abi():
2021-04-30 13:11:22 +02:00
if ContractRegistry.__abi == None:
f = open(os.path.join(datadir, 'Registry.json'), 'r')
2021-04-30 13:11:22 +02:00
ContractRegistry.__abi = json.load(f)
f.close()
2021-04-30 13:11:22 +02:00
return ContractRegistry.__abi
@staticmethod
def bytecode():
2021-04-30 13:11:22 +02:00
if ContractRegistry.__bytecode == None:
f = open(os.path.join(datadir, 'Registry.bin'))
2021-04-30 13:11:22 +02:00
ContractRegistry.__bytecode = f.read()
f.close()
2021-04-30 13:11:22 +02:00
return ContractRegistry.__bytecode
2021-03-22 18:37:00 +01:00
@staticmethod
def gas(code=None):
return 1500000
2021-04-30 13:11:22 +02:00
def constructor(self, sender_address, identifier_strings=[]):
# TODO: handle arrays in chainlib encode instead
enc = ABIContractEncoder()
enc.uint256(32)
enc.uint256(len(identifier_strings))
for s in identifier_strings:
enc.bytes32(to_identifier(s))
data = enc.get_contents()
2021-03-22 18:37:00 +01:00
tx = self.template(sender_address, None, use_nonce=True)
2021-04-30 13:11:22 +02:00
tx = self.set_code(tx, ContractRegistry.bytecode() + data)
logg.debug('bytecode {}\ndata {}\ntx {}'.format(ContractRegistry.bytecode(), data, tx))
return self.build(tx)
@staticmethod
def address(address=None):
if address != None:
2021-04-30 13:11:22 +02:00
ContractRegistry.__address = address
return Registry.__address
@staticmethod
def load_for(chain_spec):
chain_str = str(chain_spec)
raise NotImplementedError()
2021-11-14 05:23:44 +01:00
def set(self, contract_address, sender_address, identifier_string, address):
enc = ABIContractEncoder()
enc.method('set')
enc.typ(ABIContractType.BYTES32)
enc.typ(ABIContractType.ADDRESS)
identifier = to_identifier(identifier_string)
enc.bytes32(identifier)
enc.address(address)
data = enc.encode()
tx = self.template(sender_address, contract_address, use_nonce=True)
tx = self.set_code(tx, data)
return self.build(tx)
2021-06-28 09:29:37 +02:00
def identifier(self, contract_address, idx, sender_address=ZERO_ADDRESS, id_generator=None):
j = JSONRPCRequest(id_generator)
o = j.template()
o['method'] = 'eth_call'
enc = ABIContractEncoder()
enc.method('identifiers')
enc.typ(ABIContractType.UINT256)
enc.uint256(idx)
data = add_0x(enc.encode())
tx = self.template(sender_address, contract_address)
tx = self.set_code(tx, data)
o['params'].append(self.normalize(tx))
2021-06-28 09:29:37 +02:00
o = j.finalize(o)
return o
2021-03-25 09:27:31 +01:00
@classmethod
def parse_identifier(self, v):
return from_identifier_hex(v)