sbuilder-ial 0.0.1
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/action/exception.rb +13 -0
- data/lib/action/extender.rb +30 -0
- data/lib/action/file_path.rb +35 -0
- data/lib/action/model_builder.rb +74 -0
- data/lib/action/render/exception.rb +12 -0
- data/lib/action/render/producer.rb +193 -0
- data/lib/action/render/producer_ethereum.rb +404 -0
- data/lib/action/render/producer_ethereum_const.rb +221 -0
- data/lib/action/render/renderer.rb +142 -0
- data/lib/action/render/tla_element_generator.rb +1306 -0
- data/lib/action/script_eval.rb +32 -0
- data/lib/action/text.rb +17 -0
- data/lib/action/tla_rules.rb +512 -0
- data/lib/action/translator.rb +160 -0
- data/lib/app/app.rb +259 -0
- data/lib/ethereum/api.rb +669 -0
- data/lib/ethereum.rb +1 -0
- data/lib/fp/compositable.rb +185 -0
- data/lib/fp/error.rb +19 -0
- data/lib/fp/exception.rb +9 -0
- data/lib/fp/result.rb +19 -0
- data/lib/fp/sequence.rb +65 -0
- data/lib/ial/build.rb +12 -0
- data/lib/ial/exception.rb +13 -0
- data/lib/model/constants.rb +72 -0
- data/lib/model/model.rb +74 -0
- data/lib/model/model_dsl.rb +1038 -0
- data/lib/model/sexp.rb +58 -0
- data/lib/plugin/plugin.rb +273 -0
- data/lib/sbuilder-ial.rb +44 -0
- data/lib/utils/logger.rb +82 -0
- data/sbuilder-ial.gemspec +36 -0
- metadata +137 -0
data/lib/ethereum/api.rb
ADDED
@@ -0,0 +1,669 @@
|
|
1
|
+
|
2
|
+
require 'sbuilder-ial'
|
3
|
+
|
4
|
+
module Sbuilder
|
5
|
+
module Ial
|
6
|
+
class Ethereum
|
7
|
+
|
8
|
+
# ------------------------------------------------------------------
|
9
|
+
# Infra macros
|
10
|
+
INFRA_PUSH='Push'
|
11
|
+
INFRA_HEAD='Head'
|
12
|
+
INFRA_TAIL='Tail'
|
13
|
+
INFRA_POP='Pop'
|
14
|
+
INFRA_NEXT_ID='NextId'
|
15
|
+
INFRA_UPDATE_TOP='UpdateTop'
|
16
|
+
INFRA_READ_RETURN='InfrastructureServiceGetStatus'
|
17
|
+
INFRA_SVC_STACK_ACCEPT='PropageTopAndPop'
|
18
|
+
INFRA_SVC_STACK_REJECT='Tail'
|
19
|
+
|
20
|
+
|
21
|
+
# ------------------------------------------------------------------
|
22
|
+
# Constants: domains
|
23
|
+
|
24
|
+
DOMAIN_ADDRESS = "eth_address"
|
25
|
+
DOMAIN_VALUE = "eth_value"
|
26
|
+
DOMAIN_GAS = "eth_gas"
|
27
|
+
DOMAIN_CODE_HASH = "eth_code_hash"
|
28
|
+
DOMAINS = [ DOMAIN_ADDRESS, DOMAIN_VALUE, DOMAIN_GAS, DOMAIN_CODE_HASH]
|
29
|
+
# DOMAIN_BOOLEAN = "BOOLEAN"
|
30
|
+
# DOMAIN_DEFAULT = "default" # when no better candidate not found
|
31
|
+
|
32
|
+
# Ethereum field names
|
33
|
+
FIELD_NAME_ADDRESS = "address"
|
34
|
+
FIELD_NAME_CODE_HASH = "codeHash"
|
35
|
+
FIELD_NAME_BALANCE = "balance"
|
36
|
+
|
37
|
+
|
38
|
+
FIELD_NAME_CID = "cid"
|
39
|
+
FIELD_NAME_ORIGINATOR = "originator"
|
40
|
+
FIELD_NAME_SENDER = "sender"
|
41
|
+
FIELD_NAME_RECIPIENT = "recipient"
|
42
|
+
FIELD_NAME_BENEFICIARY = "beneficiary"
|
43
|
+
# FIELD_NAME_VALUE = "value"
|
44
|
+
FIELD_NAME_RESULT = "result"
|
45
|
+
FIELD_NAME_GAS = "gas"
|
46
|
+
FIELD_NAME_STATUS = "status"
|
47
|
+
|
48
|
+
|
49
|
+
# Variables
|
50
|
+
|
51
|
+
VARIABLE_ACCOUNTS = "accounts"
|
52
|
+
VARIABLE_ADDRESS = "address"
|
53
|
+
VARIABLE_MINED = "mined"
|
54
|
+
VARIABLE_STORAGE_ROOT = "storageRoot"
|
55
|
+
|
56
|
+
VARIABLE_ACCOUNTS_TEMP = "accounts_temp"
|
57
|
+
VARIABLE_STORAGE_ROOT_TEMP = "storageRoot_temp"
|
58
|
+
|
59
|
+
VARIABLE_LOCAL_ID = 'thisId'
|
60
|
+
|
61
|
+
VARIABLE_ADDRESS_FREE = "address_free"
|
62
|
+
|
63
|
+
VARIABLES = [
|
64
|
+
VARIABLE_ACCOUNTS,
|
65
|
+
VARIABLE_ADDRESS,
|
66
|
+
VARIABLE_MINED,
|
67
|
+
VARIABLE_STORAGE_ROOT,
|
68
|
+
VARIABLE_ACCOUNTS_TEMP,
|
69
|
+
VARIABLE_STORAGE_ROOT_TEMP,
|
70
|
+
VARIABLE_ADDRESS_FREE,
|
71
|
+
]
|
72
|
+
|
73
|
+
# Macros
|
74
|
+
MACRO_SERVICE_PUSH = "ethereum_service_push"
|
75
|
+
MACRO_SERVICE_POP = "ethereum_service_pop"
|
76
|
+
MACRO_SERVICE_DONE = "ethereum_service_done"
|
77
|
+
MACRO_SERVICE_START = "ethereum_service_start"
|
78
|
+
|
79
|
+
# Operators
|
80
|
+
OPERATOR_GASPRICE = 'gasPrice'
|
81
|
+
OPERATOR_INTRINSICGAS = 'intrinsicGas'
|
82
|
+
OPERATOR_TRANSACTIONGAS = 'transactionGas'
|
83
|
+
OPERATOR_UPFRONT_COST = 'upFrontCost'
|
84
|
+
OPERATOR_GAS_VALUE = 'gasValue'
|
85
|
+
|
86
|
+
|
87
|
+
|
88
|
+
# ------------------------------------------------------------------
|
89
|
+
# API
|
90
|
+
class << self
|
91
|
+
|
92
|
+
def domainDefinition( d )
|
93
|
+
Sbuilder::Ial.domain{ name d }
|
94
|
+
# ->(d) { Sbuilder::Ial.domain{ name d } }
|
95
|
+
end
|
96
|
+
|
97
|
+
def variableDefinition( v, init=nil)
|
98
|
+
# ->(v,init=nil) { Sbuilder::Ial.variable{ name v; init init } }
|
99
|
+
Sbuilder::Ial.variable do
|
100
|
+
name v
|
101
|
+
init init
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
# @return [ReferenceExpression] reference to domain 'd'
|
106
|
+
def domainRef( d )
|
107
|
+
return d unless d.is_a?( String )
|
108
|
+
# ->(d) { Sbuilder::Ial.referenceExpression { domain d } }
|
109
|
+
Sbuilder::Ial.referenceExpression do
|
110
|
+
domain d
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
# @return [ReferenceExpression] reference to variable 'v'
|
115
|
+
def variableRef( v )
|
116
|
+
return v unless v.is_a?( String )
|
117
|
+
Sbuilder::Ial.referenceExpression { variable v }
|
118
|
+
end
|
119
|
+
|
120
|
+
# @return [TlaExpression] reference formal parameter 'v'
|
121
|
+
def parameterRef( v )
|
122
|
+
return v unless v.is_a?( String )
|
123
|
+
Sbuilder::Ial.referenceExpression { parameter v }
|
124
|
+
end
|
125
|
+
|
126
|
+
# @return [ReferenceExpression] reference to local varibale 'v'
|
127
|
+
def localRef( v )
|
128
|
+
return v unless v.is_a?( String )
|
129
|
+
Sbuilder::Ial.referenceExpression { local v }
|
130
|
+
end
|
131
|
+
|
132
|
+
|
133
|
+
def fieldName( v )
|
134
|
+
return v unless v.is_a?( String )
|
135
|
+
Sbuilder::Ial.referenceExpression { parameter v }
|
136
|
+
end
|
137
|
+
|
138
|
+
def constant( v )
|
139
|
+
return v if v.is_a?( Sbuilder::Ial::Model::Expression )
|
140
|
+
Sbuilder::Ial.constantExpression { const v }
|
141
|
+
end
|
142
|
+
|
143
|
+
|
144
|
+
# return [Tlaexpression] expression producing value 'v'
|
145
|
+
#
|
146
|
+
def plainName( v )
|
147
|
+
return v if v.is_a?( Sbuilder::Ial::Model::Expression )
|
148
|
+
Sbuilder::Ial.referenceExpression { plain v }
|
149
|
+
end
|
150
|
+
|
151
|
+
def tlaIfExpression( condExpr, thenExpr, elseExpr )
|
152
|
+
Sbuilder::Ial.tlaExpression do
|
153
|
+
template :IF_expression
|
154
|
+
args condExpr
|
155
|
+
args thenExpr
|
156
|
+
args elseExpr
|
157
|
+
end
|
158
|
+
end
|
159
|
+
|
160
|
+
def tlaExceptExpression( variable, excepts )
|
161
|
+
Sbuilder::Ial.tlaExpression do
|
162
|
+
template :EXCEPT_expression
|
163
|
+
args variable
|
164
|
+
args excepts
|
165
|
+
end
|
166
|
+
end
|
167
|
+
|
168
|
+
def tlaSetGenerate( mapExpression, iterationVariable, baseSetToIterate )
|
169
|
+
Sbuilder::Ial.tlaExpression do
|
170
|
+
template :set_generate
|
171
|
+
args mapExpression
|
172
|
+
args iterationVariable
|
173
|
+
args baseSetToIterate
|
174
|
+
end
|
175
|
+
end
|
176
|
+
|
177
|
+
# @return [TlaExpression] expression 'rec.fieldName' to access
|
178
|
+
# field 'fldName' in record 'rec'
|
179
|
+
def fieldRef( rec, fldName )
|
180
|
+
Sbuilder::Ial.tlaExpression do
|
181
|
+
template :record_field
|
182
|
+
args plainName(rec)
|
183
|
+
args plainName(fldName)
|
184
|
+
end
|
185
|
+
end
|
186
|
+
|
187
|
+
# @return [TlaExpression] expression for binary exression 'left-op-right'
|
188
|
+
def binaryOperator( left, op, rigth )
|
189
|
+
Sbuilder::Ial.binaryExpression(){ expression left, op, rigth }
|
190
|
+
end
|
191
|
+
|
192
|
+
# @return [TlaExpression] expression for 'operator( *args )',
|
193
|
+
# where operator define
|
194
|
+
def operatorCall( ialOperator, *args )
|
195
|
+
Sbuilder::Ial.operatorExpression{ called ialOperator; args args }
|
196
|
+
end
|
197
|
+
|
198
|
+
# @return [TlaExpression] operator calle expression infraOperator( *args )
|
199
|
+
def infraOperatorCall( infraOperator, *args )
|
200
|
+
Sbuilder::Ial.operatorExpression{ called infraOperator; infrastructureService true; args args }
|
201
|
+
end
|
202
|
+
|
203
|
+
# @return [TlaExpression] set constructor for an element 'e' :: "{ e }"
|
204
|
+
def toSet( e )
|
205
|
+
Sbuilder::Ial.tlaExpression do
|
206
|
+
template :set
|
207
|
+
args e
|
208
|
+
end
|
209
|
+
end
|
210
|
+
|
211
|
+
|
212
|
+
# @return [sTla] template to create one TLA record key val
|
213
|
+
# mapping
|
214
|
+
#
|
215
|
+
# plainName(k) |-> eval(v).
|
216
|
+
#
|
217
|
+
# Example: address |-> NextId(address_free)
|
218
|
+
def toRecordKeyVal( k,v )
|
219
|
+
Sbuilder::Ial.tlaExpression do
|
220
|
+
template :record_field_definition
|
221
|
+
args plainName(k)
|
222
|
+
args v
|
223
|
+
end
|
224
|
+
end
|
225
|
+
|
226
|
+
# Create TLA record entry for 'hash'. Hash keys represent
|
227
|
+
# record fields, and hash values are record field value
|
228
|
+
# expression to evaluate.
|
229
|
+
#
|
230
|
+
# Example: [ k1 |-> TRUE, k2 -> Nil ]
|
231
|
+
#
|
232
|
+
def toRecord( hash )
|
233
|
+
Sbuilder::Ial.tlaExpression do
|
234
|
+
template :record
|
235
|
+
args hash.keys.map { |k| toRecordKeyVal( k, hash[k] ) }
|
236
|
+
end
|
237
|
+
end
|
238
|
+
|
239
|
+
# @return [TlaExpression] sequence constructor for an element(s) 'e' :: "<< eval(e) >>"
|
240
|
+
def toSequence( e )
|
241
|
+
Sbuilder::Ial.tlaExpression do
|
242
|
+
template :sequence
|
243
|
+
args e unless e.nil?
|
244
|
+
end
|
245
|
+
end
|
246
|
+
|
247
|
+
def emptySequence
|
248
|
+
toSequence( nil )
|
249
|
+
end
|
250
|
+
|
251
|
+
|
252
|
+
# @return [TlaExpression] expression for non Nil elements in domain 'domainName',
|
253
|
+
# more formally return 'domainRef(domainName) \ { Nil}'
|
254
|
+
def domainSetMinusNil( domainName )
|
255
|
+
Sbuilder::Ial.binaryExpression do
|
256
|
+
expression domainRef(domainName), :set_minus, toSet(:nil)
|
257
|
+
end
|
258
|
+
end
|
259
|
+
|
260
|
+
# ------------------------------------------------------------------
|
261
|
+
# common (Ethreum ) expressions
|
262
|
+
|
263
|
+
# @return [OperatorExpression] expression binding to next free
|
264
|
+
# id in variable 'address_free' :: NextId( address_free, Nil )
|
265
|
+
#
|
266
|
+
# Example: NextId( address_free,Nil );
|
267
|
+
def nextId
|
268
|
+
infraOperatorCall( INFRA_NEXT_ID, variableRef(VARIABLE_ADDRESS_FREE), :nil )
|
269
|
+
end
|
270
|
+
|
271
|
+
# @return [ReferenceExpression] this address of current id (in local variable
|
272
|
+
def currentId
|
273
|
+
localRef(VARIABLE_LOCAL_ID)
|
274
|
+
end
|
275
|
+
|
276
|
+
# @return [Expression] expression referencing storage holding
|
277
|
+
# account during transaction execution
|
278
|
+
def accountVariableExec
|
279
|
+
variableRef(VARIABLE_ACCOUNTS_TEMP)
|
280
|
+
end
|
281
|
+
|
282
|
+
def contractVariableExec
|
283
|
+
variableRef(VARIABLE_STORAGE_ROOT_TEMP)
|
284
|
+
end
|
285
|
+
|
286
|
+
|
287
|
+
# @return [Hash] hash for contract of type 'codeHash'
|
288
|
+
# address/identity 'nextId' with initial balance 'value'
|
289
|
+
def newContractHash( codeHash:, id:, value: )
|
290
|
+
{
|
291
|
+
FIELD_NAME_ADDRESS =>id,
|
292
|
+
FIELD_NAME_CODE_HASH => codeHash,
|
293
|
+
FIELD_NAME_BALANCE => value,
|
294
|
+
}
|
295
|
+
end
|
296
|
+
|
297
|
+
def newStrorageRoot( codeHash:, id:, members: )
|
298
|
+
entry = {
|
299
|
+
FIELD_NAME_ADDRESS =>id,
|
300
|
+
FIELD_NAME_CODE_HASH =>codeHash,
|
301
|
+
}.merge( members.inject({}){|h,(k,v)| h[k] = constant(v); h })
|
302
|
+
entry
|
303
|
+
end
|
304
|
+
|
305
|
+
|
306
|
+
|
307
|
+
|
308
|
+
|
309
|
+
# ------------------------------------------------------------------
|
310
|
+
# common statement (single)
|
311
|
+
|
312
|
+
def stmtOutuput( txt )
|
313
|
+
Sbuilder::Ial.printStatement() { msg txt }
|
314
|
+
end
|
315
|
+
|
316
|
+
# @return [Statement] statement assigning expression 'e' to
|
317
|
+
# local variable 'v'
|
318
|
+
def stmtAssignLocal( v, e )
|
319
|
+
Sbuilder::Ial.assignStatement(){
|
320
|
+
local localRef(v)
|
321
|
+
expression e
|
322
|
+
}
|
323
|
+
end
|
324
|
+
|
325
|
+
|
326
|
+
# @return [Statement] statement assigning expression 'e' to
|
327
|
+
# variable 'v'
|
328
|
+
#
|
329
|
+
# variableRef('v') := eval('e').
|
330
|
+
#
|
331
|
+
def stmtAssign( v, e )
|
332
|
+
Sbuilder::Ial.assignStatement(){
|
333
|
+
variable variableRef(v)
|
334
|
+
expression e
|
335
|
+
}
|
336
|
+
end
|
337
|
+
|
338
|
+
|
339
|
+
# @return [Statement] statement to update variable 'v' with
|
340
|
+
# expression
|
341
|
+
#
|
342
|
+
# eval('v') := eval('v') \op eval('e').
|
343
|
+
#
|
344
|
+
# Example: eth_address_free := eth_address_free \ { NextId(
|
345
|
+
# eth_address_free, input.address ) };
|
346
|
+
def stmtUpdateVariable( v, op, e )
|
347
|
+
stmtAssign( v, binaryOperator(variableRef(v), op, e ) )
|
348
|
+
end
|
349
|
+
|
350
|
+
|
351
|
+
# @return [Statement] statement to assign variable 'v' a value
|
352
|
+
# where set containing expression 'e', { 'e' }, is added to
|
353
|
+
# the set in the first element of the sequence in 'v'.
|
354
|
+
#
|
355
|
+
# variableRef(v) := UpdateTop( Head(variableRef(v)) \union { eval(e) }
|
356
|
+
#
|
357
|
+
#
|
358
|
+
# Example: ial_accounts_temp := UpdateTop( Head( ial_accounts_temp ) \union { Nil } )
|
359
|
+
def stmtUpdateSequenceHead( v, e )
|
360
|
+
Sbuilder::Ial.assignStatement(){
|
361
|
+
variable variableRef(v)
|
362
|
+
expression infraOperatorCall( INFRA_UPDATE_TOP, variableRef(v), binaryOperator(infraOperatorCall(INFRA_HEAD, variableRef(v)), :union, toSet(e) ))
|
363
|
+
}
|
364
|
+
end
|
365
|
+
|
366
|
+
# ethrereum statements
|
367
|
+
|
368
|
+
#
|
369
|
+
# @param [memberVariables] memberVariables, key member variable name,
|
370
|
+
# value constant expression to initialize with
|
371
|
+
#
|
372
|
+
# @param [value] balance to set on contract
|
373
|
+
#
|
374
|
+
# @return [Statement:Array] statements array to create
|
375
|
+
# contract type 'codeHash' with initial balance 'value', and
|
376
|
+
# member variables initilized with 'memberVariables'
|
377
|
+
def stmtsCreateContract( codeHash:, value:, memberVariables: )
|
378
|
+
[
|
379
|
+
# debug message
|
380
|
+
# stmtOutuput( "#{__method__}" ),
|
381
|
+
# entry to account
|
382
|
+
stmtUpdateSequenceHead( VARIABLE_ACCOUNTS_TEMP, toRecord( newContractHash(codeHash: codeHash, value: value, id: nextId )) ),
|
383
|
+
# entry to storage root
|
384
|
+
stmtUpdateSequenceHead( VARIABLE_STORAGE_ROOT_TEMP, toRecord( newStrorageRoot(codeHash: codeHash, id: nextId, members: memberVariables ))),
|
385
|
+
#
|
386
|
+
stmtAssignLocal( VARIABLE_LOCAL_ID, nextId ),
|
387
|
+
# consume next nextId
|
388
|
+
stmtUpdateVariable( VARIABLE_ADDRESS_FREE, :set_minus, toSet(nextId) ),
|
389
|
+
]
|
390
|
+
end
|
391
|
+
|
392
|
+
|
393
|
+
# @return [Statement:Array] statements array to update
|
394
|
+
# contract member variables in hash 'memberVariable' on
|
395
|
+
# contract pointed by 'addressRef' in ethreum transaction
|
396
|
+
# context 'VARIABLE_STORAGE_ROOT_TEMP'.
|
397
|
+
|
398
|
+
def stmtsUpdateContract( addressRef:, memberVariable: nil)
|
399
|
+
[
|
400
|
+
# stmtOutuput( "#{__method__} starting" ),
|
401
|
+
stmtAssign( VARIABLE_STORAGE_ROOT_TEMP, exprUpdateContract( addressRef, memberVariable) )
|
402
|
+
]
|
403
|
+
end
|
404
|
+
|
405
|
+
# @param [Hash] memberVariable keys are record fieds to set,
|
406
|
+
# values are expression to set
|
407
|
+
#
|
408
|
+
private def exprUpdateContractExpression( memberVariable )
|
409
|
+
raise "Must give at least one update" unless memberVariable && memberVariable.keys.any?
|
410
|
+
memberVariable.keys.map { |k| binaryOperator( fieldRef( "!", k ), Sbuilder::Ial::Model::Constants::OPERATOR_EQUAL , memberVariable[k] ) }
|
411
|
+
end
|
412
|
+
|
413
|
+
private def exprUpdateContract( addressRef, memberVariable )
|
414
|
+
|
415
|
+
contractRef = variableRef(VARIABLE_STORAGE_ROOT_TEMP)
|
416
|
+
iterationVariableRef = plainName( 'a' )
|
417
|
+
|
418
|
+
updateExpression = exprUpdateContractExpression( memberVariable )
|
419
|
+
|
420
|
+
condExpr = binaryOperator( fieldRef(iterationVariableRef, FIELD_NAME_ADDRESS), :equal, addressRef )
|
421
|
+
thenExpr = tlaExceptExpression( iterationVariableRef, updateExpression )
|
422
|
+
elseExpr = iterationVariableRef
|
423
|
+
|
424
|
+
mapExpression = tlaIfExpression( condExpr, thenExpr, elseExpr )
|
425
|
+
|
426
|
+
baseSetToIterate = infraOperatorCall(INFRA_HEAD, contractRef )
|
427
|
+
updateExpression = tlaSetGenerate( mapExpression, iterationVariableRef, baseSetToIterate )
|
428
|
+
|
429
|
+
# update contract data in top of stack
|
430
|
+
infraOperatorCall( INFRA_UPDATE_TOP, contractRef, updateExpression )
|
431
|
+
|
432
|
+
end
|
433
|
+
|
434
|
+
# transactions i.e. contract constructor & contract function
|
435
|
+
# call
|
436
|
+
|
437
|
+
def constructor( contract:, req: [], rply: [] )
|
438
|
+
operation = ""
|
439
|
+
Sbuilder::Ial.transaction() do
|
440
|
+
name contract
|
441
|
+
# well known local variable holding identity of contract
|
442
|
+
# being created.
|
443
|
+
locals VARIABLE_LOCAL_ID
|
444
|
+
request req.is_a?(Array) ? req : [req]
|
445
|
+
response rply.is_a?(Array) ? rply : [rply]
|
446
|
+
entryBlock do
|
447
|
+
# output "entry block called"
|
448
|
+
callMacro MACRO_SERVICE_START
|
449
|
+
callService contract, operation, plainName('input')
|
450
|
+
end
|
451
|
+
block do
|
452
|
+
stmtOutuput "preamble"
|
453
|
+
#
|
454
|
+
# transaction implementation here
|
455
|
+
#
|
456
|
+
yield self
|
457
|
+
stmtOutuput "epiloque"
|
458
|
+
end
|
459
|
+
end
|
460
|
+
end
|
461
|
+
|
462
|
+
|
463
|
+
# ------------------------------------------------------------------
|
464
|
+
# Snippets for ethereum implementation
|
465
|
+
|
466
|
+
end
|
467
|
+
|
468
|
+
class << self
|
469
|
+
|
470
|
+
# e.g. eth_storageRoot_temp := Push( eth_storageRoot_temp, Head( eth_storageRoot_temp )) ;
|
471
|
+
private def pushServiceStateVariable( variableName )
|
472
|
+
infraOperatorCall( INFRA_PUSH, variableRef(variableName), infraOperatorCall(INFRA_HEAD, variableRef(variableName)) )
|
473
|
+
end
|
474
|
+
|
475
|
+
# Create macro to inialize transaction
|
476
|
+
def operator_gasPrice
|
477
|
+
Sbuilder::Ial.operator(){
|
478
|
+
name OPERATOR_GASPRICE
|
479
|
+
expression 0
|
480
|
+
}
|
481
|
+
|
482
|
+
end
|
483
|
+
|
484
|
+
# Create macro to inialize transaction
|
485
|
+
|
486
|
+
# gasValue( gas ) == gas * gasPrice
|
487
|
+
def operator_gasValue
|
488
|
+
Sbuilder::Ial.operator(){
|
489
|
+
name OPERATOR_GAS_VALUE
|
490
|
+
gas = 'gas'
|
491
|
+
parameters gas
|
492
|
+
expression binaryOperator(parameterRef(gas), :mult, operatorCall(OPERATOR_GASPRICE))
|
493
|
+
}
|
494
|
+
end
|
495
|
+
|
496
|
+
# Create macro to inialize transaction
|
497
|
+
def operator_intrinsicGas
|
498
|
+
Sbuilder::Ial.operator(){
|
499
|
+
name OPERATOR_INTRINSICGAS
|
500
|
+
expression 1
|
501
|
+
}
|
502
|
+
end
|
503
|
+
|
504
|
+
|
505
|
+
# Create macro to inialize transaction
|
506
|
+
def operator_transactionGas
|
507
|
+
Sbuilder::Ial.operator(){
|
508
|
+
name OPERATOR_TRANSACTIONGAS
|
509
|
+
expression 1
|
510
|
+
}
|
511
|
+
end
|
512
|
+
|
513
|
+
# upFrontCost( request ) == request.value + gasPrice * intrinsicGas
|
514
|
+
def operator_upFrontCost
|
515
|
+
Sbuilder::Ial.operator(){
|
516
|
+
request = 'request'
|
517
|
+
name OPERATOR_UPFRONT_COST
|
518
|
+
parameters request
|
519
|
+
expression binaryOperator( fieldRef(parameterRef(request), 'value' ), :plus, binaryOperator( operatorCall(OPERATOR_INTRINSICGAS), :mult, operatorCall(OPERATOR_GASPRICE)))
|
520
|
+
}
|
521
|
+
end
|
522
|
+
|
523
|
+
|
524
|
+
# Create macro to inialize transaction
|
525
|
+
def service_start
|
526
|
+
Sbuilder::Ial.macro do
|
527
|
+
name MACRO_SERVICE_START
|
528
|
+
block {
|
529
|
+
assignTo {
|
530
|
+
variable variableRef(VARIABLE_STORAGE_ROOT_TEMP)
|
531
|
+
expression toSequence( variableRef(VARIABLE_STORAGE_ROOT ))
|
532
|
+
}
|
533
|
+
assignTo {
|
534
|
+
variable variableRef(VARIABLE_ACCOUNTS_TEMP)
|
535
|
+
expression toSequence( variableRef(VARIABLE_ACCOUNTS ))
|
536
|
+
}
|
537
|
+
}
|
538
|
+
|
539
|
+
end
|
540
|
+
end
|
541
|
+
|
542
|
+
|
543
|
+
# Create a macro to push 'service' state to transaction state
|
544
|
+
def service_push
|
545
|
+
|
546
|
+
Sbuilder::Ial.macro do
|
547
|
+
name MACRO_SERVICE_PUSH
|
548
|
+
block {
|
549
|
+
assignTo {
|
550
|
+
variable variableRef(VARIABLE_STORAGE_ROOT_TEMP)
|
551
|
+
expression pushServiceStateVariable(VARIABLE_STORAGE_ROOT_TEMP)
|
552
|
+
}
|
553
|
+
assignTo {
|
554
|
+
variable variableRef(VARIABLE_ACCOUNTS_TEMP)
|
555
|
+
expression pushServiceStateVariable(VARIABLE_ACCOUNTS_TEMP)
|
556
|
+
}
|
557
|
+
}
|
558
|
+
end
|
559
|
+
end
|
560
|
+
|
561
|
+
def service_pop
|
562
|
+
|
563
|
+
Sbuilder::Ial.macro do
|
564
|
+
p1 = 'interface'
|
565
|
+
|
566
|
+
name MACRO_SERVICE_POP
|
567
|
+
parameters p1
|
568
|
+
block {
|
569
|
+
|
570
|
+
ifThen( binaryOperator( infraOperatorCall(INFRA_READ_RETURN, parameterRef(p1)), :equal, true ) ) {
|
571
|
+
|
572
|
+
assignTo {
|
573
|
+
variable variableRef(VARIABLE_STORAGE_ROOT_TEMP, )
|
574
|
+
expression infraOperatorCall( INFRA_SVC_STACK_ACCEPT, variableRef(VARIABLE_STORAGE_ROOT_TEMP))
|
575
|
+
}
|
576
|
+
|
577
|
+
assignTo {
|
578
|
+
variable variableRef(VARIABLE_ACCOUNTS_TEMP)
|
579
|
+
expression infraOperatorCall( INFRA_SVC_STACK_ACCEPT, variableRef(VARIABLE_ACCOUNTS_TEMP))
|
580
|
+
}
|
581
|
+
|
582
|
+
}.elseThen {
|
583
|
+
|
584
|
+
assignTo {
|
585
|
+
variable variableRef(VARIABLE_STORAGE_ROOT_TEMP)
|
586
|
+
expression infraOperatorCall(INFRA_SVC_STACK_REJECT, variableRef(VARIABLE_STORAGE_ROOT_TEMP))
|
587
|
+
}
|
588
|
+
|
589
|
+
assignTo {
|
590
|
+
variable variableRef(VARIABLE_ACCOUNTS_TEMP)
|
591
|
+
expression infraOperatorCall(INFRA_SVC_STACK_REJECT, variableRef(VARIABLE_ACCOUNTS_TEMP))
|
592
|
+
}
|
593
|
+
|
594
|
+
}
|
595
|
+
}
|
596
|
+
end
|
597
|
+
|
598
|
+
end
|
599
|
+
|
600
|
+
def service_done
|
601
|
+
|
602
|
+
Sbuilder::Ial.macro do
|
603
|
+
p1 = 'interface'
|
604
|
+
|
605
|
+
name MACRO_SERVICE_DONE
|
606
|
+
parameters p1
|
607
|
+
block {
|
608
|
+
|
609
|
+
|
610
|
+
ifThen( binaryOperator( infraOperatorCall(INFRA_READ_RETURN, parameterRef(p1)), :equal, true ) ) {
|
611
|
+
assignTo {
|
612
|
+
variable variableRef(VARIABLE_STORAGE_ROOT, )
|
613
|
+
expression infraOperatorCall( INFRA_SVC_STACK_ACCEPT, variableRef(VARIABLE_STORAGE_ROOT_TEMP))
|
614
|
+
}
|
615
|
+
assignTo {
|
616
|
+
variable variableRef(VARIABLE_ACCOUNTS)
|
617
|
+
expression infraOperatorCall( INFRA_SVC_STACK_ACCEPT, variableRef(VARIABLE_ACCOUNTS_TEMP))
|
618
|
+
}
|
619
|
+
}
|
620
|
+
|
621
|
+
assignTo {
|
622
|
+
variable variableRef(VARIABLE_STORAGE_ROOT_TEMP)
|
623
|
+
expression true
|
624
|
+
}
|
625
|
+
|
626
|
+
assignTo {
|
627
|
+
variable variableRef(VARIABLE_ACCOUNTS_TEMP)
|
628
|
+
expression true
|
629
|
+
}
|
630
|
+
|
631
|
+
} # block
|
632
|
+
end
|
633
|
+
end
|
634
|
+
|
635
|
+
# ------------------------------------------------------------------
|
636
|
+
# Library
|
637
|
+
|
638
|
+
|
639
|
+
# @return [(Snippet|Domain):Array] model element to load to
|
640
|
+
def library
|
641
|
+
[
|
642
|
+
domainDefinition(DOMAIN_ADDRESS),
|
643
|
+
domainDefinition(DOMAIN_VALUE),
|
644
|
+
domainDefinition(DOMAIN_GAS),
|
645
|
+
domainDefinition(DOMAIN_CODE_HASH),
|
646
|
+
variableDefinition(VARIABLE_ACCOUNTS),
|
647
|
+
variableDefinition(VARIABLE_ADDRESS),
|
648
|
+
variableDefinition(VARIABLE_MINED),
|
649
|
+
variableDefinition(VARIABLE_ADDRESS_FREE, domainSetMinusNil(DOMAIN_ADDRESS) ),
|
650
|
+
variableDefinition(VARIABLE_STORAGE_ROOT),
|
651
|
+
variableDefinition(VARIABLE_ACCOUNTS_TEMP, emptySequence ),
|
652
|
+
variableDefinition(VARIABLE_STORAGE_ROOT_TEMP, emptySequence ),
|
653
|
+
# Macros
|
654
|
+
operator_gasPrice,
|
655
|
+
operator_transactionGas,
|
656
|
+
operator_intrinsicGas,
|
657
|
+
operator_upFrontCost,
|
658
|
+
operator_gasValue,
|
659
|
+
# Macros
|
660
|
+
service_start,
|
661
|
+
service_push,
|
662
|
+
service_pop,
|
663
|
+
service_done,
|
664
|
+
]
|
665
|
+
end
|
666
|
+
end # self
|
667
|
+
end # class Ethereum
|
668
|
+
end
|
669
|
+
end
|
data/lib/ethereum.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require_relative 'ethereum/ethereum.rb'
|