Skip to content

Commit

Permalink
Merge pull request #3160 from jorgemmsilva/refactor/solo-evm-helper
Browse files Browse the repository at this point in the history
refactor: (solo) add DeployEVMContract helper func
  • Loading branch information
jorgemmsilva authored Dec 12, 2023
2 parents 70da30e + e0a04b5 commit ad8c462
Show file tree
Hide file tree
Showing 4 changed files with 61 additions and 48 deletions.
45 changes: 45 additions & 0 deletions packages/solo/chain.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,27 @@ package solo

import (
"context"
"crypto/ecdsa"
"errors"
"fmt"
"io"
"math"
"math/big"
"os"
"strings"
"time"

"github.com/ethereum/go-ethereum"
"github.com/ethereum/go-ethereum/accounts/abi"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/crypto"
"github.com/stretchr/testify/require"

iotago "github.com/iotaledger/iota.go/v3"
"github.com/iotaledger/wasp/packages/chain"
"github.com/iotaledger/wasp/packages/cryptolib"
"github.com/iotaledger/wasp/packages/evm/evmutil"
"github.com/iotaledger/wasp/packages/hashing"
"github.com/iotaledger/wasp/packages/isc"
"github.com/iotaledger/wasp/packages/kv"
Expand Down Expand Up @@ -275,6 +284,42 @@ func (ch *Chain) DeployWasmContract(keyPair *cryptolib.KeyPair, name, fname stri
return ch.DeployContract(keyPair, name, hprog, params...)
}

// DeployEVMContract deploys an evm contract on the chain
func (ch *Chain) DeployEVMContract(creator *ecdsa.PrivateKey, abiJSON string, bytecode []byte, args ...interface{}) (common.Address, abi.ABI) {
creatorAddress := crypto.PubkeyToAddress(creator.PublicKey)

nonce := ch.Nonce(isc.NewEthereumAddressAgentID(ch.ChainID, creatorAddress))

contractABI, err := abi.JSON(strings.NewReader(abiJSON))
require.NoError(ch.Env.T, err)
constructorArguments, err := contractABI.Pack("", args...)
require.NoError(ch.Env.T, err)

data := []byte{}
data = append(data, bytecode...)
data = append(data, constructorArguments...)

value := big.NewInt(0)

gasLimit, err := ch.EVM().EstimateGas(ethereum.CallMsg{
From: creatorAddress,
Value: value,
Data: data,
}, nil)
require.NoError(ch.Env.T, err)

tx, err := types.SignTx(
types.NewContractCreation(nonce, value, gasLimit, ch.EVM().GasPrice(), data),
evmutil.Signer(big.NewInt(int64(ch.EVM().ChainID()))),
creator,
)
require.NoError(ch.Env.T, err)

err = ch.EVM().SendTransaction(tx)
require.NoError(ch.Env.T, err)
return crypto.CreateAddress(creatorAddress, nonce), contractABI
}

// GetInfo return main parameters of the chain:
// - chainID
// - agentID of the chain owner
Expand Down
3 changes: 2 additions & 1 deletion packages/vm/core/evm/evmtest/contractInstance.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import (
"github.com/ethereum/go-ethereum/rpc"
"github.com/stretchr/testify/require"

"github.com/iotaledger/wasp/packages/evm/evmutil"
"github.com/iotaledger/wasp/packages/isc"
)

Expand Down Expand Up @@ -103,7 +104,7 @@ func (e *EVMContractInstance) buildEthTx(opts []ethCallOptions, fnName string, a

unsignedTx := types.NewTransaction(nonce, e.address, opt.value, opt.gasLimit, opt.gasPrice, callData)

return types.SignTx(unsignedTx, e.chain.getSigner(), opt.sender)
return types.SignTx(unsignedTx, evmutil.Signer(big.NewInt(int64(e.chain.evmChain.ChainID()))), opt.sender)
}

func (e *EVMContractInstance) estimateGas(opts []ethCallOptions, fnName string, args ...interface{}) (uint64, error) {
Expand Down
17 changes: 12 additions & 5 deletions packages/vm/core/evm/evmtest/evm_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1598,7 +1598,7 @@ func TestEVMGasPriceMismatch(t *testing.T) {
nonce := storage.chain.getNonce(senderAddress)
unsignedTx := types.NewTransaction(nonce, storage.address, util.Big0, env.maxGasLimit(), gasPrice, callArguments)

tx, err := types.SignTx(unsignedTx, storage.chain.getSigner(), ethKey)
tx, err := types.SignTx(unsignedTx, evmutil.Signer(big.NewInt(int64(storage.chain.evmChain.ChainID()))), ethKey)
require.NoError(t, err)

err = storage.chain.evmChain.SendTransaction(tx)
Expand Down Expand Up @@ -2201,9 +2201,16 @@ func TestPreEIP155Transaction(t *testing.T) {
env := InitEVM(t)
ethKey, _ := env.Chain.EthereumAccountByIndexWithL2Funds(0)

// set a signer without replay protection
env.setSigner(types.HomesteadSigner{})
// use a signer without replay protection
signer := types.HomesteadSigner{}

// deploy solidity `storage` contract, it should suceeed
env.deployStorageContract(ethKey)
tx, err := types.SignTx(
types.NewContractCreation(0, big.NewInt(1_000_000_000), 1_000_000_000, env.evmChain.GasPrice(), nil),
signer,
ethKey,
)
require.NoError(t, err)

err = env.evmChain.SendTransaction(tx)
require.NoError(t, err)
}
44 changes: 2 additions & 42 deletions packages/vm/core/evm/evmtest/setup.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,9 @@ import (
"strings"
"testing"

"github.com/ethereum/go-ethereum"
"github.com/ethereum/go-ethereum/accounts/abi"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/crypto"
"github.com/stretchr/testify/require"

iotago "github.com/iotaledger/iota.go/v3"
Expand Down Expand Up @@ -258,57 +256,19 @@ func (e *SoloChainEnv) deployERC20ExampleContract(creator *ecdsa.PrivateKey) *er
return &erc20ContractInstance{e.DeployContract(creator, evmtest.ERC20ExampleContractABI, evmtest.ERC20ExampleContractBytecode)}
}

func (e *SoloChainEnv) setSigner(s types.Signer) {
e.signer = s
}

func (e *SoloChainEnv) getSigner() types.Signer {
return e.signer
}

func (e *SoloChainEnv) maxGasLimit() uint64 {
fp := e.Chain.GetGasFeePolicy()
gl := e.Chain.GetGasLimits()
return gas.EVMCallGasLimit(gl, &fp.EVMGasRatio)
}

func (e *SoloChainEnv) DeployContract(creator *ecdsa.PrivateKey, abiJSON string, bytecode []byte, args ...interface{}) *EVMContractInstance {
creatorAddress := crypto.PubkeyToAddress(creator.PublicKey)

nonce := e.getNonce(creatorAddress)

contractABI, err := abi.JSON(strings.NewReader(abiJSON))
require.NoError(e.t, err)
constructorArguments, err := contractABI.Pack("", args...)
require.NoError(e.t, err)

data := []byte{}
data = append(data, bytecode...)
data = append(data, constructorArguments...)

value := big.NewInt(0)

gasLimit, err := e.evmChain.EstimateGas(ethereum.CallMsg{
From: creatorAddress,
Value: value,
Data: data,
}, nil)
require.NoError(e.t, err)

tx, err := types.SignTx(
types.NewContractCreation(nonce, value, gasLimit, e.evmChain.GasPrice(), data),
e.getSigner(),
creator,
)
require.NoError(e.t, err)

err = e.evmChain.SendTransaction(tx)
require.NoError(e.t, err)
contractAddr, contractABI := e.Chain.DeployEVMContract(creator, abiJSON, bytecode, args...)

return &EVMContractInstance{
chain: e,
defaultSender: creator,
address: crypto.CreateAddress(creatorAddress, nonce),
address: contractAddr,
abi: contractABI,
}
}
Expand Down

0 comments on commit ad8c462

Please sign in to comment.