philip/demurrage-token-deploy #1
6
.gitignore
vendored
6
.gitignore
vendored
@ -1,3 +1,9 @@
|
||||
__pycache__
|
||||
*.pyc
|
||||
*.egg-info
|
||||
.venv
|
||||
build
|
||||
.vscode
|
||||
.idea
|
||||
contracts
|
||||
*.egg
|
0
cic/actions/__init__.py
Normal file
0
cic/actions/__init__.py
Normal file
96
cic/actions/deploy.py
Normal file
96
cic/actions/deploy.py
Normal file
@ -0,0 +1,96 @@
|
||||
# standard imports
|
||||
import logging
|
||||
import importlib
|
||||
import os
|
||||
|
||||
# external imports
|
||||
from cic_types.ext.metadata import MetadataRequestsHandler
|
||||
from cic_types.ext.metadata.signer import Signer as MetadataSigner
|
||||
|
||||
# local imports
|
||||
from cic import (
|
||||
Proof,
|
||||
Processor,
|
||||
)
|
||||
from cic.output import (
|
||||
HTTPWriter,
|
||||
KeyedWriterFactory,
|
||||
)
|
||||
from cic.meta import (
|
||||
Meta,
|
||||
MetadataWriter,
|
||||
)
|
||||
from cic.attachment import Attachment
|
||||
from cic.network import Network
|
||||
from cic.token import Token
|
||||
from typing import Optional
|
||||
logg = logging.getLogger(__name__)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
def init_writers_from_config(config):
|
||||
w = {
|
||||
'meta': None,
|
||||
'attachment': None,
|
||||
'proof': None,
|
||||
'ext': None,
|
||||
}
|
||||
for v in w.keys():
|
||||
k = 'CIC_CORE_{}_WRITER'.format(v.upper())
|
||||
(d, c) = config.get(k).rsplit('.', maxsplit=1)
|
||||
m = importlib.import_module(d)
|
||||
o = getattr(m, c)
|
||||
w[v] = o
|
||||
|
||||
return w
|
||||
|
||||
|
||||
def deploy(config, target: str,contract_directory: str, metadata_endpoint: Optional[str], keystore_directory: str, key_file_path: str, gpg_passphrase: str):
|
||||
modname = 'cic.ext.{}'.format(target)
|
||||
cmd_mod = importlib.import_module(modname)
|
||||
|
||||
writers = init_writers_from_config(config)
|
||||
output_directory = os.path.join(contract_directory, 'out')
|
||||
output_writer_path_meta = output_directory
|
||||
if metadata_endpoint != None:
|
||||
MetadataRequestsHandler.base_url = metadata_endpoint
|
||||
MetadataSigner.gpg_path = os.path.join('/tmp')
|
||||
MetadataSigner.key_file_path = key_file_path
|
||||
MetadataSigner.gpg_passphrase = gpg_passphrase
|
||||
writers['proof'] = KeyedWriterFactory(MetadataWriter, HTTPWriter).new
|
||||
writers['attachment'] = KeyedWriterFactory(None, HTTPWriter).new
|
||||
writers['meta'] = MetadataWriter
|
||||
output_writer_path_meta = metadata_endpoint
|
||||
|
||||
ct = Token(path=contract_directory)
|
||||
cm = Meta(path=contract_directory, writer=writers['meta'](path=output_writer_path_meta))
|
||||
ca = Attachment(path=contract_directory, writer=writers['attachment'](path=output_writer_path_meta))
|
||||
cp = Proof(path=contract_directory, attachments=ca, writer=writers['proof'](path=output_writer_path_meta))
|
||||
cn = Network(path=contract_directory)
|
||||
|
||||
ca.load()
|
||||
ct.load()
|
||||
cp.load()
|
||||
cm.load()
|
||||
cn.load()
|
||||
|
||||
chain_spec = None
|
||||
try:
|
||||
chain_spec = config.get('CHAIN_SPEC')
|
||||
except KeyError:
|
||||
chain_spec = cn.chain_spec
|
||||
config.add(chain_spec, 'CHAIN_SPEC', exists_ok=True)
|
||||
logg.debug(f'CHAIN_SPEC config set to {str(chain_spec)}')
|
||||
|
||||
(rpc, signer) = cmd_mod.parse_adapter(config, keystore_directory)
|
||||
|
||||
ref = cn.resource(target)
|
||||
chain_spec = cn.chain_spec(target)
|
||||
logg.debug('found reference {} chain spec {} for target {}'.format(ref['contents'], chain_spec, target))
|
||||
c = getattr(cmd_mod, 'new')(chain_spec, ref['contents'], cp, signer_hint=signer, rpc=rpc, outputs_writer=writers['ext'](path=output_directory))
|
||||
c.apply_token(ct)
|
||||
|
||||
p = Processor(proof=cp, attachment=ca, metadata=cm, extensions=[c])
|
||||
p.process()
|
@ -1,6 +1,6 @@
|
||||
# standard imports
|
||||
import os
|
||||
import logging
|
||||
import os
|
||||
|
||||
# local imports
|
||||
from .base import *
|
||||
|
351
cic/cmd/easy.py
Normal file
351
cic/cmd/easy.py
Normal file
@ -0,0 +1,351 @@
|
||||
# standard import
|
||||
import importlib
|
||||
import json
|
||||
import logging
|
||||
import os
|
||||
import subprocess
|
||||
|
||||
import requests
|
||||
|
||||
# external imports
|
||||
from chainlib.chain import ChainSpec
|
||||
|
||||
# local imports
|
||||
from cic import Proof
|
||||
from cic.actions.deploy import deploy
|
||||
from cic.attachment import Attachment
|
||||
from cic.meta import Meta
|
||||
from cic.network import Network
|
||||
from cic.token import Token
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def process_args(argparser):
|
||||
argparser.add_argument(
|
||||
"--skip-gen", action="store_true", default=False, help="Skip Generation"
|
||||
)
|
||||
argparser.add_argument(
|
||||
"--skip-deploy",
|
||||
action="store_true",
|
||||
help="Skip Deployment",
|
||||
)
|
||||
argparser.add_argument(
|
||||
"--target",
|
||||
default="eth",
|
||||
help="Contract Tech Target (eth)",
|
||||
)
|
||||
argparser.add_argument(
|
||||
"path",
|
||||
type=str,
|
||||
help="Path to generate/use contract deployment info",
|
||||
)
|
||||
argparser.add_argument(
|
||||
"-p",
|
||||
type=str,
|
||||
help="RPC Provider (http://localhost:8545)",
|
||||
)
|
||||
|
||||
|
||||
def validate_args(args):
|
||||
pass
|
||||
|
||||
|
||||
CONTRACTS = [
|
||||
{
|
||||
"url": "https://gitlab.com/cicnet/eth-erc20/-/raw/master/python/giftable_erc20_token/data/GiftableToken",
|
||||
"name": "Giftable Token",
|
||||
},
|
||||
{
|
||||
"url": "https://gitlab.com/cicnet/erc20-demurrage-token/-/raw/master/python/erc20_demurrage_token/data/DemurrageTokenMultiCap",
|
||||
"name": "Demurrage Token Multi Cap (Might not work)",
|
||||
},
|
||||
{
|
||||
"url": "https://gitlab.com/cicnet/erc20-demurrage-token/-/raw/master/python/erc20_demurrage_token/data/DemurrageTokenMultiNocap",
|
||||
"name": "Demurrage Token Multi No Cap (Might not work)",
|
||||
},
|
||||
{
|
||||
"url": "https://gitlab.com/cicnet/erc20-demurrage-token/-/raw/master/python/erc20_demurrage_token/data/DemurrageTokenSingleCap",
|
||||
"name": "Demurrage Token Single Cap (Might not work)",
|
||||
},
|
||||
{
|
||||
"url": "https://gitlab.com/cicnet/erc20-demurrage-token/-/raw/master/python/erc20_demurrage_token/data/DemurrageTokenSingleNocap",
|
||||
"name": "Demurrage Token Single No Cap",
|
||||
},
|
||||
]
|
||||
|
||||
# Download File from Url
|
||||
def download_file(url: str, directory: str, filename=None) -> (str, bytes):
|
||||
os.makedirs(directory, exist_ok=True)
|
||||
filename = filename if filename else url.split("/")[-1]
|
||||
path = os.path.join(directory, filename)
|
||||
if not os.path.exists(path):
|
||||
log.debug(f"Downloading {filename}")
|
||||
r = requests.get(url, allow_redirects=True)
|
||||
open(path, "wb").write(r.content)
|
||||
return path
|
||||
return path
|
||||
|
||||
|
||||
def get_contract_args(data: list):
|
||||
for item in data:
|
||||
if item["type"] == "constructor":
|
||||
return item["inputs"]
|
||||
raise Exception("No constructor found in contract")
|
||||
|
||||
|
||||
def print_contract_args(json_path: str):
|
||||
json_data = json.load(open(json_path))
|
||||
print(f"Contract Args:")
|
||||
for contract_arg in get_contract_args(json_data):
|
||||
print(
|
||||
f"\t{contract_arg.get('name', '<no name>')} - {contract_arg.get('type', '<no type>')}"
|
||||
)
|
||||
|
||||
|
||||
def select_contract():
|
||||
print(f"Contracts:")
|
||||
print(f"\t C - Custom (path/url to contract)")
|
||||
for idx, contract in enumerate(CONTRACTS):
|
||||
print(f"\t {idx} - {contract['name']}")
|
||||
|
||||
val = input("Select contract (C,0,1..): ")
|
||||
if val.isdigit() and int(val) < len(CONTRACTS):
|
||||
contract = CONTRACTS[int(val)]
|
||||
directory = f"./contracts/{contract['name']}"
|
||||
bin_path = os.path.abspath(download_file(contract["url"] + ".bin", directory))
|
||||
json_path = download_file(contract["url"] + ".json", directory)
|
||||
elif val == "C":
|
||||
possible_bin_location = input("Enter path/url to contract: ")
|
||||
# possible_bin_location is path
|
||||
if possible_bin_location[0] == "." or possible_bin_location[0] == "/":
|
||||
if os.path.exists(possible_bin_location):
|
||||
bin_path = os.path.abspath(possible_bin_location)
|
||||
else:
|
||||
raise Exception(f"File {possible_bin_location} does not exist")
|
||||
|
||||
possible_json_path = val.replace(".bin", ".json")
|
||||
if os.path.exists(possible_json_path):
|
||||
json_path = possible_json_path
|
||||
# possible_bin_location is url
|
||||
else:
|
||||
bin_path = download_file(contract["url"] + ".bin", directory)
|
||||
else:
|
||||
print("Invalid selection")
|
||||
exit(1)
|
||||
extra_args = []
|
||||
extra_args_types = []
|
||||
|
||||
if os.path.exists(json_path):
|
||||
json_data = json.load(open(json_path))
|
||||
for contract_arg in get_contract_args(json_data):
|
||||
arg_name = contract_arg.get("name")
|
||||
arg_type = contract_arg.get("type")
|
||||
if arg_name not in ["_decimals", "_name", "_symbol"]:
|
||||
val = input(f"Enter value for {arg_name} ({arg_type}): ")
|
||||
extra_args.append(val)
|
||||
extra_args_types.append(arg_type)
|
||||
|
||||
return {
|
||||
"bin_path": bin_path,
|
||||
"json_path": json_path,
|
||||
"extra_args": extra_args,
|
||||
"extra_args_types": extra_args_types,
|
||||
}
|
||||
|
||||
|
||||
def init_token(
|
||||
directory: str,
|
||||
code="",
|
||||
extra_args=[],
|
||||
extra_args_types=[],
|
||||
):
|
||||
contract = select_contract()
|
||||
code = contract["bin_path"]
|
||||
extra_args = contract["extra_args"]
|
||||
extra_args_types = contract["extra_args_types"]
|
||||
|
||||
name = input("Enter Token Name (Foo Token): ") or "Foo Token"
|
||||
symbol = input("Enter Token Symbol (FOO): ") or "FOO"
|
||||
precision = input("Enter Token Precision (6): ") or 6
|
||||
supply = input("Enter Token Supply (0): ") or 0
|
||||
|
||||
contract_token = Token(
|
||||
directory,
|
||||
name=name,
|
||||
symbol=symbol,
|
||||
precision=precision,
|
||||
extra_args=extra_args,
|
||||
extra_args_types=extra_args_types,
|
||||
supply=supply,
|
||||
code=code,
|
||||
)
|
||||
contract_token.start()
|
||||
return contract_token
|
||||
|
||||
|
||||
def init_proof(directory):
|
||||
description = input("Enter Proof Description (None): ") or None
|
||||
namespace = input("Enter Proof Namespace (ge): ") or "ge"
|
||||
issuer = input("Enter Proof Issuer (None): ") or None
|
||||
contract_proof = Proof(directory, description, namespace, issuer)
|
||||
contract_proof.start()
|
||||
return contract_proof
|
||||
|
||||
|
||||
def init_meta(directory):
|
||||
name = input("Enter Name (None): ") or ""
|
||||
country_code = input("Enter Country Code (KE): ") or "KE"
|
||||
location = input("Enter Location (None): ") or ""
|
||||
adding_contact_info = True
|
||||
contact = {}
|
||||
while adding_contact_info:
|
||||
value = input("Enter contact info (e.g 'phone: +254723522718'): ") or None
|
||||
if value:
|
||||
data = value.split(":")
|
||||
if len(data) != 2:
|
||||
print("Invalid contact info, you must enter in the format 'key: value'")
|
||||
continue
|
||||
contact[data[0].strip()] = data[1].strip()
|
||||
else:
|
||||
adding_contact_info = False
|
||||
contract_meta = Meta(
|
||||
directory,
|
||||
name=name,
|
||||
country_code=country_code,
|
||||
location=location,
|
||||
contact=contact,
|
||||
)
|
||||
contract_meta.start()
|
||||
return contract_meta
|
||||
|
||||
|
||||
def init_attachment(directory):
|
||||
contract_attchment = Attachment(directory)
|
||||
contract_attchment.start()
|
||||
input(
|
||||
f"Please add attachment files to '{os.path.abspath(os.path.join(directory,'attachments'))}' and then press ENTER to continue"
|
||||
)
|
||||
contract_attchment.load()
|
||||
return contract_attchment
|
||||
|
||||
|
||||
def init_network(
|
||||
directory, registry_address,key_account_address, chain_spec, rpc_provider, targets=["eth"]
|
||||
):
|
||||
contract_network = Network(directory, targets=targets)
|
||||
contract_network.start()
|
||||
|
||||
for target in targets:
|
||||
m = importlib.import_module(f"cic.ext.{target}.start")
|
||||
m.extension_start(
|
||||
contract_network,
|
||||
registry_address=registry_address,
|
||||
chain_spec=chain_spec,
|
||||
rpc_provider=rpc_provider,
|
||||
key_account_address=key_account_address
|
||||
)
|
||||
contract_network.load()
|
||||
return contract_network
|
||||
|
||||
|
||||
def execute(config, eargs):
|
||||
directory = eargs.path
|
||||
if os.path.exists(directory):
|
||||
contine = input(
|
||||
"Directory already exists, Would you like to delete it? (y/n): "
|
||||
)
|
||||
if contine.lower() != "y":
|
||||
print("Exiting")
|
||||
exit(1)
|
||||
else:
|
||||
print(f"Deleted {directory}")
|
||||
os.system(f"rm -rf {directory}")
|
||||
target = eargs.target
|
||||
if not eargs.skip_gen:
|
||||
os.makedirs(directory)
|
||||
# Defaults
|
||||
default_contract_registry = config.get(
|
||||
"CIC_CONTRACT_REGISTRY_ADDRESS",
|
||||
"0xcf60ebc445b636a5ab787f9e8bc465a2a3ef8299",
|
||||
)
|
||||
default_key_account = config.get(
|
||||
"CIC_KEY_ACCOUNT_ADDRESS", "eb3907ecad74a0013c259d5874ae7f22dcbcc95c"
|
||||
)
|
||||
default_metadata_endpoint = "http://localhost:63380" or config.get(
|
||||
"META_ENDPOINT", "http://localhost:63380"
|
||||
)
|
||||
default_wallet_keyfile = config.get(
|
||||
"WALLET_KEY_FILE",
|
||||
"/home/will/grassroots/cic-internal-integration/apps/cic-ussd/tests/data/pgp/privatekeys_meta.asc",
|
||||
)
|
||||
default_wallet_passphrase = config.get("WALLET_PASSPHRASE", "merman")
|
||||
|
||||
default_chain_spec = config.get("CHAIN_SPEC", "evm:byzantium:8996:bloxberg")
|
||||
default_rpc_provider = config.get("RPC_PROVIDER", "http://localhost:63545")
|
||||
|
||||
# Options
|
||||
contract_registry = (
|
||||
input(f"Enter Contract Registry ({default_contract_registry}): ")
|
||||
or default_contract_registry
|
||||
)
|
||||
rpc_provider = (
|
||||
input(f"Enter RPC Provider ({default_rpc_provider}): ")
|
||||
or default_rpc_provider
|
||||
)
|
||||
chain_spec = ChainSpec.from_chain_str(
|
||||
(input(f"Enter ChainSpec ({default_chain_spec}): ") or default_chain_spec)
|
||||
)
|
||||
key_account = (
|
||||
input(f"Enter KeyAccount ({default_key_account}): ") or default_key_account
|
||||
)
|
||||
metadata_endpoint = (
|
||||
input(f"Enter Metadata Endpoint ({default_metadata_endpoint}): ")
|
||||
or default_metadata_endpoint
|
||||
)
|
||||
|
||||
token = init_token(directory)
|
||||
proof = init_proof(directory)
|
||||
meta = init_meta(directory)
|
||||
attachment = init_attachment(directory)
|
||||
network = init_network(
|
||||
directory,
|
||||
registry_address=contract_registry,
|
||||
key_account_address=key_account,
|
||||
chain_spec=chain_spec,
|
||||
rpc_provider=rpc_provider,
|
||||
targets=[target],
|
||||
)
|
||||
print(f"[cic.header]\nversion = {proof.version()}\n")
|
||||
print(f"[cic.token]\n{token}")
|
||||
print(f"[cic.proof]\n{proof}")
|
||||
print(f"[cic.meta]\n{meta}")
|
||||
print(f"[cic.attachment]\n{attachment}")
|
||||
print(f"[cic.network]\n{network}")
|
||||
if not eargs.skip_deploy:
|
||||
ready_to_deploy = input("Ready to deploy? (y/n): ")
|
||||
if ready_to_deploy == "y":
|
||||
deploy(
|
||||
config,
|
||||
contract_directory=directory,
|
||||
gpg_passphrase=default_wallet_passphrase,
|
||||
key_file_path=default_wallet_keyfile,
|
||||
metadata_endpoint=metadata_endpoint,
|
||||
keystore_directory="/home/will/grassroots/cic-internal-integration/apps/contract-migration/keystore",
|
||||
target=target,
|
||||
)
|
||||
print("Deployed")
|
||||
else:
|
||||
print("Not deploying")
|
||||
|
||||
|
||||
#
|
||||
#
|
||||
# rpc="http://localhost:63545"
|
||||
|
||||
# python -m cic.runnable.cic_cmd init --target eth --name "$token_name" --symbol $token_symbol --precision 6 $token_symbol_lowercase
|
||||
|
||||
# python -m cic.runnable.cic_cmd ext -p $rpc -i $chain_spec --registry $contract_registry -d $token_symbol_lowercase eth -vv
|
||||
# python -m cic.runnable.cic_cmd export -p $rpc --metadata-endpoint http://localhost:63380 -vv -y /home/will/grassroots/cic-internal-integration/apps/contract-migration/keystore -o $token_symbol_lowercase/out -d $token_symbol_lowercase eth
|
||||
if __name__ == "__main__":
|
||||
execute()
|
@ -23,7 +23,7 @@ from cic.meta import (
|
||||
from cic.attachment import Attachment
|
||||
from cic.network import Network
|
||||
from cic.token import Token
|
||||
|
||||
from typing import Optional
|
||||
logg = logging.getLogger(__name__)
|
||||
|
||||
|
||||
@ -56,8 +56,9 @@ def init_writers_from_config(config):
|
||||
|
||||
return w
|
||||
|
||||
EArgs = {'target': str, 'directory': str, 'output_directory': str, 'metadata_endpoint': Optional[str], 'y': str}
|
||||
|
||||
def execute(config, eargs):
|
||||
def execute(config, eargs: EArgs):
|
||||
modname = 'cic.ext.{}'.format(eargs.target)
|
||||
cmd_mod = importlib.import_module(modname)
|
||||
|
||||
@ -67,7 +68,7 @@ def execute(config, eargs):
|
||||
if eargs.metadata_endpoint != None:
|
||||
MetadataRequestsHandler.base_url = eargs.metadata_endpoint
|
||||
MetadataSigner.gpg_path = os.path.join('/tmp')
|
||||
MetadataSigner.key_file_path = '/home/lash/src/client/cic/grassrootseconomics/cic-internal-integration/apps/cic-ussd/tests/data/pgp/privatekeys_meta.asc'
|
||||
MetadataSigner.key_file_path = '/home/will/grassroots/cic-internal-integration/apps/cic-ussd/tests/data/pgp/privatekeys_meta.asc'
|
||||
MetadataSigner.gpg_passphrase = 'merman'
|
||||
writers['proof'] = KeyedWriterFactory(MetadataWriter, HTTPWriter).new
|
||||
writers['attachment'] = KeyedWriterFactory(None, HTTPWriter).new
|
||||
|
@ -25,6 +25,6 @@ def execute(config, eargs):
|
||||
|
||||
|
||||
chain_spec = ChainSpec.from_chain_str(eargs.i)
|
||||
m = importlib.import_module('cic.ext.{}.start'.format(eargs.target))
|
||||
m = importlib.import_module(f'cic.ext.{eargs.target}.start')
|
||||
m.extension_start(cn, registry_address=eargs.registry, chain_spec=chain_spec, rpc_provider=config.get('RPC_PROVIDER'))
|
||||
|
||||
|
@ -3,3 +3,10 @@ meta_writer = cic.output.KVWriter
|
||||
attachment_writer = cic.output.KVWriter
|
||||
proof_writer = cic.output.KVWriter
|
||||
ext_writer = cic.output.KVWriter
|
||||
|
||||
[cic]
|
||||
contract_registry_address =
|
||||
key_account_address =
|
||||
|
||||
[meta]
|
||||
endpoint=https://meta.grassecon.net
|
||||
|
@ -1,6 +1,6 @@
|
||||
# external imports
|
||||
from cic_eth_registry import CICRegistry
|
||||
from chainlib.eth.connection import RPCConnection
|
||||
from cic_eth_registry import CICRegistry
|
||||
|
||||
|
||||
def extension_start(network, *args, **kwargs):
|
||||
@ -9,18 +9,26 @@ def extension_start(network, *args, **kwargs):
|
||||
:param network: Network object to read and write settings from
|
||||
:type network: cic.network.Network
|
||||
"""
|
||||
CICRegistry.address = kwargs['registry_address']
|
||||
CICRegistry.address = kwargs["registry_address"]
|
||||
|
||||
RPCConnection.register_location(kwargs['rpc_provider'], kwargs['chain_spec'])
|
||||
conn = RPCConnection.connect(kwargs['chain_spec'])
|
||||
key_account_address = kwargs["key_account_address"] or ""
|
||||
|
||||
registry = CICRegistry(kwargs['chain_spec'], conn)
|
||||
RPCConnection.register_location(kwargs["rpc_provider"], kwargs["chain_spec"])
|
||||
conn = RPCConnection.connect(kwargs["chain_spec"])
|
||||
|
||||
address_declarator = registry.by_name('AddressDeclarator')
|
||||
network.resource_set('eth', 'address_declarator', address_declarator)
|
||||
registry = CICRegistry(kwargs["chain_spec"], conn)
|
||||
|
||||
token_index = registry.by_name('TokenRegistry')
|
||||
network.resource_set('eth', 'token_index', token_index)
|
||||
address_declarator = registry.by_name("AddressDeclarator")
|
||||
network.resource_set(
|
||||
"eth", "address_declarator", address_declarator, key_account=key_account_address
|
||||
)
|
||||
|
||||
network.set('eth', kwargs['chain_spec'])
|
||||
token_index = registry.by_name("TokenRegistry")
|
||||
network.resource_set(
|
||||
"eth", "token_index", token_index, key_account=key_account_address
|
||||
)
|
||||
|
||||
network.resource_set("eth", "token", None, key_account=key_account_address)
|
||||
|
||||
network.set("eth", kwargs["chain_spec"])
|
||||
network.save()
|
||||
|
42
cic/meta.py
42
cic/meta.py
@ -1,21 +1,20 @@
|
||||
# standard imports
|
||||
import os
|
||||
import base64
|
||||
import json
|
||||
import logging
|
||||
import base64
|
||||
import os
|
||||
|
||||
# external imports
|
||||
from cic_types import MetadataPointer
|
||||
from cic_types.processor import generate_metadata_pointer
|
||||
from cic_types.ext.metadata import MetadataRequestsHandler
|
||||
from cic_types.processor import generate_metadata_pointer
|
||||
from hexathon import strip_0x
|
||||
|
||||
# local imports
|
||||
from .base import (
|
||||
Data,
|
||||
data_dir,
|
||||
)
|
||||
from cic.output import OutputWriter
|
||||
|
||||
# local imports
|
||||
from .base import Data, data_dir
|
||||
|
||||
logg = logging.getLogger(__name__)
|
||||
|
||||
|
||||
@ -29,10 +28,12 @@ class Meta(Data):
|
||||
:param writer: Writer interface receiving the output of the processor
|
||||
:type writer: cic.output.OutputWriter
|
||||
"""
|
||||
def __init__(self, path='.', writer=None):
|
||||
def __init__(self, path='.', writer=None, name="", location="", country_code="", contact={}):
|
||||
super(Meta, self).__init__()
|
||||
self.name = None
|
||||
self.contact = {}
|
||||
self.contact = contact
|
||||
self.country_code = country_code
|
||||
self.location = location
|
||||
self.path = path
|
||||
self.writer = writer
|
||||
self.meta_path = os.path.join(self.path, 'meta.json')
|
||||
@ -49,7 +50,8 @@ class Meta(Data):
|
||||
|
||||
self.name = o['name']
|
||||
self.contact = o['contact']
|
||||
|
||||
self.country_code = o['country_code']
|
||||
self.location = o['location']
|
||||
self.inited = True
|
||||
|
||||
|
||||
@ -64,6 +66,11 @@ class Meta(Data):
|
||||
o = json.load(f)
|
||||
f.close()
|
||||
|
||||
o['name'] = self.name
|
||||
o['contact'] = self.contact
|
||||
o['country_code'] = self.country_code
|
||||
o['location'] = self.location
|
||||
|
||||
f = open(self.meta_path, 'w')
|
||||
json.dump(o, f, sort_keys=True, indent="\t")
|
||||
f.close()
|
||||
@ -107,12 +114,15 @@ class Meta(Data):
|
||||
|
||||
|
||||
def __str__(self):
|
||||
s = "contact.name = {}\n".format(self.name)
|
||||
|
||||
for k in self.contact.keys():
|
||||
if self.contact[k] == '':
|
||||
s = f"contact.name = {self.name}\n"
|
||||
s = f"contact.country_code = {self.country_code}\n"
|
||||
s = f"contact.location = {self.location}\n"
|
||||
for contact_key in self.contact.keys():
|
||||
contact_value = self.contact[contact_key]
|
||||
if not contact_value:
|
||||
s += f"contact.{contact_key} = \n"
|
||||
continue
|
||||
s += "contact.{} = {}\n".format(k.lower(), self.contact[k])
|
||||
s += f"contact.{contact_key} = {contact_value}\n"
|
||||
|
||||
return s
|
||||
|
||||
|
@ -54,7 +54,7 @@ class Network(Data):
|
||||
"""
|
||||
super(Network, self).load()
|
||||
|
||||
network_template_file_path = os.path.join(data_dir, 'network_template_v{}.json'.format(self.version()))
|
||||
network_template_file_path = os.path.join(data_dir, f'network_template_v{self.version()}.json')
|
||||
|
||||
f = open(network_template_file_path)
|
||||
o_part = json.load(f)
|
||||
@ -138,11 +138,11 @@ class Network(Data):
|
||||
|
||||
def __str__(self):
|
||||
s = ''
|
||||
for k in self.resources.keys():
|
||||
for kk in self.resources[k]['contents'].keys():
|
||||
v = self.resources[k]['contents'][kk]
|
||||
if v == None:
|
||||
v = ''
|
||||
s += '{}.{} = {}\n'.format(k, kk, v)
|
||||
for resource in self.resources.keys():
|
||||
for content_key in self.resources[resource]['contents'].keys():
|
||||
content_value = self.resources[resource]['contents'][content_key]
|
||||
if content_value == None:
|
||||
content_value = ''
|
||||
s += f'{resource}.{content_key} = {content_value}\n'
|
||||
|
||||
return s
|
||||
|
118
cic/proof.py
118
cic/proof.py
@ -33,34 +33,40 @@ class Proof(Data):
|
||||
:type writer: cic.output.OutputWriter
|
||||
"""
|
||||
|
||||
def __init__(self, path='.', attachments=None, writer=None):
|
||||
def __init__(
|
||||
self,
|
||||
path=".",
|
||||
description=None,
|
||||
namespace="ge",
|
||||
issuer=None,
|
||||
attachments=None,
|
||||
writer=None,
|
||||
):
|
||||
super(Proof, self).__init__()
|
||||
self.proofs = []
|
||||
self.namespace = 'ge'
|
||||
self.description = None
|
||||
self.issuer = None
|
||||
self.namespace = namespace
|
||||
self.description = description
|
||||
self.issuer = issuer
|
||||
self.path = path
|
||||
self.writer = writer
|
||||
self.extra_attachments = attachments
|
||||
self.attachments = {}
|
||||
self.proof_path = os.path.join(self.path, 'proof.json')
|
||||
self.proof_path = os.path.join(self.path, "proof.json")
|
||||
self.temp_proof_path = tempfile.mkstemp()[1]
|
||||
|
||||
|
||||
def load(self):
|
||||
"""Load proof data from settings.
|
||||
"""
|
||||
"""Load proof data from settings."""
|
||||
super(Proof, self).load()
|
||||
|
||||
f = open(self.proof_path, 'r')
|
||||
f = open(self.proof_path, "r")
|
||||
o = json.load(f)
|
||||
f.close()
|
||||
|
||||
self.set_version(o['version'])
|
||||
self.description = o['description']
|
||||
self.namespace = o['namespace']
|
||||
self.issuer = o['issuer']
|
||||
self.proofs = o['proofs']
|
||||
self.set_version(o["version"])
|
||||
self.description = o["description"]
|
||||
self.namespace = o["namespace"]
|
||||
self.issuer = o["issuer"]
|
||||
self.proofs = o["proofs"]
|
||||
|
||||
if self.extra_attachments != None:
|
||||
a = self.extra_attachments.asdict()
|
||||
@ -72,34 +78,33 @@ class Proof(Data):
|
||||
|
||||
self.inited = True
|
||||
|
||||
|
||||
def start(self):
|
||||
"""Initialize proof settings from template.
|
||||
"""
|
||||
"""Initialize proof settings from template."""
|
||||
super(Proof, self).start()
|
||||
|
||||
proof_template_file_path = os.path.join(data_dir, 'proof_template_v{}.json'.format(self.version()))
|
||||
proof_template_file_path = os.path.join(
|
||||
data_dir, "proof_template_v{}.json".format(self.version())
|
||||
)
|
||||
|
||||
f = open(proof_template_file_path)
|
||||
o = json.load(f)
|
||||
f.close()
|
||||
|
||||
f = open(self.proof_path, 'w')
|
||||
o["issuer"] = self.issuer
|
||||
o["description"] = self.description
|
||||
o["namespace"] = self.namespace
|
||||
f = open(self.proof_path, "w")
|
||||
json.dump(o, f, sort_keys=True, indent="\t")
|
||||
f.close()
|
||||
|
||||
|
||||
def asdict(self):
|
||||
"""Output proof state to dict.
|
||||
"""
|
||||
"""Output proof state to dict."""
|
||||
return {
|
||||
'version': self.version(),
|
||||
'namespace': self.namespace,
|
||||
'description': self.description,
|
||||
'issuer': self.issuer,
|
||||
'proofs': self.proofs,
|
||||
}
|
||||
|
||||
"version": self.version(),
|
||||
"namespace": self.namespace,
|
||||
"description": self.description,
|
||||
"issuer": self.issuer,
|
||||
"proofs": self.proofs,
|
||||
}
|
||||
|
||||
# TODO: the efficiency of this method could probably be improved.
|
||||
def __get_ordered_hashes(self):
|
||||
@ -108,30 +113,26 @@ class Proof(Data):
|
||||
|
||||
return ks
|
||||
|
||||
|
||||
# def get(self):
|
||||
# hsh = self.hash(b).hex()
|
||||
# self.attachments[hsh] = self.temp_proof_path
|
||||
# logg.debug('cbor of {} is {} hashes to {}'.format(v, b.hex(), hsh))
|
||||
|
||||
# def get(self):
|
||||
# hsh = self.hash(b).hex()
|
||||
# self.attachments[hsh] = self.temp_proof_path
|
||||
# logg.debug('cbor of {} is {} hashes to {}'.format(v, b.hex(), hsh))
|
||||
|
||||
def root(self):
|
||||
"""Calculate the root digest from the serialized proof object.
|
||||
"""
|
||||
"""Calculate the root digest from the serialized proof object."""
|
||||
v = self.asdict()
|
||||
#b = cbor2.dumps(v)
|
||||
# b = cbor2.dumps(v)
|
||||
b = json.dumps(v)
|
||||
|
||||
f = open(self.temp_proof_path, 'w')
|
||||
f = open(self.temp_proof_path, "w")
|
||||
f.write(b)
|
||||
f.close()
|
||||
|
||||
b = b.encode('utf-8')
|
||||
b = b.encode("utf-8")
|
||||
k = self.hash(b)
|
||||
|
||||
return (k.hex(), b)
|
||||
|
||||
|
||||
def process(self, token_address=None, token_symbol=None, writer=None):
|
||||
"""Serialize and publish proof.
|
||||
|
||||
@ -144,38 +145,39 @@ class Proof(Data):
|
||||
writer.write(k, v)
|
||||
root_key = k
|
||||
|
||||
token_symbol_bytes = token_symbol.encode('utf-8')
|
||||
k = generate_metadata_pointer(token_symbol_bytes, MetadataPointer.TOKEN_PROOF_SYMBOL)
|
||||
token_symbol_bytes = token_symbol.encode("utf-8")
|
||||
k = generate_metadata_pointer(
|
||||
token_symbol_bytes, MetadataPointer.TOKEN_PROOF_SYMBOL
|
||||
)
|
||||
writer.write(k, v)
|
||||
|
||||
token_address_bytes = bytes.fromhex(strip_0x(token_address))
|
||||
k = generate_metadata_pointer(token_address_bytes, MetadataPointer.TOKEN_PROOF)
|
||||
writer.write(k, v)
|
||||
|
||||
# (hsh, hshs) = self.get()
|
||||
#hshs = list(map(strip_0x, hshs))
|
||||
# hshs_bin = list(map(bytes.fromhex, hshs))
|
||||
# hshs_cat = b''.join(hshs_bin)
|
||||
# (hsh, hshs) = self.get()
|
||||
# hshs = list(map(strip_0x, hshs))
|
||||
# hshs_bin = list(map(bytes.fromhex, hshs))
|
||||
# hshs_cat = b''.join(hshs_bin)
|
||||
|
||||
# f = open(self.temp_proof_path, 'rb')
|
||||
# v = f.read()
|
||||
# f.close()
|
||||
# writer.write(hsh, v)
|
||||
# f = open(self.temp_proof_path, 'rb')
|
||||
# v = f.read()
|
||||
# f.close()
|
||||
# writer.write(hsh, v)
|
||||
|
||||
# r = self.hash(hshs_cat)
|
||||
# r_hex = r.hex()
|
||||
# r = self.hash(hshs_cat)
|
||||
# r_hex = r.hex()
|
||||
|
||||
#logg.debug('generated proof {} for hashes {}'.format(r_hex, hshs))
|
||||
# logg.debug('generated proof {} for hashes {}'.format(r_hex, hshs))
|
||||
|
||||
#writer.write(r_hex, hshs_cat)
|
||||
# writer.write(r_hex, hshs_cat)
|
||||
|
||||
o = self.asdict()
|
||||
f = open(self.proof_path, 'w')
|
||||
f = open(self.proof_path, "w")
|
||||
json.dump(o, f, sort_keys=True, indent="\t")
|
||||
f.close()
|
||||
|
||||
return root_key
|
||||
|
||||
|
||||
def __str__(self):
|
||||
return "description = {}\n".format(self.description)
|
||||
|
@ -11,6 +11,7 @@ import cic.cmd.init as cmd_init
|
||||
import cic.cmd.show as cmd_show
|
||||
import cic.cmd.ext as cmd_ext
|
||||
import cic.cmd.export as cmd_export
|
||||
import cic.cmd.easy as cmd_easy
|
||||
|
||||
logging.basicConfig(level=logging.WARNING)
|
||||
logg = logging.getLogger()
|
||||
@ -34,6 +35,8 @@ cmd_export.process_args(sub_export)
|
||||
sub_ext = sub.add_parser('ext', help='extension helpers')
|
||||
cmd_ext.process_args(sub_ext)
|
||||
|
||||
sub_easy = sub.add_parser('easy', help='Easy Mode Contract Deployment')
|
||||
cmd_easy.process_args(sub_easy)
|
||||
|
||||
args = argparser.parse_args(sys.argv[1:])
|
||||
|
||||
|
82
cic/token.py
82
cic/token.py
@ -1,12 +1,9 @@
|
||||
# standard imports
|
||||
import os
|
||||
import json
|
||||
import os
|
||||
|
||||
# local imports
|
||||
from .base import (
|
||||
Data,
|
||||
data_dir,
|
||||
)
|
||||
from .base import Data, data_dir
|
||||
|
||||
|
||||
class Token(Data):
|
||||
@ -27,40 +24,49 @@ class Token(Data):
|
||||
:param code: Bytecode for token chain application
|
||||
:type code: str (hex)
|
||||
"""
|
||||
def __init__(self, path='.', name=None, symbol=None, precision=1, supply=0, code=None):
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
path=".",
|
||||
name=None,
|
||||
symbol=None,
|
||||
precision=1,
|
||||
supply=0,
|
||||
code=None,
|
||||
extra_args=[],
|
||||
extra_args_types=[],
|
||||
):
|
||||
super(Token, self).__init__()
|
||||
self.name = name
|
||||
self.symbol = symbol
|
||||
self.supply = supply
|
||||
self.precision = precision
|
||||
self.code = code
|
||||
self.extra_args: list = []
|
||||
self.extra_args_types: list = []
|
||||
self.extra_args = extra_args
|
||||
self.extra_args_types = extra_args_types
|
||||
self.path = path
|
||||
self.token_path = os.path.join(self.path, 'token.json')
|
||||
|
||||
self.token_path = os.path.join(self.path, "token.json")
|
||||
|
||||
def load(self):
|
||||
"""Load token data from settings.
|
||||
"""
|
||||
"""Load token data from settings."""
|
||||
super(Token, self).load()
|
||||
|
||||
f = open(self.token_path, 'r')
|
||||
f = open(self.token_path, "r")
|
||||
o = json.load(f)
|
||||
f.close()
|
||||
|
||||
self.name = o['name']
|
||||
self.symbol = o['symbol']
|
||||
self.precision = o['precision']
|
||||
self.code = o['code']
|
||||
self.supply = o['supply']
|
||||
self.name = o["name"]
|
||||
self.symbol = o["symbol"]
|
||||
self.precision = o["precision"]
|
||||
self.code = o["code"]
|
||||
self.supply = o["supply"]
|
||||
extras = []
|
||||
extra_types = []
|
||||
token_extras: list = o['extra']
|
||||
token_extras: list = o["extra"]
|
||||
if token_extras:
|
||||
for token_extra in token_extras:
|
||||
arg = token_extra.get('arg')
|
||||
arg_type = token_extra.get('arg_type')
|
||||
arg = token_extra.get("arg")
|
||||
arg_type = token_extra.get("arg_type")
|
||||
if arg:
|
||||
extras.append(arg)
|
||||
if arg_type:
|
||||
@ -69,32 +75,40 @@ class Token(Data):
|
||||
self.extra_args_types = extra_types
|
||||
self.inited = True
|
||||
|
||||
|
||||
def start(self):
|
||||
"""Initialize token settings from arguments passed to the constructor and/or template.
|
||||
"""
|
||||
"""Initialize token settings from arguments passed to the constructor and/or template."""
|
||||
super(Token, self).load()
|
||||
|
||||
token_template_file_path = os.path.join(data_dir, 'token_template_v{}.json'.format(self.version()))
|
||||
token_template_file_path = os.path.join(
|
||||
data_dir, "token_template_v{}.json".format(self.version())
|
||||
)
|
||||
|
||||
f = open(token_template_file_path)
|
||||
o = json.load(f)
|
||||
f.close()
|
||||
o["name"] = self.name
|
||||
o["symbol"] = self.symbol
|
||||
o["precision"] = self.precision
|
||||
o["code"] = self.code
|
||||
o["supply"] = self.supply
|
||||
extra = []
|
||||
for i in range(len(self.extra_args)):
|
||||
extra.append(
|
||||
{"arg": self.extra_args[i], "arg_type": self.extra_args_types[i]}
|
||||
)
|
||||
if len(extra):
|
||||
o["extra"] = extra
|
||||
print(extra)
|
||||
|
||||
o['name'] = self.name
|
||||
o['symbol'] = self.symbol
|
||||
o['precision'] = self.precision
|
||||
o['code'] = self.code
|
||||
o['supply'] = self.supply
|
||||
|
||||
f = open(self.token_path, 'w')
|
||||
f = open(self.token_path, "w")
|
||||
json.dump(o, f, sort_keys=True, indent="\t")
|
||||
f.close()
|
||||
|
||||
|
||||
def __str__(self):
|
||||
s = """name = {}
|
||||
symbol = {}
|
||||
precision = {}
|
||||
""".format(self.name, self.symbol, self.precision)
|
||||
""".format(
|
||||
self.name, self.symbol, self.precision
|
||||
)
|
||||
return s
|
||||
|
@ -3,3 +3,4 @@ cic-types~=0.2.1a5
|
||||
confini~=0.5.1
|
||||
chainlib~=0.0.13
|
||||
cbor2==5.4.1
|
||||
click==8.0.3
|
Loading…
Reference in New Issue
Block a user