@@ -37,9 +37,9 @@ def contract_names(cls, code):
37
37
return re .findall (r'^\s*(contract|library) (\S*) ' , code , re .MULTILINE )
38
38
39
39
@classmethod
40
- def compile (cls , code , libraries = None , contract_name = '' ):
40
+ def compile (cls , code , path = None , libraries = None , contract_name = '' ):
41
41
"returns binary of last contract in code"
42
- sorted_contracts = cls .combined (code )
42
+ sorted_contracts = cls .combined (code , path = path )
43
43
if contract_name :
44
44
idx = [x [0 ] for x in sorted_contracts ].index (contract_name )
45
45
else :
@@ -48,24 +48,38 @@ def compile(cls, code, libraries=None, contract_name=''):
48
48
if cls .compiler_version () < "0.1.2" :
49
49
raise CompileError ('Compiler does not support libraries. Please update compiler.' )
50
50
for lib_name , lib_address in libraries .iteritems ():
51
- sorted_contracts [idx ][1 ]['bin' ] = sorted_contracts [idx ][1 ]['bin' ].replace ("__{}{}" .format (lib_name , "_" * (38 - len (lib_name ))), lib_address )
51
+ sorted_contracts [idx ][1 ]['bin' ] = sorted_contracts [idx ][1 ]['bin' ].replace (
52
+ "__{}{}" .format (lib_name , "_" * (38 - len (lib_name ))), lib_address )
52
53
return sorted_contracts [idx ][1 ]['bin' ].decode ('hex' )
53
54
54
55
@classmethod
55
- def mk_full_signature (cls , code , libraries = None , contract_name = '' ):
56
+ def mk_full_signature (cls , code , path = None , libraries = None , contract_name = '' ):
56
57
"returns signature of last contract in code"
57
- sorted_contracts = cls .combined (code )
58
+ sorted_contracts = cls .combined (code , path = path )
58
59
if contract_name :
59
60
idx = [x [0 ] for x in sorted_contracts ].index (contract_name )
60
61
else :
61
62
idx = - 1
62
63
return sorted_contracts [idx ][1 ]['abi' ]
63
64
64
65
@classmethod
65
- def combined (cls , code ):
66
- p = subprocess .Popen (['solc' , '--add-std' , '--optimize' , '--combined-json' , 'abi,bin,devdoc,userdoc' ],
67
- stdin = subprocess .PIPE , stdout = subprocess .PIPE )
68
- stdoutdata , stderrdata = p .communicate (input = code )
66
+ def combined (cls , code , path = None ):
67
+ """compile combined-json with abi,bin,devdoc,userdoc
68
+ @param code: literal solidity code as a string.
69
+ @param path: absolute path to solidity-file. Note: code & path are exclusive!
70
+ """
71
+ p = None
72
+ if path is None :
73
+ p = subprocess .Popen (['solc' , '--add-std' , '--optimize' , '--combined-json' , 'abi,bin,devdoc,userdoc' ],
74
+ stdin = subprocess .PIPE , stdout = subprocess .PIPE )
75
+ stdoutdata , stderrdata = p .communicate (input = code )
76
+ else :
77
+ assert code is None or len (code ) == 0 , "`code` and `path` are exclusive!"
78
+ workdir , fn = os .path .split (path )
79
+ p = subprocess .Popen (['solc' , '--add-std' , '--optimize' , '--combined-json' , 'abi,bin,devdoc,userdoc' , fn ],
80
+ stdout = subprocess .PIPE , cwd = workdir )
81
+ stdoutdata = p .stdout .read ().strip ()
82
+ p .terminate ()
69
83
if p .returncode :
70
84
raise CompileError ('compilation failed' )
71
85
# contracts = json.loads(stdoutdata)['contracts']
@@ -75,7 +89,7 @@ def combined(cls, code):
75
89
data ['devdoc' ] = yaml .safe_load (data ['devdoc' ])
76
90
data ['userdoc' ] = yaml .safe_load (data ['userdoc' ])
77
91
78
- names = cls .contract_names (code )
92
+ names = cls .contract_names (code or open ( path ). read () )
79
93
assert len (names ) <= len (contracts ) # imported contracts are not returned
80
94
sorted_contracts = []
81
95
for name in names :
@@ -90,7 +104,7 @@ def compiler_version(cls):
90
104
return match .group (1 )
91
105
92
106
@classmethod
93
- def compile_rich (cls , code ):
107
+ def compile_rich (cls , code , path = None ):
94
108
"""full format as returned by jsonrpc"""
95
109
96
110
return {
@@ -107,7 +121,7 @@ def compile_rich(cls, code):
107
121
},
108
122
}
109
123
for contract_name , contract
110
- in cls .combined (code )
124
+ in cls .combined (code , path = path )
111
125
}
112
126
113
127
0 commit comments