github.com/core-coin/go-core/v2@v2.1.9/accounts/abi/bind/backends/simulated_test.go (about)

     1  // Copyright 2019 by the Authors
     2  // This file is part of the go-core library.
     3  //
     4  // The go-core library is free software: you can redistribute it and/or modify
     5  // it under the terms of the GNU Lesser General Public License as published by
     6  // the Free Software Foundation, either version 3 of the License, or
     7  // (at your option) any later version.
     8  //
     9  // The go-core library is distributed in the hope that it will be useful,
    10  // but WITHOUT ANY WARRANTY; without even the implied warranty of
    11  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    12  // GNU Lesser General Public License for more details.
    13  //
    14  // You should have received a copy of the GNU Lesser General Public License
    15  // along with the go-core library. If not, see <http://www.gnu.org/licenses/>.
    16  
    17  package backends
    18  
    19  import (
    20  	"bytes"
    21  	"context"
    22  	crand "crypto/rand"
    23  	"errors"
    24  	"math/big"
    25  	"reflect"
    26  	"strings"
    27  	"testing"
    28  	"time"
    29  
    30  	c "github.com/core-coin/go-core/v2"
    31  	"github.com/core-coin/go-core/v2/accounts/abi"
    32  	"github.com/core-coin/go-core/v2/accounts/abi/bind"
    33  	"github.com/core-coin/go-core/v2/common"
    34  	"github.com/core-coin/go-core/v2/core"
    35  	"github.com/core-coin/go-core/v2/core/types"
    36  	"github.com/core-coin/go-core/v2/crypto"
    37  	"github.com/core-coin/go-core/v2/params"
    38  )
    39  
    40  func TestSimulatedBackend(t *testing.T) {
    41  	var energyLimit uint64 = 8000029
    42  	key, _ := crypto.GenerateKey(crand.Reader) // nolint: gosec
    43  	auth, _ := bind.NewKeyedTransactorWithNetworkID(key, big.NewInt(1))
    44  	genAlloc := make(core.GenesisAlloc)
    45  	genAlloc[auth.From] = core.GenesisAccount{Balance: big.NewInt(9223372036854775807)}
    46  	sim := NewSimulatedBackend(genAlloc, energyLimit)
    47  	defer sim.Close()
    48  
    49  	// should return an error if the tx is not found
    50  	txHash := common.HexToHash("2")
    51  	_, isPending, err := sim.TransactionByHash(context.Background(), txHash)
    52  
    53  	if isPending {
    54  		t.Fatal("transaction should not be pending")
    55  	}
    56  	if err != c.NotFound {
    57  		t.Fatalf("err should be `core.NotFound` but received %v", err)
    58  	}
    59  
    60  	// generate a transaction and confirm you can retrieve it
    61  	code := `6060604052600a8060106000396000f360606040526008565b00`
    62  	var energy uint64 = 3000000
    63  	tx := types.NewContractCreation(0, big.NewInt(0), energy, big.NewInt(1), common.FromHex(code))
    64  	tx, err = types.SignTx(tx, types.NewNucleusSigner(sim.config.NetworkID), key)
    65  	err = sim.SendTransaction(context.Background(), tx)
    66  	if err != nil {
    67  		t.Fatal("error sending transaction")
    68  	}
    69  
    70  	txHash = tx.Hash()
    71  	_, isPending, err = sim.TransactionByHash(context.Background(), txHash)
    72  	if err != nil {
    73  		t.Fatalf("error getting transaction with hash: %v", txHash.String())
    74  	}
    75  	if !isPending {
    76  		t.Fatal("transaction should have pending status")
    77  	}
    78  
    79  	sim.Commit()
    80  	_, isPending, err = sim.TransactionByHash(context.Background(), txHash)
    81  	if err != nil {
    82  		t.Fatalf("error getting transaction with hash: %v", txHash.String())
    83  	}
    84  	if isPending {
    85  		t.Fatal("transaction should not have pending status")
    86  	}
    87  }
    88  
    89  var testKey, failure = crypto.UnmarshalPrivateKeyHex("ab856a9af6b0b651dd2f43b5e12193652ec1701c4da6f1c0d2a366ac4b9dabc9433ef09e41ca129552bd2c029086d9b03604de872a3b343204")
    90  
    91  //	 the following is based on this contract:
    92  //	 contract T {
    93  //	 	event received(address sender, uint amount, bytes memo);
    94  //	 	event receivedAddr(address sender);
    95  //
    96  //	 	function receive(bytes calldata memo) external payable returns (string memory res) {
    97  //	 		emit received(msg.sender, msg.value, memo);
    98  //	 		emit receivedAddr(msg.sender);
    99  //			    return "hello world";
   100  //	 	}
   101  //	 }
   102  const abiJSON = `[{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"sender","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"bytes","name":"memo","type":"bytes"}],"name":"received","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"sender","type":"address"}],"name":"receivedAddr","type":"event"},{"inputs":[{"internalType":"bytes","name":"memo","type":"bytes"}],"name":"receive","outputs":[{"internalType":"string","name":"res","type":"string"}],"stateMutability":"payable","type":"function"}]`
   103  const abiBin = `608060405234801561001057600080fd5b506102ba806100206000396000f3fe60806040526004361061001e5760003560e01c80631a96cac114610023575b600080fd5b61009a6004803603602081101561003957600080fd5b810190808035906020019064010000000081111561005657600080fd5b82018360208201111561006857600080fd5b8035906020019184600183028401116401000000008311171561008a57600080fd5b9091929391929390505050610115565b6040518080602001828103825283818151815260200191508051906020019080838360005b838110156100da5780820151818401526020810190506100bf565b50505050905090810190601f1680156101075780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b60607ff04f3ac9177f6321985a4ac7cbba630e5510274550eba61663bd547dc067666c33348585604051808575ffffffffffffffffffffffffffffffffffffffffffff1675ffffffffffffffffffffffffffffffffffffffffffff168152602001848152602001806020018281038252848482818152602001925080828437600081840152601f19601f8201169050808301925050509550505050505060405180910390a17f3af7ac6f20ac0da4b0a8a72bc30d72ea12f8a2d3dd9fbe292400ebee0e7f559d33604051808275ffffffffffffffffffffffffffffffffffffffffffff1675ffffffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a16040518060400160405280600b81526020017f68656c6c6f20776f726c6400000000000000000000000000000000000000000081525090509291505056fea2646970667358221220ed9a4a0d373eb4629e50a4569370026d7334b397204cc19b02cb97e3f57d65c764736f6c637827302e362e392d646576656c6f702e323032302e372e32312b636f6d6d69742e33633832373333370058`
   104  const deployedCode = `60806040526004361061001e5760003560e01c80631a96cac114610023575b600080fd5b61009a6004803603602081101561003957600080fd5b810190808035906020019064010000000081111561005657600080fd5b82018360208201111561006857600080fd5b8035906020019184600183028401116401000000008311171561008a57600080fd5b9091929391929390505050610115565b6040518080602001828103825283818151815260200191508051906020019080838360005b838110156100da5780820151818401526020810190506100bf565b50505050905090810190601f1680156101075780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b60607ff04f3ac9177f6321985a4ac7cbba630e5510274550eba61663bd547dc067666c33348585604051808575ffffffffffffffffffffffffffffffffffffffffffff1675ffffffffffffffffffffffffffffffffffffffffffff168152602001848152602001806020018281038252848482818152602001925080828437600081840152601f19601f8201169050808301925050509550505050505060405180910390a17f3af7ac6f20ac0da4b0a8a72bc30d72ea12f8a2d3dd9fbe292400ebee0e7f559d33604051808275ffffffffffffffffffffffffffffffffffffffffffff1675ffffffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a16040518060400160405280600b81526020017f68656c6c6f20776f726c6400000000000000000000000000000000000000000081525090509291505056fea2646970667358221220ed9a4a0d373eb4629e50a4569370026d7334b397204cc19b02cb97e3f57d65c764736f6c637827302e362e392d646576656c6f702e323032302e372e32312b636f6d6d69742e33633832373333370058`
   105  
   106  // expected return value contains "hello world"
   107  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}
   108  
   109  func simTestBackend(testAddr common.Address) *SimulatedBackend {
   110  	return NewSimulatedBackend(
   111  		core.GenesisAlloc{
   112  			testAddr: {Balance: big.NewInt(10000000000)},
   113  		}, 10000000,
   114  	)
   115  }
   116  
   117  func TestNewSimulatedBackend(t *testing.T) {
   118  	expectedBal := big.NewInt(10000000000)
   119  	sim := simTestBackend(testKey.Address())
   120  	defer sim.Close()
   121  
   122  	if sim.config != params.MainnetChainConfig {
   123  		t.Errorf("expected sim config to equal params.MainnetChainConfig, got %v", sim.config)
   124  	}
   125  
   126  	if sim.blockchain.Config() != params.MainnetChainConfig {
   127  		t.Errorf("expected sim blockchain config to equal params.MainnetChainConfig, got %v", sim.config)
   128  	}
   129  
   130  	stateDB, _ := sim.blockchain.State()
   131  	bal := stateDB.GetBalance(testKey.Address())
   132  	if bal.Cmp(expectedBal) != 0 {
   133  		t.Errorf("expected balance for test address not received. expected: %v actual: %v", expectedBal, bal)
   134  	}
   135  }
   136  
   137  func TestSimulatedBackend_AdjustTime(t *testing.T) {
   138  	sim := NewSimulatedBackend(
   139  		core.GenesisAlloc{}, 10000000,
   140  	)
   141  	defer sim.Close()
   142  
   143  	prevTime := sim.pendingBlock.Time()
   144  	if err := sim.AdjustTime(time.Second); err != nil {
   145  		t.Error(err)
   146  	}
   147  	newTime := sim.pendingBlock.Time()
   148  
   149  	if newTime-prevTime != uint64(time.Second.Seconds()) {
   150  		t.Errorf("adjusted time not equal to a second. prev: %v, new: %v", prevTime, newTime)
   151  	}
   152  }
   153  
   154  func TestNewSimulatedBackend_AdjustTimeFail(t *testing.T) {
   155  	sim := simTestBackend(testKey.Address())
   156  	// Create tx and send
   157  	tx := types.NewTransaction(0, testKey.Address(), big.NewInt(1000), params.TxEnergy, big.NewInt(1), nil)
   158  	signedTx, err := types.SignTx(tx, types.NewNucleusSigner(sim.config.NetworkID), testKey)
   159  	if err != nil {
   160  		t.Errorf("could not sign tx: %v", err)
   161  	}
   162  	sim.SendTransaction(context.Background(), signedTx)
   163  	// AdjustTime should fail on non-empty block
   164  	if err := sim.AdjustTime(time.Second); err == nil {
   165  		t.Error("Expected adjust time to error on non-empty block")
   166  	}
   167  	sim.Commit()
   168  
   169  	prevTime := sim.pendingBlock.Time()
   170  	if err := sim.AdjustTime(time.Minute); err != nil {
   171  		t.Error(err)
   172  	}
   173  	newTime := sim.pendingBlock.Time()
   174  	if newTime-prevTime != uint64(time.Minute.Seconds()) {
   175  		t.Errorf("adjusted time not equal to a minute. prev: %v, new: %v", prevTime, newTime)
   176  	}
   177  	// Put a transaction after adjusting time
   178  	tx2 := types.NewTransaction(1, testKey.Address(), big.NewInt(1000), params.TxEnergy, big.NewInt(1), nil)
   179  	signedTx2, err := types.SignTx(tx2, types.NewNucleusSigner(sim.config.NetworkID), testKey)
   180  	if err != nil {
   181  		t.Errorf("could not sign tx: %v", err)
   182  	}
   183  	sim.SendTransaction(context.Background(), signedTx2)
   184  	sim.Commit()
   185  	newTime = sim.pendingBlock.Time()
   186  	if newTime-prevTime >= uint64(time.Minute.Seconds()) {
   187  		t.Errorf("time adjusted, but shouldn't be: prev: %v, new: %v", prevTime, newTime)
   188  	}
   189  }
   190  
   191  func TestSimulatedBackend_BalanceAt(t *testing.T) {
   192  
   193  	expectedBal := big.NewInt(10000000000)
   194  	sim := simTestBackend(testKey.Address())
   195  	defer sim.Close()
   196  	bgCtx := context.Background()
   197  
   198  	bal, err := sim.BalanceAt(bgCtx, testKey.Address(), nil)
   199  	if err != nil {
   200  		t.Error(err)
   201  	}
   202  
   203  	if bal.Cmp(expectedBal) != 0 {
   204  		t.Errorf("expected balance for test address not received. expected: %v actual: %v", expectedBal, bal)
   205  	}
   206  }
   207  
   208  func TestSimulatedBackend_BlockByHash(t *testing.T) {
   209  	sim := NewSimulatedBackend(
   210  		core.GenesisAlloc{}, 10000000,
   211  	)
   212  	defer sim.Close()
   213  	bgCtx := context.Background()
   214  
   215  	block, err := sim.BlockByNumber(bgCtx, nil)
   216  	if err != nil {
   217  		t.Errorf("could not get recent block: %v", err)
   218  	}
   219  	blockByHash, err := sim.BlockByHash(bgCtx, block.Hash())
   220  	if err != nil {
   221  		t.Errorf("could not get recent block: %v", err)
   222  	}
   223  
   224  	if block.Hash() != blockByHash.Hash() {
   225  		t.Errorf("did not get expected block")
   226  	}
   227  }
   228  
   229  func TestSimulatedBackend_BlockByNumber(t *testing.T) {
   230  	sim := NewSimulatedBackend(
   231  		core.GenesisAlloc{}, 10000000,
   232  	)
   233  	defer sim.Close()
   234  	bgCtx := context.Background()
   235  
   236  	block, err := sim.BlockByNumber(bgCtx, nil)
   237  	if err != nil {
   238  		t.Errorf("could not get recent block: %v", err)
   239  	}
   240  	if block.NumberU64() != 0 {
   241  		t.Errorf("did not get most recent block, instead got block number %v", block.NumberU64())
   242  	}
   243  
   244  	// create one block
   245  	sim.Commit()
   246  
   247  	block, err = sim.BlockByNumber(bgCtx, nil)
   248  	if err != nil {
   249  		t.Errorf("could not get recent block: %v", err)
   250  	}
   251  	if block.NumberU64() != 1 {
   252  		t.Errorf("did not get most recent block, instead got block number %v", block.NumberU64())
   253  	}
   254  
   255  	blockByNumber, err := sim.BlockByNumber(bgCtx, big.NewInt(1))
   256  	if err != nil {
   257  		t.Errorf("could not get block by number: %v", err)
   258  	}
   259  	if blockByNumber.Hash() != block.Hash() {
   260  		t.Errorf("did not get the same block with height of 1 as before")
   261  	}
   262  }
   263  
   264  func TestSimulatedBackend_NonceAt(t *testing.T) {
   265  
   266  	sim := simTestBackend(testKey.Address())
   267  	defer sim.Close()
   268  	bgCtx := context.Background()
   269  
   270  	nonce, err := sim.NonceAt(bgCtx, testKey.Address(), big.NewInt(0))
   271  	if err != nil {
   272  		t.Errorf("could not get nonce for test addr: %v", err)
   273  	}
   274  
   275  	if nonce != uint64(0) {
   276  		t.Errorf("received incorrect nonce. expected 0, got %v", nonce)
   277  	}
   278  
   279  	// create a signed transaction to send
   280  	tx := types.NewTransaction(nonce, testKey.Address(), big.NewInt(1000), params.TxEnergy, big.NewInt(1), nil)
   281  	signedTx, err := types.SignTx(tx, types.NewNucleusSigner(sim.config.NetworkID), testKey)
   282  	if err != nil {
   283  		t.Errorf("could not sign tx: %v", err)
   284  	}
   285  
   286  	// send tx to simulated backend
   287  	err = sim.SendTransaction(bgCtx, signedTx)
   288  	if err != nil {
   289  		t.Errorf("could not add tx to pending block: %v", err)
   290  	}
   291  	sim.Commit()
   292  
   293  	newNonce, err := sim.NonceAt(bgCtx, testKey.Address(), big.NewInt(1))
   294  	if err != nil {
   295  		t.Errorf("could not get nonce for test addr: %v", err)
   296  	}
   297  
   298  	if newNonce != nonce+uint64(1) {
   299  		t.Errorf("received incorrect nonce. expected 1, got %v", nonce)
   300  	}
   301  	// create some more blocks
   302  	sim.Commit()
   303  	// Check that we can get data for an older block/state
   304  	newNonce, err = sim.NonceAt(bgCtx, testKey.Address(), big.NewInt(1))
   305  	if err != nil {
   306  		t.Fatalf("could not get nonce for test addr: %v", err)
   307  	}
   308  	if newNonce != nonce+uint64(1) {
   309  		t.Fatalf("received incorrect nonce. expected 1, got %v", nonce)
   310  	}
   311  }
   312  
   313  func TestSimulatedBackend_SendTransaction(t *testing.T) {
   314  
   315  	sim := simTestBackend(testKey.Address())
   316  	defer sim.Close()
   317  	bgCtx := context.Background()
   318  
   319  	// create a signed transaction to send
   320  	tx := types.NewTransaction(uint64(0), testKey.Address(), big.NewInt(1000), params.TxEnergy, big.NewInt(1), nil)
   321  	signedTx, err := types.SignTx(tx, types.NewNucleusSigner(sim.config.NetworkID), testKey)
   322  	if err != nil {
   323  		t.Errorf("could not sign tx: %v", err)
   324  	}
   325  
   326  	// send tx to simulated backend
   327  	err = sim.SendTransaction(bgCtx, signedTx)
   328  	if err != nil {
   329  		t.Errorf("could not add tx to pending block: %v", err)
   330  	}
   331  	sim.Commit()
   332  
   333  	block, err := sim.BlockByNumber(bgCtx, big.NewInt(1))
   334  	if err != nil {
   335  		t.Errorf("could not get block at height 1: %v", err)
   336  	}
   337  
   338  	if signedTx.Hash() != block.Transactions()[0].Hash() {
   339  		t.Errorf("did not commit sent transaction. expected hash %v got hash %v", block.Transactions()[0].Hash(), signedTx.Hash())
   340  	}
   341  }
   342  
   343  func TestSimulatedBackend_TransactionByHash(t *testing.T) {
   344  
   345  	sim := NewSimulatedBackend(
   346  		core.GenesisAlloc{
   347  			testKey.Address(): {Balance: big.NewInt(10000000000)},
   348  		}, 10000000,
   349  	)
   350  	defer sim.Close()
   351  	bgCtx := context.Background()
   352  
   353  	// create a signed transaction to send
   354  	tx := types.NewTransaction(uint64(0), testKey.Address(), big.NewInt(1000), params.TxEnergy, big.NewInt(1), nil)
   355  	signedTx, err := types.SignTx(tx, types.NewNucleusSigner(sim.config.NetworkID), testKey)
   356  	if err != nil {
   357  		t.Errorf("could not sign tx: %v", err)
   358  	}
   359  
   360  	// send tx to simulated backend
   361  	err = sim.SendTransaction(bgCtx, signedTx)
   362  	if err != nil {
   363  		t.Errorf("could not add tx to pending block: %v", err)
   364  	}
   365  
   366  	// ensure tx is committed pending
   367  	receivedTx, pending, err := sim.TransactionByHash(bgCtx, signedTx.Hash())
   368  	if err != nil {
   369  		t.Errorf("could not get transaction by hash %v: %v", signedTx.Hash(), err)
   370  	}
   371  	if !pending {
   372  		t.Errorf("expected transaction to be in pending state")
   373  	}
   374  	if receivedTx.Hash() != signedTx.Hash() {
   375  		t.Errorf("did not received committed transaction. expected hash %v got hash %v", signedTx.Hash(), receivedTx.Hash())
   376  	}
   377  
   378  	sim.Commit()
   379  
   380  	// ensure tx is not and committed pending
   381  	receivedTx, pending, err = sim.TransactionByHash(bgCtx, signedTx.Hash())
   382  	if err != nil {
   383  		t.Errorf("could not get transaction by hash %v: %v", signedTx.Hash(), err)
   384  	}
   385  	if pending {
   386  		t.Errorf("expected transaction to not be in pending state")
   387  	}
   388  	if receivedTx.Hash() != signedTx.Hash() {
   389  		t.Errorf("did not received committed transaction. expected hash %v got hash %v", signedTx.Hash(), receivedTx.Hash())
   390  	}
   391  }
   392  
   393  func TestSimulatedBackend_EstimateEnergy(t *testing.T) {
   394  	/*
   395  		pragma solidity ^0.6.4;
   396  		contract EnergyEstimation {
   397  		    function PureRevert() public { revert(); }
   398  		    function Revert() public { revert("revert reason");}
   399  		    function OOG() public { for (uint i = 0; ; i++) {}}
   400  		    function Assert() public { assert(false);}
   401  		    function Valid() public {}
   402  		}*/
   403  	const contractAbi = "[{\"inputs\":[],\"name\":\"Assert\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"OOG\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"PureRevert\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"Revert\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"Valid\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]"
   404  	const contractBin = "608060405234801561001057600080fd5b50610277806100206000396000f3fe608060405234801561001057600080fd5b50600436106100575760003560e01c80633ae247141461005c578063593b9361146100665780636c5fcd821461007057806396be6e031461007a578063a842ede314610084575b600080fd5b61006461008e565b005b61006e6100c9565b005b6100786100ce565b005b6100826100e4565b005b61008c6100e6565b005b6040517f4e401cbe0000000000000000000000000000000000000000000000000000000081526004016100c090610140565b60405180910390fd5b600080fd5b60005b80806100dc9061017b565b9150506100d1565b565b600061011b577f4b1f2ce300000000000000000000000000000000000000000000000000000000600052600160045260246000fd5b565b600061012a600d83610160565b9150610135826101f3565b602082019050919050565b600060208201905081810360008301526101598161011d565b9050919050565b600082825260208201905092915050565b6000819050919050565b600061018682610171565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8214156101b9576101b86101c4565b5b600182019050919050565b7f4b1f2ce300000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f72657665727420726561736f6e0000000000000000000000000000000000000060008201525056fea2646970667358221220a6fc6aa476f9e0ac54c080bfe2449a444d3ff8e7f0af4a847631b09f2022c3ae64736f6c637827302e382e342d646576656c6f702e323032322e382e32322b636f6d6d69742e37383961353965650058"
   405  
   406  	key, _ := crypto.GenerateKey(crand.Reader)
   407  	addr := key.Address()
   408  	opts, _ := bind.NewKeyedTransactorWithNetworkID(key, big.NewInt(1))
   409  
   410  	sim := NewSimulatedBackend(core.GenesisAlloc{addr: {Balance: big.NewInt(params.Core)}}, 10000000)
   411  	defer sim.Close()
   412  
   413  	parsed, _ := abi.JSON(strings.NewReader(contractAbi))
   414  	contractAddr, _, _, _ := bind.DeployContract(opts, parsed, common.FromHex(contractBin), sim)
   415  	sim.Commit()
   416  
   417  	var cases = []struct {
   418  		name        string
   419  		message     c.CallMsg
   420  		expect      uint64
   421  		expectError error
   422  		expectData  interface{}
   423  	}{
   424  		{"plain transfer(valid)", c.CallMsg{
   425  			From:        addr,
   426  			To:          &addr,
   427  			Energy:      0,
   428  			EnergyPrice: big.NewInt(0),
   429  			Value:       big.NewInt(1),
   430  			Data:        nil,
   431  		}, params.TxEnergy, nil, nil},
   432  
   433  		{"plain transfer(invalid)", c.CallMsg{
   434  			From:        addr,
   435  			To:          &contractAddr,
   436  			Energy:      0,
   437  			EnergyPrice: big.NewInt(0),
   438  			Value:       big.NewInt(1),
   439  			Data:        nil,
   440  		}, 0, errors.New("execution reverted"), nil},
   441  
   442  		{"Revert", c.CallMsg{
   443  			From:        addr,
   444  			To:          &contractAddr,
   445  			Energy:      0,
   446  			EnergyPrice: big.NewInt(0),
   447  			Value:       nil,
   448  			Data:        common.Hex2Bytes("3ae24714"),
   449  		}, 0, errors.New("execution reverted: revert reason"), "0x4e401cbe0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000d72657665727420726561736f6e00000000000000000000000000000000000000"},
   450  
   451  		{"PureRevert", c.CallMsg{
   452  			From:        addr,
   453  			To:          &contractAddr,
   454  			Energy:      0,
   455  			EnergyPrice: big.NewInt(0),
   456  			Value:       nil,
   457  			Data:        common.Hex2Bytes("593b9361"),
   458  		}, 0, errors.New("execution reverted"), nil},
   459  
   460  		{"OOG", c.CallMsg{
   461  			From:        addr,
   462  			To:          &contractAddr,
   463  			Energy:      100000,
   464  			EnergyPrice: big.NewInt(0),
   465  			Value:       nil,
   466  			Data:        common.Hex2Bytes("6c5fcd82"),
   467  		}, 0, errors.New("energy required exceeds allowance (100000)"), nil},
   468  
   469  		// t.Skip("temporary skip")
   470  		//{"Assert", c.CallMsg{
   471  		//	From:        addr,
   472  		//	To:          &contractAddr,
   473  		//	Energy:      100000,
   474  		//	EnergyPrice: big.NewInt(0),
   475  		//	Value:       nil,
   476  		//	Data:        common.Hex2Bytes("a842ede3"),
   477  		//}, 0, errors.New("invalid opcode: opcode 0xfe not defined"), nil},
   478  
   479  		{"Valid", c.CallMsg{
   480  			From:        addr,
   481  			To:          &contractAddr,
   482  			Energy:      100000,
   483  			EnergyPrice: big.NewInt(0),
   484  			Value:       nil,
   485  			Data:        common.Hex2Bytes("96be6e03"),
   486  		}, 21252, nil, nil},
   487  	}
   488  	for _, c := range cases {
   489  		got, err := sim.EstimateEnergy(context.Background(), c.message)
   490  		if c.expectError != nil {
   491  			if err == nil {
   492  				t.Fatalf("Expect error, got nil")
   493  			}
   494  			if c.expectError.Error() != err.Error() {
   495  				t.Fatalf("Expect error, want %v, got %v", c.expectError, err)
   496  			}
   497  			if c.expectData != nil {
   498  				if err, ok := err.(*revertError); !ok {
   499  					t.Fatalf("Expect revert error, got %T", err)
   500  				} else if !reflect.DeepEqual(err.ErrorData(), c.expectData) {
   501  					t.Fatalf("Error data mismatch, want %v, got %v", c.expectData, err.ErrorData())
   502  				}
   503  			}
   504  			continue
   505  		}
   506  		if got != c.expect {
   507  			t.Fatalf("Energy estimation mismatch, want %d, got %d", c.expect, got)
   508  		}
   509  	}
   510  }
   511  
   512  func TestSimulatedBackend_EstimateEnergyWithPrice(t *testing.T) {
   513  	key, _ := crypto.GenerateKey(crand.Reader)
   514  	addr := key.Address()
   515  
   516  	sim := NewSimulatedBackend(core.GenesisAlloc{addr: {Balance: big.NewInt(params.Core*2 + 2e17)}}, 10000000)
   517  	defer sim.Close()
   518  
   519  	recipient, err := common.HexToAddress("cb76a631db606f1452ddc2432931d611f1d5b126f848")
   520  	if err != nil {
   521  		t.Error(err)
   522  	}
   523  	var cases = []struct {
   524  		name        string
   525  		message     c.CallMsg
   526  		expect      uint64
   527  		expectError error
   528  	}{
   529  		{"EstimateWithoutPrice", c.CallMsg{
   530  			From:        addr,
   531  			To:          &recipient,
   532  			Energy:      0,
   533  			EnergyPrice: big.NewInt(0),
   534  			Value:       big.NewInt(1000),
   535  			Data:        nil,
   536  		}, 21000, nil},
   537  
   538  		{"EstimateWithPrice", c.CallMsg{
   539  			From:        addr,
   540  			To:          &recipient,
   541  			Energy:      0,
   542  			EnergyPrice: big.NewInt(1000),
   543  			Value:       big.NewInt(1000),
   544  			Data:        nil,
   545  		}, 21000, nil},
   546  
   547  		{"EstimateWithVeryHighPrice", c.CallMsg{
   548  			From:        addr,
   549  			To:          &recipient,
   550  			Energy:      0,
   551  			EnergyPrice: big.NewInt(1e14), // energycost = 2.1core
   552  			Value:       big.NewInt(1e17), // the remaining balance for fee is 2.1core
   553  			Data:        nil,
   554  		}, 21000, nil},
   555  
   556  		{"EstimateWithSuperhighPrice", c.CallMsg{
   557  			From:        addr,
   558  			To:          &recipient,
   559  			Energy:      0,
   560  			EnergyPrice: big.NewInt(2e14), // energycost = 4.2core
   561  			Value:       big.NewInt(1000),
   562  			Data:        nil,
   563  		}, 21000, errors.New("energy required exceeds allowance (10999)")}, // 10999=(2.2core-1000ore)/(2e14)
   564  	}
   565  	for _, c := range cases {
   566  		got, err := sim.EstimateEnergy(context.Background(), c.message)
   567  		if c.expectError != nil {
   568  			if err == nil {
   569  				t.Fatalf("Expect error, got nil")
   570  			}
   571  			if c.expectError.Error() != err.Error() {
   572  				t.Fatalf("Expect error, want %v, got %v", c.expectError, err)
   573  			}
   574  			continue
   575  		}
   576  		if got != c.expect {
   577  			t.Fatalf("Energy estimation mismatch, want %d, got %d", c.expect, got)
   578  		}
   579  	}
   580  }
   581  
   582  func TestSimulatedBackend_HeaderByHash(t *testing.T) {
   583  
   584  	sim := simTestBackend(testKey.Address())
   585  	defer sim.Close()
   586  	bgCtx := context.Background()
   587  
   588  	header, err := sim.HeaderByNumber(bgCtx, nil)
   589  	if err != nil {
   590  		t.Errorf("could not get recent block: %v", err)
   591  	}
   592  	headerByHash, err := sim.HeaderByHash(bgCtx, header.Hash())
   593  	if err != nil {
   594  		t.Errorf("could not get recent block: %v", err)
   595  	}
   596  
   597  	if header.Hash() != headerByHash.Hash() {
   598  		t.Errorf("did not get expected block")
   599  	}
   600  }
   601  
   602  func TestSimulatedBackend_HeaderByNumber(t *testing.T) {
   603  
   604  	sim := simTestBackend(testKey.Address())
   605  	defer sim.Close()
   606  	bgCtx := context.Background()
   607  
   608  	latestBlockHeader, err := sim.HeaderByNumber(bgCtx, nil)
   609  	if err != nil {
   610  		t.Errorf("could not get header for tip of chain: %v", err)
   611  	}
   612  	if latestBlockHeader == nil {
   613  		t.Errorf("received a nil block header")
   614  	}
   615  	if latestBlockHeader.Number.Uint64() != uint64(0) {
   616  		t.Errorf("expected block header number 0, instead got %v", latestBlockHeader.Number.Uint64())
   617  	}
   618  
   619  	sim.Commit()
   620  
   621  	latestBlockHeader, err = sim.HeaderByNumber(bgCtx, nil)
   622  	if err != nil {
   623  		t.Errorf("could not get header for blockheight of 1: %v", err)
   624  	}
   625  
   626  	blockHeader, err := sim.HeaderByNumber(bgCtx, big.NewInt(1))
   627  	if err != nil {
   628  		t.Errorf("could not get header for blockheight of 1: %v", err)
   629  	}
   630  
   631  	if blockHeader.Hash() != latestBlockHeader.Hash() {
   632  		t.Errorf("block header and latest block header are not the same")
   633  	}
   634  	if blockHeader.Number.Int64() != int64(1) {
   635  		t.Errorf("did not get blockheader for block 1. instead got block %v", blockHeader.Number.Int64())
   636  	}
   637  
   638  	block, err := sim.BlockByNumber(bgCtx, big.NewInt(1))
   639  	if err != nil {
   640  		t.Errorf("could not get block for blockheight of 1: %v", err)
   641  	}
   642  
   643  	if block.Hash() != blockHeader.Hash() {
   644  		t.Errorf("block hash and block header hash do not match. expected %v, got %v", block.Hash(), blockHeader.Hash())
   645  	}
   646  }
   647  
   648  func TestSimulatedBackend_TransactionCount(t *testing.T) {
   649  
   650  	sim := simTestBackend(testKey.Address())
   651  	defer sim.Close()
   652  	bgCtx := context.Background()
   653  	currentBlock, err := sim.BlockByNumber(bgCtx, nil)
   654  	if err != nil || currentBlock == nil {
   655  		t.Error("could not get current block")
   656  	}
   657  
   658  	count, err := sim.TransactionCount(bgCtx, currentBlock.Hash())
   659  	if err != nil {
   660  		t.Error("could not get current block's transaction count")
   661  	}
   662  
   663  	if count != 0 {
   664  		t.Errorf("expected transaction count of %v does not match actual count of %v", 0, count)
   665  	}
   666  
   667  	// create a signed transaction to send
   668  	tx := types.NewTransaction(uint64(0), testKey.Address(), big.NewInt(1000), params.TxEnergy, big.NewInt(1), nil)
   669  	signedTx, err := types.SignTx(tx, types.NewNucleusSigner(sim.config.NetworkID), testKey)
   670  	if err != nil {
   671  		t.Errorf("could not sign tx: %v", err)
   672  	}
   673  
   674  	// send tx to simulated backend
   675  	err = sim.SendTransaction(bgCtx, signedTx)
   676  	if err != nil {
   677  		t.Errorf("could not add tx to pending block: %v", err)
   678  	}
   679  
   680  	sim.Commit()
   681  
   682  	lastBlock, err := sim.BlockByNumber(bgCtx, nil)
   683  	if err != nil {
   684  		t.Errorf("could not get header for tip of chain: %v", err)
   685  	}
   686  
   687  	count, err = sim.TransactionCount(bgCtx, lastBlock.Hash())
   688  	if err != nil {
   689  		t.Error("could not get current block's transaction count")
   690  	}
   691  
   692  	if count != 1 {
   693  		t.Errorf("expected transaction count of %v does not match actual count of %v", 1, count)
   694  	}
   695  }
   696  
   697  func TestSimulatedBackend_TransactionInBlock(t *testing.T) {
   698  
   699  	sim := simTestBackend(testKey.Address())
   700  	defer sim.Close()
   701  	bgCtx := context.Background()
   702  
   703  	transaction, err := sim.TransactionInBlock(bgCtx, sim.pendingBlock.Hash(), uint(0))
   704  	if err == nil && err != errTransactionDoesNotExist {
   705  		t.Errorf("expected a transaction does not exist error to be received but received %v", err)
   706  	}
   707  	if transaction != nil {
   708  		t.Errorf("expected transaction to be nil but received %v", transaction)
   709  	}
   710  
   711  	// expect pending nonce to be 0 since account has not been used
   712  	pendingNonce, err := sim.PendingNonceAt(bgCtx, testKey.Address())
   713  	if err != nil {
   714  		t.Errorf("did not get the pending nonce: %v", err)
   715  	}
   716  
   717  	if pendingNonce != uint64(0) {
   718  		t.Errorf("expected pending nonce of 0 got %v", pendingNonce)
   719  	}
   720  
   721  	// create a signed transaction to send
   722  	tx := types.NewTransaction(uint64(0), testKey.Address(), big.NewInt(1000), params.TxEnergy, big.NewInt(1), nil)
   723  	signedTx, err := types.SignTx(tx, types.NewNucleusSigner(sim.config.NetworkID), testKey)
   724  	if err != nil {
   725  		t.Errorf("could not sign tx: %v", err)
   726  	}
   727  
   728  	// send tx to simulated backend
   729  	err = sim.SendTransaction(bgCtx, signedTx)
   730  	if err != nil {
   731  		t.Errorf("could not add tx to pending block: %v", err)
   732  	}
   733  
   734  	sim.Commit()
   735  
   736  	lastBlock, err := sim.BlockByNumber(bgCtx, nil)
   737  	if err != nil {
   738  		t.Errorf("could not get header for tip of chain: %v", err)
   739  	}
   740  
   741  	transaction, err = sim.TransactionInBlock(bgCtx, lastBlock.Hash(), uint(1))
   742  	if err == nil && err != errTransactionDoesNotExist {
   743  		t.Errorf("expected a transaction does not exist error to be received but received %v", err)
   744  	}
   745  	if transaction != nil {
   746  		t.Errorf("expected transaction to be nil but received %v", transaction)
   747  	}
   748  
   749  	transaction, err = sim.TransactionInBlock(bgCtx, lastBlock.Hash(), uint(0))
   750  	if err != nil {
   751  		t.Errorf("could not get transaction in the lastest block with hash %v: %v", lastBlock.Hash().String(), err)
   752  	}
   753  
   754  	if signedTx.Hash().String() != transaction.Hash().String() {
   755  		t.Errorf("received transaction that did not match the sent transaction. expected hash %v, got hash %v", signedTx.Hash().String(), transaction.Hash().String())
   756  	}
   757  }
   758  
   759  func TestSimulatedBackend_PendingNonceAt(t *testing.T) {
   760  
   761  	sim := simTestBackend(testKey.Address())
   762  	defer sim.Close()
   763  	bgCtx := context.Background()
   764  
   765  	// expect pending nonce to be 0 since account has not been used
   766  	pendingNonce, err := sim.PendingNonceAt(bgCtx, testKey.Address())
   767  	if err != nil {
   768  		t.Errorf("did not get the pending nonce: %v", err)
   769  	}
   770  
   771  	if pendingNonce != uint64(0) {
   772  		t.Errorf("expected pending nonce of 0 got %v", pendingNonce)
   773  	}
   774  
   775  	// create a signed transaction to send
   776  	tx := types.NewTransaction(uint64(0), testKey.Address(), big.NewInt(1000), params.TxEnergy, big.NewInt(1), nil)
   777  	signedTx, err := types.SignTx(tx, types.NewNucleusSigner(sim.config.NetworkID), testKey)
   778  	if err != nil {
   779  		t.Errorf("could not sign tx: %v", err)
   780  	}
   781  
   782  	// send tx to simulated backend
   783  	err = sim.SendTransaction(bgCtx, signedTx)
   784  	if err != nil {
   785  		t.Errorf("could not add tx to pending block: %v", err)
   786  	}
   787  
   788  	// expect pending nonce to be 1 since account has submitted one transaction
   789  	pendingNonce, err = sim.PendingNonceAt(bgCtx, testKey.Address())
   790  	if err != nil {
   791  		t.Errorf("did not get the pending nonce: %v", err)
   792  	}
   793  
   794  	if pendingNonce != uint64(1) {
   795  		t.Errorf("expected pending nonce of 1 got %v", pendingNonce)
   796  	}
   797  
   798  	// make a new transaction with a nonce of 1
   799  	tx = types.NewTransaction(uint64(1), testKey.Address(), big.NewInt(1000), params.TxEnergy, big.NewInt(1), nil)
   800  	signedTx, err = types.SignTx(tx, types.NewNucleusSigner(sim.config.NetworkID), testKey)
   801  	if err != nil {
   802  		t.Errorf("could not sign tx: %v", err)
   803  	}
   804  	err = sim.SendTransaction(bgCtx, signedTx)
   805  	if err != nil {
   806  		t.Errorf("could not send tx: %v", err)
   807  	}
   808  
   809  	// expect pending nonce to be 2 since account now has two transactions
   810  	pendingNonce, err = sim.PendingNonceAt(bgCtx, testKey.Address())
   811  	if err != nil {
   812  		t.Errorf("did not get the pending nonce: %v", err)
   813  	}
   814  
   815  	if pendingNonce != uint64(2) {
   816  		t.Errorf("expected pending nonce of 2 got %v", pendingNonce)
   817  	}
   818  }
   819  
   820  func TestSimulatedBackend_TransactionReceipt(t *testing.T) {
   821  
   822  	sim := simTestBackend(testKey.Address())
   823  	defer sim.Close()
   824  	bgCtx := context.Background()
   825  
   826  	// create a signed transaction to send
   827  	tx := types.NewTransaction(uint64(0), testKey.Address(), big.NewInt(1000), params.TxEnergy, big.NewInt(1), nil)
   828  	signedTx, err := types.SignTx(tx, types.NewNucleusSigner(sim.config.NetworkID), testKey)
   829  	if err != nil {
   830  		t.Errorf("could not sign tx: %v", err)
   831  	}
   832  
   833  	// send tx to simulated backend
   834  	err = sim.SendTransaction(bgCtx, signedTx)
   835  	if err != nil {
   836  		t.Errorf("could not add tx to pending block: %v", err)
   837  	}
   838  	sim.Commit()
   839  
   840  	receipt, err := sim.TransactionReceipt(bgCtx, signedTx.Hash())
   841  	if err != nil {
   842  		t.Errorf("could not get transaction receipt: %v", err)
   843  	}
   844  
   845  	if receipt.ContractAddress != testKey.Address() && receipt.TxHash != signedTx.Hash() {
   846  		t.Errorf("received receipt is not correct: %v", receipt)
   847  	}
   848  }
   849  
   850  func TestSimulatedBackend_SuggestEnergyPrice(t *testing.T) {
   851  	sim := NewSimulatedBackend(
   852  		core.GenesisAlloc{},
   853  		10000000,
   854  	)
   855  	defer sim.Close()
   856  	bgCtx := context.Background()
   857  	energyPrice, err := sim.SuggestEnergyPrice(bgCtx)
   858  	if err != nil {
   859  		t.Errorf("could not get energy price: %v", err)
   860  	}
   861  	if energyPrice.Uint64() != uint64(1) {
   862  		t.Errorf("energy price was not expected value of 1. actual: %v", energyPrice.Uint64())
   863  	}
   864  }
   865  
   866  func TestSimulatedBackend_PendingCodeAt(t *testing.T) {
   867  
   868  	sim := simTestBackend(testKey.Address())
   869  	defer sim.Close()
   870  	bgCtx := context.Background()
   871  	code, err := sim.CodeAt(bgCtx, testKey.Address(), nil)
   872  	if err != nil {
   873  		t.Errorf("could not get code at test addr: %v", err)
   874  	}
   875  	if len(code) != 0 {
   876  		t.Errorf("got code for account that does not have contract code")
   877  	}
   878  
   879  	parsed, err := abi.JSON(strings.NewReader(abiJSON))
   880  	if err != nil {
   881  		t.Errorf("could not get code at test addr: %v", err)
   882  	}
   883  	auth, _ := bind.NewKeyedTransactorWithNetworkID(testKey, big.NewInt(1))
   884  	contractAddr, tx, contract, err := bind.DeployContract(auth, parsed, common.FromHex(abiBin), sim)
   885  	if err != nil {
   886  		t.Errorf("could not deploy contract: %v tx: %v contract: %v", err, tx, contract)
   887  	}
   888  
   889  	code, err = sim.PendingCodeAt(bgCtx, contractAddr)
   890  	if err != nil {
   891  		t.Errorf("could not get code at test addr: %v", err)
   892  	}
   893  	if len(code) == 0 {
   894  		t.Errorf("did not get code for account that has contract code")
   895  	}
   896  	// ensure code received equals code deployed
   897  	if !bytes.Equal(code, common.FromHex(deployedCode)) {
   898  		t.Errorf("code received did not match expected deployed code:\n expected %v\n actual %v", common.FromHex(deployedCode), code)
   899  	}
   900  }
   901  
   902  func TestSimulatedBackend_CodeAt(t *testing.T) {
   903  
   904  	sim := simTestBackend(testKey.Address())
   905  	defer sim.Close()
   906  	bgCtx := context.Background()
   907  	code, err := sim.CodeAt(bgCtx, testKey.Address(), nil)
   908  	if err != nil {
   909  		t.Errorf("could not get code at test addr: %v", err)
   910  	}
   911  	if len(code) != 0 {
   912  		t.Errorf("got code for account that does not have contract code")
   913  	}
   914  
   915  	parsed, err := abi.JSON(strings.NewReader(abiJSON))
   916  	if err != nil {
   917  		t.Errorf("could not get code at test addr: %v", err)
   918  	}
   919  	auth, _ := bind.NewKeyedTransactorWithNetworkID(testKey, big.NewInt(1))
   920  	contractAddr, tx, contract, err := bind.DeployContract(auth, parsed, common.FromHex(abiBin), sim)
   921  	if err != nil {
   922  		t.Errorf("could not deploy contract: %v tx: %v contract: %v", err, tx, contract)
   923  	}
   924  
   925  	sim.Commit()
   926  	code, err = sim.CodeAt(bgCtx, contractAddr, nil)
   927  	if err != nil {
   928  		t.Errorf("could not get code at test addr: %v", err)
   929  	}
   930  	if len(code) == 0 {
   931  		t.Errorf("did not get code for account that has contract code")
   932  	}
   933  	// ensure code received equals code deployed
   934  	if !bytes.Equal(code, common.FromHex(deployedCode)) {
   935  		t.Errorf("code received did not match expected deployed code:\n expected %v\n actual %v", common.FromHex(deployedCode), code)
   936  	}
   937  }
   938  
   939  // When receive("X") is called with sender 0x00... and value 1, it produces this tx receipt:
   940  //
   941  //	receipt{status=1 cenergy=23949 bloom=00000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000040200000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 logs=[log: b6818c8064f645cd82d99b59a1a267d6d61117ef [75fd880d39c1daf53b6547ab6cb59451fc6452d27caa90e5b6649dd8293b9eed] 000000000000000000000000376c47978271565f56deb45495afa69e59c16ab200000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000000158 9ae378b6d4409eada347a5dc0c180f186cb62dc68fcc0f043425eb917335aa28 0 95d429d309bb9d753954195fe2d69bd140b4ae731b9b5b605c34323de162cf00 0]}
   942  func TestSimulatedBackend_PendingAndCallContract(t *testing.T) {
   943  
   944  	sim := simTestBackend(testKey.Address())
   945  	defer sim.Close()
   946  	bgCtx := context.Background()
   947  
   948  	parsed, err := abi.JSON(strings.NewReader(abiJSON))
   949  	if err != nil {
   950  		t.Errorf("could not get code at test addr: %v", err)
   951  	}
   952  	contractAuth, _ := bind.NewKeyedTransactorWithNetworkID(testKey, big.NewInt(1))
   953  	addr, _, _, err := bind.DeployContract(contractAuth, parsed, common.FromHex(abiBin), sim)
   954  	if err != nil {
   955  		t.Errorf("could not deploy contract: %v", err)
   956  	}
   957  
   958  	input, err := parsed.Pack("receive", []byte("X"))
   959  	if err != nil {
   960  		t.Errorf("could not pack receive function on contract: %v", err)
   961  	}
   962  
   963  	// make sure you can call the contract in pending state
   964  	res, err := sim.PendingCallContract(bgCtx, c.CallMsg{
   965  		From: testKey.Address(),
   966  		To:   &addr,
   967  		Data: input,
   968  	})
   969  	if err != nil {
   970  		t.Errorf("could not call receive method on contract: %v", err)
   971  	}
   972  	if len(res) == 0 {
   973  		t.Errorf("result of contract call was empty: %v", res)
   974  	}
   975  
   976  	// while comparing against the byte array is more exact, also compare against the human readable string for readability
   977  	if !bytes.Equal(res, expectedReturn) || !strings.Contains(string(res), "hello world") {
   978  		t.Errorf("response from calling contract was expected to be 'hello world' instead received %v", string(res))
   979  	}
   980  
   981  	sim.Commit()
   982  
   983  	// make sure you can call the contract
   984  	res, err = sim.CallContract(bgCtx, c.CallMsg{
   985  		From: testKey.Address(),
   986  		To:   &addr,
   987  		Data: input,
   988  	}, nil)
   989  	if err != nil {
   990  		t.Errorf("could not call receive method on contract: %v", err)
   991  	}
   992  	if len(res) == 0 {
   993  		t.Errorf("result of contract call was empty: %v", res)
   994  	}
   995  
   996  	if !bytes.Equal(res, expectedReturn) || !strings.Contains(string(res), "hello world") {
   997  		t.Errorf("response from calling contract was expected to be 'hello world' instead received %v", string(res))
   998  	}
   999  }
  1000  
  1001  // This test is based on the following contract:
  1002  /*
  1003  contract Reverter {
  1004      function revertString() public pure{
  1005          require(false, "some error");
  1006      }
  1007      function revertNoString() public pure {
  1008          require(false, "");
  1009      }
  1010      function revertASM() public pure {
  1011          assembly {
  1012              revert(0x0, 0x0)
  1013          }
  1014      }
  1015      function noRevert() public pure {
  1016          assembly {
  1017              // Assembles something that looks like require(false, "some error") but is not reverted
  1018              mstore(0x0, 0x08c379a000000000000000000000000000000000000000000000000000000000)
  1019              mstore(0x4, 0x0000000000000000000000000000000000000000000000000000000000000020)
  1020              mstore(0x24, 0x000000000000000000000000000000000000000000000000000000000000000a)
  1021              mstore(0x44, 0x736f6d65206572726f7200000000000000000000000000000000000000000000)
  1022              return(0x0, 0x64)
  1023          }
  1024      }
  1025  }*/
  1026  func TestSimulatedBackend_CallContractRevert(t *testing.T) {
  1027  
  1028  	sim := simTestBackend(testKey.Address())
  1029  	defer sim.Close()
  1030  	bgCtx := context.Background()
  1031  
  1032  	reverterABI := `[{"inputs":[],"name":"noRevert","outputs":[],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"revertASM","outputs":[],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"revertNoString","outputs":[],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"revertString","outputs":[],"stateMutability":"pure","type":"function"}]`
  1033  	reverterBin := "608060405234801561001057600080fd5b5061027a806100206000396000f3fe608060405234801561001057600080fd5b506004361061004c5760003560e01c80631bc682271461005157806323e686fd1461005b578063aa23755d14610065578063db19521a1461006f575b600080fd5b610059610079565b005b6100636100bc565b005b61006d6100ff565b005b610077610104565b005b60006100ba576040517f4e401cbe0000000000000000000000000000000000000000000000000000000081526004016100b1906101c2565b60405180910390fd5b565b60006100fd576040517f4e401cbe0000000000000000000000000000000000000000000000000000000081526004016100f4906101a2565b60405180910390fd5b565b600080fd5b7f08c379a0000000000000000000000000000000000000000000000000000000006000526020600452600a6024527f736f6d65206572726f720000000000000000000000000000000000000000000060445260646000f35b60006101696000836101e2565b9150610174826101f3565b600082019050919050565b600061018c600a836101e2565b9150610197826101f6565b602082019050919050565b600060208201905081810360008301526101bb8161015c565b9050919050565b600060208201905081810360008301526101db8161017f565b9050919050565b600082825260208201905092915050565b50565b7f736f6d65206572726f720000000000000000000000000000000000000000000060008201525056fea26469706673582212200ded3e17706b826f4ac3dc836add593cfd265f5c6dd5a76aece39f406aad20d364736f6c637827302e382e342d646576656c6f702e323032322e382e32322b636f6d6d69742e37383961353965650058"
  1034  
  1035  	parsed, err := abi.JSON(strings.NewReader(reverterABI))
  1036  	if err != nil {
  1037  		t.Errorf("could not get code at test addr: %v", err)
  1038  	}
  1039  	contractAuth, _ := bind.NewKeyedTransactorWithNetworkID(testKey, big.NewInt(1))
  1040  	addr, _, _, err := bind.DeployContract(contractAuth, parsed, common.FromHex(reverterBin), sim)
  1041  	if err != nil {
  1042  		t.Errorf("could not deploy contract: %v", err)
  1043  	}
  1044  
  1045  	inputs := make(map[string]interface{}, 3)
  1046  	inputs["revertASM"] = nil
  1047  	inputs["revertNoString"] = ""
  1048  	inputs["revertString"] = "some error"
  1049  
  1050  	call := make([]func([]byte) ([]byte, error), 2)
  1051  	call[0] = func(input []byte) ([]byte, error) {
  1052  		return sim.PendingCallContract(bgCtx, c.CallMsg{
  1053  			From: testKey.Address(),
  1054  			To:   &addr,
  1055  			Data: input,
  1056  		})
  1057  	}
  1058  	call[1] = func(input []byte) ([]byte, error) {
  1059  		return sim.CallContract(bgCtx, c.CallMsg{
  1060  			From: testKey.Address(),
  1061  			To:   &addr,
  1062  			Data: input,
  1063  		}, nil)
  1064  	}
  1065  
  1066  	// Run pending calls then commit
  1067  	for _, cl := range call {
  1068  		for key, val := range inputs {
  1069  			input, err := parsed.Pack(key)
  1070  			if err != nil {
  1071  				t.Errorf("could not pack %v function on contract: %v", key, err)
  1072  			}
  1073  
  1074  			res, err := cl(input)
  1075  			if err == nil {
  1076  				t.Errorf("call to %v was not reverted", key)
  1077  			}
  1078  			if res != nil {
  1079  				t.Errorf("result from %v was not nil: %v", key, res)
  1080  			}
  1081  			if val != nil {
  1082  				rerr, ok := err.(*revertError)
  1083  				if !ok {
  1084  					t.Errorf("expect revert error")
  1085  				}
  1086  				if rerr.Error() != "execution reverted: "+val.(string) {
  1087  					t.Errorf("error was malformed: got %v want %v", rerr.Error(), val)
  1088  				}
  1089  			} else {
  1090  				// revert(0x0,0x0)
  1091  				if err.Error() != "execution reverted" {
  1092  					t.Errorf("error was malformed: got %v want %v", err, "execution reverted")
  1093  				}
  1094  			}
  1095  		}
  1096  		input, err := parsed.Pack("noRevert")
  1097  		if err != nil {
  1098  			t.Errorf("could not pack noRevert function on contract: %v", err)
  1099  		}
  1100  		res, err := cl(input)
  1101  		if err != nil {
  1102  			t.Error("call to noRevert was reverted")
  1103  		}
  1104  		if res == nil {
  1105  			t.Errorf("result from noRevert was nil")
  1106  		}
  1107  		sim.Commit()
  1108  	}
  1109  }