@@ -7,23 +7,41 @@ import { keccak256 } from '../utils/keccak256';
7
7
import { RlpEncoder } from '../rlp' ;
8
8
import { getBufferFromHex } from '../utils/getBufferFromHex' ;
9
9
import { Address } from './Address' ;
10
+ import { convertNumberToPadHex } from '../utils/convertNumberToPadHex' ;
11
+ import { EvmMemory } from './EvmMemory' ;
12
+ import { ExposedEvm } from './ExposedEvm' ;
13
+ import { collapseTextChangeRangesAcrossMultipleVersions } from 'typescript' ;
10
14
11
15
export class Contract {
12
16
private _address : string ;
17
+ private _returnData ?: Buffer ;
13
18
14
19
constructor (
15
20
private bytes : Buffer ,
16
21
private _value : BigNumber ,
17
- private context : TxContext
22
+ private context : TxContext ,
23
+ private salt ?: Buffer // private evm?: Evm
18
24
) {
19
25
// https://ethereum.stackexchange.com/a/101340
20
26
// https://www.evm.codes/#f0
21
27
const rlp = getClassFromTestContainer ( RlpEncoder ) ;
22
28
const encoding = rlp . encode ( {
23
29
input : [ context . sender . raw || crypto . randomBytes ( 32 ) , context . nonce ] ,
24
30
} ) ;
25
- this . _address =
26
- '0x' + keccak256 ( getBufferFromHex ( encoding ) ) . slice ( 12 ) . toString ( 'hex' ) ;
31
+ if ( this . salt ) {
32
+ const dataHash = keccak256 ( bytes ) ;
33
+ const address = keccak256 (
34
+ getBufferFromHex (
35
+ `0xff${ convertNumberToPadHex (
36
+ context . sender . raw . toString ( 16 )
37
+ ) } ${ salt ?. toString ( 'hex' ) } ${ dataHash . toString ( 'hex' ) } `
38
+ )
39
+ ) ;
40
+ this . _address = '0x' + address . slice ( 12 ) . toString ( 'hex' ) ;
41
+ } else {
42
+ this . _address =
43
+ '0x' + keccak256 ( getBufferFromHex ( encoding ) ) . slice ( 12 ) . toString ( 'hex' ) ;
44
+ }
27
45
}
28
46
29
47
public get value ( ) {
@@ -42,24 +60,42 @@ export class Contract {
42
60
return new Address ( this . _address ) ;
43
61
}
44
62
45
- public execute ( ) {
63
+ public execute (
64
+ options : Partial < TxContext > & {
65
+ evm ?: Evm ;
66
+ }
67
+ ) {
46
68
// This should be done in another way -> Redo this in a better way.
47
69
// The result of this execution will also effect the previous context, so we need to be able to continue in same context.
48
70
// by having it in a different container this is not the case.
49
71
// I think that all access sets done in this new contract also will affect the ones in the current context.
50
- const evm = getClassFromTestContainer ( Evm )
51
- . boot ( this . bytes , {
52
- value : new Wei ( this . value . toNumber ( ) ) ,
53
- data : Buffer . from ( '' ) ,
54
- nonce : 0 ,
55
- sender : this . context . sender ,
56
- gasLimit : this . context . gasLimit ,
57
- } )
72
+ const data = options . data || Buffer . from ( '' ) ;
73
+ const evm = getClassFromTestContainer ( ExposedEvm ) ;
74
+ if ( options . evm ) {
75
+ evm . copy ( options . evm ) ;
76
+ }
77
+ evm
78
+ . boot (
79
+ this . bytes ,
80
+ {
81
+ value : new Wei ( this . value . toNumber ( ) ) ,
82
+ data,
83
+ nonce : 0 ,
84
+ sender : this . context . sender ,
85
+ gasLimit : this . context . gasLimit ,
86
+ } ,
87
+ { debug : false }
88
+ )
58
89
. execute ( ) ;
59
90
if ( evm . callingContextReturnData ) {
91
+ this . _returnData = evm . callingContextReturnData ;
60
92
this . bytes = evm . callingContextReturnData ;
61
93
}
62
94
63
95
return this ;
64
96
}
97
+
98
+ public get returnData ( ) {
99
+ return this . _returnData ;
100
+ }
65
101
}
0 commit comments