diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..2833bee --- /dev/null +++ b/.gitignore @@ -0,0 +1,8 @@ +*.egg* +*.pyc +__pycache__ +build/ +dist/ +solidity/*.json +solidity/*.bin +.venv \ No newline at end of file diff --git a/custodial_registration_proxy/__init__.py b/custodial_registration_proxy/__init__.py new file mode 100644 index 0000000..9c38d5e --- /dev/null +++ b/custodial_registration_proxy/__init__.py @@ -0,0 +1,4 @@ +from .custodial_registration_proxy import ( + CustodialRegistrationProxy, + CustodialRegistrationProxySettings, + ) \ No newline at end of file diff --git a/custodial_registration_proxy/custodial_registration_proxy.py b/custodial_registration_proxy/custodial_registration_proxy.py new file mode 100644 index 0000000..eb541e4 --- /dev/null +++ b/custodial_registration_proxy/custodial_registration_proxy.py @@ -0,0 +1,69 @@ +# Adapted from cicnet like libraries https://holbrook.no/src/ +# Changes: Uses custodial registration proxy ABI and bytecode +# Original Author: Louis Holbrook 0826EDA1702D1E87C6E2875121D2E7BB88C2A746 +# SPDX-License-Identifier: AGPL-3.0-or-later +# File-version: 1 +# Description: Python interface to abi and bin files for custodial proxy + +# standard imports +import logging +import json +import os + +# external imports +from chainlib.eth.tx import TxFactory +from chainlib.eth.contract import ABIContractEncoder +from chainlib.eth.tx import ( + TxFactory, + TxFormat, + ) +from chainlib.jsonrpc import JSONRPCRequest + +logg = logging.getLogger().getChild(__name__) + +moddir = os.path.dirname(__file__) +datadir = os.path.join(moddir, 'data') + +class CustodialRegistrationProxySettings: + def __init__(self): + self.eth_faucet_address = None + self.custodial_account_index_address = None + self.training_voucher_address = None + self.system_account_address = None + +class CustodialRegistrationProxy(TxFactory): + __abi = None + __bytecode = None + + @staticmethod + def abi(): + if CustodialRegistrationProxy.__abi == None: + f = open(os.path.join(datadir, 'CustodialRegistrationProxy.json'), 'r') + CustodialRegistrationProxy.__abi = json.load(f) + f.close() + return CustodialRegistrationProxy.__abi + + + @staticmethod + def bytecode(): + if CustodialRegistrationProxy.__bytecode == None: + f = open(os.path.join(datadir, 'CustodialRegistrationProxy.bin')) + CustodialRegistrationProxy.__bytecode = f.read() + f.close() + return CustodialRegistrationProxy.__bytecode + + @staticmethod + def gas(code=None): + return 2000000 + + def constructor(self, sender_address, settings): + code = CustodialRegistrationProxy.bytecode() + enc = ABIContractEncoder() + enc.address(settings.eth_faucet_address) + enc.address(settings.custodial_account_index_address) + enc.address(settings.training_voucher_address) + enc.address(settings.system_account_address) + code += enc.get() + tx = self.template(sender_address, None, use_nonce=True) + tx = self.set_code(tx, code) + return self.build(tx) diff --git a/data/CutodialRegistrationProxy.bin b/custodial_registration_proxy/data/CustodialRegistrationProxy.bin similarity index 100% rename from data/CutodialRegistrationProxy.bin rename to custodial_registration_proxy/data/CustodialRegistrationProxy.bin diff --git a/data/CustodialRegistrationProxy.json b/custodial_registration_proxy/data/CustodialRegistrationProxy.json similarity index 100% rename from data/CustodialRegistrationProxy.json rename to custodial_registration_proxy/data/CustodialRegistrationProxy.json diff --git a/data/metadata.json b/custodial_registration_proxy/data/metadata.json similarity index 100% rename from data/metadata.json rename to custodial_registration_proxy/data/metadata.json diff --git a/custodial_registration_proxy/runnable/publish.py b/custodial_registration_proxy/runnable/publish.py new file mode 100644 index 0000000..5d2fdbd --- /dev/null +++ b/custodial_registration_proxy/runnable/publish.py @@ -0,0 +1,113 @@ +"""Deploys custodial registration proxy + +.. adapted from cicnet like libraries https://holbrook.no/src/ +.. changelog: use custodial proxy contract + +.. moduleauthor:: Louis Holbrook +.. pgp:: 0826EDA1702D1E87C6E2875121D2E7BB88C2A746 + +""" + +# standard imports +import sys +import os +import logging + +# external imports +import chainlib.eth.cli +from chainlib.chain import ChainSpec +from chainlib.eth.connection import EthHTTPConnection +from chainlib.eth.tx import receipt +from chainlib.eth.cli.arg import ( + Arg, + ArgFlag, + process_args, + ) +from chainlib.eth.cli.config import ( + Config, + process_config, + ) +from chainlib.eth.cli.log import process_log +from chainlib.eth.settings import process_settings +from chainlib.settings import ChainSettings + +# local imports +from custodial_registration_proxy import ( + CustodialRegistrationProxy, + CustodialRegistrationProxySettings, +) + +logging.basicConfig(level=logging.WARNING) +logg = logging.getLogger() + +def process_config_local(config, arg, args, flags): + config.add(args.proxy_eth_faucet_address, 'PROXY_ETH_FAUCET_ADDRESS') + config.add(args.proxy_custodial_account_index_address, 'PROXY_CUSTODIAL_ACCOUNT_INDEX_ADDRESS') + config.add(args.proxy_training_voucher_address, 'PROXY_TRAINING_VOUCHER_ADDRESS') + config.add(args.proxy_system_account_address, 'PROXY_SYSTEM_ACCOUNT_ADDRESS') + return config + +arg_flags = ArgFlag() +arg = Arg(arg_flags) +flags = arg_flags.STD_WRITE + +argparser = chainlib.eth.cli.ArgumentParser() +argparser = process_args(argparser, arg, flags) +argparser.add_argument('--eth-faucet-address', dest='proxy_eth_faucet_address', type=str, help='Faucet address') +argparser.add_argument('--account-index-address', dest='proxy_custodial_account_index_address', type=str, help='Account index address') +argparser.add_argument('--training-voucher-address', dest='proxy_training_voucher_address', type=str, help='Training voucher address') +argparser.add_argument('--system-account-address', dest='proxy_system_account_address', type=str, help='System account address') +args = argparser.parse_args() + +logg = process_log(args, logg) + +config = Config() +config = process_config(config, arg, args, flags) +config = process_config_local(config, arg, args, flags) +logg.debug('config loaded:\n{}'.format(config)) + +settings = ChainSettings() +settings = process_settings(settings, config) +logg.debug('settings loaded:\n{}'.format(settings)) + + +def main(): + conn = settings.get('CONN') + + c = CustodialRegistrationProxy( + settings.get('CHAIN_SPEC'), + signer=settings.get('SIGNER'), + gas_oracle=settings.get('FEE_ORACLE'), + nonce_oracle=settings.get('NONCE_ORACLE'), + ) + + c_args = CustodialRegistrationProxySettings() + c_args.eth_faucet_address = config.get('PROXY_ETH_FAUCET_ADDRESS') + c_args.custodial_account_index_address = config.get('PROXY_CUSTODIAL_ACCOUNT_INDEX_ADDRESS') + c_args.training_voucher_address = config.get('PROXY_TRAINING_VOUCHER_ADDRESS') + c_args.system_account_address = config.get('PROXY_SYSTEM_ACCOUNT_ADDRESS') + + (tx_hash_hex, o) = c.constructor( + settings.get('SENDER_ADDRESS'), + c_args, + ) + + if settings.get('RPC_SEND'): + conn.do(o) + if config.true('_WAIT'): + r = conn.wait(tx_hash_hex) + if r['status'] == 0: + sys.stderr.write('EVM revert while deploying contract. Wish I had more to tell you') + sys.exit(1) + # TODO: pass through translator for keys (evm tester uses underscore instead of camelcase) + address = r['contractAddress'] + + print(address) + else: + print(tx_hash_hex) + else: + print(o) + + +if __name__ == '__main__': + main() diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..8d2cd18 --- /dev/null +++ b/requirements.txt @@ -0,0 +1,2 @@ +chainlib-eth~=0.4.17 +chainlib~=0.4.12 \ No newline at end of file diff --git a/setup.cfg b/setup.cfg new file mode 100644 index 0000000..54bc18c --- /dev/null +++ b/setup.cfg @@ -0,0 +1,38 @@ +[metadata] +name = custodial-registration-proxy +version = 0.1.0 +description = Atomically registers a custodial user on-chain and provisions necessary gas and training vouchers. +long_description = Atomically registers a custodial user on-chain and provisions necessary gas and training vouchers. +author = Mohamed Sohail +author_email = sohail@grassecon.org +url = https://github.com/grassrootseconomics/custodial-registration-proxy +keywords = + ethereum +classifiers = + Programming Language :: Python :: 3 + Operating System :: OS Independent + Development Status :: 4 - Beta + Environment :: Console + Intended Audience :: Developers + License :: OSI Approved :: GNU Affero General Public License v3 or later (AGPLv3+) + Topic :: Internet + Topic :: Software Development :: Libraries +license = AGPLv3+ +licence_files = + LICENSE + +[options] +include_package_data = True +python_requires = >= 3.6 +packages = + custodial_registration_proxy + custodial_registration_proxy.runnable + +[options.package_data] +* = + **/data/*.json + **/data/*.bin + +[options.entry_points] +console_scripts = + ge-custodial-registration-proxy-publish = custodial_registration_proxy.runnable.publish:main diff --git a/setup.py b/setup.py new file mode 100644 index 0000000..82e01ed --- /dev/null +++ b/setup.py @@ -0,0 +1,21 @@ +from setuptools import setup + +requirements = [] +f = open('requirements.txt', 'r') +while True: + l = f.readline() + if l == '': + break + requirements.append(l.rstrip()) +f.close() + +setup( + package_data={ + '': [ + 'data/*.abi.json', + 'data/*.bin', + ], + }, + include_package_data=True, + install_requires=requirements, +) diff --git a/CustodialRegistrationProxy.sol b/solidity/CustodialRegistrationProxy.sol similarity index 99% rename from CustodialRegistrationProxy.sol rename to solidity/CustodialRegistrationProxy.sol index fa846da..7d4bfa4 100644 --- a/CustodialRegistrationProxy.sol +++ b/solidity/CustodialRegistrationProxy.sol @@ -66,4 +66,4 @@ contract CustodialRegistrationProxy { TrainingVoucher.mintTo(_subject, trainingVoucerGiftAmount); emit NewRegistration(_subject); } -} +} \ No newline at end of file