@@ -25,6 +25,7 @@ import (
25
25
"github.com/ethereum/go-ethereum/crypto"
26
26
"github.com/ethereum/go-ethereum/params"
27
27
"github.com/holiman/uint256"
28
+ "github.com/zama-ai/fhevm-go/fhevm"
28
29
)
29
30
30
31
type (
@@ -120,7 +121,17 @@ type EVM struct {
120
121
// callGasTemp holds the gas available for the current call. This is needed because the
121
122
// available gas is calculated in gasCall* according to the 63/64 rule and later
122
123
// applied in opCall*.
123
- callGasTemp uint64
124
+ callGasTemp uint64
125
+ fhevmEnvironment FhevmImplementation
126
+ isGasEstimation bool
127
+ isEthCall bool
128
+ }
129
+
130
+ type FhevmImplementation struct {
131
+ interpreter * EVMInterpreter
132
+ data fhevm.FhevmData
133
+ logger fhevm.Logger
134
+ params fhevm.FhevmParams
124
135
}
125
136
126
137
// NewEVM returns a new EVM. The returned EVM is not thread safe and should
@@ -138,14 +149,19 @@ func NewEVM(blockCtx BlockContext, txCtx TxContext, statedb StateDB, chainConfig
138
149
}
139
150
}
140
151
evm := & EVM {
141
- Context : blockCtx ,
142
- TxContext : txCtx ,
143
- StateDB : statedb ,
144
- Config : config ,
145
- chainConfig : chainConfig ,
146
- chainRules : chainConfig .Rules (blockCtx .BlockNumber , blockCtx .Random != nil , blockCtx .Time ),
152
+ Context : blockCtx ,
153
+ TxContext : txCtx ,
154
+ StateDB : statedb ,
155
+ Config : config ,
156
+ chainConfig : chainConfig ,
157
+ chainRules : chainConfig .Rules (blockCtx .BlockNumber , blockCtx .Random != nil , blockCtx .Time ),
158
+ fhevmEnvironment : FhevmImplementation {interpreter : nil , logger : & fhevm.DefaultLogger {}, data : fhevm .NewFhevmData (), params : fhevm .DefaultFhevmParams ()},
159
+ isGasEstimation : config .IsGasEstimation ,
160
+ isEthCall : config .IsEthCall ,
147
161
}
148
162
evm .interpreter = NewEVMInterpreter (evm )
163
+ evm .fhevmEnvironment .interpreter = evm .interpreter
164
+ fhevm .InitFhevm (& evm .fhevmEnvironment )
149
165
return evm
150
166
}
151
167
@@ -224,7 +240,7 @@ func (evm *EVM) Call(caller ContractRef, addr common.Address, input []byte, gas
224
240
}
225
241
226
242
if isPrecompile {
227
- ret , gas , err = RunPrecompiledContract (p , input , gas )
243
+ ret , gas , err = RunPrecompiledContract (p , evm , caller . Address (), addr , input , gas )
228
244
} else {
229
245
// Initialise a new contract and set the code that is to be used by the EVM.
230
246
// The contract is a scoped environment for this execution context only.
@@ -287,7 +303,7 @@ func (evm *EVM) CallCode(caller ContractRef, addr common.Address, input []byte,
287
303
288
304
// It is allowed to call precompiles, even via delegatecall
289
305
if p , isPrecompile := evm .precompile (addr ); isPrecompile {
290
- ret , gas , err = RunPrecompiledContract (p , input , gas )
306
+ ret , gas , err = RunPrecompiledContract (p , evm , caller . Address (), addr , input , gas )
291
307
} else {
292
308
addrCopy := addr
293
309
// Initialise a new contract and set the code that is to be used by the EVM.
@@ -332,7 +348,7 @@ func (evm *EVM) DelegateCall(caller ContractRef, addr common.Address, input []by
332
348
333
349
// It is allowed to call precompiles, even via delegatecall
334
350
if p , isPrecompile := evm .precompile (addr ); isPrecompile {
335
- ret , gas , err = RunPrecompiledContract (p , input , gas )
351
+ ret , gas , err = RunPrecompiledContract (p , evm , caller . Address (), addr , input , gas )
336
352
} else {
337
353
addrCopy := addr
338
354
// Initialise a new contract and make initialise the delegate values
@@ -381,7 +397,7 @@ func (evm *EVM) StaticCall(caller ContractRef, addr common.Address, input []byte
381
397
}
382
398
383
399
if p , isPrecompile := evm .precompile (addr ); isPrecompile {
384
- ret , gas , err = RunPrecompiledContract (p , input , gas )
400
+ ret , gas , err = RunPrecompiledContract (p , evm , caller . Address (), addr , input , gas )
385
401
} else {
386
402
// At this point, we use a copy of address. If we don't, the go compiler will
387
403
// leak the 'contract' to the outer scope, and make allocation for 'contract'
@@ -511,19 +527,80 @@ func (evm *EVM) create(caller ContractRef, codeAndHash *codeAndHash, gas uint64,
511
527
512
528
// Create creates a new contract using code as deployment code.
513
529
func (evm * EVM ) Create (caller ContractRef , code []byte , gas uint64 , value * big.Int ) (ret []byte , contractAddr common.Address , leftOverGas uint64 , err error ) {
514
- contractAddr = crypto .CreateAddress (caller .Address (), evm .StateDB .GetNonce (caller .Address ()))
515
- return evm .create (caller , & codeAndHash {code : code }, gas , value , contractAddr , CREATE )
530
+ return fhevm .Create (evm .FhevmEnvironment (), caller .Address (), code , gas , value )
516
531
}
517
532
518
533
// Create2 creates a new contract using code as deployment code.
519
534
//
520
535
// The different between Create2 with Create is Create2 uses keccak256(0xff ++ msg.sender ++ salt ++ keccak256(init_code))[12:]
521
536
// instead of the usual sender-and-nonce-hash as the address where the contract is initialized at.
522
537
func (evm * EVM ) Create2 (caller ContractRef , code []byte , gas uint64 , endowment * big.Int , salt * uint256.Int ) (ret []byte , contractAddr common.Address , leftOverGas uint64 , err error ) {
523
- codeAndHash := & codeAndHash {code : code }
524
- contractAddr = crypto .CreateAddress2 (caller .Address (), salt .Bytes32 (), codeAndHash .Hash ().Bytes ())
525
- return evm .create (caller , codeAndHash , gas , endowment , contractAddr , CREATE2 )
538
+ return fhevm .Create2 (evm .FhevmEnvironment (), caller .Address (), code , gas , endowment , salt )
526
539
}
527
540
528
541
// ChainConfig returns the environment's chain configuration
529
542
func (evm * EVM ) ChainConfig () * params.ChainConfig { return evm .chainConfig }
543
+
544
+ func (evm * EVM ) FhevmEnvironment () fhevm.EVMEnvironment { return & evm .fhevmEnvironment }
545
+
546
+ func (evm * FhevmImplementation ) GetState (addr common.Address , hash common.Hash ) common.Hash {
547
+ return evm .interpreter .evm .StateDB .GetState (addr , hash )
548
+ }
549
+
550
+ func (evm * FhevmImplementation ) SetState (addr common.Address , hash common.Hash , input common.Hash ) {
551
+ evm .interpreter .evm .StateDB .SetState (addr , hash , input )
552
+ }
553
+
554
+ func (evm * FhevmImplementation ) GetNonce (addr common.Address ) uint64 {
555
+ return evm .interpreter .evm .StateDB .GetNonce (addr )
556
+ }
557
+
558
+ func (evm * FhevmImplementation ) AddBalance (addr common.Address , value * big.Int ) {
559
+ evm .interpreter .evm .StateDB .AddBalance (addr , value )
560
+ }
561
+
562
+ func (evm * FhevmImplementation ) GetBalance (addr common.Address ) * big.Int {
563
+ return evm .interpreter .evm .StateDB .GetBalance (addr )
564
+ }
565
+
566
+ // FIXME: Maybe change the interface to SelfDestruct (new version of geth)
567
+ func (evm * FhevmImplementation ) Suicide (addr common.Address ) bool {
568
+ evm .interpreter .evm .StateDB .SelfDestruct (addr )
569
+ return evm .interpreter .evm .StateDB .HasSelfDestructed (addr )
570
+ }
571
+
572
+ func (evm * FhevmImplementation ) GetDepth () int {
573
+ return evm .interpreter .evm .depth
574
+ }
575
+
576
+ func (evm * FhevmImplementation ) IsCommitting () bool {
577
+ return ! evm .interpreter .evm .isGasEstimation
578
+ }
579
+
580
+ func (evm * FhevmImplementation ) IsEthCall () bool {
581
+ return evm .interpreter .evm .isEthCall
582
+ }
583
+
584
+ func (evm * FhevmImplementation ) IsReadOnly () bool {
585
+ return evm .interpreter .readOnly
586
+ }
587
+
588
+ func (evm * FhevmImplementation ) GetLogger () fhevm.Logger {
589
+ return evm .logger
590
+ }
591
+
592
+ func (evm * FhevmImplementation ) FhevmData () * fhevm.FhevmData {
593
+ return & evm .data
594
+ }
595
+
596
+ func (evm * FhevmImplementation ) FhevmParams () * fhevm.FhevmParams {
597
+ return & evm .params
598
+ }
599
+
600
+ func (evm * FhevmImplementation ) CreateContract (caller common.Address , code []byte , gas uint64 , value * big.Int , address common.Address ) ([]byte , common.Address , uint64 , error ) {
601
+ return evm .interpreter .evm .create (AccountRef (caller ), & codeAndHash {code : code }, gas , value , address , CREATE )
602
+ }
603
+
604
+ func (evm * FhevmImplementation ) CreateContract2 (caller common.Address , code []byte , codeHash common.Hash , gas uint64 , value * big.Int , address common.Address ) ([]byte , common.Address , uint64 , error ) {
605
+ return evm .interpreter .evm .create (AccountRef (caller ), & codeAndHash {code : code , hash : codeHash }, gas , value , address , CREATE2 )
606
+ }
0 commit comments