-
Notifications
You must be signed in to change notification settings - Fork 0
/
solidity.py
169 lines (137 loc) · 5.83 KB
/
solidity.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
#!/usr/bin/env python
#coding: utf8
import os, sys, json
BASE_PATH = os.path.dirname(os.path.abspath(__file__))
# Solc Compiler
SOLC = "solc"
build_dir = os.path.join(BASE_PATH, "build")
src_dir = os.path.join(BASE_PATH, "src")
dst_dir = os.path.join(BASE_PATH, "build/src")
bin_dir = os.path.join(BASE_PATH, "build/bin")
abi_dir = os.path.join(BASE_PATH, "build/abi")
ast_dir = os.path.join(BASE_PATH, "build/ast")
src_entry = os.path.join(src_dir, "main.sol")
def rmdir(path):
for root, dirs, files in os.walk(path, topdown=False):
for name in files:
os.remove(os.path.join(root, name))
for name in dirs:
os.rmdir(os.path.join(root, name))
os.rmdir(path)
def diff_path():
if not os.path.exists(build_dir):
os.mkdir(build_dir)
if not os.path.exists(dst_dir):
os.mkdir(dst_dir)
if not os.path.exists(bin_dir):
os.mkdir(bin_dir)
if not os.path.exists(abi_dir):
os.mkdir(abi_dir)
if not os.path.exists(ast_dir):
os.mkdir(ast_dir)
assert(os.path.exists(build_dir) and os.path.isdir(build_dir) )
assert(os.path.exists(src_dir) and os.path.isdir(src_dir) )
assert(os.path.exists(dst_dir) and os.path.isdir(dst_dir) )
assert(os.path.exists(bin_dir) and os.path.isdir(bin_dir) )
assert(os.path.exists(abi_dir) and os.path.isdir(abi_dir) )
assert(os.path.exists(ast_dir) and os.path.isdir(ast_dir) )
src_paths = map(lambda (root, dirs, files): root.replace(src_dir, ""), os.walk(src_dir) )
dst_paths = map(lambda (root, dirs, files): root.replace(dst_dir, ""), os.walk(dst_dir) )
_paths = filter(lambda p: p not in src_paths, dst_paths)
paths = map(lambda p: os.path.join(dst_dir, p[1:] if p.startswith("/") else p ), _paths )
map(lambda p: rmdir(p), paths )
_paths = filter(lambda p: p not in dst_paths, src_paths)
paths = map(lambda p: os.path.join(dst_dir, p[1:] if p.startswith("/") else p ), _paths )
map(lambda p: os.mkdir(p), paths)
def clean_dst_path():
rmdir(dst_dir)
os.mkdir(dst_dir)
def find_compilers():
paths = os.environ["PATH"].split(":")
solc = filter(lambda p: os.path.exists(os.path.join(p, "solc")) and os.path.isfile(os.path.join(p, "solc")), paths)
# os.path.exists(os.path.join(p, "solcjs")) and os.path.isfile(os.path.join(p, "solcjs"))
serpent = filter(lambda p: os.path.exists(os.path.join(p, "serpent")) and os.path.isfile(os.path.join(p, "serpent")), paths)
lllc = filter(lambda p: os.path.exists(os.path.join(p, "lllc")) and os.path.isfile(os.path.join(p, "lllc")), paths)
result = []
if len(solc) > 0:
result.append("Solidity")
if len(serpent) > 0:
result.append("Serpent")
if len(lllc) > 0:
result.append("LLL")
return result
def complie_soldity():
"""
solc --optimize --bin -o ./build/bin contract.sol
solc --optimize --ast -o ./build/ast contract.sol
solc --optimize --abi -o ./build contract.sol
"""
assert(os.path.exists(src_entry) and os.path.isfile(src_entry) )
commands = [
[SOLC, "--optimize", "--bin", "-o", os.path.relpath(bin_dir), os.path.relpath(src_entry) ]
, [SOLC, "--optimize", "--ast", "-o", os.path.relpath(ast_dir), os.path.relpath(src_entry) ]
, [SOLC, "--optimize", "--abi", "-o", os.path.relpath(build_dir), os.path.relpath(src_entry) ]
]
print("======================Complie Solidity Language=========================")
for cmd in commands:
command = " ".join(cmd)
print(command)
os.system(command)
# result = map(lambda cmd: os.system(" ".join(cmd)), commands )
# print(result)
def restruct():
contract = {}
bin_files = reduce(lambda a, (root, dirs, files): a + map(lambda filename: os.path.join(root, filename), files ), os.walk(bin_dir), [] )
abi_files = reduce(lambda a, (root, dirs, files): a + map(lambda filename: os.path.join(root, filename), files ), os.walk(dst_dir), [] )
def path_handle(data, filepath):
_, filename = os.path.split(filepath)
assert(filename.endswith(".bin") or filename.endswith(".abi") )
if filename.endswith(".bin"):
key = "code"
elif filename.endswith(".abi"):
key = "interface"
else:
pass
object_name = filename[:-4]
_tmp = object_name.split(":")
if len(_tmp) > 1:
object_name = _tmp[-1]
if object_name not in data or type(data[object_name]) != dict:
data[object_name] = {}
if key not in data[object_name]:
res = open(filepath, "rb").read()
if key == "interface":
open(os.path.join(abi_dir, object_name+".abi"), "wb").write(res)
data[object_name][key] = json.loads(res)
elif key == "code":
res = "0x" + res
data[object_name][key] = res
else:
data[object_name][key] = res
return data
data = reduce(path_handle, abi_files, reduce(path_handle, bin_files, {}) )
print("======================Contract=========================")
output = json.dumps(data)
open(os.path.join(build_dir, "contract.json"), "wb").write(output)
print(output)
def usage():
message = """
$ python solidity.py -src ./src -entry main.sol -out ./build -target contract.json
-src solidity source dir
-entry source entry file
-out output dir
-target solidity bytecode and interface file (JSON Format)
--help show this help text
"""
print(message)
def main():
compilers = find_compilers()
print("====================Compilers====================")
print(compilers)
assert("Solidity" in compilers)
clean_dst_path()
diff_path()
complie_soldity()
restruct()
if __name__ == '__main__':
main()