py3port: ERC20: support/require Solidity compiler version 0.5.3
This commit is contained in:
parent
61b4f5a07a
commit
fb07b089be
2 changed files with 52 additions and 39 deletions
|
|
@ -16,7 +16,7 @@
|
|||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import sys,os,json
|
||||
import sys,os,json,re
|
||||
from subprocess import Popen,PIPE
|
||||
from mmgen.common import *
|
||||
from mmgen.obj import CoinAddr,is_coin_addr
|
||||
|
|
@ -25,6 +25,7 @@ decimals = 18
|
|||
supply = 10**26
|
||||
name = 'MMGen Token'
|
||||
symbol = 'MMT'
|
||||
solc_version = '0.5.3'
|
||||
|
||||
opts_data = lambda: {
|
||||
'desc': 'Create an ERC20 token contract',
|
||||
|
|
@ -37,21 +38,24 @@ opts_data = lambda: {
|
|||
-t, --supply= t Total supply of the token (default: {t})
|
||||
-s, --symbol= s Token symbol (default: {s})
|
||||
-S, --stdout Output data in JSON format to stdout instead of files
|
||||
-v, --verbose Produce more verbose output
|
||||
""".format(d=decimals,n=name,s=symbol,t=supply)
|
||||
}
|
||||
|
||||
cmd_args = opts.init(opts_data)
|
||||
assert g.coin in ('ETH','ETC'),'--coin option must be set to ETH or ETC'
|
||||
|
||||
if not len(cmd_args) == 1 or not is_coin_addr(cmd_args[0]):
|
||||
if not len(cmd_args) == 1 or not is_coin_addr(cmd_args[0].lower()):
|
||||
opts.usage()
|
||||
|
||||
owner_addr = '0x' + CoinAddr(cmd_args[0])
|
||||
owner_addr = '0x' + cmd_args[0]
|
||||
|
||||
# ERC Token Standard #20 Interface
|
||||
# https://github.com/ethereum/EIPs/blob/master/EIPS/eip-20-token-standard.md
|
||||
|
||||
code_in = """
|
||||
pragma solidity ^0.4.18;
|
||||
|
||||
pragma solidity >0.5.2 <0.5.4;
|
||||
|
||||
contract SafeMath {
|
||||
function safeAdd(uint a, uint b) public pure returns (uint c) {
|
||||
|
|
@ -73,9 +77,9 @@ contract SafeMath {
|
|||
}
|
||||
|
||||
contract ERC20Interface {
|
||||
function totalSupply() public constant returns (uint);
|
||||
function balanceOf(address tokenOwner) public constant returns (uint balance);
|
||||
function allowance(address tokenOwner, address spender) public constant returns (uint remaining);
|
||||
function totalSupply() public returns (uint);
|
||||
function balanceOf(address tokenOwner) public returns (uint balance);
|
||||
function allowance(address tokenOwner, address spender) public returns (uint remaining);
|
||||
function transfer(address to, uint tokens) public returns (bool success);
|
||||
function approve(address spender, uint tokens) public returns (bool success);
|
||||
function transferFrom(address from, address to, uint tokens) public returns (bool success);
|
||||
|
|
@ -84,11 +88,6 @@ contract ERC20Interface {
|
|||
event Approval(address indexed tokenOwner, address indexed spender, uint tokens);
|
||||
}
|
||||
|
||||
// Contract function to receive approval and execute function in one call
|
||||
contract ApproveAndCallFallBack {
|
||||
function receiveApproval(address from, uint256 tokens, address token, bytes data) public;
|
||||
}
|
||||
|
||||
contract Owned {
|
||||
address public owner;
|
||||
address public newOwner;
|
||||
|
|
@ -136,10 +135,10 @@ contract Token is ERC20Interface, Owned, SafeMath {
|
|||
balances[<OWNER_ADDR>] = _totalSupply;
|
||||
emit Transfer(address(0), <OWNER_ADDR>, _totalSupply);
|
||||
}
|
||||
function totalSupply() public constant returns (uint) {
|
||||
function totalSupply() public returns (uint) {
|
||||
return _totalSupply - balances[address(0)];
|
||||
}
|
||||
function balanceOf(address tokenOwner) public constant returns (uint balance) {
|
||||
function balanceOf(address tokenOwner) public returns (uint balance) {
|
||||
return balances[tokenOwner];
|
||||
}
|
||||
function transfer(address to, uint tokens) public returns (bool success) {
|
||||
|
|
@ -160,19 +159,9 @@ contract Token is ERC20Interface, Owned, SafeMath {
|
|||
emit Transfer(from, to, tokens);
|
||||
return true;
|
||||
}
|
||||
function allowance(address tokenOwner, address spender) public constant returns (uint remaining) {
|
||||
function allowance(address tokenOwner, address spender) public returns (uint remaining) {
|
||||
return allowed[tokenOwner][spender];
|
||||
}
|
||||
function approveAndCall(address spender, uint tokens, bytes data) public returns (bool success) {
|
||||
allowed[msg.sender][spender] = tokens;
|
||||
emit Approval(msg.sender, spender, tokens);
|
||||
ApproveAndCallFallBack(spender).receiveApproval(msg.sender, tokens, this, data);
|
||||
return true;
|
||||
}
|
||||
// Don't accept ETH
|
||||
function () public payable {
|
||||
revert();
|
||||
}
|
||||
// Owner can transfer out any accidentally sent ERC20 tokens
|
||||
function transferAnyERC20Token(address tokenAddress, uint tokens) public onlyOwner returns (bool success) {
|
||||
return ERC20Interface(tokenAddress).transfer(owner, tokens);
|
||||
|
|
@ -181,20 +170,42 @@ contract Token is ERC20Interface, Owned, SafeMath {
|
|||
"""
|
||||
|
||||
def create_src(code):
|
||||
for k in ('decimals','supply','name','symbol','owner_addr'):
|
||||
for k in ('decimals','supply','name','symbol','owner_addr','solc_version'):
|
||||
if hasattr(opt,k) and getattr(opt,k): globals()[k] = getattr(opt,k)
|
||||
code = code.replace('<{}>'.format(k.upper()),str(globals()[k]))
|
||||
return code
|
||||
|
||||
def check_version():
|
||||
p = Popen(['solc','--version'],stdout=PIPE)
|
||||
res = p.stdout.read().decode()
|
||||
ver = re.search(r'Version:\s*(.*)',res).group(1)
|
||||
msg("Installed solc version: {}".format(ver))
|
||||
if not re.search(r'{}\b'.format(solc_version),ver):
|
||||
ydie(1,'Incorrect Solidity compiler version (need version {})'.format(solc_version))
|
||||
|
||||
def compile_code(code):
|
||||
check_version()
|
||||
cmd = ['solc','--optimize','--bin','--overwrite']
|
||||
if not opt.stdout: cmd += ['--output-dir', opt.outdir or '.']
|
||||
cmd += ['-']
|
||||
msg('Executing: {}'.format(' '.join(cmd)))
|
||||
p = Popen(cmd,stdin=PIPE,stdout=PIPE,stderr=PIPE)
|
||||
res = p.communicate(code.encode())
|
||||
o = res[0].decode().replace('\r','').split('\n')
|
||||
dmsg(res[1])
|
||||
out = res[0].decode().replace('\r','')
|
||||
err = res[1].decode().replace('\r','').strip()
|
||||
rc = p.wait()
|
||||
if rc != 0:
|
||||
rmsg('Solidity compiler produced the following error:')
|
||||
msg(err)
|
||||
rdie(2,'Solidity compiler exited with error (return val: {})'.format(rc))
|
||||
if err:
|
||||
ymsg('Solidity compiler produced the following warning:')
|
||||
msg(err)
|
||||
if opt.stdout:
|
||||
o = out.split('\n')
|
||||
return dict((k,o[i+2]) for k in ('SafeMath','Owned','Token') for i in range(len(o)) if k in o[i])
|
||||
else:
|
||||
vmsg(out)
|
||||
|
||||
src = create_src(code_in)
|
||||
out = compile_code(src)
|
||||
|
|
|
|||
24
test/test.py
24
test/test.py
|
|
@ -133,6 +133,7 @@ opts_data = lambda: {
|
|||
--, --longhelp Print help message for long options (common options)
|
||||
-B, --bech32 Generate and use Bech32 addresses
|
||||
-b, --buf-keypress Use buffered keypresses as with real human input
|
||||
(often required on slow systems, or under emulation)
|
||||
-c, --print-cmdline Print the command line of each spawned command
|
||||
-C, --coverage Produce code coverage info using trace module
|
||||
-x, --debug-pexpect Produce debugging output for pexpect calls
|
||||
|
|
@ -635,6 +636,7 @@ dfl_words = os.path.join(ref_dir,cfgs['8']['seed_id']+'.mmwords')
|
|||
|
||||
# The Parity dev address with lots of coins. Create with "ethkey -b info ''":
|
||||
eth_addr = '00a329c0648769a73afac7f9381e08fb43dbea72'
|
||||
eth_addr_chk = '00a329c0648769A73afAc7F9381E08FB43dBEA72'
|
||||
eth_key = '4d5db4107d237df6a3d58ee5f70ae63d73d7658d4026f2eefd2f204c81682cb7'
|
||||
eth_burn_addr = 'deadbeef'*5
|
||||
eth_amt1 = '999999.12345689012345678'
|
||||
|
|
@ -655,31 +657,31 @@ eth_bals = {
|
|||
(eth_burn_addr + '\s+Non-MMGen',eth_amt1)],
|
||||
'8': [ ('98831F3A:E:1','0'),
|
||||
('98831F3A:E:2','23.45495'),
|
||||
('98831F3A:E:11','1.2288376','a'),
|
||||
('98831F3A:E:11','1.2288487','a'),
|
||||
('98831F3A:E:12','99.99895'),
|
||||
('98831F3A:E:21','2.345'),
|
||||
(eth_burn_addr + '\s+Non-MMGen',eth_amt1)],
|
||||
'9': [ ('98831F3A:E:1','0'),
|
||||
('98831F3A:E:2','23.45495'),
|
||||
('98831F3A:E:11','1.2288376','a'),
|
||||
('98831F3A:E:12','99.997087072'),
|
||||
('98831F3A:E:11','1.2288487','a'),
|
||||
('98831F3A:E:12','99.997092733'),
|
||||
('98831F3A:E:21','2.345'),
|
||||
(eth_burn_addr + '\s+Non-MMGen',eth_amt1)]
|
||||
}
|
||||
eth_token_bals = {
|
||||
'1': [ ('98831F3A:E:11','1000','1.234')],
|
||||
'2': [ ('98831F3A:E:11','998.76544','1.2314236','a'),
|
||||
'2': [ ('98831F3A:E:11','998.76544','1.23142915','a'),
|
||||
('98831F3A:E:12','1.23456','0')],
|
||||
'3': [ ('98831F3A:E:11','110.654317776666555545','1.2288376','a'),
|
||||
'3': [ ('98831F3A:E:11','110.654317776666555545','1.2288487','a'),
|
||||
('98831F3A:E:12','1.23456','0')],
|
||||
'4': [ ('98831F3A:E:11','110.654317776666555545','1.2288376','a'),
|
||||
'4': [ ('98831F3A:E:11','110.654317776666555545','1.2288487','a'),
|
||||
('98831F3A:E:12','1.23456','0'),
|
||||
(eth_burn_addr + '\s+Non-MMGen',eth_amt2,eth_amt1)],
|
||||
'5': [ ('98831F3A:E:11','110.654317776666555545','1.2288376','a'),
|
||||
'5': [ ('98831F3A:E:11','110.654317776666555545','1.2288487','a'),
|
||||
('98831F3A:E:12','1.23456','99.99895'),
|
||||
(eth_burn_addr + '\s+Non-MMGen',eth_amt2,eth_amt1)],
|
||||
'6': [ ('98831F3A:E:11','110.654317776666555545','1.2288376','a'),
|
||||
('98831F3A:E:12','0','99.997087072'),
|
||||
'6': [ ('98831F3A:E:11','110.654317776666555545','1.2288487','a'),
|
||||
('98831F3A:E:12','0','99.997092733'),
|
||||
('98831F3A:E:13','1.23456','0'),
|
||||
(eth_burn_addr + '\s+Non-MMGen',eth_amt2,eth_amt1)]
|
||||
}
|
||||
|
|
@ -3523,7 +3525,7 @@ class MMGenTestSuite(object):
|
|||
MMGenExpect(name,'',msg_only=True)
|
||||
cmd_args = ['--{}={}'.format(k,v) for k,v in list(token_data.items())]
|
||||
imsg("Compiling solidity token contract '{}' with 'solc'".format(token_data['symbol']))
|
||||
cmd = ['scripts/create-token.py','--coin='+g.coin,'--outdir='+cfg['tmpdir']] + cmd_args + [eth_addr]
|
||||
cmd = ['scripts/create-token.py','--coin='+g.coin,'--outdir='+cfg['tmpdir']] + cmd_args + [eth_addr_chk]
|
||||
imsg("Executing: {}".format(' '.join(cmd)))
|
||||
subprocess.check_output(cmd,stderr=subprocess.STDOUT)
|
||||
imsg("ERC20 token '{}' compiled".format(token_data['symbol']))
|
||||
|
|
@ -3685,7 +3687,7 @@ class MMGenTestSuite(object):
|
|||
t.ok()
|
||||
|
||||
def ethdev_bal1_getbalance(self,name,t_non_mmgen='',t_mmgen=''):
|
||||
ebal = Decimal('127.0287876')
|
||||
ebal = Decimal('127.0287987')
|
||||
if g.coin == 'ETC': ebal += self.bal_corr
|
||||
self.ethdev_bal_getbalance(name,t_non_mmgen='999999.12345689012345678',t_mmgen=str(ebal))
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue