Skip to content
This repository was archived by the owner on May 23, 2023. It is now read-only.

Commit c61d2da

Browse files
committed
use solc --combined and robustness
1 parent 35b0530 commit c61d2da

File tree

3 files changed

+34
-31
lines changed

3 files changed

+34
-31
lines changed

ethereum/_solidity.py

Lines changed: 27 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import subprocess
22
import os
3+
import yaml # use yaml instead of json to get non unicode
34

45

56
class CompileError(Exception):
@@ -35,7 +36,8 @@ def split_contracts(cls, code):
3536
contracts = []
3637
contract = None
3738
for line in code.split('\n'):
38-
if line.lstrip().startswith('contract '): # FIXME
39+
line = line.lstrip()
40+
if line.startswith('contract '): # FIXME
3941
if contract:
4042
contracts.append('\n'.join(contract))
4143
contract = [line]
@@ -46,25 +48,38 @@ def split_contracts(cls, code):
4648
return contracts
4749

4850
@classmethod
49-
def compile(cls, code):
50-
p = subprocess.Popen(['solc', '--binary', 'stdout'],
51-
stdin=subprocess.PIPE, stdout=subprocess.PIPE)
52-
stdoutdata, stderrdata = p.communicate(input=code)
53-
if p.returncode:
54-
raise CompileError('compilation failed')
51+
def contract_names(cls, code):
52+
names = []
53+
for contract in cls.split_contracts(code):
54+
keyword, name, _ = contract.split(' ', 2)
55+
assert keyword == 'contract' and len(name)
56+
names.append(name)
57+
return names
5558

56-
hex_code = stdoutdata.rsplit('Binary: \n')[-1].strip()
57-
return hex_code.decode('hex')
59+
@classmethod
60+
def compile(cls, code):
61+
"returns binary of last contract in code"
62+
contracts = cls.combined(code)
63+
return contracts[cls.contract_names(code)[-1]]['binary'].decode('hex')
5864

5965
@classmethod
6066
def mk_full_signature(cls, code):
61-
p = subprocess.Popen(['solc', '--json-abi', 'stdout'],
67+
"returns signature of last contract in code"
68+
contracts = cls.combined(code)
69+
return contracts[cls.contract_names(code)[-1]]['json-abi']
70+
71+
@classmethod
72+
def combined(cls, code):
73+
p = subprocess.Popen(['solc', '--combined-json', 'json-abi,binary'],
6274
stdin=subprocess.PIPE, stdout=subprocess.PIPE)
6375
stdoutdata, stderrdata = p.communicate(input=code)
6476
if p.returncode:
6577
raise CompileError('compilation failed')
66-
jsonabi = stdoutdata.rsplit('Contract JSON ABI\n')[-1].strip()
67-
return jsonabi
78+
# contracts = json.loads(stdoutdata)['contracts']
79+
contracts = yaml.safe_load(stdoutdata)['contracts']
80+
for contract_name, data in contracts.items():
81+
data['json-abi'] = yaml.safe_load(data['json-abi'])
82+
return contracts
6883

6984

7085
def get_solidity():

ethereum/abi.py

Lines changed: 5 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,13 @@
11
import sys
22
import re
3-
import json
3+
import yaml # use yaml instead of json to get non unicode (works with ascii only data)
44
from ethereum import utils
55
from rlp.utils import decode_hex, encode_hex
66
from ethereum.utils import encode_int, zpad, big_endian_to_int, is_numeric, is_string
77

8-
if sys.version_info.major == 2:
9-
def json_decode(x):
10-
return json_non_unicode(json.loads(x))
118

12-
def json_non_unicode(x):
13-
if isinstance(x, unicode):
14-
return str(x)
15-
elif isinstance(x, list):
16-
return [json_non_unicode(y) for y in x]
17-
elif isinstance(x, dict):
18-
return {x: json_non_unicode(y) for x, y in x.items()}
19-
else:
20-
return x
21-
else:
22-
def json_decode(x):
23-
return json.loads(x)
9+
def json_decode(x):
10+
return yaml.safe_load(x)
2411

2512

2613
class ContractTranslator():
@@ -38,9 +25,9 @@ def __init__(self, full_signature):
3825
name = name[:name.find('(')]
3926
if name in v:
4027
i = 2
41-
while name + to_string(i) in v:
28+
while name + utils.to_string(i) in v:
4229
i += 1
43-
name += to_string(i)
30+
name += utils.to_string(i)
4431
sys.stderr.write("Warning: multiple methods with the same "
4532
" name. Use %s to call %s with types %r"
4633
% (name, sig_item['name'], encode_types))

ethereum/tests/test_solidity.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,11 +21,12 @@ def sub1():
2121
y = 7;
2222
}
2323
}
24-
2524
"""
2625

2726

2827
def test_interop():
28+
if 'solidity' not in tester.languages:
29+
return
2930
s = tester.state()
3031
c1 = s.abi_contract(serpent_contract)
3132
c2 = s.abi_contract(solidity_contract, language='solidity') # should be zoo

0 commit comments

Comments
 (0)