forked from FISCO-BCOS/python-sdk
-
Notifications
You must be signed in to change notification settings - Fork 0
/
codegen.py
127 lines (115 loc) · 4.43 KB
/
codegen.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
import sys
from client.datatype_parser import DatatypeParser
from utils.abi import (
filter_by_type
)
import os
import json
class ABICodegen:
parser = DatatypeParser()
abi_file = ""
name = ""
# four spaces for indent
indent = " "
template = ""
template_file = "client/codegen_template.py"
def __init__(self, abi_file):
if len(abi_file) > 0:
self.load_abi(abi_file)
with open(self.template_file, "r") as f:
self.template = f.read()
f.close()
def load_abi(self, abi_file):
self.abi_file = abi_file
self.parser.load_abi_file(abi_file)
fname = os.path.basename(abi_file)
(self.name, ext) = os.path.splitext(fname)
def make_function(self, func_abi):
func_lines = []
func_def = "def {}(self".format(func_abi["name"])
args_def = ""
args_value = ""
i = 0
for param in func_abi["inputs"]:
if i > 0:
args_def += ", "
args_value += ", "
args_def += param["name"]
if param['type'] == "address":
args_value += "to_checksum_address({})".format(param["name"])
else:
args_value += param["name"]
i += 1
if len(args_def) > 0:
func_def += ", " + args_def
func_def += "):"
func_lines.append(func_def)
func_lines.append("{}func_name = '{}'".format(self.indent, func_abi["name"]))
func_lines.append("{}args = [{}]".format(self.indent, args_value))
if func_abi["constant"] is False:
func_lines.append(self.indent + ("receipt = self.client.sendRawTransactionGetReceipt"
"(self.address, self.contract_abi, func_name, args)"))
func_lines.append(self.indent + ("outputresult = self.data_parser.parse_receipt_output"
"(func_name, receipt['output'])"))
func_lines.append(self.indent + "return outputresult, receipt")
if func_abi["constant"] is True:
func_lines.append(self.indent + ("result = self.client.call(self.address, "
"self.contract_abi, func_name, args)"))
func_lines.append(self.indent + "return result")
return func_lines
def gen_all(self):
all_func_code_line = []
func_abi_list = filter_by_type("function", self.parser.contract_abi)
for func_abi in func_abi_list:
func_lines = self.make_function(func_abi)
all_func_code_line.append("")
all_func_code_line.append("# ------------------------------------------")
all_func_code_line.extend(func_lines)
# print(func_lines)
template = self.template
template = template.replace("TEMPLATE_CLASSNAME", self.name)
template = template.replace("TEMPLATE_ABIFILE", self.abi_file)
contract_abi = json.dumps(self.parser.contract_abi).replace("\r", "")
contract_abi = contract_abi.replace("\n", " ")
template = template.replace("TEMPLATE_CONTRACT_ABI", contract_abi)
for line in all_func_code_line:
if not line:
template += "\n"
else:
template += self.indent + line + "\n"
return template
def usage():
usagetext = '''usage:
python codegen.py [abifile(eg: ./contracts/SimpleInfo.abi)]
[outputpath(eg: ./contracts/)] '''
print(usagetext)
if __name__ == '__main__':
if(len(sys.argv) < 3):
usage()
sys.exit(0)
abi_file = sys.argv[1]
outputdir = sys.argv[2]
forcewrite = False
if(len(sys.argv) == 4):
isSave = sys.argv[3]
if isSave == "save":
forcewrite = True
codegen = ABICodegen(abi_file)
template = codegen.gen_all()
print(template)
name = codegen.name + '.py'
outputfile = os.path.join(outputdir, name)
print(" output file : {}".format(outputfile))
if os.access(outputfile, os.F_OK) and forcewrite is False:
str = input(">> file [{}] exist , continue (y/n): ".format(outputfile))
if str.lower() == "y":
forcewrite = True
else:
forcewrite = False
else:
forcewrite = True
if forcewrite:
with open(outputfile, "wb") as f:
f.write(bytes(template, "utf-8"))
f.close()
print("write {} done".format(outputfile))