github.com/klaytn/klaytn@v1.10.2/accounts/abi/bind/backends/simulated_test.go (about)

     1  // Modifications Copyright 2020 The klaytn Authors
     2  // Copyright 2019 The go-ethereum Authors
     3  // This file is part of the go-ethereum library.
     4  //
     5  // The go-ethereum library is free software: you can redistribute it and/or modify
     6  // it under the terms of the GNU Lesser General Public License as published by
     7  // the Free Software Foundation, either version 3 of the License, or
     8  // (at your option) any later version.
     9  //
    10  // The go-ethereum library is distributed in the hope that it will be useful,
    11  // but WITHOUT ANY WARRANTY; without even the implied warranty of
    12  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    13  // GNU Lesser General Public License for more details.
    14  //
    15  // You should have received a copy of the GNU Lesser General Public License
    16  // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
    17  //
    18  // This file is derived from accounts/abi/bind/backends/simulated_test.go(2020/11/24).
    19  // Modified and improved for the klaytn development.
    20  
    21  package backends
    22  
    23  import (
    24  	"bytes"
    25  	"context"
    26  	"math/big"
    27  	"strings"
    28  	"testing"
    29  	"time"
    30  
    31  	"github.com/klaytn/klaytn"
    32  	"github.com/klaytn/klaytn/accounts/abi"
    33  	"github.com/klaytn/klaytn/accounts/abi/bind"
    34  	"github.com/klaytn/klaytn/blockchain"
    35  	"github.com/klaytn/klaytn/blockchain/types"
    36  	"github.com/klaytn/klaytn/common"
    37  	"github.com/klaytn/klaytn/crypto"
    38  	"github.com/klaytn/klaytn/params"
    39  )
    40  
    41  func TestSimulatedBackend(t *testing.T) {
    42  	key, _ := crypto.GenerateKey() // nolint: gosec
    43  	auth := bind.NewKeyedTransactor(key)
    44  	genAlloc := make(blockchain.GenesisAlloc)
    45  	genAlloc[auth.From] = blockchain.GenesisAccount{Balance: big.NewInt(9223372036854775807)}
    46  
    47  	sim := NewSimulatedBackend(genAlloc)
    48  	defer sim.Close()
    49  
    50  	// should return an error if the tx is not found
    51  	txHash := common.HexToHash("2")
    52  	_, isPending, err := sim.TransactionByHash(context.Background(), txHash)
    53  
    54  	if isPending {
    55  		t.Fatal("transaction should not be pending")
    56  	}
    57  	if err != klaytn.NotFound {
    58  		t.Fatalf("err should be `klaytn.NotFound` but received %v", err)
    59  	}
    60  
    61  	// generate a transaction and confirm you can retrieve it
    62  	code := `6060604052600a8060106000396000f360606040526008565b00`
    63  	var gas uint64 = 3000000
    64  	tx := types.NewContractCreation(0, big.NewInt(0), gas, big.NewInt(1), common.FromHex(code))
    65  	tx, _ = types.SignTx(tx, types.LatestSignerForChainID(sim.config.ChainID), key)
    66  
    67  	err = sim.SendTransaction(context.Background(), tx)
    68  	if err != nil {
    69  		t.Fatal("error sending transaction")
    70  	}
    71  
    72  	txHash = tx.Hash()
    73  	_, isPending, err = sim.TransactionByHash(context.Background(), txHash)
    74  	if err != nil {
    75  		t.Fatalf("error getting transaction with hash: %v", txHash.String())
    76  	}
    77  	if !isPending {
    78  		t.Fatal("transaction should have pending status")
    79  	}
    80  
    81  	sim.Commit()
    82  	_, isPending, err = sim.TransactionByHash(context.Background(), txHash)
    83  	if err != nil {
    84  		t.Fatalf("error getting transaction with hash: %v", txHash.String())
    85  	}
    86  	if isPending {
    87  		t.Fatal("transaction should not have pending status")
    88  	}
    89  }
    90  
    91  var testKey, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
    92  
    93  //  the following is based on this contract:
    94  //  contract T {
    95  //  	event received(address sender, uint amount, bytes memo);
    96  //  	event receivedAddr(address sender);
    97  //
    98  //  	function receive(bytes calldata memo) external payable returns (string memory res) {
    99  //  		emit received(msg.sender, msg.value, memo);
   100  //  		emit receivedAddr(msg.sender);
   101  //		    return "hello world";
   102  //  	}
   103  //  }
   104  const abiJSON = `[ { "constant": false, "inputs": [ { "name": "memo", "type": "bytes" } ], "name": "receive", "outputs": [ { "name": "res", "type": "string" } ], "payable": true, "stateMutability": "payable", "type": "function" }, { "anonymous": false, "inputs": [ { "indexed": false, "name": "sender", "type": "address" }, { "indexed": false, "name": "amount", "type": "uint256" }, { "indexed": false, "name": "memo", "type": "bytes" } ], "name": "received", "type": "event" }, { "anonymous": false, "inputs": [ { "indexed": false, "name": "sender", "type": "address" } ], "name": "receivedAddr", "type": "event" } ]`
   105  
   106  const (
   107  	abiBin       = `0x608060405234801561001057600080fd5b506102a0806100206000396000f3fe60806040526004361061003b576000357c010000000000000000000000000000000000000000000000000000000090048063a69b6ed014610040575b600080fd5b6100b76004803603602081101561005657600080fd5b810190808035906020019064010000000081111561007357600080fd5b82018360208201111561008557600080fd5b803590602001918460018302840111640100000000831117156100a757600080fd5b9091929391929390505050610132565b6040518080602001828103825283818151815260200191508051906020019080838360005b838110156100f75780820151818401526020810190506100dc565b50505050905090810190601f1680156101245780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b60607f75fd880d39c1daf53b6547ab6cb59451fc6452d27caa90e5b6649dd8293b9eed33348585604051808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001848152602001806020018281038252848482818152602001925080828437600081840152601f19601f8201169050808301925050509550505050505060405180910390a17f46923992397eac56cf13058aced2a1871933622717e27b24eabc13bf9dd329c833604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a16040805190810160405280600b81526020017f68656c6c6f20776f726c6400000000000000000000000000000000000000000081525090509291505056fea165627a7a72305820ff0c57dad254cfeda48c9cfb47f1353a558bccb4d1bc31da1dae69315772d29e0029`
   108  	deployedCode = `60806040526004361061003b576000357c010000000000000000000000000000000000000000000000000000000090048063a69b6ed014610040575b600080fd5b6100b76004803603602081101561005657600080fd5b810190808035906020019064010000000081111561007357600080fd5b82018360208201111561008557600080fd5b803590602001918460018302840111640100000000831117156100a757600080fd5b9091929391929390505050610132565b6040518080602001828103825283818151815260200191508051906020019080838360005b838110156100f75780820151818401526020810190506100dc565b50505050905090810190601f1680156101245780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b60607f75fd880d39c1daf53b6547ab6cb59451fc6452d27caa90e5b6649dd8293b9eed33348585604051808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001848152602001806020018281038252848482818152602001925080828437600081840152601f19601f8201169050808301925050509550505050505060405180910390a17f46923992397eac56cf13058aced2a1871933622717e27b24eabc13bf9dd329c833604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a16040805190810160405280600b81526020017f68656c6c6f20776f726c6400000000000000000000000000000000000000000081525090509291505056fea165627a7a72305820ff0c57dad254cfeda48c9cfb47f1353a558bccb4d1bc31da1dae69315772d29e0029`
   109  )
   110  
   111  // expected return value contains "hello world"
   112  var expectedReturn = []byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 104, 101, 108, 108, 111, 32, 119, 111, 114, 108, 100, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
   113  
   114  func simTestBackend(testAddr common.Address) *SimulatedBackend {
   115  	return NewSimulatedBackend(
   116  		blockchain.GenesisAlloc{
   117  			testAddr: {Balance: big.NewInt(10000000000)},
   118  		},
   119  	)
   120  }
   121  
   122  func TestNewSimulatedBackend(t *testing.T) {
   123  	testAddr := crypto.PubkeyToAddress(testKey.PublicKey)
   124  	expectedBal := big.NewInt(10000000000)
   125  	sim := simTestBackend(testAddr)
   126  	defer sim.Close()
   127  
   128  	if sim.config != params.AllGxhashProtocolChanges {
   129  		t.Errorf("expected sim config to equal params.AllGxhashProtocolChanges, got %v", sim.config)
   130  	}
   131  
   132  	if sim.blockchain.Config() != params.AllGxhashProtocolChanges {
   133  		t.Errorf("expected sim blockchain config to equal params.AllGxhashProtocolChanges, got %v", sim.config)
   134  	}
   135  
   136  	stateDB, _ := sim.blockchain.State()
   137  	bal := stateDB.GetBalance(testAddr)
   138  	if bal.Cmp(expectedBal) != 0 {
   139  		t.Errorf("expected balance for test address not received. expected: %v actual: %v", expectedBal, bal)
   140  	}
   141  }
   142  
   143  func TestSimulatedBackend_AdjustTime(t *testing.T) {
   144  	sim := NewSimulatedBackend(
   145  		blockchain.GenesisAlloc{},
   146  	)
   147  	defer sim.Close()
   148  
   149  	prevTime := sim.pendingBlock.Time()
   150  	if err := sim.AdjustTime(time.Second); err != nil {
   151  		t.Error(err)
   152  	}
   153  	newTime := sim.pendingBlock.Time()
   154  
   155  	if newTime.Uint64()-prevTime.Uint64() != uint64(time.Second.Seconds()) {
   156  		t.Errorf("adjusted time not equal to a second. prev: %v, new: %v", prevTime, newTime)
   157  	}
   158  }
   159  
   160  func TestNewSimulatedBackend_AdjustTimeFail(t *testing.T) {
   161  	testAddr := crypto.PubkeyToAddress(testKey.PublicKey)
   162  	sim := simTestBackend(testAddr)
   163  	// Create tx and send
   164  	tx := types.NewTransaction(0, testAddr, big.NewInt(1000), params.TxGas, big.NewInt(1), nil)
   165  	signedTx, err := types.SignTx(tx, types.LatestSignerForChainID(sim.config.ChainID), testKey)
   166  	if err != nil {
   167  		t.Errorf("could not sign tx: %v", err)
   168  	}
   169  	sim.SendTransaction(context.Background(), signedTx)
   170  	// AdjustTime should fail on non-empty block
   171  	if err := sim.AdjustTime(time.Second); err == nil {
   172  		t.Error("Expected adjust time to error on non-empty block")
   173  	}
   174  	sim.Commit()
   175  
   176  	prevTime := sim.pendingBlock.Time()
   177  	if err := sim.AdjustTime(time.Minute); err != nil {
   178  		t.Error(err)
   179  	}
   180  	newTime := sim.pendingBlock.Time()
   181  	if newTime.Uint64()-prevTime.Uint64() != uint64(time.Minute.Seconds()) {
   182  		t.Errorf("adjusted time not equal to a minute. prev: %v, new: %v", prevTime, newTime)
   183  	}
   184  	// Put a transaction after adjusting time
   185  	tx2 := types.NewTransaction(1, testAddr, big.NewInt(1000), params.TxGas, big.NewInt(1), nil)
   186  	signedTx2, err := types.SignTx(tx2, types.LatestSignerForChainID(sim.config.ChainID), testKey)
   187  	if err != nil {
   188  		t.Errorf("could not sign tx: %v", err)
   189  	}
   190  	sim.SendTransaction(context.Background(), signedTx2)
   191  	sim.Commit()
   192  	newTime = sim.pendingBlock.Time()
   193  	if newTime.Uint64()-prevTime.Uint64() >= uint64(time.Minute.Seconds()) {
   194  		t.Errorf("time adjusted, but shouldn't be: prev: %v, new: %v", prevTime, newTime)
   195  	}
   196  }
   197  
   198  func TestSimulatedBackend_BalanceAt(t *testing.T) {
   199  	testAddr := crypto.PubkeyToAddress(testKey.PublicKey)
   200  	expectedBal := big.NewInt(10000000000)
   201  	sim := simTestBackend(testAddr)
   202  	defer sim.Close()
   203  	bgCtx := context.Background()
   204  
   205  	bal, err := sim.BalanceAt(bgCtx, testAddr, nil)
   206  	if err != nil {
   207  		t.Error(err)
   208  	}
   209  
   210  	if bal.Cmp(expectedBal) != 0 {
   211  		t.Errorf("expected balance for test address not received. expected: %v actual: %v", expectedBal, bal)
   212  	}
   213  }
   214  
   215  func TestSimulatedBackend_BlockByHash(t *testing.T) {
   216  	sim := NewSimulatedBackend(
   217  		blockchain.GenesisAlloc{},
   218  	)
   219  	defer sim.Close()
   220  	bgCtx := context.Background()
   221  
   222  	block, err := sim.BlockByNumber(bgCtx, nil)
   223  	if err != nil {
   224  		t.Errorf("could not get recent block: %v", err)
   225  	}
   226  	blockByHash, err := sim.BlockByHash(bgCtx, block.Hash())
   227  	if err != nil {
   228  		t.Errorf("could not get recent block: %v", err)
   229  	}
   230  
   231  	if block.Hash() != blockByHash.Hash() {
   232  		t.Errorf("did not get expected block")
   233  	}
   234  }
   235  
   236  func TestSimulatedBackend_BlockByNumber(t *testing.T) {
   237  	sim := NewSimulatedBackend(
   238  		blockchain.GenesisAlloc{},
   239  	)
   240  	defer sim.Close()
   241  	bgCtx := context.Background()
   242  
   243  	block, err := sim.BlockByNumber(bgCtx, nil)
   244  	if err != nil {
   245  		t.Errorf("could not get recent block: %v", err)
   246  	}
   247  	if block.NumberU64() != 0 {
   248  		t.Errorf("did not get most recent block, instead got block number %v", block.NumberU64())
   249  	}
   250  
   251  	// create one block
   252  	sim.Commit()
   253  
   254  	block, err = sim.BlockByNumber(bgCtx, nil)
   255  	if err != nil {
   256  		t.Errorf("could not get recent block: %v", err)
   257  	}
   258  	if block.NumberU64() != 1 {
   259  		t.Errorf("did not get most recent block, instead got block number %v", block.NumberU64())
   260  	}
   261  
   262  	blockByNumber, err := sim.BlockByNumber(bgCtx, big.NewInt(1))
   263  	if err != nil {
   264  		t.Errorf("could not get block by number: %v", err)
   265  	}
   266  	if blockByNumber.Hash() != block.Hash() {
   267  		t.Errorf("did not get the same block with height of 1 as before")
   268  	}
   269  }
   270  
   271  func TestSimulatedBackend_NonceAt(t *testing.T) {
   272  	testAddr := crypto.PubkeyToAddress(testKey.PublicKey)
   273  
   274  	sim := simTestBackend(testAddr)
   275  	defer sim.Close()
   276  	bgCtx := context.Background()
   277  
   278  	nonce, err := sim.NonceAt(bgCtx, testAddr, big.NewInt(0))
   279  	if err != nil {
   280  		t.Errorf("could not get nonce for test addr: %v", err)
   281  	}
   282  
   283  	if nonce != uint64(0) {
   284  		t.Errorf("received incorrect nonce. expected 0, got %v", nonce)
   285  	}
   286  
   287  	// create a signed transaction to send
   288  	tx := types.NewTransaction(nonce, testAddr, big.NewInt(1000), params.TxGas, big.NewInt(1), nil)
   289  	signedTx, err := types.SignTx(tx, types.LatestSignerForChainID(sim.config.ChainID), testKey)
   290  	if err != nil {
   291  		t.Errorf("could not sign tx: %v", err)
   292  	}
   293  
   294  	// send tx to simulated backend
   295  	err = sim.SendTransaction(bgCtx, signedTx)
   296  	if err != nil {
   297  		t.Errorf("could not add tx to pending block: %v", err)
   298  	}
   299  	sim.Commit()
   300  
   301  	newNonce, err := sim.NonceAt(bgCtx, testAddr, big.NewInt(1))
   302  	if err != nil {
   303  		t.Errorf("could not get nonce for test addr: %v", err)
   304  	}
   305  
   306  	if newNonce != nonce+uint64(1) {
   307  		t.Errorf("received incorrect nonce. expected 1, got %v", nonce)
   308  	}
   309  	// create some more blocks
   310  	sim.Commit()
   311  	// Check that we can get data for an older block/state
   312  	newNonce, err = sim.NonceAt(bgCtx, testAddr, big.NewInt(1))
   313  	if err != nil {
   314  		t.Fatalf("could not get nonce for test addr: %v", err)
   315  	}
   316  	if newNonce != nonce+uint64(1) {
   317  		t.Fatalf("received incorrect nonce. expected 1, got %v", nonce)
   318  	}
   319  }
   320  
   321  func TestSimulatedBackend_SendTransaction(t *testing.T) {
   322  	testAddr := crypto.PubkeyToAddress(testKey.PublicKey)
   323  
   324  	sim := simTestBackend(testAddr)
   325  	defer sim.Close()
   326  	bgCtx := context.Background()
   327  
   328  	// create a signed transaction to send
   329  	tx := types.NewTransaction(uint64(0), testAddr, big.NewInt(1000), params.TxGas, big.NewInt(1), nil)
   330  	signedTx, err := types.SignTx(tx, types.LatestSignerForChainID(sim.config.ChainID), testKey)
   331  	if err != nil {
   332  		t.Errorf("could not sign tx: %v", err)
   333  	}
   334  
   335  	// send tx to simulated backend
   336  	err = sim.SendTransaction(bgCtx, signedTx)
   337  	if err != nil {
   338  		t.Errorf("could not add tx to pending block: %v", err)
   339  	}
   340  	sim.Commit()
   341  
   342  	block, err := sim.BlockByNumber(bgCtx, big.NewInt(1))
   343  	if err != nil {
   344  		t.Errorf("could not get block at height 1: %v", err)
   345  	}
   346  
   347  	if signedTx.Hash() != block.Transactions()[0].Hash() {
   348  		t.Errorf("did not commit sent transaction. expected hash %v got hash %v", block.Transactions()[0].Hash(), signedTx.Hash())
   349  	}
   350  }
   351  
   352  func TestSimulatedBackend_TransactionByHash(t *testing.T) {
   353  	testAddr := crypto.PubkeyToAddress(testKey.PublicKey)
   354  
   355  	sim := simTestBackend(testAddr)
   356  	defer sim.Close()
   357  	bgCtx := context.Background()
   358  
   359  	// create a signed transaction to send
   360  	tx := types.NewTransaction(uint64(0), testAddr, big.NewInt(1000), params.TxGas, big.NewInt(1), nil)
   361  	signedTx, err := types.SignTx(tx, types.LatestSignerForChainID(sim.config.ChainID), testKey)
   362  	if err != nil {
   363  		t.Errorf("could not sign tx: %v", err)
   364  	}
   365  
   366  	// send tx to simulated backend
   367  	err = sim.SendTransaction(bgCtx, signedTx)
   368  	if err != nil {
   369  		t.Errorf("could not add tx to pending block: %v", err)
   370  	}
   371  
   372  	// ensure tx is committed pending
   373  	receivedTx, pending, err := sim.TransactionByHash(bgCtx, signedTx.Hash())
   374  	if err != nil {
   375  		t.Errorf("could not get transaction by hash %v: %v", signedTx.Hash(), err)
   376  	}
   377  	if !pending {
   378  		t.Errorf("expected transaction to be in pending state")
   379  	}
   380  	if receivedTx.Hash() != signedTx.Hash() {
   381  		t.Errorf("did not received committed transaction. expected hash %v got hash %v", signedTx.Hash(), receivedTx.Hash())
   382  	}
   383  
   384  	sim.Commit()
   385  
   386  	// ensure tx is not and committed pending
   387  	receivedTx, pending, err = sim.TransactionByHash(bgCtx, signedTx.Hash())
   388  	if err != nil {
   389  		t.Errorf("could not get transaction by hash %v: %v", signedTx.Hash(), err)
   390  	}
   391  	if pending {
   392  		t.Errorf("expected transaction to not be in pending state")
   393  	}
   394  	if receivedTx.Hash() != signedTx.Hash() {
   395  		t.Errorf("did not received committed transaction. expected hash %v got hash %v", signedTx.Hash(), receivedTx.Hash())
   396  	}
   397  }
   398  
   399  func TestSimulatedBackend_EstimateGas(t *testing.T) {
   400  	sim := NewSimulatedBackend(
   401  		blockchain.GenesisAlloc{},
   402  	)
   403  	defer sim.Close()
   404  	bgCtx := context.Background()
   405  	testAddr := crypto.PubkeyToAddress(testKey.PublicKey)
   406  
   407  	gas, err := sim.EstimateGas(bgCtx, klaytn.CallMsg{
   408  		From:  testAddr,
   409  		To:    &testAddr,
   410  		Value: big.NewInt(1000),
   411  		Data:  []byte{},
   412  	})
   413  	if err != nil {
   414  		t.Errorf("could not estimate gas: %v", err)
   415  	}
   416  
   417  	if gas != params.TxGas {
   418  		t.Errorf("expected 21000 gas cost for a transaction got %v", gas)
   419  	}
   420  }
   421  
   422  func TestSimulatedBackend_HeaderByHash(t *testing.T) {
   423  	testAddr := crypto.PubkeyToAddress(testKey.PublicKey)
   424  
   425  	sim := simTestBackend(testAddr)
   426  	defer sim.Close()
   427  	bgCtx := context.Background()
   428  
   429  	header, err := sim.HeaderByNumber(bgCtx, nil)
   430  	if err != nil {
   431  		t.Errorf("could not get recent block: %v", err)
   432  	}
   433  	headerByHash, err := sim.HeaderByHash(bgCtx, header.Hash())
   434  	if err != nil {
   435  		t.Errorf("could not get recent block: %v", err)
   436  	}
   437  
   438  	if header.Hash() != headerByHash.Hash() {
   439  		t.Errorf("did not get expected block")
   440  	}
   441  }
   442  
   443  func TestSimulatedBackend_HeaderByNumber(t *testing.T) {
   444  	testAddr := crypto.PubkeyToAddress(testKey.PublicKey)
   445  
   446  	sim := simTestBackend(testAddr)
   447  	defer sim.Close()
   448  	bgCtx := context.Background()
   449  
   450  	latestBlockHeader, err := sim.HeaderByNumber(bgCtx, nil)
   451  	if err != nil {
   452  		t.Errorf("could not get header for tip of chain: %v", err)
   453  	}
   454  	if latestBlockHeader == nil {
   455  		t.Errorf("received a nil block header")
   456  	}
   457  	if latestBlockHeader.Number.Uint64() != uint64(0) {
   458  		t.Errorf("expected block header number 0, instead got %v", latestBlockHeader.Number.Uint64())
   459  	}
   460  
   461  	sim.Commit()
   462  
   463  	latestBlockHeader, err = sim.HeaderByNumber(bgCtx, nil)
   464  	if err != nil {
   465  		t.Errorf("could not get header for blockheight of 1: %v", err)
   466  	}
   467  
   468  	blockHeader, err := sim.HeaderByNumber(bgCtx, big.NewInt(1))
   469  	if err != nil {
   470  		t.Errorf("could not get header for blockheight of 1: %v", err)
   471  	}
   472  
   473  	if blockHeader.Hash() != latestBlockHeader.Hash() {
   474  		t.Errorf("block header and latest block header are not the same")
   475  	}
   476  	if blockHeader.Number.Int64() != int64(1) {
   477  		t.Errorf("did not get blockheader for block 1. instead got block %v", blockHeader.Number.Int64())
   478  	}
   479  
   480  	block, err := sim.BlockByNumber(bgCtx, big.NewInt(1))
   481  	if err != nil {
   482  		t.Errorf("could not get block for blockheight of 1: %v", err)
   483  	}
   484  
   485  	if block.Hash() != blockHeader.Hash() {
   486  		t.Errorf("block hash and block header hash do not match. expected %v, got %v", block.Hash(), blockHeader.Hash())
   487  	}
   488  }
   489  
   490  func TestSimulatedBackend_TransactionCount(t *testing.T) {
   491  	testAddr := crypto.PubkeyToAddress(testKey.PublicKey)
   492  
   493  	sim := simTestBackend(testAddr)
   494  	defer sim.Close()
   495  	bgCtx := context.Background()
   496  	currentBlock, err := sim.BlockByNumber(bgCtx, nil)
   497  	if err != nil || currentBlock == nil {
   498  		t.Error("could not get current block")
   499  	}
   500  
   501  	count, err := sim.TransactionCount(bgCtx, currentBlock.Hash())
   502  	if err != nil {
   503  		t.Error("could not get current block's transaction count")
   504  	}
   505  
   506  	if count != 0 {
   507  		t.Errorf("expected transaction count of %v does not match actual count of %v", 0, count)
   508  	}
   509  
   510  	// create a signed transaction to send
   511  	tx := types.NewTransaction(uint64(0), testAddr, big.NewInt(1000), params.TxGas, big.NewInt(1), nil)
   512  	signedTx, err := types.SignTx(tx, types.LatestSignerForChainID(sim.config.ChainID), testKey)
   513  	if err != nil {
   514  		t.Errorf("could not sign tx: %v", err)
   515  	}
   516  
   517  	// send tx to simulated backend
   518  	err = sim.SendTransaction(bgCtx, signedTx)
   519  	if err != nil {
   520  		t.Errorf("could not add tx to pending block: %v", err)
   521  	}
   522  
   523  	sim.Commit()
   524  
   525  	lastBlock, err := sim.BlockByNumber(bgCtx, nil)
   526  	if err != nil {
   527  		t.Errorf("could not get header for tip of chain: %v", err)
   528  	}
   529  
   530  	count, err = sim.TransactionCount(bgCtx, lastBlock.Hash())
   531  	if err != nil {
   532  		t.Error("could not get current block's transaction count")
   533  	}
   534  
   535  	if count != 1 {
   536  		t.Errorf("expected transaction count of %v does not match actual count of %v", 1, count)
   537  	}
   538  }
   539  
   540  func TestSimulatedBackend_TransactionInBlock(t *testing.T) {
   541  	testAddr := crypto.PubkeyToAddress(testKey.PublicKey)
   542  
   543  	sim := simTestBackend(testAddr)
   544  	defer sim.Close()
   545  	bgCtx := context.Background()
   546  
   547  	transaction, err := sim.TransactionInBlock(bgCtx, sim.pendingBlock.Hash(), uint(0))
   548  	if err == nil && err != errTransactionDoesNotExist {
   549  		t.Errorf("expected a transaction does not exist error to be received but received %v", err)
   550  	}
   551  	if transaction != nil {
   552  		t.Errorf("expected transaction to be nil but received %v", transaction)
   553  	}
   554  
   555  	// expect pending nonce to be 0 since account has not been used
   556  	pendingNonce, err := sim.PendingNonceAt(bgCtx, testAddr)
   557  	if err != nil {
   558  		t.Errorf("did not get the pending nonce: %v", err)
   559  	}
   560  
   561  	if pendingNonce != uint64(0) {
   562  		t.Errorf("expected pending nonce of 0 got %v", pendingNonce)
   563  	}
   564  
   565  	// create a signed transaction to send
   566  	tx := types.NewTransaction(uint64(0), testAddr, big.NewInt(1000), params.TxGas, big.NewInt(1), nil)
   567  	signedTx, err := types.SignTx(tx, types.LatestSignerForChainID(sim.config.ChainID), testKey)
   568  	if err != nil {
   569  		t.Errorf("could not sign tx: %v", err)
   570  	}
   571  
   572  	// send tx to simulated backend
   573  	err = sim.SendTransaction(bgCtx, signedTx)
   574  	if err != nil {
   575  		t.Errorf("could not add tx to pending block: %v", err)
   576  	}
   577  
   578  	sim.Commit()
   579  
   580  	lastBlock, err := sim.BlockByNumber(bgCtx, nil)
   581  	if err != nil {
   582  		t.Errorf("could not get header for tip of chain: %v", err)
   583  	}
   584  
   585  	transaction, err = sim.TransactionInBlock(bgCtx, lastBlock.Hash(), uint(1))
   586  	if err == nil && err != errTransactionDoesNotExist {
   587  		t.Errorf("expected a transaction does not exist error to be received but received %v", err)
   588  	}
   589  	if transaction != nil {
   590  		t.Errorf("expected transaction to be nil but received %v", transaction)
   591  	}
   592  
   593  	transaction, err = sim.TransactionInBlock(bgCtx, lastBlock.Hash(), uint(0))
   594  	if err != nil {
   595  		t.Errorf("could not get transaction in the lastest block with hash %v: %v", lastBlock.Hash().String(), err)
   596  	}
   597  
   598  	if signedTx.Hash().String() != transaction.Hash().String() {
   599  		t.Errorf("received transaction that did not match the sent transaction. expected hash %v, got hash %v", signedTx.Hash().String(), transaction.Hash().String())
   600  	}
   601  }
   602  
   603  func TestSimulatedBackend_PendingNonceAt(t *testing.T) {
   604  	testAddr := crypto.PubkeyToAddress(testKey.PublicKey)
   605  
   606  	sim := simTestBackend(testAddr)
   607  	defer sim.Close()
   608  	bgCtx := context.Background()
   609  
   610  	// expect pending nonce to be 0 since account has not been used
   611  	pendingNonce, err := sim.PendingNonceAt(bgCtx, testAddr)
   612  	if err != nil {
   613  		t.Errorf("did not get the pending nonce: %v", err)
   614  	}
   615  
   616  	if pendingNonce != uint64(0) {
   617  		t.Errorf("expected pending nonce of 0 got %v", pendingNonce)
   618  	}
   619  
   620  	// create a signed transaction to send
   621  	tx := types.NewTransaction(uint64(0), testAddr, big.NewInt(1000), params.TxGas, big.NewInt(1), nil)
   622  	signedTx, err := types.SignTx(tx, types.LatestSignerForChainID(sim.config.ChainID), testKey)
   623  	if err != nil {
   624  		t.Errorf("could not sign tx: %v", err)
   625  	}
   626  
   627  	// send tx to simulated backend
   628  	err = sim.SendTransaction(bgCtx, signedTx)
   629  	if err != nil {
   630  		t.Errorf("could not add tx to pending block: %v", err)
   631  	}
   632  
   633  	// expect pending nonce to be 1 since account has submitted one transaction
   634  	pendingNonce, err = sim.PendingNonceAt(bgCtx, testAddr)
   635  	if err != nil {
   636  		t.Errorf("did not get the pending nonce: %v", err)
   637  	}
   638  
   639  	if pendingNonce != uint64(1) {
   640  		t.Errorf("expected pending nonce of 1 got %v", pendingNonce)
   641  	}
   642  
   643  	// make a new transaction with a nonce of 1
   644  	tx = types.NewTransaction(uint64(1), testAddr, big.NewInt(1000), params.TxGas, big.NewInt(1), nil)
   645  	signedTx, err = types.SignTx(tx, types.LatestSignerForChainID(sim.config.ChainID), testKey)
   646  	if err != nil {
   647  		t.Errorf("could not sign tx: %v", err)
   648  	}
   649  	err = sim.SendTransaction(bgCtx, signedTx)
   650  	if err != nil {
   651  		t.Errorf("could not send tx: %v", err)
   652  	}
   653  
   654  	// expect pending nonce to be 2 since account now has two transactions
   655  	pendingNonce, err = sim.PendingNonceAt(bgCtx, testAddr)
   656  	if err != nil {
   657  		t.Errorf("did not get the pending nonce: %v", err)
   658  	}
   659  
   660  	if pendingNonce != uint64(2) {
   661  		t.Errorf("expected pending nonce of 2 got %v", pendingNonce)
   662  	}
   663  }
   664  
   665  func TestSimulatedBackend_TransactionReceipt(t *testing.T) {
   666  	testAddr := crypto.PubkeyToAddress(testKey.PublicKey)
   667  
   668  	sim := simTestBackend(testAddr)
   669  	defer sim.Close()
   670  	bgCtx := context.Background()
   671  
   672  	// create a signed transaction to send
   673  	tx := types.NewTransaction(uint64(0), testAddr, big.NewInt(1000), params.TxGas, big.NewInt(1), nil)
   674  	signedTx, err := types.SignTx(tx, types.LatestSignerForChainID(sim.config.ChainID), testKey)
   675  	if err != nil {
   676  		t.Errorf("could not sign tx: %v", err)
   677  	}
   678  
   679  	// send tx to simulated backend
   680  	err = sim.SendTransaction(bgCtx, signedTx)
   681  	if err != nil {
   682  		t.Errorf("could not add tx to pending block: %v", err)
   683  	}
   684  	sim.Commit()
   685  
   686  	receipt, err := sim.TransactionReceipt(bgCtx, signedTx.Hash())
   687  	if err != nil {
   688  		t.Errorf("could not get transaction receipt: %v", err)
   689  	}
   690  
   691  	if receipt.ContractAddress != testAddr && receipt.TxHash != signedTx.Hash() {
   692  		t.Errorf("received receipt is not correct: %v", receipt)
   693  	}
   694  }
   695  
   696  func TestSimulatedBackend_SuggestGasPrice(t *testing.T) {
   697  	sim := NewSimulatedBackend(
   698  		blockchain.GenesisAlloc{},
   699  	)
   700  	defer sim.Close()
   701  	bgCtx := context.Background()
   702  	gasPrice, err := sim.SuggestGasPrice(bgCtx)
   703  	if err != nil {
   704  		t.Errorf("could not get gas price: %v", err)
   705  	}
   706  	if gasPrice.Uint64() != uint64(0) {
   707  		t.Errorf("gas price was not expected value of 0. actual: %v", gasPrice.Uint64())
   708  	}
   709  }
   710  
   711  func TestSimulatedBackend_PendingCodeAt(t *testing.T) {
   712  	testAddr := crypto.PubkeyToAddress(testKey.PublicKey)
   713  	sim := simTestBackend(testAddr)
   714  	defer sim.Close()
   715  	bgCtx := context.Background()
   716  	code, err := sim.CodeAt(bgCtx, testAddr, nil)
   717  	if err != nil {
   718  		t.Errorf("could not get code at test addr: %v", err)
   719  	}
   720  	if len(code) != 0 {
   721  		t.Errorf("got code for account that does not have contract code")
   722  	}
   723  
   724  	parsed, err := abi.JSON(strings.NewReader(abiJSON))
   725  	if err != nil {
   726  		t.Errorf("could not get code at test addr: %v", err)
   727  	}
   728  	auth := bind.NewKeyedTransactor(testKey)
   729  	contractAddr, tx, contract, err := bind.DeployContract(auth, parsed, common.FromHex(abiBin), sim)
   730  	if err != nil {
   731  		t.Errorf("could not deploy contract: %v tx: %v contract: %v", err, tx, contract)
   732  	}
   733  
   734  	code, err = sim.PendingCodeAt(bgCtx, contractAddr)
   735  	if err != nil {
   736  		t.Errorf("could not get code at test addr: %v", err)
   737  	}
   738  	if len(code) == 0 {
   739  		t.Errorf("did not get code for account that has contract code")
   740  	}
   741  	// ensure code received equals code deployed
   742  	if !bytes.Equal(code, common.FromHex(deployedCode)) {
   743  		t.Errorf("code received did not match expected deployed code:\n expected %v\n actual %v", common.FromHex(deployedCode), code)
   744  	}
   745  }
   746  
   747  func TestSimulatedBackend_CodeAt(t *testing.T) {
   748  	testAddr := crypto.PubkeyToAddress(testKey.PublicKey)
   749  	sim := simTestBackend(testAddr)
   750  	defer sim.Close()
   751  	bgCtx := context.Background()
   752  	code, err := sim.CodeAt(bgCtx, testAddr, nil)
   753  	if err != nil {
   754  		t.Errorf("could not get code at test addr: %v", err)
   755  	}
   756  	if len(code) != 0 {
   757  		t.Errorf("got code for account that does not have contract code")
   758  	}
   759  
   760  	parsed, err := abi.JSON(strings.NewReader(abiJSON))
   761  	if err != nil {
   762  		t.Errorf("could not get code at test addr: %v", err)
   763  	}
   764  	auth := bind.NewKeyedTransactor(testKey)
   765  	contractAddr, tx, contract, err := bind.DeployContract(auth, parsed, common.FromHex(abiBin), sim)
   766  	if err != nil {
   767  		t.Errorf("could not deploy contract: %v tx: %v contract: %v", err, tx, contract)
   768  	}
   769  
   770  	sim.Commit()
   771  	code, err = sim.CodeAt(bgCtx, contractAddr, nil)
   772  	if err != nil {
   773  		t.Errorf("could not get code at test addr: %v", err)
   774  	}
   775  	if len(code) == 0 {
   776  		t.Errorf("did not get code for account that has contract code")
   777  	}
   778  	// ensure code received equals code deployed
   779  	if !bytes.Equal(code, common.FromHex(deployedCode)) {
   780  		t.Errorf("code received did not match expected deployed code:\n expected %v\n actual %v", common.FromHex(deployedCode), code)
   781  	}
   782  }
   783  
   784  // When receive("X") is called with sender 0x00... and value 1, it produces this tx receipt:
   785  //   receipt{status=1 cgas=23949 bloom=00000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000040200000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 logs=[log: b6818c8064f645cd82d99b59a1a267d6d61117ef [75fd880d39c1daf53b6547ab6cb59451fc6452d27caa90e5b6649dd8293b9eed] 000000000000000000000000376c47978271565f56deb45495afa69e59c16ab200000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000000158 9ae378b6d4409eada347a5dc0c180f186cb62dc68fcc0f043425eb917335aa28 0 95d429d309bb9d753954195fe2d69bd140b4ae731b9b5b605c34323de162cf00 0]}
   786  func TestSimulatedBackend_PendingAndCallContract(t *testing.T) {
   787  	testAddr := crypto.PubkeyToAddress(testKey.PublicKey)
   788  	sim := simTestBackend(testAddr)
   789  	defer sim.Close()
   790  	bgCtx := context.Background()
   791  
   792  	parsed, err := abi.JSON(strings.NewReader(abiJSON))
   793  	if err != nil {
   794  		t.Errorf("could not get code at test addr: %v", err)
   795  	}
   796  	contractAuth := bind.NewKeyedTransactor(testKey)
   797  	addr, _, _, err := bind.DeployContract(contractAuth, parsed, common.FromHex(abiBin), sim)
   798  	if err != nil {
   799  		t.Errorf("could not deploy contract: %v", err)
   800  	}
   801  
   802  	input, err := parsed.Pack("receive", []byte("X"))
   803  	if err != nil {
   804  		t.Errorf("could not pack receive function on contract: %v", err)
   805  	}
   806  
   807  	// make sure you can call the contract in pending state
   808  	res, err := sim.PendingCallContract(bgCtx, klaytn.CallMsg{
   809  		From: testAddr,
   810  		To:   &addr,
   811  		Data: input,
   812  	})
   813  	if err != nil {
   814  		t.Errorf("could not call receive method on contract: %v", err)
   815  	}
   816  	if len(res) == 0 {
   817  		t.Errorf("result of contract call was empty: %v", res)
   818  	}
   819  
   820  	// while comparing against the byte array is more exact, also compare against the human readable string for readability
   821  	if !bytes.Equal(res, expectedReturn) || !strings.Contains(string(res), "hello world") {
   822  		t.Errorf("response from calling contract was expected to be 'hello world' instead received %v", string(res))
   823  	}
   824  
   825  	sim.Commit()
   826  
   827  	// make sure you can call the contract
   828  	res, err = sim.CallContract(bgCtx, klaytn.CallMsg{
   829  		From: testAddr,
   830  		To:   &addr,
   831  		Data: input,
   832  	}, nil)
   833  	if err != nil {
   834  		t.Errorf("could not call receive method on contract: %v", err)
   835  	}
   836  	if len(res) == 0 {
   837  		t.Errorf("result of contract call was empty: %v", res)
   838  	}
   839  
   840  	if !bytes.Equal(res, expectedReturn) || !strings.Contains(string(res), "hello world") {
   841  		t.Errorf("response from calling contract was expected to be 'hello world' instead received %v", string(res))
   842  	}
   843  }