|
@@ -20,18 +20,18 @@
|
|
|
scripts/create-token.py: Automated ERC20 token creation for the MMGen suite
|
|
|
"""
|
|
|
|
|
|
-import sys,json,re
|
|
|
-from subprocess import run,PIPE
|
|
|
+import sys, json, re
|
|
|
+from subprocess import run, PIPE
|
|
|
from collections import namedtuple
|
|
|
|
|
|
import script_init
|
|
|
from mmgen.main import launch
|
|
|
from mmgen.cfg import Config
|
|
|
-from mmgen.util import Msg,msg,rmsg,ymsg,die
|
|
|
+from mmgen.util import Msg, msg, rmsg, ymsg, die
|
|
|
|
|
|
-ti = namedtuple('token_param_info',['default','conversion','test'])
|
|
|
+ti = namedtuple('token_param_info', ['default', 'conversion', 'test'])
|
|
|
class TokenData:
|
|
|
- fields = ('decimals','supply','name','symbol','owner_addr')
|
|
|
+ fields = ('decimals', 'supply', 'name', 'symbol', 'owner_addr')
|
|
|
decimals = ti('18', int, lambda s: s.isascii() and s.isdigit() and 0 < int(s) <= 36)
|
|
|
name = ti(None, str, lambda s: s.isascii() and s.isprintable() and len(s) < 256)
|
|
|
supply = ti(None, int, lambda s: s.isascii() and s.isdigit() and 0 < int(s) < 2**256)
|
|
@@ -186,25 +186,25 @@ contract Token is ERC20Interface, Owned, SafeMath {
|
|
|
}
|
|
|
""" % req_solc_ver_pat
|
|
|
|
|
|
-def create_src(cfg,template,token_data):
|
|
|
+def create_src(cfg, template, token_data):
|
|
|
|
|
|
def gen():
|
|
|
for k in token_data.fields:
|
|
|
- field = getattr(token_data,k)
|
|
|
+ field = getattr(token_data, k)
|
|
|
if k == 'owner_addr':
|
|
|
owner_addr = cfg._args[0]
|
|
|
from mmgen.addr import is_coin_addr
|
|
|
- if not is_coin_addr( cfg._proto, owner_addr.lower() ):
|
|
|
- die(1,f'{owner_addr}: not a valid {cfg._proto.coin} coin address')
|
|
|
+ if not is_coin_addr(cfg._proto, owner_addr.lower()):
|
|
|
+ die(1, f'{owner_addr}: not a valid {cfg._proto.coin} coin address')
|
|
|
val = '0x' + owner_addr
|
|
|
else:
|
|
|
val = (
|
|
|
- getattr(cfg,k)
|
|
|
- or getattr(field,'default',None)
|
|
|
- or die(1,f'The --{k} option must be specified')
|
|
|
+ getattr(cfg, k)
|
|
|
+ or getattr(field, 'default', None)
|
|
|
+ or die(1, f'The --{k} option must be specified')
|
|
|
)
|
|
|
if not field.test(val):
|
|
|
- die(1,f'{val!r}: invalid parameter for option --{k}')
|
|
|
+ die(1, f'{val!r}: invalid parameter for option --{k}')
|
|
|
|
|
|
yield (k, field.conversion(val))
|
|
|
|
|
@@ -216,7 +216,7 @@ def check_solc_version():
|
|
|
The output is used by other programs, so write to stdout only
|
|
|
"""
|
|
|
try:
|
|
|
- cp = run(['solc','--version'],check=True,stdout=PIPE)
|
|
|
+ cp = run(['solc', '--version'], check=True, stdout=PIPE)
|
|
|
except:
|
|
|
msg('solc missing or could not be executed') # this must go to stderr
|
|
|
return False
|
|
@@ -226,14 +226,14 @@ def check_solc_version():
|
|
|
return False
|
|
|
|
|
|
line = cp.stdout.decode().splitlines()[1]
|
|
|
- version_str = re.sub(r'Version:\s*','',line)
|
|
|
- m = re.match(r'(\d+)\.(\d+)\.(\d+)',version_str)
|
|
|
+ version_str = re.sub(r'Version:\s*', '', line)
|
|
|
+ m = re.match(r'(\d+)\.(\d+)\.(\d+)', version_str)
|
|
|
|
|
|
if not m:
|
|
|
Msg(f'Unrecognized solc version string: {version_str}')
|
|
|
return False
|
|
|
|
|
|
- from semantic_version import Version,NpmSpec
|
|
|
+ from semantic_version import Version, NpmSpec
|
|
|
version = Version('{}.{}.{}'.format(*m.groups()))
|
|
|
|
|
|
if version in NpmSpec(req_solc_ver_pat):
|
|
@@ -243,25 +243,25 @@ def check_solc_version():
|
|
|
Msg(f'solc version ({version_str}) does not match requirement ({req_solc_ver_pat})')
|
|
|
return False
|
|
|
|
|
|
-def compile_code(cfg,code):
|
|
|
+def compile_code(cfg, code):
|
|
|
cmd = ['solc', '--optimize', '--bin', '--overwrite', '--evm-version=constantinople']
|
|
|
if not cfg.stdout:
|
|
|
cmd += ['--output-dir', cfg.outdir or '.']
|
|
|
cmd += ['-']
|
|
|
msg(f"Executing: {' '.join(cmd)}")
|
|
|
- cp = run(cmd,input=code.encode(),stdout=PIPE,stderr=PIPE)
|
|
|
- out = cp.stdout.decode().replace('\r','')
|
|
|
- err = cp.stderr.decode().replace('\r','').strip()
|
|
|
+ cp = run(cmd, input=code.encode(), stdout=PIPE, stderr=PIPE)
|
|
|
+ out = cp.stdout.decode().replace('\r', '')
|
|
|
+ err = cp.stderr.decode().replace('\r', '').strip()
|
|
|
if cp.returncode != 0:
|
|
|
rmsg('Solidity compiler produced the following error:')
|
|
|
msg(err)
|
|
|
- die(4,f'Solidity compiler exited with error (return val: {cp.returncode})')
|
|
|
+ die(4, f'Solidity compiler exited with error (return val: {cp.returncode})')
|
|
|
if err:
|
|
|
ymsg('Solidity compiler produced the following warning:')
|
|
|
msg(err)
|
|
|
if cfg.stdout:
|
|
|
o = out.split('\n')
|
|
|
- return {k:o[i+2] for k in ('SafeMath','Owned','Token') for i in range(len(o)) if k in o[i]}
|
|
|
+ return {k:o[i+2] for k in ('SafeMath', 'Owned', 'Token') for i in range(len(o)) if k in o[i]}
|
|
|
else:
|
|
|
cfg._util.vmsg(out)
|
|
|
|
|
@@ -271,19 +271,19 @@ def main():
|
|
|
if cfg.check_solc_version:
|
|
|
sys.exit(0 if check_solc_version() else 1)
|
|
|
|
|
|
- if not cfg._proto.coin in ('ETH','ETC'):
|
|
|
- die(1,'--coin option must be ETH or ETC')
|
|
|
+ if not cfg._proto.coin in ('ETH', 'ETC'):
|
|
|
+ die(1, '--coin option must be ETH or ETC')
|
|
|
|
|
|
if not len(cfg._args) == 1:
|
|
|
cfg._usage()
|
|
|
|
|
|
- code = create_src( cfg, solidity_code_template, token_data )
|
|
|
+ code = create_src(cfg, solidity_code_template, token_data)
|
|
|
|
|
|
if cfg.preprocess:
|
|
|
Msg(code)
|
|
|
sys.exit(0)
|
|
|
|
|
|
- out = compile_code( cfg, code )
|
|
|
+ out = compile_code(cfg, code)
|
|
|
|
|
|
if cfg.stdout:
|
|
|
print(json.dumps(out))
|