sbuilder-ethereum 0.0.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/VERSION +1 -0
- data/lib/mixer/decl_ref.rb +19 -0
- data/lib/mixer/domain_ref.rb +18 -0
- data/lib/mixer/scope.rb +92 -0
- data/lib/mixer/scoped.rb +17 -0
- data/lib/mixer/symbol_ref.rb +16 -0
- data/lib/mixer/type_symbol.rb +75 -0
- data/lib/plugin/plugin.rb +332 -0
- data/lib/resources/correctness/accouns_type.tla +1 -0
- data/lib/resources/correctness/accounts_unique.tla +2 -0
- data/lib/resources/correctness/accounts_valid.tla +2 -0
- data/lib/resources/correctness/storage_root_unique.tla +2 -0
- data/lib/resources/correctness/total_value.tla +1 -0
- data/lib/resources/eth/accounts_state.tla +2 -0
- data/lib/resources/eth/accounts_temp.tla +2 -0
- data/lib/resources/eth/address_free.tla +2 -0
- data/lib/resources/eth/mined_state.tla +1 -0
- data/lib/resources/eth/storageRoot.tla +1 -0
- data/lib/resources/eth/storageRoot_temp.tla +1 -0
- data/lib/resources/mine/mine_entry.tla +4 -0
- data/lib/resources/mine/mine_service.tla +22 -0
- data/lib/resources/operators/elementExists.tla +4 -0
- data/lib/resources/operators/gasPrice.tla +2 -0
- data/lib/resources/operators/gasValue.tla +2 -0
- data/lib/resources/operators/getElement.tla +5 -0
- data/lib/resources/operators/intrinsicGas.tla +4 -0
- data/lib/resources/operators/transactionGas.tla +4 -0
- data/lib/resources/operators/upFrontCost.tla +6 -0
- data/lib/resources/personal_newAccount/personal_newAccount_done.tla +14 -0
- data/lib/resources/personal_newAccount/personal_newAccount_entry.tla +10 -0
- data/lib/resources/personal_newAccount/personal_newAccount_service.tla +29 -0
- data/lib/resources/removed/sendTransaction_entry.tla +5 -0
- data/lib/resources/removed/sendTransaction_service.tla +36 -0
- data/lib/resources/removed/tst.tla +1 -0
- data/lib/resources/transaction/ethereum_service_done.tla +24 -0
- data/lib/resources/transaction/ethereum_service_pop.tla +24 -0
- data/lib/resources/transaction/ethereum_service_push.tla +14 -0
- data/lib/resources/transaction/ethereum_service_start.tla +13 -0
- data/lib/resources/transaction/status_fail.tla +1 -0
- data/lib/resources/transaction/status_ok.tla +1 -0
- data/lib/sbuilder-ethereum.rb +52 -0
- data/lib/sbuilder/compile.rb +163 -0
- data/lib/sbuilder/constants.rb +93 -0
- data/lib/sbuilder/exception.rb +22 -0
- data/lib/sbuilder/generate/sexp_processor_tla.rb +2674 -0
- data/lib/sbuilder/generate/tla_element_generator.rb +1206 -0
- data/lib/sbuilder/generate/tla_element_text.rb +703 -0
- data/lib/sbuilder/load.rb +119 -0
- data/lib/sbuilder/mustache/renderer.rb +152 -0
- data/lib/sbuilder/render.rb +141 -0
- data/lib/sbuilder/s.rb +21 -0
- data/lib/sbuilder/sexp_ast.rb +1378 -0
- data/lib/sbuilder/sexp_processor_api.rb +184 -0
- data/lib/sbuilder/sexp_processor_canonize.rb +326 -0
- data/lib/sbuilder/sexp_processor_dataflow.rb +461 -0
- data/lib/sbuilder/sexp_processor_ethereum.rb +127 -0
- data/lib/sbuilder/sexp_processor_need_to_canonize.rb +572 -0
- data/lib/sbuilder/sexp_processor_snippet.rb +154 -0
- data/lib/sbuilder/sexp_processor_symboltable1.rb +296 -0
- data/lib/sbuilder/sexp_processor_symboltable2.rb +175 -0
- data/lib/sbuilder/sexp_utils.rb +417 -0
- data/lib/utils/logger.rb +82 -0
- data/lib/utils/string_inject.rb +11 -0
- data/sbuilder-ethereum.gemspec +39 -0
- metadata +190 -0
@@ -0,0 +1,417 @@
|
|
1
|
+
module Sbuilder
|
2
|
+
module Ethereum
|
3
|
+
|
4
|
+
class SexpUtils
|
5
|
+
|
6
|
+
# ------------------------------------------------------------------
|
7
|
+
# @!group Id-generator
|
8
|
+
|
9
|
+
# @attr [Integer] idGenerator class variable used to generate
|
10
|
+
# unique identifiers
|
11
|
+
@@idGenerator = 1
|
12
|
+
|
13
|
+
##
|
14
|
+
# @return [String] nextId unique indetifier generated for each call
|
15
|
+
def self.nextId
|
16
|
+
@@idGenerator += 1
|
17
|
+
"canonized-#{@@idGenerator}"
|
18
|
+
end
|
19
|
+
|
20
|
+
# ##
|
21
|
+
# # Wrap to self.class.nextId
|
22
|
+
# def nextId
|
23
|
+
# self.class.nextId
|
24
|
+
# end
|
25
|
+
|
26
|
+
# @!endgroup
|
27
|
+
|
28
|
+
# ------------------------------------------------------------------
|
29
|
+
# @!group create nodes
|
30
|
+
|
31
|
+
##
|
32
|
+
# Add 'chldExp' to 'exp'
|
33
|
+
def self.addNewChild( exp, chldExp )
|
34
|
+
chldExp.setParent( exp )
|
35
|
+
exp << chldExp
|
36
|
+
exp
|
37
|
+
end
|
38
|
+
|
39
|
+
##
|
40
|
+
# Add method to FunctionDefintion 'exp'. It returns inteface
|
41
|
+
# names like 'Demo()', 'Send()', 'Demo(set)', to be used for
|
42
|
+
# example on setup step 'interface' properties. for function
|
43
|
+
def self.defineInterfaceName( exp, interfaceName )
|
44
|
+
exp.define_singleton_method( :interfaceName ) do
|
45
|
+
interfaceName
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
|
50
|
+
# @!endgroup
|
51
|
+
|
52
|
+
# ------------------------------------------------------------------
|
53
|
+
# @!group create nodes
|
54
|
+
|
55
|
+
##
|
56
|
+
# @return [FunctionDefinition] functionAst for +functionName+
|
57
|
+
def self.createFunction( functionName, isConstructor )
|
58
|
+
|
59
|
+
yaml_str=<<-EOS
|
60
|
+
name: FunctionDefinition
|
61
|
+
id: #{nextId}
|
62
|
+
attributes:
|
63
|
+
constant: false
|
64
|
+
name: #{functionName}
|
65
|
+
public: true
|
66
|
+
children:
|
67
|
+
- children: []
|
68
|
+
id: #{nextId}
|
69
|
+
name: ParameterList
|
70
|
+
- children: []
|
71
|
+
id: #{nextId}
|
72
|
+
name: ParameterList
|
73
|
+
- name: Block
|
74
|
+
children: []
|
75
|
+
id: #{nextId}
|
76
|
+
EOS
|
77
|
+
hash = YAML.load(yaml_str)
|
78
|
+
# logger.debug "#{__method__}: function hash #{hash}"
|
79
|
+
exp = SexpAst.build_sexp( hash )
|
80
|
+
exp
|
81
|
+
|
82
|
+
end
|
83
|
+
|
84
|
+
# ##
|
85
|
+
# # Contruct 'FunctionDefinition' sexp for 'functionName'.
|
86
|
+
# # Add also 'interfaceName' method to this sexp.
|
87
|
+
# def self.createBoolFunction( functionName )
|
88
|
+
|
89
|
+
# yaml_str=<<-EOS
|
90
|
+
# name: FunctionDefinition
|
91
|
+
# id: #{nextId}
|
92
|
+
# attributes:
|
93
|
+
# constant: false
|
94
|
+
# name: #{functionName}
|
95
|
+
# public: true
|
96
|
+
# children:
|
97
|
+
# - children: []
|
98
|
+
# id: #{nextId}
|
99
|
+
# name: ParameterList
|
100
|
+
# - children:
|
101
|
+
# - attributes:
|
102
|
+
# name: ''
|
103
|
+
# type: bool
|
104
|
+
# children:
|
105
|
+
# - attributes:
|
106
|
+
# name: bool
|
107
|
+
# id: #{nextId}
|
108
|
+
# name: ElementaryTypeName
|
109
|
+
# id: #{nextId}
|
110
|
+
# name: VariableDeclaration
|
111
|
+
# id: #{nextId}
|
112
|
+
# name: ParameterList
|
113
|
+
# - children: []
|
114
|
+
# id: #{nextId}
|
115
|
+
# name: Block
|
116
|
+
# EOS
|
117
|
+
# hash = YAML.load(yaml_str)
|
118
|
+
# # logger.debug "#{__method__}: function hash #{hash}"
|
119
|
+
# exp = SexpAst.build_sexp( hash )
|
120
|
+
|
121
|
+
# interfaceName = "#{functionName}()"
|
122
|
+
# defineInterfaceName( exp, interfaceName )
|
123
|
+
# exp
|
124
|
+
# end
|
125
|
+
|
126
|
+
|
127
|
+
|
128
|
+
##
|
129
|
+
# @return [FunctionDefinition] constructor for +contractName+
|
130
|
+
#
|
131
|
+
# @see createFunction
|
132
|
+
def self.createConstructorNode( contractName )
|
133
|
+
constructor = createFunction( contractName, true )
|
134
|
+
|
135
|
+
interfaceName = "#{contractName}()"
|
136
|
+
defineInterfaceName( constructor, interfaceName )
|
137
|
+
constructor
|
138
|
+
|
139
|
+
end
|
140
|
+
|
141
|
+
# @param [String] operator like +=, *=
|
142
|
+
# @return [String] operator like +, *, ...
|
143
|
+
def self.mapAssignmentOperator( operator )
|
144
|
+
operatorMapper = {
|
145
|
+
"+=" => '+'
|
146
|
+
}
|
147
|
+
mapped = operatorMapper[operator]
|
148
|
+
raise "DO not know how to map operator #{operator}" if mapped.nil?
|
149
|
+
mapped
|
150
|
+
end
|
151
|
+
|
152
|
+
def self.createBinaryOperator( operator )
|
153
|
+
yaml_str=<<-EOS
|
154
|
+
name: BinaryOperation
|
155
|
+
id: #{nextId}
|
156
|
+
attributes:
|
157
|
+
operator: #{operator}
|
158
|
+
type: uint256
|
159
|
+
children: []
|
160
|
+
EOS
|
161
|
+
hash = YAML.load(yaml_str)
|
162
|
+
exp = SexpAst.build_sexp( hash )
|
163
|
+
exp
|
164
|
+
end
|
165
|
+
|
166
|
+
def self.createBoolDecl
|
167
|
+
yaml_str=<<-EOS
|
168
|
+
name: VariableDeclaration
|
169
|
+
id: #{nextId}
|
170
|
+
attributes:
|
171
|
+
name: ''
|
172
|
+
type: bool
|
173
|
+
children:
|
174
|
+
- name: ElementaryTypeName
|
175
|
+
id: #{nextId}
|
176
|
+
children:
|
177
|
+
attributes:
|
178
|
+
name: bool
|
179
|
+
EOS
|
180
|
+
hash = YAML.load(yaml_str)
|
181
|
+
exp = SexpAst.build_sexp( hash )
|
182
|
+
exp
|
183
|
+
end
|
184
|
+
|
185
|
+
def self.createReturn()
|
186
|
+
yaml_str=<<-EOS
|
187
|
+
name: Return
|
188
|
+
id: #{nextId}
|
189
|
+
children:
|
190
|
+
- name: Literal
|
191
|
+
id: #{nextId}
|
192
|
+
attributes:
|
193
|
+
string: 'true'
|
194
|
+
type: bool
|
195
|
+
value: 'true'
|
196
|
+
EOS
|
197
|
+
hash = YAML.load(yaml_str)
|
198
|
+
exp = SexpAst.build_sexp( hash )
|
199
|
+
exp
|
200
|
+
end
|
201
|
+
|
202
|
+
def splitOperator( operator, assigned, expr )
|
203
|
+
end
|
204
|
+
|
205
|
+
# @return [FunctionDefinition] getter SexpAst for +variableName+
|
206
|
+
def self.createGetter( variableName )
|
207
|
+
|
208
|
+
getterForVariable = variableName[0,1].upcase + variableName[1..-1]
|
209
|
+
getterName = "get#{getterForVariable}"
|
210
|
+
|
211
|
+
|
212
|
+
# Type should be of no interest because specification uses
|
213
|
+
# domains. use
|
214
|
+
type ="uint256"
|
215
|
+
elementaryType="uint"
|
216
|
+
|
217
|
+
|
218
|
+
getterStr = <<-EOS
|
219
|
+
attributes:
|
220
|
+
constant: true
|
221
|
+
name: #{getterName}
|
222
|
+
public: true
|
223
|
+
children:
|
224
|
+
- children: []
|
225
|
+
id: #{nextId}
|
226
|
+
name: ParameterList
|
227
|
+
src: ""
|
228
|
+
- children:
|
229
|
+
- attributes:
|
230
|
+
name: #{variableName}
|
231
|
+
type: uint256
|
232
|
+
children:
|
233
|
+
- attributes:
|
234
|
+
name: uint
|
235
|
+
id: #{nextId}
|
236
|
+
name: ElementaryTypeName
|
237
|
+
src: ""
|
238
|
+
id: #{nextId}
|
239
|
+
name: VariableDeclaration
|
240
|
+
src: ""
|
241
|
+
id: #{nextId}
|
242
|
+
name: ParameterList
|
243
|
+
src: ""
|
244
|
+
- children:
|
245
|
+
- children:
|
246
|
+
- attributes:
|
247
|
+
type: uint256
|
248
|
+
value: #{variableName}
|
249
|
+
id: #{nextId}
|
250
|
+
name: Identifier
|
251
|
+
src: ""
|
252
|
+
id: #{nextId}
|
253
|
+
name: Return
|
254
|
+
src: ""
|
255
|
+
id: #{nextId}
|
256
|
+
name: Block
|
257
|
+
src: ""
|
258
|
+
id: #{nextId}
|
259
|
+
name: FunctionDefinition
|
260
|
+
src: ""
|
261
|
+
EOS
|
262
|
+
|
263
|
+
getterHash = YAML.load(getterStr)
|
264
|
+
# logger.debug "#{__method__}: getterHash=#{getterHash}"
|
265
|
+
SexpAst.build_sexp( getterHash )
|
266
|
+
|
267
|
+
end
|
268
|
+
|
269
|
+
# @return [VariableDeclaration] variableDeclarion SexpAst for +variableName+
|
270
|
+
def self.createVariableDeclaration( variableName )
|
271
|
+
|
272
|
+
|
273
|
+
# Type should be of no interest because specification uses
|
274
|
+
# domains. use
|
275
|
+
type ="uint256"
|
276
|
+
elementaryType="uint"
|
277
|
+
|
278
|
+
variableStr=<<-EOS
|
279
|
+
name: VariableDeclaration
|
280
|
+
id: #{nextId}
|
281
|
+
attributes:
|
282
|
+
name: #{variableName}
|
283
|
+
type: #{type}
|
284
|
+
children:
|
285
|
+
- attributes:
|
286
|
+
name: #{elementaryType}
|
287
|
+
name: ElementaryTypeName
|
288
|
+
id: #{nextId}
|
289
|
+
EOS
|
290
|
+
|
291
|
+
|
292
|
+
variable = YAML.load(variableStr)
|
293
|
+
# logger.debug "#{__method__}: variable #{hash}"
|
294
|
+
SexpAst.build_sexp( variable )
|
295
|
+
|
296
|
+
|
297
|
+
end
|
298
|
+
|
299
|
+
|
300
|
+
def self.createVariableDeclarationWithDomain( variableName, domainName )
|
301
|
+
|
302
|
+
# Type should be of no interest because specification uses
|
303
|
+
# domains. use
|
304
|
+
type =domainName
|
305
|
+
elementaryType="uint"
|
306
|
+
|
307
|
+
# eg. knows how to resolve 'send' and other address releated functions
|
308
|
+
solidityType = domainName == Constants::DOMAIN_ADDRESS ? Constants::SOL_ADDRESS : nil
|
309
|
+
|
310
|
+
variableStr=<<-EOS
|
311
|
+
name: VariableDeclaration
|
312
|
+
id: #{nextId}
|
313
|
+
attributes:
|
314
|
+
name: #{variableName}
|
315
|
+
type: #{type}
|
316
|
+
children:
|
317
|
+
- attributes:
|
318
|
+
name: #{domainName}
|
319
|
+
solidityType: #{solidityType}
|
320
|
+
name: Domain
|
321
|
+
id: #{nextId}
|
322
|
+
EOS
|
323
|
+
|
324
|
+
variable = YAML.load(variableStr)
|
325
|
+
# logger.debug "#{__method__}: variable #{hash}"
|
326
|
+
SexpAst.build_sexp( variable )
|
327
|
+
|
328
|
+
end
|
329
|
+
|
330
|
+
# @!endgroup
|
331
|
+
|
332
|
+
# ------------------------------------------------------------------
|
333
|
+
# @!group Id-generator
|
334
|
+
|
335
|
+
def self.createGlobalScope
|
336
|
+
|
337
|
+
scope = GlobalScope.new
|
338
|
+
|
339
|
+
scopeName = "GlobalScope"
|
340
|
+
|
341
|
+
globalFunctions = [Constants::SOL_SEND].inject( { }) do |memo,fname|
|
342
|
+
memo[fname] = initFunction( scopeName, fname )
|
343
|
+
memo
|
344
|
+
end
|
345
|
+
|
346
|
+
|
347
|
+
# generate uqiue identfiers
|
348
|
+
# id = 1
|
349
|
+
# scope.define( Constants::SOL_NOW, Now.new( "GLOB-#{id}" ) ); id += 1;
|
350
|
+
|
351
|
+
# global scope acts as a contract - add global functions there
|
352
|
+
globalFunctions.each do |name, func |
|
353
|
+
scope << func
|
354
|
+
scope.define( func.interfaceName, func )
|
355
|
+
end
|
356
|
+
|
357
|
+
# add built in types, possibly define some function
|
358
|
+
# e.g. address send
|
359
|
+
[
|
360
|
+
[ Constants::SOL_BOOLEAN_TYPE, nil],
|
361
|
+
[ Constants::SOL_UINT, nil],
|
362
|
+
[ Constants::SOL_ADDRESS, globalFunctions],
|
363
|
+
].each do |builtIn|
|
364
|
+
builtInType = builtIn[0]
|
365
|
+
funcs = builtIn[1]
|
366
|
+
newType = BuiltInSymbol.new( builtInType )
|
367
|
+
scope.define( builtInType, newType )
|
368
|
+
|
369
|
+
# funcs is a hash
|
370
|
+
funcs && funcs.each do |name,func|
|
371
|
+
newType.define( name, func)
|
372
|
+
end
|
373
|
+
end
|
374
|
+
|
375
|
+
scope
|
376
|
+
end
|
377
|
+
|
378
|
+
##
|
379
|
+
# Create function 'functionName', in 'scopeName', and add common
|
380
|
+
# request paramerters
|
381
|
+
def self.initFunction( scopeName, functionName )
|
382
|
+
|
383
|
+
isConstructor = false
|
384
|
+
functionSexp = SexpUtils.createFunction(functionName, isConstructor)
|
385
|
+
interfaceName = "#{scopeName}(#{functionName})"
|
386
|
+
defineInterfaceName( functionSexp, interfaceName )
|
387
|
+
|
388
|
+
functionSexp.block<< SexpUtils.createReturn()
|
389
|
+
|
390
|
+
# add common requet parameters
|
391
|
+
requestParameters = functionSexp.parameterList
|
392
|
+
TlaElementText.commonMsgProperties( 'request', isConstructor ).each do |parameter|
|
393
|
+
newParameter = SexpUtils.createVariableDeclarationWithDomain( parameter[1], parameter[2] )
|
394
|
+
SexpUtils.addNewChild( requestParameters, newParameter )
|
395
|
+
end
|
396
|
+
|
397
|
+
# Add return parameters for boolean variable
|
398
|
+
TlaElementText.commonMsgProperties( 'response-bool', isConstructor ).each do |parameter|
|
399
|
+
newParameter = SexpUtils.createVariableDeclarationWithDomain( parameter[1], parameter[2] )
|
400
|
+
SexpUtils.addNewChild( functionSexp.returnList, newParameter )
|
401
|
+
end
|
402
|
+
|
403
|
+
#
|
404
|
+
return functionSexp
|
405
|
+
end
|
406
|
+
|
407
|
+
|
408
|
+
|
409
|
+
# @!endgroup
|
410
|
+
|
411
|
+
|
412
|
+
|
413
|
+
end
|
414
|
+
|
415
|
+
end
|
416
|
+
|
417
|
+
end
|
data/lib/utils/logger.rb
ADDED
@@ -0,0 +1,82 @@
|
|
1
|
+
module Sbuilder
|
2
|
+
module Ethereum
|
3
|
+
require 'logger'
|
4
|
+
|
5
|
+
# see http://hawkins.io/2013/08/using-the-ruby-logger/
|
6
|
+
|
7
|
+
module MyLogger
|
8
|
+
|
9
|
+
# no logging done
|
10
|
+
|
11
|
+
class NullLoger < Logger
|
12
|
+
def initialize(*args)
|
13
|
+
end
|
14
|
+
|
15
|
+
def add(*args, &block)
|
16
|
+
end
|
17
|
+
|
18
|
+
def debug?
|
19
|
+
false
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
@@logfile = nil # absolute path to log file
|
24
|
+
LOGFILE="sbuilder.log"
|
25
|
+
|
26
|
+
def logfile( options )
|
27
|
+
return @@logfile if @@logfile
|
28
|
+
@@logfile = options[:logfile] || File.join( Dir.getwd, LOGFILE )
|
29
|
+
@@logfile
|
30
|
+
end
|
31
|
+
|
32
|
+
def getLogger( progname=nil, options={} )
|
33
|
+
|
34
|
+
|
35
|
+
progname = self.class.name.split('::').last if progname.nil?
|
36
|
+
level = get_level( options )
|
37
|
+
|
38
|
+
if level.nil?
|
39
|
+
|
40
|
+
return NullLoger.new
|
41
|
+
|
42
|
+
else
|
43
|
+
|
44
|
+
|
45
|
+
logger = Logger.new( logfile(options) )
|
46
|
+
logger.level=level
|
47
|
+
logger.progname = progname
|
48
|
+
return logger
|
49
|
+
|
50
|
+
end
|
51
|
+
|
52
|
+
end # getLogger
|
53
|
+
|
54
|
+
|
55
|
+
# ------------------------------------------------------------------
|
56
|
+
private
|
57
|
+
|
58
|
+
def get_level( options )
|
59
|
+
|
60
|
+
level_name = options && options[:log] ? options[:log] : ENV['LOG_LEVEL']
|
61
|
+
|
62
|
+
level = case level_name
|
63
|
+
when 'warn', 'WARN'
|
64
|
+
Logger::WARN
|
65
|
+
when 'info', 'INFO'
|
66
|
+
Logger::INFO
|
67
|
+
when 'debug', 'DEBUG'
|
68
|
+
Logger::DEBUG
|
69
|
+
when 'error', 'ERROR'
|
70
|
+
Logger::ERROR
|
71
|
+
else
|
72
|
+
nil
|
73
|
+
end
|
74
|
+
|
75
|
+
return level
|
76
|
+
end
|
77
|
+
|
78
|
+
end
|
79
|
+
|
80
|
+
|
81
|
+
end
|
82
|
+
end
|