1
1
import subprocess
2
2
import os
3
+ import yaml # use yaml instead of json to get non unicode
3
4
4
5
5
6
class CompileError (Exception ):
@@ -35,7 +36,8 @@ def split_contracts(cls, code):
35
36
contracts = []
36
37
contract = None
37
38
for line in code .split ('\n ' ):
38
- if line .lstrip ().startswith ('contract ' ): # FIXME
39
+ line = line .lstrip ()
40
+ if line .startswith ('contract ' ): # FIXME
39
41
if contract :
40
42
contracts .append ('\n ' .join (contract ))
41
43
contract = [line ]
@@ -46,25 +48,38 @@ def split_contracts(cls, code):
46
48
return contracts
47
49
48
50
@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
55
58
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' )
58
64
59
65
@classmethod
60
66
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' ],
62
74
stdin = subprocess .PIPE , stdout = subprocess .PIPE )
63
75
stdoutdata , stderrdata = p .communicate (input = code )
64
76
if p .returncode :
65
77
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
68
83
69
84
70
85
def get_solidity ():
0 commit comments