github.com/onflow/flow-go@v0.33.17/fvm/evm/testutils/accounts.go (about) 1 package testutils 2 3 import ( 4 "bytes" 5 "crypto/ecdsa" 6 "io" 7 "math/big" 8 "sync" 9 "testing" 10 11 gethCommon "github.com/ethereum/go-ethereum/common" 12 gethTypes "github.com/ethereum/go-ethereum/core/types" 13 gethCrypto "github.com/ethereum/go-ethereum/crypto" 14 "github.com/stretchr/testify/require" 15 16 "github.com/onflow/atree" 17 18 "github.com/onflow/flow-go/fvm/evm/emulator" 19 "github.com/onflow/flow-go/fvm/evm/types" 20 "github.com/onflow/flow-go/model/flow" 21 ) 22 23 // address: 658bdf435d810c91414ec09147daa6db62406379 24 const EOATestAccount1KeyHex = "9c647b8b7c4e7c3490668fb6c11473619db80c93704c70893d3813af4090c39c" 25 26 type EOATestAccount struct { 27 address gethCommon.Address 28 key *ecdsa.PrivateKey 29 nonce uint64 30 signer gethTypes.Signer 31 lock sync.Mutex 32 } 33 34 func (a *EOATestAccount) Address() types.Address { 35 return types.Address(a.address) 36 } 37 38 func (a *EOATestAccount) PrepareSignAndEncodeTx( 39 t testing.TB, 40 to gethCommon.Address, 41 data []byte, 42 amount *big.Int, 43 gasLimit uint64, 44 gasPrice *big.Int, 45 ) []byte { 46 tx := a.PrepareAndSignTx(t, to, data, amount, gasLimit, gasPrice) 47 var b bytes.Buffer 48 writer := io.Writer(&b) 49 err := tx.EncodeRLP(writer) 50 require.NoError(t, err) 51 return b.Bytes() 52 } 53 54 func (a *EOATestAccount) PrepareAndSignTx( 55 t testing.TB, 56 to gethCommon.Address, 57 data []byte, 58 amount *big.Int, 59 gasLimit uint64, 60 gasPrice *big.Int, 61 ) *gethTypes.Transaction { 62 a.lock.Lock() 63 defer a.lock.Unlock() 64 65 tx := a.signTx( 66 t, 67 gethTypes.NewTransaction( 68 a.nonce, 69 to, 70 amount, 71 gasLimit, 72 gasPrice, 73 data, 74 ), 75 ) 76 a.nonce++ 77 78 return tx 79 } 80 81 func (a *EOATestAccount) SignTx( 82 t testing.TB, 83 tx *gethTypes.Transaction, 84 ) *gethTypes.Transaction { 85 a.lock.Lock() 86 defer a.lock.Unlock() 87 88 return a.signTx(t, tx) 89 } 90 91 func (a *EOATestAccount) signTx( 92 t testing.TB, 93 tx *gethTypes.Transaction, 94 ) *gethTypes.Transaction { 95 tx, err := gethTypes.SignTx(tx, a.signer, a.key) 96 require.NoError(t, err) 97 return tx 98 } 99 100 func (a *EOATestAccount) SetNonce(nonce uint64) { 101 a.lock.Lock() 102 defer a.lock.Unlock() 103 104 a.nonce = nonce 105 } 106 107 func GetTestEOAAccount(t testing.TB, keyHex string) *EOATestAccount { 108 key, _ := gethCrypto.HexToECDSA(keyHex) 109 address := gethCrypto.PubkeyToAddress(key.PublicKey) 110 signer := emulator.GetDefaultSigner() 111 return &EOATestAccount{ 112 address: address, 113 key: key, 114 signer: signer, 115 lock: sync.Mutex{}, 116 } 117 } 118 119 func RunWithEOATestAccount(t testing.TB, led atree.Ledger, flowEVMRootAddress flow.Address, f func(*EOATestAccount)) { 120 account := FundAndGetEOATestAccount(t, led, flowEVMRootAddress) 121 f(account) 122 } 123 124 func FundAndGetEOATestAccount(t testing.TB, led atree.Ledger, flowEVMRootAddress flow.Address) *EOATestAccount { 125 account := GetTestEOAAccount(t, EOATestAccount1KeyHex) 126 127 // fund account 128 e := emulator.NewEmulator(led, flowEVMRootAddress) 129 130 blk, err := e.NewBlockView(types.NewDefaultBlockContext(2)) 131 require.NoError(t, err) 132 133 _, err = blk.DirectCall( 134 types.NewDepositCall( 135 account.Address(), 136 new(big.Int).Mul(big.NewInt(1e18), big.NewInt(1000)), 137 ), 138 ) 139 require.NoError(t, err) 140 141 blk2, err := e.NewReadOnlyBlockView(types.NewDefaultBlockContext(2)) 142 require.NoError(t, err) 143 144 bal, err := blk2.BalanceOf(account.Address()) 145 require.NoError(t, err) 146 require.Greater(t, bal.Uint64(), uint64(0)) 147 148 return account 149 }