Skip to content
This repository has been archived by the owner on Dec 23, 2024. It is now read-only.

feat: implement opCreate and opCreate2 in fhevm-go #25

Merged
merged 1 commit into from
Oct 30, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 28 additions & 0 deletions fhevm/evm.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/crypto"
"github.com/holiman/uint256"
ps "github.com/zama-ai/fhevm-go/crypto"
)

// A Logger interface for the EVM.
Expand Down Expand Up @@ -166,3 +167,30 @@ func padArrayTo32Multiple(input []byte) []byte {
}
return input
}

func Create(evm EVMEnvironment, caller common.Address, code []byte, gas uint64, value *big.Int) (ret []byte, contractAddr common.Address, leftOverGas uint64, err error) {
contractAddr = crypto.CreateAddress(caller, evm.GetNonce(caller))
protectedStorageAddr := ps.CreateProtectedStorageContractAddress(contractAddr)
_, _, leftOverGas, err = evm.CreateContract(caller, nil, gas, big.NewInt(0), protectedStorageAddr)
if err != nil {
ret = nil
contractAddr = common.Address{}
return
}
// TODO: consider reverting changes to `protectedStorageAddr` if actual contract creation fails.
return evm.CreateContract(caller, code, leftOverGas, value, contractAddr)
}

func Create2(evm EVMEnvironment, caller common.Address, code []byte, gas uint64, endowment *big.Int, salt *uint256.Int) (ret []byte, contractAddr common.Address, leftOverGas uint64, err error) {
codeHash := crypto.Keccak256Hash(code)
contractAddr = crypto.CreateAddress2(caller, salt.Bytes32(), codeHash.Bytes())
protectedStorageAddr := ps.CreateProtectedStorageContractAddress(contractAddr)
_, _, leftOverGas, err = evm.CreateContract2(caller, nil, common.Hash{}, gas, big.NewInt(0), protectedStorageAddr)
if err != nil {
ret = nil
contractAddr = common.Address{}
return
}
// TODO: consider reverting changes to `protectedStorageAddr` if actual contract creation fails.
return evm.CreateContract2(caller, code, codeHash, leftOverGas, endowment, contractAddr)
}
6 changes: 6 additions & 0 deletions fhevm/interface.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package fhevm

import (
"math/big"

"github.com/ethereum/go-ethereum/common"
"github.com/holiman/uint256"
)
Expand All @@ -9,6 +11,7 @@ type EVMEnvironment interface {
// StateDB related functions
GetState(common.Address, common.Hash) common.Hash
SetState(common.Address, common.Hash, common.Hash)
GetNonce(common.Address) uint64

// EVM call stack depth
GetDepth() int
Expand All @@ -21,6 +24,9 @@ type EVMEnvironment interface {
IsEthCall() bool
IsReadOnly() bool

CreateContract(caller common.Address, code []byte, gas uint64, value *big.Int, address common.Address) ([]byte, common.Address, uint64, error)
CreateContract2(caller common.Address, code []byte, codeHash common.Hash, gas uint64, value *big.Int, address common.Address) ([]byte, common.Address, uint64, error)

GetFhevmData() *FhevmData
}

Expand Down