1
+ import BN = require( 'bn.js' )
2
+ import PStateManager from '../state/promisified'
3
+ import Message from './message'
4
+ import { toBuffer } from 'ethereumjs-util'
1
5
const promisify = require ( 'util.promisify' )
2
- const BN = require ( 'bn.js' )
3
6
const { VmError, ERROR } = require ( '../exceptions' )
4
- const PStateManager = require ( '../state/promisified' ) . default
5
- const Message = require ( './message' )
6
7
7
- module . exports = class EEI {
8
- constructor ( env ) {
8
+ export default class EEI {
9
+ _env : any
10
+ _state : PStateManager
11
+
12
+ constructor ( env : any ) {
9
13
this . _env = env
10
14
this . _state = new PStateManager ( this . _env . stateManager )
11
15
}
@@ -15,7 +19,7 @@ module.exports = class EEI {
15
19
* @param {BN } amount - Amount of gas to consume
16
20
* @throws if out of gas
17
21
*/
18
- useGas ( amount ) {
22
+ useGas ( amount : BN ) : void {
19
23
this . _env . gasLeft . isub ( amount )
20
24
if ( this . _env . gasLeft . ltn ( 0 ) ) {
21
25
this . _env . gasLeft = new BN ( 0 )
@@ -27,24 +31,24 @@ module.exports = class EEI {
27
31
* Returns address of currently executing account.
28
32
* @returns {Buffer }
29
33
*/
30
- getAddress ( ) {
34
+ getAddress ( ) : Buffer {
31
35
return this . _env . address
32
36
}
33
37
34
38
/**
35
39
* Returns balance of the given account.
36
40
* @param {BN } address - Address of account
37
41
*/
38
- async getExternalBalance ( address ) {
39
- address = addressToBuffer ( address )
42
+ async getExternalBalance ( address : BN ) : Promise < BN > {
43
+ const addressBuf = addressToBuffer ( address )
40
44
41
45
// shortcut if current account
42
- if ( address . toString ( 'hex' ) === this . _env . address . toString ( 'hex' ) ) {
46
+ if ( addressBuf . toString ( 'hex' ) === this . _env . address . toString ( 'hex' ) ) {
43
47
return new BN ( this . _env . contract . balance )
44
48
}
45
49
46
50
// otherwise load account then return balance
47
- const account = await this . _state . getAccount ( address )
51
+ const account = await this . _state . getAccount ( addressBuf )
48
52
return new BN ( account . balance )
49
53
}
50
54
@@ -53,7 +57,7 @@ module.exports = class EEI {
53
57
* that is directly responsible for this execution.
54
58
* @returns {BN }
55
59
*/
56
- getCaller ( ) {
60
+ getCaller ( ) : BN {
57
61
return new BN ( this . _env . caller )
58
62
}
59
63
@@ -62,7 +66,7 @@ module.exports = class EEI {
62
66
* responsible for this execution.
63
67
* @returns {BN }
64
68
*/
65
- getCallValue ( ) {
69
+ getCallValue ( ) : BN {
66
70
return new BN ( this . _env . callValue )
67
71
}
68
72
@@ -72,7 +76,7 @@ module.exports = class EEI {
72
76
* @param {BN } pos - Offset of calldata
73
77
* @returns {Buffer }
74
78
*/
75
- getCallData ( pos ) {
79
+ getCallData ( pos : BN ) : Buffer {
76
80
return this . _env . callData
77
81
}
78
82
@@ -81,7 +85,7 @@ module.exports = class EEI {
81
85
* input data passed with the message call instruction or transaction.
82
86
* @returns {BN }
83
87
*/
84
- getCallDataSize ( ) {
88
+ getCallDataSize ( ) : BN {
85
89
if ( this . _env . callData . length === 1 && this . _env . callData [ 0 ] === 0 ) {
86
90
return new BN ( 0 )
87
91
}
@@ -93,33 +97,33 @@ module.exports = class EEI {
93
97
* Returns the size of code running in current environment.
94
98
* @returns {BN }
95
99
*/
96
- getCodeSize ( ) {
100
+ getCodeSize ( ) : BN {
97
101
return new BN ( this . _env . code . length )
98
102
}
99
103
100
104
/**
101
105
* Returns the code running in current environment.
102
106
* @returns {BN }
103
107
*/
104
- getCode ( ) {
108
+ getCode ( ) : BN {
105
109
return this . _env . code
106
110
}
107
111
108
112
/**
109
113
* Get size of an account’s code.
110
114
* @param {BN } address - Address of account
111
115
*/
112
- async getExternalCodeSize ( address ) {
113
- address = addressToBuffer ( address )
114
- const code = await this . _state . getContractCode ( address )
116
+ async getExternalCodeSize ( address : BN ) : Promise < BN > {
117
+ const addressBuf = addressToBuffer ( address )
118
+ const code = await this . _state . getContractCode ( addressBuf )
115
119
return new BN ( code . length )
116
120
}
117
121
118
122
/**
119
123
* Returns code of an account.
120
124
* @param {BN } address - Address of account
121
125
*/
122
- async getExternalCode ( address ) {
126
+ async getExternalCode ( address : BN | Buffer ) : Promise < Buffer > {
123
127
if ( ! Buffer . isBuffer ( address ) ) {
124
128
address = addressToBuffer ( address )
125
129
}
@@ -132,7 +136,7 @@ module.exports = class EEI {
132
136
* Note: create only fills the return data buffer in case of a failure.
133
137
* @returns {BN }
134
138
*/
135
- getReturnDataSize ( ) {
139
+ getReturnDataSize ( ) : BN {
136
140
return new BN ( this . _env . lastReturned . length )
137
141
}
138
142
@@ -142,15 +146,15 @@ module.exports = class EEI {
142
146
* Note: create only fills the return data buffer in case of a failure.
143
147
* @returns {Buffer }
144
148
*/
145
- getReturnData ( ) {
149
+ getReturnData ( ) : Buffer {
146
150
return this . _env . lastReturned
147
151
}
148
152
149
153
/**
150
154
* Returns price of gas in current environment.
151
155
* @returns {BN }
152
156
*/
153
- getTxGasPrice ( ) {
157
+ getTxGasPrice ( ) : BN {
154
158
return new BN ( this . _env . gasPrice )
155
159
}
156
160
@@ -160,56 +164,56 @@ module.exports = class EEI {
160
164
* non-empty associated code.
161
165
* @returns {BN }
162
166
*/
163
- getTxOrigin ( ) {
167
+ getTxOrigin ( ) : BN {
164
168
return new BN ( this . _env . origin )
165
169
}
166
170
167
171
/**
168
172
* Returns the block’s number.
169
173
* @returns {BN }
170
174
*/
171
- getBlockNumber ( ) {
175
+ getBlockNumber ( ) : BN {
172
176
return new BN ( this . _env . block . header . number )
173
177
}
174
178
175
179
/**
176
180
* Returns the block's beneficiary address.
177
181
* @returns {BN }
178
182
*/
179
- getBlockCoinbase ( ) {
183
+ getBlockCoinbase ( ) : BN {
180
184
return new BN ( this . _env . block . header . coinbase )
181
185
}
182
186
183
187
/**
184
188
* Returns the block's timestamp.
185
189
* @returns {BN }
186
190
*/
187
- getBlockTimestamp ( ) {
191
+ getBlockTimestamp ( ) : BN {
188
192
return new BN ( this . _env . block . header . timestamp )
189
193
}
190
194
191
195
/**
192
196
* Returns the block's difficulty.
193
197
* @returns {BN }
194
198
*/
195
- getBlockDifficulty ( ) {
199
+ getBlockDifficulty ( ) : BN {
196
200
return new BN ( this . _env . block . header . difficulty )
197
201
}
198
202
199
203
/**
200
204
* Returns the block's gas limit.
201
205
* @returns {BN }
202
206
*/
203
- getBlockGasLimit ( ) {
207
+ getBlockGasLimit ( ) : BN {
204
208
return new BN ( this . _env . block . header . gasLimit )
205
209
}
206
210
207
211
/**
208
212
* Returns Gets the hash of one of the 256 most recent complete blocks.
209
213
* @param {BN } - Number of block
210
214
*/
211
- async getBlockHash ( number ) {
212
- const block = await promisify ( this . _env . blockchain . getBlock ) . bind ( this . _env . blockchain ) ( number )
215
+ async getBlockHash ( num : BN ) : Promise < BN > {
216
+ const block = await promisify ( this . _env . blockchain . getBlock ) . bind ( this . _env . blockchain ) ( num )
213
217
return new BN ( block . hash ( ) )
214
218
}
215
219
@@ -218,7 +222,7 @@ module.exports = class EEI {
218
222
* @param {Buffer } key
219
223
* @param {Buffer } value
220
224
*/
221
- async storageStore ( key , value ) {
225
+ async storageStore ( key : Buffer , value : Buffer ) : Promise < void > {
222
226
await this . _state . putContractStorage ( this . _env . address , key , value )
223
227
const account = await this . _state . getAccount ( this . _env . address )
224
228
this . _env . contract = account
@@ -229,23 +233,23 @@ module.exports = class EEI {
229
233
* @param {Buffer } key - Storage key
230
234
* @returns {Buffer }
231
235
*/
232
- async storageLoad ( key ) {
236
+ async storageLoad ( key : Buffer ) : Promise < Buffer > {
233
237
return this . _state . getContractStorage ( this . _env . address , key )
234
238
}
235
239
236
240
/**
237
241
* Returns the current gasCounter.
238
242
* @returns {BN }
239
243
*/
240
- getGasLeft ( ) {
244
+ getGasLeft ( ) : BN {
241
245
return new BN ( this . _env . gasLeft )
242
246
}
243
247
244
248
/**
245
249
* Set the returning output data for the execution.
246
250
* @param {Buffer } returnData - Output data to return
247
251
*/
248
- finish ( returnData ) {
252
+ finish ( returnData : Buffer ) : void {
249
253
this . _env . returnValue = returnData
250
254
}
251
255
@@ -254,7 +258,7 @@ module.exports = class EEI {
254
258
* execution immediately and set the execution result to "reverted".
255
259
* @param {Buffer } returnData - Output data to return
256
260
*/
257
- revert ( returnData ) {
261
+ revert ( returnData : Buffer ) : void {
258
262
this . _env . returnValue = returnData
259
263
trap ( ERROR . REVERT )
260
264
}
@@ -265,11 +269,11 @@ module.exports = class EEI {
265
269
* execution will be aborted immediately.
266
270
* @param {Buffer } toAddress - Beneficiary address
267
271
*/
268
- async selfDestruct ( toAddress ) {
272
+ async selfDestruct ( toAddress : Buffer ) : Promise < void > {
269
273
return this . _selfDestruct ( toAddress )
270
274
}
271
275
272
- async _selfDestruct ( toAddress ) {
276
+ async _selfDestruct ( toAddress : Buffer ) : Promise < void > {
273
277
// TODO: Determine if gas consumption & refund should happen in EEI or opFn
274
278
if ( ( new BN ( this . _env . contract . balance ) ) . gtn ( 0 ) ) {
275
279
const empty = await this . _state . accountIsEmpty ( toAddress )
@@ -289,12 +293,12 @@ module.exports = class EEI {
289
293
// Add to beneficiary balance
290
294
const toAccount = await this . _state . getAccount ( toAddress )
291
295
const newBalance = new BN ( this . _env . contract . balance ) . add ( new BN ( toAccount . balance ) )
292
- toAccount . balance = newBalance
296
+ toAccount . balance = toBuffer ( newBalance )
293
297
await this . _state . putAccount ( toAddress , toAccount )
294
298
295
299
// Subtract from contract balance
296
300
const account = await this . _state . getAccount ( this . _env . address )
297
- account . balance = new BN ( 0 )
301
+ account . balance = toBuffer ( new BN ( 0 ) )
298
302
await this . _state . putAccount ( this . _env . address , account )
299
303
}
300
304
@@ -304,7 +308,7 @@ module.exports = class EEI {
304
308
* @param {Number } numberOfTopics
305
309
* @param {BN[] } topics
306
310
*/
307
- log ( data , numberOfTopics , topics ) {
311
+ log ( data : Buffer , numberOfTopics : number , topics : BN [ ] ) : void {
308
312
if ( numberOfTopics < 0 || numberOfTopics > 4 ) {
309
313
trap ( ERROR . OUT_OF_RANGE )
310
314
}
@@ -329,7 +333,7 @@ module.exports = class EEI {
329
333
* @param {BN } value
330
334
* @param {Buffer } data
331
335
*/
332
- async call ( gasLimit , address , value , data ) {
336
+ async call ( gasLimit : BN , address : Buffer , value : BN , data : Buffer ) : Promise < BN > {
333
337
const msg = new Message ( {
334
338
caller : this . _env . address ,
335
339
gasLimit : gasLimit ,
@@ -350,7 +354,7 @@ module.exports = class EEI {
350
354
* @param {BN } value
351
355
* @param {Buffer } data
352
356
*/
353
- async callCode ( gasLimit , address , value , data ) {
357
+ async callCode ( gasLimit : BN , address : Buffer , value : BN , data : Buffer ) : Promise < BN > {
354
358
const msg = new Message ( {
355
359
caller : this . _env . address ,
356
360
gasLimit : gasLimit ,
@@ -374,7 +378,7 @@ module.exports = class EEI {
374
378
* @param {BN } value
375
379
* @param {Buffer } data
376
380
*/
377
- async callStatic ( gasLimit , address , value , data ) {
381
+ async callStatic ( gasLimit : BN , address : Buffer , value : BN , data : Buffer ) : Promise < BN > {
378
382
const msg = new Message ( {
379
383
caller : this . _env . address ,
380
384
gasLimit : gasLimit ,
@@ -396,7 +400,7 @@ module.exports = class EEI {
396
400
* @param {BN } value
397
401
* @param {Buffer } data
398
402
*/
399
- async callDelegate ( gasLimit , address , value , data ) {
403
+ async callDelegate ( gasLimit : BN , address : Buffer , value : BN , data : Buffer ) : Promise < BN > {
400
404
const msg = new Message ( {
401
405
caller : this . _env . caller ,
402
406
gasLimit : gasLimit ,
@@ -412,7 +416,7 @@ module.exports = class EEI {
412
416
return this . _baseCall ( msg )
413
417
}
414
418
415
- async _baseCall ( msg ) {
419
+ async _baseCall ( msg : Message ) : Promise < BN > {
416
420
const selfdestruct = Object . assign ( { } , this . _env . selfdestruct )
417
421
msg . selfdestruct = selfdestruct
418
422
@@ -460,7 +464,7 @@ module.exports = class EEI {
460
464
* @param {BN } value
461
465
* @param {Buffer } data
462
466
*/
463
- async create ( gasLimit , value , data , salt = null ) {
467
+ async create ( gasLimit : BN , value : BN , data : Buffer , salt : Buffer | null = null ) : Promise < BN > {
464
468
const selfdestruct = Object . assign ( { } , this . _env . selfdestruct )
465
469
const msg = new Message ( {
466
470
caller : this . _env . address ,
@@ -530,16 +534,16 @@ module.exports = class EEI {
530
534
* @param {Buffer } data
531
535
* @param {Buffer } salt
532
536
*/
533
- async create2 ( gasLimit , value , data , salt ) {
537
+ async create2 ( gasLimit : BN , value : BN , data : Buffer , salt : Buffer ) : Promise < BN > {
534
538
return this . create ( gasLimit , value , data , salt )
535
539
}
536
540
}
537
541
538
- function trap ( err ) {
542
+ function trap ( err : string ) {
539
543
throw new VmError ( err )
540
544
}
541
545
542
546
const MASK_160 = new BN ( 1 ) . shln ( 160 ) . subn ( 1 )
543
- function addressToBuffer ( address ) {
547
+ function addressToBuffer ( address : BN ) {
544
548
return address . and ( MASK_160 ) . toArrayLike ( Buffer , 'be' , 20 )
545
549
}
0 commit comments