github.com/fibonacci-chain/fbc@v0.0.0-20231124064014-c7636198c1e9/app/rpc/tests/rpc_test.go (about)

     1  // This is a test utility for Ethermint's Web3 JSON-RPC services.
     2  //
     3  // To run these tests please first ensure you have the ethermintd running
     4  // and have started the RPC service with `ethermintcli rest-server`.
     5  //
     6  // You can configure the desired HOST and MODE as well
     7  package tests
     8  
     9  import (
    10  	"bytes"
    11  	"encoding/json"
    12  	"fmt"
    13  	"io/ioutil"
    14  	"math/big"
    15  	"math/rand"
    16  	"net"
    17  	"net/http"
    18  	"os"
    19  	"strings"
    20  	"sync"
    21  	"testing"
    22  	"time"
    23  
    24  	ethcmn "github.com/ethereum/go-ethereum/common"
    25  	"github.com/ethereum/go-ethereum/common/hexutil"
    26  	ethtypes "github.com/ethereum/go-ethereum/core/types"
    27  	gorpc "github.com/ethereum/go-ethereum/rpc"
    28  	"github.com/spf13/viper"
    29  	"github.com/stretchr/testify/require"
    30  	"github.com/stretchr/testify/suite"
    31  
    32  	"github.com/fibonacci-chain/fbc/app/crypto/ethsecp256k1"
    33  	"github.com/fibonacci-chain/fbc/app/rpc/backend"
    34  	cosmos_context "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/client/context"
    35  	"github.com/fibonacci-chain/fbc/libs/cosmos-sdk/client/flags"
    36  	cmserver "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/server"
    37  	"github.com/fibonacci-chain/fbc/libs/cosmos-sdk/store/mpt"
    38  	cosmost "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/store/types"
    39  	sdk "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/types"
    40  	tmtypes "github.com/fibonacci-chain/fbc/libs/tendermint/types"
    41  	"github.com/fibonacci-chain/fbc/x/evm/watcher"
    42  
    43  	"github.com/fibonacci-chain/fbc/app/rpc"
    44  	"github.com/fibonacci-chain/fbc/app/rpc/types"
    45  	apptesting "github.com/fibonacci-chain/fbc/libs/ibc-go/testing"
    46  	abci "github.com/fibonacci-chain/fbc/libs/tendermint/abci/types"
    47  	tmamino "github.com/fibonacci-chain/fbc/libs/tendermint/crypto/encoding/amino"
    48  	"github.com/fibonacci-chain/fbc/libs/tendermint/crypto/multisig"
    49  	"github.com/fibonacci-chain/fbc/libs/tendermint/libs/log"
    50  )
    51  
    52  const (
    53  	addrAStoreKey          = 0
    54  	defaultProtocolVersion = 65
    55  	defaultChainID         = 65
    56  	defaultMinGasPrice     = "0.0000000001fibo"
    57  	safeLowGP              = "0.0000000001fibo"
    58  	avgGP                  = "0.0000000001fibo"
    59  	fastestGP              = "0.00000000015fibo"
    60  	latestBlockNumber      = "latest"
    61  	pendingBlockNumber     = "pending"
    62  )
    63  
    64  var (
    65  	receiverAddr   = ethcmn.BytesToAddress([]byte("receiver"))
    66  	inexistentAddr = ethcmn.BytesToAddress([]byte{0})
    67  	inexistentHash = ethcmn.BytesToHash([]byte("inexistent hash"))
    68  	MODE           = os.Getenv("MODE")
    69  	from           = []byte{1}
    70  )
    71  
    72  func init() {
    73  	tmamino.RegisterKeyType(ethsecp256k1.PubKey{}, ethsecp256k1.PubKeyName)
    74  	multisig.RegisterKeyType(ethsecp256k1.PubKey{}, ethsecp256k1.PubKeyName)
    75  }
    76  
    77  type RPCTestSuite struct {
    78  	suite.Suite
    79  
    80  	coordinator *apptesting.Coordinator
    81  
    82  	// testing chains used for convenience and readability
    83  	chain apptesting.TestChainI
    84  
    85  	apiServer     *gorpc.Server
    86  	Mux           *http.ServeMux
    87  	cliCtx        *cosmos_context.CLIContext
    88  	rpcListener   net.Listener
    89  	addr          string
    90  	tmRpcListener net.Listener
    91  	tmAddr        string
    92  }
    93  
    94  func (suite *RPCTestSuite) SetupTest() {
    95  
    96  	viper.Set(rpc.FlagDebugAPI, true)
    97  	viper.Set(cmserver.FlagPruning, cosmost.PruningOptionNothing)
    98  	// set fbchaincli path
    99  	cliDir, err := ioutil.TempDir("", ".fbchaincli")
   100  	if err != nil {
   101  		panic(err)
   102  	}
   103  	defer os.RemoveAll(cliDir)
   104  	viper.Set(cmserver.FlagUlockKeyHome, cliDir)
   105  
   106  	// set fbchaind path
   107  	serverDir, err := ioutil.TempDir("", ".fbchaind")
   108  	if err != nil {
   109  		panic(err)
   110  	}
   111  	defer os.RemoveAll(serverDir)
   112  	viper.Set(flags.FlagHome, serverDir)
   113  
   114  	chainId := apptesting.GetOKChainID(1)
   115  	suite.coordinator = apptesting.NewEthCoordinator(suite.T(), 1)
   116  	suite.chain = suite.coordinator.GetChain(chainId)
   117  	suite.chain.App().SetOption(abci.RequestSetOption{
   118  		Key:   "CheckChainID",
   119  		Value: chainId,
   120  	})
   121  
   122  	//Kb = keys.NewInMemory(hd.EthSecp256k1Options()...)
   123  	//info, err := Kb.CreateAccount("captain", "puzzle glide follow cruel say burst deliver wild tragic galaxy lumber offer", "", "12345678", "m/44'/60'/0'/0/1", "eth_secp256k1")
   124  
   125  	mck := NewMockClient(chainId, suite.chain, suite.chain.App())
   126  	suite.tmRpcListener, suite.tmAddr, err = mck.StartTmRPC()
   127  	if err != nil {
   128  		panic(err)
   129  	}
   130  	viper.Set("rpc.laddr", suite.tmAddr)
   131  
   132  	cliCtx := cosmos_context.NewCLIContext().
   133  		WithProxy(suite.chain.Codec()).
   134  		WithTrustNode(true).
   135  		WithChainID(chainId).
   136  		WithClient(mck).
   137  		WithBroadcastMode(flags.BroadcastSync)
   138  
   139  	suite.cliCtx = &cliCtx
   140  	commitBlock(suite)
   141  
   142  	suite.apiServer = gorpc.NewServer()
   143  
   144  	viper.Set(rpc.FlagDisableAPI, "")
   145  
   146  	viper.Set(backend.FlagApiBackendBlockLruCache, 100)
   147  	viper.Set(backend.FlagApiBackendTxLruCache, 100)
   148  	viper.Set(watcher.FlagFastQueryLru, 100)
   149  	viper.Set(flags.FlagKeyringBackend, "test")
   150  
   151  	viper.Set(rpc.FlagPersonalAPI, true)
   152  
   153  	senderPv := suite.chain.SenderAccountPVBZ()
   154  	genesisAcc = suite.chain.SenderAccount().GetAddress()
   155  	senderAddr = ethcmn.BytesToAddress(genesisAcc.Bytes())
   156  	apis := rpc.GetAPIs(cliCtx, log.NewNopLogger(), []ethsecp256k1.PrivKey{ethsecp256k1.PrivKey(senderPv)}...)
   157  	for _, api := range apis {
   158  		if err := suite.apiServer.RegisterName(api.Namespace, api.Service); err != nil {
   159  			panic(err)
   160  		}
   161  	}
   162  	StartRpc(suite)
   163  }
   164  
   165  func (suite *RPCTestSuite) TearDownTest() {
   166  	if suite.rpcListener != nil {
   167  		suite.rpcListener.Close()
   168  	}
   169  	if suite.tmRpcListener != nil {
   170  		suite.rpcListener.Close()
   171  	}
   172  }
   173  func StartRpc(suite *RPCTestSuite) {
   174  	suite.Mux = http.NewServeMux()
   175  	suite.Mux.HandleFunc("/", suite.apiServer.ServeHTTP)
   176  	listener, err := net.Listen("tcp", ":0")
   177  	if err != nil {
   178  		panic(err)
   179  	}
   180  	suite.rpcListener = listener
   181  	suite.addr = fmt.Sprintf("http://localhost:%d", listener.Addr().(*net.TCPAddr).Port)
   182  	go func() {
   183  		http.Serve(listener, suite.Mux)
   184  	}()
   185  }
   186  func TestRPCTestSuite(t *testing.T) {
   187  	suite.Run(t, new(RPCTestSuite))
   188  }
   189  
   190  func TestRPCTestSuiteWithMarsHeight2(t *testing.T) {
   191  	mpt.TrieWriteAhead = true
   192  	tmtypes.UnittestOnlySetMilestoneMarsHeight(2)
   193  	suite.Run(t, new(RPCTestSuite))
   194  }
   195  
   196  func TestRPCTestSuiteWithMarsHeight1(t *testing.T) {
   197  	mpt.TrieWriteAhead = true
   198  	tmtypes.UnittestOnlySetMilestoneMarsHeight(1)
   199  	suite.Run(t, new(RPCTestSuite))
   200  }
   201  
   202  func commitBlock(suite *RPCTestSuite) {
   203  	mck, ok := suite.cliCtx.Client.(*MockClient)
   204  	suite.Require().True(ok)
   205  	mck.CommitBlock()
   206  }
   207  func (suite *RPCTestSuite) TestEth_GetBalance() {
   208  	// initial balance of hexAddr2 is 1000000000fibo in test.sh
   209  	initialBalance := suite.chain.SenderAccount().GetCoins()[0]
   210  	genesisAcc := ethcmn.BytesToAddress(suite.chain.SenderAccount().GetAddress().Bytes()).String()
   211  
   212  	rpcRes, err := CallWithError(suite.addr, "eth_getBalance", []interface{}{genesisAcc, latestBlockNumber})
   213  	suite.Require().NoError(err)
   214  
   215  	rpcRes2, err := CallWithError(suite.addr, "eth_getBalance", []interface{}{genesisAcc, latestBlockNumber})
   216  	suite.Require().NoError(err)
   217  	suite.Require().NotNil(rpcRes2)
   218  
   219  	var balance hexutil.Big
   220  	suite.Require().NoError(json.Unmarshal(rpcRes.Result, &balance))
   221  	suite.Require().Equal(initialBalance.Amount.Int, balance.ToInt())
   222  
   223  	//suite.coordinator.CommitBlock(suite.chain)
   224  	// query on certain block height (2)
   225  	rpcRes, err = CallWithError(suite.addr, "eth_getBalance", []interface{}{genesisAcc, hexutil.EncodeUint64(1)})
   226  	suite.Require().NoError(err)
   227  	suite.Require().NoError(json.Unmarshal(rpcRes.Result, &balance))
   228  	suite.Require().Equal(initialBalance.Amount.Int, balance.ToInt())
   229  
   230  	// query with pending -> no tx in mempool
   231  	rpcRes, err = CallWithError(suite.addr, "eth_getBalance", []interface{}{genesisAcc, pendingBlockNumber})
   232  	suite.Require().NoError(err)
   233  	suite.Require().NoError(json.Unmarshal(rpcRes.Result, &balance))
   234  	suite.Require().Equal(initialBalance.Amount.Int, balance.ToInt())
   235  
   236  	// inexistent addr -> zero balance
   237  	rpcRes, err = CallWithError(suite.addr, "eth_getBalance", []interface{}{inexistentAddr, latestBlockNumber})
   238  	suite.Require().NoError(err)
   239  	suite.Require().NoError(json.Unmarshal(rpcRes.Result, &balance))
   240  	suite.Require().Equal(big.NewInt(0).Int64(), balance.ToInt().Int64())
   241  
   242  	// error check
   243  	// empty hex string
   244  	_, err = CallWithError(suite.addr, "eth_getBalance", []interface{}{hexAddr2, ""})
   245  	suite.Require().Error(err)
   246  
   247  	// missing argument
   248  	_, err = CallWithError(suite.addr, "eth_getBalance", []interface{}{hexAddr2})
   249  	suite.Require().Error(err)
   250  }
   251  func (suite *RPCTestSuite) TestEth_Accounts() {
   252  	// all unlocked addresses
   253  	rpcRes, err := CallWithError(suite.addr, "eth_accounts", nil)
   254  	suite.Require().NoError(err)
   255  	suite.Require().Equal(1, rpcRes.ID)
   256  
   257  	var addrsUnlocked []ethcmn.Address
   258  	suite.Require().NoError(json.Unmarshal(rpcRes.Result, &addrsUnlocked))
   259  	//suite.Require().Equal(addrCounter, len(addrsUnlocked))
   260  	//suite.Require().True(addrsUnlocked[0] == hexAddr1)
   261  	//suite.Require().True(addrsUnlocked[1] == hexAddr2)
   262  }
   263  
   264  func (suite *RPCTestSuite) TestEth_ProtocolVersion() {
   265  	rpcRes, err := CallWithError(suite.addr, "eth_protocolVersion", nil)
   266  	suite.Require().NoError(err)
   267  
   268  	var version hexutil.Uint
   269  	suite.Require().NoError(json.Unmarshal(rpcRes.Result, &version))
   270  	suite.Require().Equal(version, hexutil.Uint(defaultProtocolVersion))
   271  }
   272  
   273  func (suite *RPCTestSuite) TestEth_ChainId() {
   274  	rpcRes, err := CallWithError(suite.addr, "eth_chainId", nil)
   275  	suite.Require().NoError(err)
   276  
   277  	var chainID hexutil.Uint
   278  	suite.Require().NoError(json.Unmarshal(rpcRes.Result, &chainID))
   279  	suite.Require().Equal(hexutil.Uint(1), chainID)
   280  }
   281  
   282  func (suite *RPCTestSuite) TestEth_Syncing() {
   283  	rpcRes, err := CallWithError(suite.addr, "eth_syncing", nil)
   284  	suite.Require().NoError(err)
   285  
   286  	// single node for test.sh -> always leading without syncing
   287  	var catchingUp bool
   288  	suite.Require().NoError(json.Unmarshal(rpcRes.Result, &catchingUp))
   289  	suite.Require().False(catchingUp)
   290  
   291  	// TODO: set an evn in multi-nodes testnet to test the sycing status of a lagging node
   292  }
   293  
   294  func (suite *RPCTestSuite) TestEth_Coinbase() {
   295  	// single node -> always the same addr for coinbase
   296  	rpcRes, err := CallWithError(suite.addr, "eth_coinbase", nil)
   297  	suite.Require().NoError(err)
   298  
   299  	var coinbaseAddr1 ethcmn.Address
   300  	suite.Require().NoError(json.Unmarshal(rpcRes.Result, &coinbaseAddr1))
   301  
   302  	// wait for 5s as an block interval
   303  	time.Sleep(5 * time.Second)
   304  
   305  	// query again
   306  	rpcRes, err = CallWithError(suite.addr, "eth_coinbase", nil)
   307  	suite.Require().NoError(err)
   308  
   309  	var coinbaseAddr2 ethcmn.Address
   310  	suite.Require().NoError(json.Unmarshal(rpcRes.Result, &coinbaseAddr2))
   311  
   312  	suite.Require().Equal(coinbaseAddr1, coinbaseAddr2)
   313  }
   314  
   315  func (suite *RPCTestSuite) TestEth_PowAttribute() {
   316  	// eth_mining -> always false
   317  	rpcRes, err := CallWithError(suite.addr, "eth_mining", nil)
   318  	suite.Require().NoError(err)
   319  
   320  	var mining bool
   321  	suite.Require().NoError(json.Unmarshal(rpcRes.Result, &mining))
   322  	suite.Require().False(mining)
   323  
   324  	// eth_hashrate -> always 0
   325  	rpcRes, err = CallWithError(suite.addr, "eth_hashrate", nil)
   326  	suite.Require().NoError(err)
   327  
   328  	var hashrate hexutil.Uint64
   329  	suite.Require().NoError(json.Unmarshal(rpcRes.Result, &hashrate))
   330  	suite.Require().True(hashrate == 0)
   331  
   332  	// eth_getUncleCountByBlockHash -> 0 for any hash
   333  	rpcRes, err = CallWithError(suite.addr, "eth_getUncleCountByBlockHash", []interface{}{inexistentHash})
   334  	suite.Require().NoError(err)
   335  
   336  	var uncleCount hexutil.Uint
   337  	suite.Require().NoError(json.Unmarshal(rpcRes.Result, &uncleCount))
   338  	suite.Require().True(uncleCount == 0)
   339  
   340  	// eth_getUncleCountByBlockNumber -> 0 for any block number
   341  	rpcRes, err = CallWithError(suite.addr, "eth_getUncleCountByBlockNumber", []interface{}{latestBlockNumber})
   342  	suite.Require().NoError(err)
   343  
   344  	suite.Require().NoError(json.Unmarshal(rpcRes.Result, &uncleCount))
   345  	suite.Require().True(uncleCount == 0)
   346  
   347  	// eth_getUncleByBlockHashAndIndex -> always "null"
   348  	rand.Seed(time.Now().UnixNano())
   349  	luckyNum := int64(rand.Int())
   350  	randomBlockHash := ethcmn.BigToHash(big.NewInt(luckyNum))
   351  	randomIndex := hexutil.Uint(luckyNum)
   352  	rpcRes, err = CallWithError(suite.addr, "eth_getUncleByBlockHashAndIndex", []interface{}{randomBlockHash, randomIndex})
   353  	suite.Require().NoError(err)
   354  	assertNullFromJSONResponse(suite.T(), rpcRes.Result)
   355  
   356  	// error check
   357  	// miss argument
   358  	_, err = CallWithError(suite.addr, "eth_getUncleByBlockHashAndIndex", []interface{}{randomBlockHash})
   359  	suite.Require().Error(err)
   360  
   361  	_, err = CallWithError(suite.addr, "eth_getUncleByBlockHashAndIndex", nil)
   362  	suite.Require().Error(err)
   363  
   364  	// eth_getUncleByBlockNumberAndIndex -> always "null"
   365  	luckyNum = int64(rand.Int())
   366  	randomBlockHeight := hexutil.Uint(luckyNum)
   367  	randomIndex = hexutil.Uint(luckyNum)
   368  	rpcRes, err = CallWithError(suite.addr, "eth_getUncleByBlockNumberAndIndex", []interface{}{randomBlockHeight, randomIndex})
   369  	suite.Require().NoError(err)
   370  	assertNullFromJSONResponse(suite.T(), rpcRes.Result)
   371  
   372  	// error check
   373  	// miss argument
   374  	_, err = CallWithError(suite.addr, "eth_getUncleByBlockNumberAndIndex", []interface{}{randomBlockHeight})
   375  	suite.Require().Error(err)
   376  
   377  	_, err = CallWithError(suite.addr, "eth_getUncleByBlockNumberAndIndex", nil)
   378  	suite.Require().Error(err)
   379  }
   380  
   381  func (suite *RPCTestSuite) TestEth_GasPrice() {
   382  	rpcRes, err := CallWithError(suite.addr, "eth_gasPrice", nil)
   383  	suite.Require().NoError(err)
   384  
   385  	var gasPrice hexutil.Big
   386  	suite.Require().NoError(json.Unmarshal(rpcRes.Result, &gasPrice))
   387  
   388  	// min gas price in test.sh is "0.000000001fibo"
   389  	mgp, err := sdk.ParseDecCoin(defaultMinGasPrice)
   390  	suite.Require().NoError(err)
   391  
   392  	suite.Require().Equal(mgp.Amount.BigInt(), gasPrice.ToInt())
   393  }
   394  
   395  func (suite *RPCTestSuite) TestEth_GasPriceIn3Gears() {
   396  	rpcRes, err := CallWithError(suite.addr, "eth_gasPriceIn3Gears", nil)
   397  	suite.Require().NoError(err)
   398  
   399  	var gpIn3Gears types.GPIn3Gears
   400  	suite.Require().NoError(json.Unmarshal(rpcRes.Result, &gpIn3Gears))
   401  
   402  	mgp, err := sdk.ParseDecCoin(safeLowGP)
   403  	suite.Require().NoError(err)
   404  	agp, err := sdk.ParseDecCoin(avgGP)
   405  	suite.Require().NoError(err)
   406  	fgp, err := sdk.ParseDecCoin(fastestGP)
   407  	suite.Require().NoError(err)
   408  
   409  	suite.Require().Equal(mgp.Amount.BigInt(), gpIn3Gears.SafeLow.ToInt())
   410  	suite.Require().Equal(agp.Amount.BigInt(), gpIn3Gears.Average.ToInt())
   411  	suite.Require().Equal(fgp.Amount.BigInt(), gpIn3Gears.Fastest.ToInt())
   412  }
   413  
   414  func (suite *RPCTestSuite) TestEth_BlockNumber() {
   415  	rpcRes := Call(suite.T(), suite.addr, "eth_blockNumber", nil)
   416  	var blockNumber1 hexutil.Uint64
   417  	suite.Require().NoError(json.Unmarshal(rpcRes.Result, &blockNumber1))
   418  
   419  	commitBlock(suite)
   420  	commitBlock(suite)
   421  
   422  	rpcRes = Call(suite.T(), suite.addr, "eth_blockNumber", nil)
   423  	var blockNumber2 hexutil.Uint64
   424  	suite.Require().NoError(json.Unmarshal(rpcRes.Result, &blockNumber2))
   425  
   426  	suite.Require().True(blockNumber2 > blockNumber1)
   427  }
   428  func (suite *RPCTestSuite) TestDebug_traceTransaction_Transfer() {
   429  
   430  	value := sdk.NewDec(1)
   431  	param := make([]map[string]string, 1)
   432  	param[0] = make(map[string]string)
   433  	param[0]["from"] = senderAddr.Hex()
   434  	param[0]["to"] = receiverAddr.Hex()
   435  	param[0]["value"] = (*hexutil.Big)(value.BigInt()).String()
   436  	param[0]["gasPrice"] = (*hexutil.Big)(defaultGasPrice.Amount.BigInt()).String()
   437  
   438  	rpcRes := Call(suite.T(), suite.addr, "eth_sendTransaction", param)
   439  
   440  	var hash ethcmn.Hash
   441  	suite.Require().NoError(json.Unmarshal(rpcRes.Result, &hash))
   442  
   443  	commitBlock(suite)
   444  	commitBlock(suite)
   445  	receipt := WaitForReceipt(suite.T(), suite.addr, hash)
   446  	suite.Require().NotNil(receipt)
   447  	suite.Require().Equal("0x1", receipt["status"].(string))
   448  
   449  	debugParam := make([]interface{}, 2)
   450  	debugParam[0] = hash.Hex()
   451  	debugParam[1] = map[string]string{}
   452  
   453  	rpcRes = Call(suite.T(), suite.addr, "debug_traceTransaction", debugParam)
   454  	suite.Require().NotNil(rpcRes.Result)
   455  }
   456  
   457  func (suite *RPCTestSuite) TestEth_SendTransaction_Transfer() {
   458  
   459  	value := sdk.NewDec(1)
   460  	param := make([]map[string]string, 1)
   461  	param[0] = make(map[string]string)
   462  	param[0]["from"] = senderAddr.Hex()
   463  	param[0]["to"] = receiverAddr.Hex()
   464  	param[0]["value"] = (*hexutil.Big)(value.BigInt()).String()
   465  	param[0]["gasPrice"] = (*hexutil.Big)(defaultGasPrice.Amount.BigInt()).String()
   466  
   467  	rpcRes := Call(suite.T(), suite.addr, "eth_sendTransaction", param)
   468  
   469  	var hash ethcmn.Hash
   470  	suite.Require().NoError(json.Unmarshal(rpcRes.Result, &hash))
   471  
   472  	commitBlock(suite)
   473  	commitBlock(suite)
   474  	receipt := WaitForReceipt(suite.T(), suite.addr, hash)
   475  	suite.Require().NotNil(receipt)
   476  	suite.Require().Equal("0x1", receipt["status"].(string))
   477  	//suite.T().Logf("%s transfers %sfibo to %s successfully\n", hexAddr1.Hex(), value.String(), receiverAddr.Hex())
   478  
   479  	// TODO: logic bug, fix it later
   480  	// ignore gas price -> default 'ethermint.DefaultGasPrice' on node -> successfully
   481  	//delete(param[0], "gasPrice")
   482  	//rpcRes = Call(suite.T(), suite.addr, "eth_sendTransaction", param)
   483  	//
   484  	//suite.Require().NoError(json.Unmarshal(rpcRes.Result, &hash))
   485  	//receipt = WaitForReceipt(suite.T(), hash)
   486  	//suite.Require().NotNil(receipt)
   487  	//suite.Require().Equal("0x1", receipt["status"].(string))
   488  	//suite.T().Logf("%s transfers %sfibo to %s successfully with nil gas price \n", hexAddr1.Hex(), value.String(), receiverAddr.Hex())
   489  
   490  	// error check
   491  	// sender is not unlocked on the node
   492  	param[0]["from"] = receiverAddr.Hex()
   493  	param[0]["to"] = hexAddr1.Hex()
   494  	_, err := CallWithError(suite.addr, "eth_sendTransaction", param)
   495  	suite.Require().Error(err)
   496  
   497  	// data.Data and data.Input are not same
   498  	param[0]["from"], param[0]["to"] = param[0]["to"], param[0]["from"]
   499  	param[0]["data"] = "0x1234567890abcdef"
   500  	param[0]["input"] = param[0]["data"][:len(param[0]["data"])-2]
   501  	_, err = CallWithError(suite.addr, "eth_sendTransaction", param)
   502  	suite.Require().Error(err)
   503  
   504  	// input and toAddr are all empty
   505  	delete(param[0], "to")
   506  	delete(param[0], "input")
   507  	delete(param[0], "data")
   508  
   509  	_, err = CallWithError(suite.addr, "eth_sendTransaction", param)
   510  	suite.Require().Error(err)
   511  
   512  	// 0 gas price
   513  	param[0]["to"] = receiverAddr.Hex()
   514  	param[0]["gasPrice"] = (*hexutil.Big)(sdk.ZeroDec().BigInt()).String()
   515  	_, err = CallWithError(suite.addr, "eth_sendTransaction", param)
   516  	suite.Require().Error(err)
   517  }
   518  
   519  /*func (suite *RPCTestSuite) TestEth_SendTransaction_ContractDeploy() {
   520  
   521  	param := make([]map[string]string, 1)
   522  	param[0] = make(map[string]string)
   523  	param[0]["from"] = senderAddr.Hex()
   524  	param[0]["data"] = "0x6080604052348015600f57600080fd5b5060117f775a94827b8fd9b519d36cd827093c664f93347070a554f65e4a6f56cd73889860405160405180910390a2603580604b6000396000f3fe6080604052600080fdfea165627a7a723058206cab665f0f557620554bb45adf266708d2bd349b8a4314bdff205ee8440e3c240029"
   525  	param[0]["gasPrice"] = (*hexutil.Big)(defaultGasPrice.Amount.BigInt()).String()
   526  	rpcRes := Call(suite.T(), suite.addr, "eth_sendTransaction", param)
   527  
   528  	var hash ethcmn.Hash
   529  	suite.Require().NoError(json.Unmarshal(rpcRes.Result, &hash))
   530  
   531  	commitBlock(suite)
   532  	commitBlock(suite)
   533  
   534  	receipt := WaitForReceipt(suite.T(), suite.addr, hash)
   535  	suite.Require().NotNil(receipt)
   536  	suite.Require().Equal("0x1", receipt["status"].(string))
   537  	//suite.T().Logf("%s deploys contract (filled \"data\") successfully with tx hash %s\n", hexAddr1.Hex(), hash.String())
   538  
   539  	// TODO: logic bug, fix it later
   540  	// ignore gas price -> default 'ethermint.DefaultGasPrice' on node -> successfully
   541  	//delete(param[0], "gasPrice")
   542  	//rpcRes = Call(suite.T(), suite.addr, "eth_sendTransaction", param)
   543  	//
   544  	//suite.Require().NoError(json.Unmarshal(rpcRes.Result, &hash))
   545  	//receipt = WaitForReceipt(suite.T(), hash)
   546  	//suite.Require().NotNil(receipt)
   547  	//suite.Require().Equal("0x1", receipt["status"].(string))
   548  	//suite.T().Logf("%s deploys contract successfully with tx hash %s and nil gas price\n", hexAddr1.Hex(), hash.String())
   549  
   550  	// same payload filled in both 'input' and 'data' -> ok
   551  	param[0]["input"] = param[0]["data"]
   552  
   553  	rpcRes = Call(suite.T(), suite.addr, "eth_sendTransaction", param)
   554  
   555  	suite.Require().NoError(json.Unmarshal(rpcRes.Result, &hash))
   556  
   557  	commitBlock(suite)
   558  	commitBlock(suite)
   559  	receipt = WaitForReceipt(suite.T(), suite.addr, hash)
   560  	suite.Require().NotNil(receipt)
   561  	suite.Require().Equal("0x1", receipt["status"].(string))
   562  	//suite.T().Logf("%s deploys contract (filled \"input\" and \"data\") successfully with tx hash %s\n", hexAddr1.Hex(), hash.String())
   563  
   564  	// TODO: logic bug, fix it later
   565  	// filled in 'input' -> ok
   566  	//delete(param[0], "data")
   567  	//rpcRes = Call(suite.T(), suite.addr, "eth_sendTransaction", param)
   568  	//
   569  	//suite.Require().NoError(json.Unmarshal(rpcRes.Result, &hash))
   570  	//receipt = WaitForReceipt(suite.T(), hash)
   571  	//suite.Require().NotNil(receipt)
   572  	//suite.Require().Equal("0x1", receipt["status"].(string))
   573  	//suite.T().Logf("%s deploys contract (filled \"input\") successfully with tx hash %s\n", hexAddr1.Hex(), hash.String())
   574  
   575  	// error check
   576  	// sender is not unlocked on the node
   577  	param[0]["from"] = receiverAddr.Hex()
   578  	//suite.chain.GetContextPointer().SetAccountNonce(0)
   579  	_, err := CallWithError(suite.addr, "eth_sendTransaction", param)
   580  	suite.Require().Error(err)
   581  
   582  	// data.Data and data.Input are not same
   583  	param[0]["from"] = hexAddr1.Hex()
   584  	//suite.chain.GetContextPointer().SetAccountNonce(0)
   585  	param[0]["input"] = param[0]["data"][:len(param[0]["data"])-2]
   586  	_, err = CallWithError(suite.addr, "eth_sendTransaction", param)
   587  	suite.Require().Error(err)
   588  
   589  	// 0 gas price
   590  	delete(param[0], "input")
   591  	param[0]["gasPrice"] = (*hexutil.Big)(sdk.ZeroDec().BigInt()).String()
   592  	_, err = CallWithError(suite.addr, "eth_sendTransaction", param)
   593  	suite.Require().Error(err)
   594  
   595  	// no payload of contract deployment
   596  	delete(param[0], "data")
   597  
   598  	_, err = CallWithError(suite.addr, "eth_sendTransaction", param)
   599  	suite.Require().Error(err)
   600  }*/
   601  
   602  func (suite *RPCTestSuite) TestEth_GetStorageAt() {
   603  	expectedRes := hexutil.Bytes{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, 0}
   604  	rpcRes := Call(suite.T(), suite.addr, "eth_getStorageAt", []string{hexAddr1.Hex(), fmt.Sprint(addrAStoreKey), latestBlockNumber})
   605  
   606  	var storage hexutil.Bytes
   607  	suite.Require().NoError(storage.UnmarshalJSON(rpcRes.Result))
   608  
   609  	suite.T().Logf("Got value [%X] for %s with key %X\n", storage, hexAddr1.Hex(), addrAStoreKey)
   610  
   611  	suite.Require().True(bytes.Equal(storage, expectedRes), "expected: %d (%d bytes) got: %d (%d bytes)", expectedRes, len(expectedRes), storage, len(storage))
   612  
   613  	// error check
   614  	// miss argument
   615  	_, err := CallWithError(suite.addr, "eth_getStorageAt", []string{hexAddr1.Hex(), fmt.Sprint(addrAStoreKey)})
   616  	suite.Require().Error(err)
   617  
   618  	_, err = CallWithError(suite.addr, "eth_getStorageAt", []string{hexAddr1.Hex()})
   619  	suite.Require().Error(err)
   620  }
   621  
   622  func (suite *RPCTestSuite) TestEth_GetTransactionByHash() {
   623  
   624  	hash := sendTestTransaction(suite.T(), suite.addr, senderAddr, receiverAddr, 1024)
   625  
   626  	commitBlock(suite)
   627  	commitBlock(suite)
   628  
   629  	rpcRes := Call(suite.T(), suite.addr, "eth_getTransactionByHash", []interface{}{hash})
   630  
   631  	var transaction watcher.Transaction
   632  	suite.Require().NoError(json.Unmarshal(rpcRes.Result, &transaction))
   633  	suite.Require().True(senderAddr.Hex() == transaction.From.Hex())
   634  	suite.Require().True(receiverAddr == *transaction.To)
   635  	suite.Require().True(hash == transaction.Hash)
   636  	suite.Require().True(transaction.Value.ToInt().Cmp(big.NewInt(1024)) == 0)
   637  	suite.Require().True(transaction.GasPrice.ToInt().Cmp(defaultGasPrice.Amount.BigInt()) == 0)
   638  	// no input for a transfer tx
   639  	suite.Require().Equal(0, len(transaction.Input))
   640  
   641  	// hash not found -> rpcRes.Result -> "null"
   642  	rpcRes, err := CallWithError(suite.addr, "eth_getTransactionByHash", []interface{}{inexistentHash})
   643  	suite.Require().NoError(err)
   644  	assertNullFromJSONResponse(suite.T(), rpcRes.Result)
   645  	suite.Require().Nil(rpcRes.Error)
   646  }
   647  
   648  func (suite *RPCTestSuite) TestEth_GetTransactionCount() {
   649  
   650  	hash := sendTestTransaction(suite.T(), suite.addr, senderAddr, receiverAddr, 1024)
   651  
   652  	commitBlock(suite)
   653  	commitBlock(suite)
   654  
   655  	height := getBlockHeightFromTxHash(suite.T(), suite.addr, hash)
   656  
   657  	rpcRes := Call(suite.T(), suite.addr, "eth_getTransactionCount", []interface{}{senderAddr.Hex(), height.String()})
   658  
   659  	var nonce, preNonce hexutil.Uint64
   660  	suite.Require().NoError(json.Unmarshal(rpcRes.Result, &nonce))
   661  
   662  	// query height - 1
   663  	/*rpcRes = Call(suite.T(), suite.addr, "eth_getTransactionCount", []interface{}{senderAddr.Hex(), (height - 1).String()})
   664  	suite.Require().NoError(json.Unmarshal(rpcRes.Result, &preNonce))
   665  
   666  	suite.Require().True(nonce-preNonce == 1)
   667  	*/
   668  	// latestBlock query
   669  	rpcRes = Call(suite.T(), suite.addr, "eth_getTransactionCount", []interface{}{senderAddr.Hex(), latestBlockNumber})
   670  	suite.Require().NoError(json.Unmarshal(rpcRes.Result, &preNonce))
   671  	suite.Require().Equal(nonce, preNonce)
   672  
   673  	// pendingBlock query
   674  	rpcRes = Call(suite.T(), suite.addr, "eth_getTransactionCount", []interface{}{senderAddr.Hex(), pendingBlockNumber})
   675  	suite.Require().NoError(json.Unmarshal(rpcRes.Result, &nonce))
   676  	suite.Require().Equal(preNonce, nonce)
   677  
   678  	// error check
   679  	// miss argument
   680  	_, err := CallWithError(suite.addr, "eth_getTransactionCount", []interface{}{senderAddr.Hex()})
   681  	suite.Require().Error(err)
   682  
   683  	_, err = CallWithError(suite.addr, "eth_getTransactionCount", nil)
   684  	suite.Require().Error(err)
   685  }
   686  
   687  func (suite *RPCTestSuite) TestEth_GetBlockTransactionCountByHash() {
   688  	hash := sendTestTransaction(suite.T(), suite.addr, senderAddr, receiverAddr, 1024)
   689  
   690  	commitBlock(suite)
   691  	commitBlock(suite)
   692  
   693  	blockhash := getBlockHashFromTxHash(suite.T(), suite.addr, hash)
   694  	//suite.Require().NotNil(blockHash)
   695  
   696  	rpcRes := Call(suite.T(), suite.addr, "eth_getBlockTransactionCountByHash", []interface{}{blockhash.Hex()})
   697  
   698  	var txCount hexutil.Uint
   699  	suite.Require().NoError(json.Unmarshal(rpcRes.Result, &txCount))
   700  	// only 1 tx on that height in this single node testnet
   701  	suite.Require().True(txCount == 1)
   702  
   703  	// inexistent hash -> return nil
   704  	rpcRes = Call(suite.T(), suite.addr, "eth_getBlockTransactionCountByHash", []interface{}{inexistentHash})
   705  	assertNullFromJSONResponse(suite.T(), rpcRes.Result)
   706  
   707  	// error check
   708  	// miss argument
   709  	_, err := CallWithError(suite.addr, "eth_getBlockTransactionCountByHash", nil)
   710  	suite.Require().Error(err)
   711  }
   712  
   713  func (suite *RPCTestSuite) TestEth_GetBlockTransactionCountByNumber() {
   714  	hash := sendTestTransaction(suite.T(), suite.addr, senderAddr, receiverAddr, 1024)
   715  
   716  	commitBlock(suite)
   717  	commitBlock(suite)
   718  
   719  	// sleep for a while
   720  	height := getBlockHeightFromTxHash(suite.T(), suite.addr, hash)
   721  	suite.Require().True(height != 0)
   722  
   723  	rpcRes := Call(suite.T(), suite.addr, "eth_getBlockTransactionCountByNumber", []interface{}{height.String()})
   724  
   725  	var txCount hexutil.Uint
   726  	suite.Require().NoError(json.Unmarshal(rpcRes.Result, &txCount))
   727  	// only 1 tx on that height in this single node testnet
   728  	suite.Require().True(txCount == 1)
   729  
   730  	// latestBlock query
   731  	rpcRes = Call(suite.T(), suite.addr, "eth_getBlockTransactionCountByNumber", []interface{}{latestBlockNumber})
   732  	suite.Require().NoError(json.Unmarshal(rpcRes.Result, &txCount))
   733  	// there is no tx on latest block
   734  	suite.Require().True(txCount == 0)
   735  
   736  	// pendingBlock query
   737  	rpcRes = Call(suite.T(), suite.addr, "eth_getBlockTransactionCountByNumber", []interface{}{pendingBlockNumber})
   738  	suite.Require().NoError(json.Unmarshal(rpcRes.Result, &txCount))
   739  	// there is no tx on latest block and mempool
   740  	suite.Require().Equal(hexutil.Uint(0), txCount)
   741  
   742  	// error check
   743  	// miss argument
   744  	_, err := CallWithError(suite.addr, "eth_getBlockTransactionCountByNumber", nil)
   745  	suite.Require().Error(err)
   746  	fmt.Println(err)
   747  }
   748  
   749  func (suite *RPCTestSuite) TestEth_GetCode() {
   750  	// TODO: logic bug, fix it later
   751  	// erc20 contract
   752  	//hash, receipet := deployTestContract(hexAddr1, erc20ContractKind)
   753  	//height := getBlockHeightFromTxHash(hash)
   754  	//suite.Require().True(height != 0)
   755  	//
   756  	//rpcRes := Call(suite.T(), suite.addr, "eth_getCode", []interface{}{receipet["contractAddress"], height.String()})
   757  	//var code hexutil.Bytes
   758  	//suite.Require().NoError(json.Unmarshal(rpcRes.Result, &code))
   759  	//suite.Require().True(strings.EqualFold(erc20ContractByteCode, code.String()))
   760  
   761  	// test contract
   762  	// TODO: logic bug, fix it later
   763  	//hash, receipet := deployTestContract(hexAddr1, testContractKind)
   764  	//height := getBlockHeightFromTxHash(hash)
   765  	//suite.Require().True(height != 0)
   766  	//
   767  	//rpcRes := Call(suite.T(), suite.addr, "eth_getCode", []interface{}{receipet["contractAddress"], height.String()})
   768  	//var code hexutil.Bytes
   769  	//suite.Require().NoError(json.Unmarshal(rpcRes.Result, &code))
   770  	//fmt.Println(testContractByteCode)
   771  	//fmt.Println(code.String())
   772  	//suite.Require().True(strings.EqualFold(testContractByteCode, code.String()))
   773  
   774  	// error check
   775  	// miss argument
   776  	// TODO: use a valid contract address as the first argument in params
   777  	_, err := CallWithError(suite.addr, "eth_getCode", []interface{}{hexAddr1})
   778  	suite.Require().Error(err)
   779  
   780  	_, err = CallWithError(suite.addr, "eth_getCode", nil)
   781  	suite.Require().Error(err)
   782  }
   783  
   784  func (suite *RPCTestSuite) TestEth_GetTransactionLogs() {
   785  	hash := sendTestTransaction(suite.T(), suite.addr, senderAddr, receiverAddr, 1024)
   786  
   787  	commitBlock(suite)
   788  	commitBlock(suite)
   789  
   790  	rpcRes := Call(suite.T(), suite.addr, "eth_getTransactionLogs", []interface{}{hash})
   791  	var transactionLogs []ethtypes.Log
   792  	suite.Require().NoError(json.Unmarshal(rpcRes.Result, &transactionLogs))
   793  	// no transaction log for an evm transfer
   794  	assertNullFromJSONResponse(suite.T(), rpcRes.Result)
   795  
   796  	// test contract that emits an event in its constructor
   797  	/*hash, receipt := deployTestContract(suite, suite.addr, senderAddr, testContractKind)
   798  
   799  	rpcRes = Call(suite.T(), suite.addr, "eth_getTransactionLogs", []interface{}{hash})
   800  	suite.Require().NoError(json.Unmarshal(rpcRes.Result, &transactionLogs))
   801  	suite.Require().Equal(1, len(transactionLogs))
   802  	suite.Require().True(ethcmn.HexToAddress(receipt["contractAddress"].(string)) == transactionLogs[0].Address)
   803  	suite.Require().True(hash == transactionLogs[0].TxHash)
   804  	// event in test contract constructor keeps the value: 1024
   805  	suite.Require().True(transactionLogs[0].Topics[1].Big().Cmp(big.NewInt(1024)) == 0)
   806  
   807  	// inexistent tx hash
   808  	_, err := CallWithError(suite.addr, "eth_getTransactionLogs", []interface{}{inexistentHash})
   809  	suite.Require().Error(err)
   810  
   811  	// error check
   812  	// miss argument
   813  	_, err = CallWithError(suite.addr, "eth_getTransactionLogs", nil)
   814  	suite.Require().Error(err)*/
   815  }
   816  
   817  func (suite *RPCTestSuite) TestEth_Sign() {
   818  	data := []byte("context to sign")
   819  	//expectedSignature, err := signWithAccNameAndPasswd("alice", defaultPassWd, data)
   820  	//suite.Require().NoError(err)
   821  
   822  	rpcRes := Call(suite.T(), suite.addr, "eth_sign", []interface{}{senderAddr.Hex(), hexutil.Bytes(data)})
   823  	var sig hexutil.Bytes
   824  	suite.Require().NoError(json.Unmarshal(rpcRes.Result, &sig))
   825  
   826  	//suite.Require().True(bytes.Equal(expectedSignature, sig))
   827  
   828  	// error check
   829  	// inexistent signer
   830  	_, err := CallWithError(suite.addr, "eth_sign", []interface{}{receiverAddr, hexutil.Bytes(data)})
   831  	suite.Require().Error(err)
   832  
   833  	// miss argument
   834  	_, err = CallWithError(suite.addr, "eth_sign", []interface{}{receiverAddr})
   835  	suite.Require().Error(err)
   836  
   837  	_, err = CallWithError(suite.addr, "eth_sign", nil)
   838  	suite.Require().Error(err)
   839  }
   840  
   841  func (suite *RPCTestSuite) TestEth_Call() {
   842  	// simulate evm transfer
   843  	callArgs := make(map[string]string)
   844  	callArgs["from"] = senderAddr.Hex()
   845  	callArgs["to"] = receiverAddr.Hex()
   846  	callArgs["value"] = hexutil.Uint(1024).String()
   847  	callArgs["gasPrice"] = (*hexutil.Big)(defaultGasPrice.Amount.BigInt()).String()
   848  	_, err := CallWithError(suite.addr, "eth_call", []interface{}{callArgs, latestBlockNumber})
   849  	suite.Require().NoError(err)
   850  
   851  	// simulate contract deployment
   852  	delete(callArgs, "to")
   853  	delete(callArgs, "value")
   854  	callArgs["data"] = erc20ContractDeployedByteCode
   855  	_, err = CallWithError(suite.addr, "eth_call", []interface{}{callArgs, latestBlockNumber})
   856  	suite.Require().NoError(err)
   857  
   858  	// error check
   859  	// miss argument
   860  	_, err = CallWithError(suite.addr, "eth_call", []interface{}{callArgs})
   861  	suite.Require().Error(err)
   862  
   863  	_, err = CallWithError(suite.addr, "eth_call", nil)
   864  	suite.Require().Error(err)
   865  }
   866  func (suite *RPCTestSuite) TestEth_Call_Overrides() {
   867  	// simulate evm transfer
   868  	callArgs := make(map[string]string)
   869  	callArgs["from"] = senderAddr.Hex()
   870  	callArgs["to"] = "0x45dD91b0289E60D89Cec94dF0Aac3a2f539c514a"
   871  	callArgs["data"] = "0x2e64cec1"
   872  	expected := "0x0000000000000000000000000000000000000000000000000000000000000007"
   873  	overridesArgs := map[string]interface{}{}
   874  	overrideAccount := map[string]interface{}{}
   875  	code := "0x608060405234801561001057600080fd5b506004361061004c5760003560e01c80632e64cec1146100515780634cd8de131461006f5780636057361d1461009f578063f8b2cb4f146100bb575b600080fd5b6100596100eb565b604051610066919061025a565b60405180910390f35b61008960048036038101906100849190610196565b6100f4565b6040516100969190610238565b60405180910390f35b6100b960048036038101906100b491906101c3565b610130565b005b6100d560048036038101906100d09190610196565b61014b565b6040516100e2919061025a565b60405180910390f35b60008054905090565b60608173ffffffffffffffffffffffffffffffffffffffff16803b806020016040519081016040528181526000908060200190933c9050919050565b806000808282546101419190610291565b9250508190555050565b60008173ffffffffffffffffffffffffffffffffffffffff16319050919050565b60008135905061017b8161039b565b92915050565b600081359050610190816103b2565b92915050565b6000602082840312156101ac576101ab610385565b5b60006101ba8482850161016c565b91505092915050565b6000602082840312156101d9576101d8610385565b5b60006101e784828501610181565b91505092915050565b60006101fb82610275565b6102058185610280565b9350610215818560208601610323565b61021e8161038a565b840191505092915050565b61023281610319565b82525050565b6000602082019050818103600083015261025281846101f0565b905092915050565b600060208201905061026f6000830184610229565b92915050565b600081519050919050565b600082825260208201905092915050565b600061029c82610319565b91506102a783610319565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff038211156102dc576102db610356565b5b828201905092915050565b60006102f2826102f9565b9050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b60005b83811015610341578082015181840152602081019050610326565b83811115610350576000848401525b50505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600080fd5b6000601f19601f8301169050919050565b6103a4816102e7565b81146103af57600080fd5b50565b6103bb81610319565b81146103c657600080fd5b5056fea26469706673582212202f99901e5c26c9c389fef67564f7c7b71316025fe9346120d3b01d4b7066034364736f6c63430008070033"
   876  	overrideAccount["code"] = code
   877  	overrideAccount["state"] = map[string]string{
   878  		"0x0000000000000000000000000000000000000000000000000000000000000000": expected,
   879  	}
   880  	overridesArgs["0x45dD91b0289E60D89Cec94dF0Aac3a2f539c514a"] = overrideAccount
   881  
   882  	resp, err := CallWithError(suite.addr, "eth_call", []interface{}{callArgs, latestBlockNumber, overridesArgs})
   883  	suite.Require().NoError(err)
   884  
   885  	var res string
   886  	_ = json.Unmarshal(resp.Result, &res)
   887  	suite.Require().EqualValues(expected, res)
   888  
   889  	callArgs["data"] = "0xf8b2cb4f000000000000000000000000bbe4733d85bc2b90682147779da49cab38c0aa1f" // get balance of bbe4733d85bc2b90682147779da49cab38c0aa1f
   890  	expectedBal := "0x10000000000000000000000000000000000000000000000000000000003e8000"
   891  	overridesArgs["0xbbE4733d85bc2b90682147779DA49caB38C0aA1F"] = map[string]string{"balance": expectedBal}
   892  	resp, err = CallWithError(suite.addr, "eth_call", []interface{}{callArgs, latestBlockNumber, overridesArgs})
   893  	suite.Require().NoError(err)
   894  
   895  	_ = json.Unmarshal(resp.Result, &res)
   896  	suite.Require().EqualValues(expectedBal, res)
   897  
   898  	callArgs["data"] = "0x4cd8de1300000000000000000000000045dd91b0289e60d89cec94df0aac3a2f539c514a" // get code of 0x45dD91b0289E60D89Cec94dF0Aac3a2f539c514a
   899  	resp, err = CallWithError(suite.addr, "eth_call", []interface{}{callArgs, latestBlockNumber, overridesArgs})
   900  	suite.Require().NoError(err)
   901  
   902  	_ = json.Unmarshal(resp.Result, &res)
   903  	suite.Require().EqualValues(code+"00", strings.Replace(res, "0x000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000003ff", "0x", -1))
   904  }
   905  func (suite *RPCTestSuite) TestEth_EstimateGas_WithoutArgs() {
   906  	// error check
   907  	// miss argument
   908  	res, err := CallWithError(suite.addr, "eth_estimateGas", nil)
   909  	suite.Require().Error(err)
   910  	suite.Require().Nil(res)
   911  }
   912  
   913  func (suite *RPCTestSuite) TestEth_EstimateGas_Transfer() {
   914  	param := make([]map[string]string, 1)
   915  	param[0] = make(map[string]string)
   916  	param[0]["from"] = senderAddr.Hex()
   917  	param[0]["to"] = "0x1122334455667788990011223344556677889900"
   918  	param[0]["value"] = "0x1"
   919  	param[0]["gasPrice"] = (*hexutil.Big)(defaultGasPrice.Amount.BigInt()).String()
   920  	rpcRes := Call(suite.T(), suite.addr, "eth_estimateGas", param)
   921  	suite.Require().NotNil(rpcRes)
   922  	suite.Require().NotEmpty(rpcRes.Result)
   923  
   924  	var gas string
   925  	err := json.Unmarshal(rpcRes.Result, &gas)
   926  	suite.Require().NoError(err, string(rpcRes.Result))
   927  
   928  	suite.Require().Equal("0x5208", gas)
   929  }
   930  
   931  func (suite *RPCTestSuite) TestEth_EstimateGas_ContractDeployment() {
   932  	bytecode := "0x608060405234801561001057600080fd5b5060117f775a94827b8fd9b519d36cd827093c664f93347070a554f65e4a6f56cd73889860405160405180910390a260d08061004d6000396000f3fe6080604052348015600f57600080fd5b506004361060285760003560e01c8063eb8ac92114602d575b600080fd5b606060048036036040811015604157600080fd5b8101908080359060200190929190803590602001909291905050506062565b005b8160008190555080827ff3ca124a697ba07e8c5e80bebcfcc48991fc16a63170e8a9206e30508960d00360405160405180910390a3505056fea265627a7a723158201d94d2187aaf3a6790527b615fcc40970febf0385fa6d72a2344848ebd0df3e964736f6c63430005110032"
   933  
   934  	param := make([]map[string]string, 1)
   935  	param[0] = make(map[string]string)
   936  	param[0]["from"] = senderAddr.Hex()
   937  	param[0]["data"] = bytecode
   938  
   939  	rpcRes := Call(suite.T(), suite.addr, "eth_estimateGas", param)
   940  	suite.Require().NotNil(rpcRes)
   941  	suite.Require().NotEmpty(rpcRes.Result)
   942  
   943  	var gas hexutil.Uint64
   944  	err := json.Unmarshal(rpcRes.Result, &gas)
   945  	suite.Require().NoError(err, string(rpcRes.Result))
   946  
   947  	suite.Require().Equal("0x271fc", gas.String())
   948  }
   949  
   950  func (suite *RPCTestSuite) TestEth_GetBlockByHash() {
   951  	hash := sendTestTransaction(suite.T(), suite.addr, senderAddr, receiverAddr, 1024)
   952  	expectedBlockHash := getBlockHashFromTxHash(suite.T(), suite.addr, hash)
   953  
   954  	// TODO: fbchainonly supports the block query with txs' hash inside no matter what the second bool argument is.
   955  	// 		eth rpc: 	false -> txs' hash inside
   956  	//				  	true  -> txs full content
   957  
   958  	// TODO: block hash bug , wait for pr merge
   959  	//rpcRes := Call(suite.T(), suite.addr, "eth_getBlockByHash", []interface{}{expectedBlockHash, false})
   960  	//var res map[string]interface{}
   961  	//suite.Require().NoError(json.Unmarshal(rpcRes.Result, &res))
   962  	//suite.Require().True(strings.EqualFold(expectedBlockHash, res["hash"].(string)))
   963  	//
   964  	//rpcRes = Call(suite.T(), suite.addr, "eth_getBlockByHash", []interface{}{expectedBlockHash, true})
   965  	//suite.Require().NoError(json.Unmarshal(rpcRes.Result, &res))
   966  	//suite.Require().True(strings.EqualFold(expectedBlockHash, res["hash"].(string)))
   967  
   968  	// inexistent hash
   969  	//rpcRes, err :=CallWithError(suite.addr, "eth_getBlockByHash", []interface{}{inexistentHash, false})
   970  
   971  	// error check
   972  	// miss argument
   973  	_, err := CallWithError(suite.addr, "eth_getBlockByHash", []interface{}{expectedBlockHash})
   974  	suite.Require().Error(err)
   975  
   976  	_, err = CallWithError(suite.addr, "eth_getBlockByHash", nil)
   977  	suite.Require().Error(err)
   978  }
   979  
   980  func (suite *RPCTestSuite) TestEth_GetBlockByNumber() {
   981  	hash := sendTestTransaction(suite.T(), suite.addr, senderAddr, receiverAddr, 1024)
   982  
   983  	// sleep for a while
   984  	//time.Sleep(3 * time.Second)
   985  	commitBlock(suite)
   986  	commitBlock(suite)
   987  
   988  	expectedHeight := getBlockHeightFromTxHash(suite.T(), suite.addr, hash)
   989  
   990  	// TODO: fbchainonly supports the block query with txs' hash inside no matter what the second bool argument is.
   991  	// 		eth rpc: 	false -> txs' hash inside
   992  	rpcRes := Call(suite.T(), suite.addr, "eth_getBlockByNumber", []interface{}{expectedHeight, false})
   993  	var res map[string]interface{}
   994  	suite.Require().NoError(json.Unmarshal(rpcRes.Result, &res))
   995  	//suite.Require().True(strings.EqualFold(expectedHeight.String(), res["number"].(string)))
   996  
   997  	rpcRes = Call(suite.T(), suite.addr, "eth_getBlockByNumber", []interface{}{expectedHeight, true})
   998  	suite.Require().NoError(json.Unmarshal(rpcRes.Result, &res))
   999  	//suite.Require().True(strings.EqualFold(expectedHeight.String(), res["number"].(string)))
  1000  
  1001  	// error check
  1002  	// future block height -> return nil without error
  1003  	rpcRes = Call(suite.T(), suite.addr, "eth_blockNumber", nil)
  1004  	var currentBlockHeight hexutil.Uint64
  1005  	suite.Require().NoError(json.Unmarshal(rpcRes.Result, &currentBlockHeight))
  1006  
  1007  	rpcRes, err := CallWithError(suite.addr, "eth_getBlockByNumber", []interface{}{currentBlockHeight + 100, false})
  1008  	suite.Require().NoError(err)
  1009  	assertNullFromJSONResponse(suite.T(), rpcRes.Result)
  1010  
  1011  	// miss argument
  1012  	_, err = CallWithError(suite.addr, "eth_getBlockByNumber", []interface{}{currentBlockHeight})
  1013  	suite.Require().Error(err)
  1014  
  1015  	_, err = CallWithError(suite.addr, "eth_getBlockByNumber", nil)
  1016  	suite.Require().Error(err)
  1017  }
  1018  
  1019  func (suite *RPCTestSuite) TestEth_GetTransactionByBlockHashAndIndex() {
  1020  	hash := sendTestTransaction(suite.T(), suite.addr, senderAddr, receiverAddr, 1024)
  1021  
  1022  	// sleep for a while
  1023  	//time.Sleep(5 * time.Second)
  1024  	commitBlock(suite)
  1025  	commitBlock(suite)
  1026  	blockHash, index := getBlockHashFromTxHash(suite.T(), suite.addr, hash), hexutil.Uint(0)
  1027  	rpcRes := Call(suite.T(), suite.addr, "eth_getTransactionByBlockHashAndIndex", []interface{}{blockHash, index})
  1028  	var transaction watcher.Transaction
  1029  	suite.Require().NoError(json.Unmarshal(rpcRes.Result, &transaction))
  1030  	suite.Require().Equal(hash, transaction.Hash)
  1031  	suite.Require().True(*blockHash == *transaction.BlockHash)
  1032  	suite.Require().True(hexutil.Uint64(index) == *transaction.TransactionIndex)
  1033  
  1034  	// inexistent block hash
  1035  	// TODO: error:{"code":1,"log":"internal","height":1497,"codespace":"undefined"}, fix it later
  1036  	//rpcRes, err :=CallWithError(suite.addr, "eth_getTransactionByBlockHashAndIndex", []interface{}{inexistentHash, index})
  1037  	//fmt.Println(err)
  1038  
  1039  	// inexistent transaction index -> nil
  1040  	rpcRes, err := CallWithError(suite.addr, "eth_getTransactionByBlockHashAndIndex", []interface{}{blockHash, index + 100})
  1041  	suite.Require().NoError(err)
  1042  	assertNullFromJSONResponse(suite.T(), rpcRes.Result)
  1043  
  1044  	// error check
  1045  	// miss argument
  1046  	_, err = CallWithError(suite.addr, "eth_getTransactionByBlockHashAndIndex", []interface{}{blockHash})
  1047  	suite.Require().Error(err)
  1048  
  1049  	_, err = CallWithError(suite.addr, "eth_getTransactionByBlockHashAndIndex", nil)
  1050  	suite.Require().Error(err)
  1051  }
  1052  
  1053  func (suite *RPCTestSuite) TestEth_GetTransactionReceipt() {
  1054  	hash := sendTestTransaction(suite.T(), suite.addr, senderAddr, receiverAddr, 1024)
  1055  
  1056  	// sleep for a while
  1057  	commitBlock(suite)
  1058  	commitBlock(suite)
  1059  	rpcRes := Call(suite.T(), suite.addr, "eth_getTransactionReceipt", []interface{}{hash})
  1060  
  1061  	var receipt map[string]interface{}
  1062  	suite.Require().NoError(json.Unmarshal(rpcRes.Result, &receipt))
  1063  	suite.Require().True(strings.EqualFold(senderAddr.Hex(), receipt["from"].(string)))
  1064  	suite.Require().True(strings.EqualFold(receiverAddr.Hex(), receipt["to"].(string)))
  1065  	suite.Require().True(strings.EqualFold(hexutil.Uint(1).String(), receipt["status"].(string)))
  1066  	suite.Require().True(strings.EqualFold(hash.Hex(), receipt["transactionHash"].(string)))
  1067  
  1068  	// contract deployment
  1069  	/*hash, receipt = deployTestContract(suite, suite.addr, senderAddr, erc20ContractKind)
  1070  
  1071  	suite.Require().True(strings.EqualFold(senderAddr.Hex(), receipt["from"].(string)))
  1072  	suite.Require().True(strings.EqualFold(hexutil.Uint(1).String(), receipt["status"].(string)))
  1073  	suite.Require().True(strings.EqualFold(hash.Hex(), receipt["transactionHash"].(string)))
  1074  
  1075  	// inexistent hash -> nil without error
  1076  	rpcRes, err := CallWithError(suite.addr, "eth_getTransactionReceipt", []interface{}{inexistentHash})
  1077  	suite.Require().NoError(err)
  1078  	assertNullFromJSONResponse(suite.T(), rpcRes.Result)
  1079  
  1080  	// error check
  1081  	// miss argument
  1082  	_, err = CallWithError(suite.addr, "eth_getTransactionReceipt", nil)
  1083  	suite.Require().Error(err)*/
  1084  }
  1085  
  1086  func (suite *RPCTestSuite) TestEth_PendingTransactions() {
  1087  	// there will be no pending tx in mempool because of the quick grab of block building
  1088  	rpcRes := Call(suite.T(), suite.addr, "eth_pendingTransactions", nil)
  1089  	var transactions []watcher.Transaction
  1090  	suite.Require().NoError(json.Unmarshal(rpcRes.Result, &transactions))
  1091  	suite.Require().Zero(len(transactions))
  1092  }
  1093  
  1094  func (suite *RPCTestSuite) TestBlockBloom() {
  1095  	hash, receipt := deployTestContract(suite, suite.addr, senderAddr, testContractKind)
  1096  
  1097  	rpcRes := Call(suite.T(), suite.addr, "eth_getBlockByNumber", []interface{}{receipt["blockNumber"].(string), false})
  1098  	var blockInfo map[string]interface{}
  1099  	suite.Require().NoError(json.Unmarshal(rpcRes.Result, &blockInfo))
  1100  	logsBloom := hexToBloom(suite.T(), blockInfo["logsBloom"].(string))
  1101  
  1102  	// get the transaction log with tx hash
  1103  	rpcRes = Call(suite.T(), suite.addr, "eth_getTransactionLogs", []interface{}{hash})
  1104  	var transactionLogs []ethtypes.Log
  1105  	suite.Require().NoError(json.Unmarshal(rpcRes.Result, &transactionLogs))
  1106  	suite.Require().Equal(1, len(transactionLogs))
  1107  
  1108  	// all the topics in the transactionLogs should be included in the logs bloom of the block
  1109  	suite.Require().True(logsBloom.Test(transactionLogs[0].Topics[0].Bytes()))
  1110  	suite.Require().True(logsBloom.Test(transactionLogs[0].Topics[1].Bytes()))
  1111  	// check the consistency of tx hash
  1112  	suite.Require().True(strings.EqualFold(hash.Hex(), blockInfo["transactions"].([]interface{})[0].(string)))
  1113  }
  1114  
  1115  /*
  1116  func (suite *RPCTestSuite) TestEth_GetLogs_NoLogs() {
  1117  	param := make([]map[string][]string, 1)
  1118  	param[0] = make(map[string][]string)
  1119  	// inexistent topics
  1120  	inexistentTopicsHash := ethcmn.BytesToHash([]byte("inexistent topics")).Hex()
  1121  	param[0]["topics"] = []string{inexistentTopicsHash}
  1122  	rpcRes, err := CallWithError(suite.addr, "eth_getLogs", param)
  1123  	suite.Require().NoError(err)
  1124  
  1125  	var logs []ethtypes.Log
  1126  	suite.Require().NoError(json.Unmarshal(rpcRes.Result, &logs))
  1127  	suite.Require().Zero(len(logs))
  1128  
  1129  	// error check
  1130  	_, err = CallWithError(suite.addr, "eth_getLogs", nil)
  1131  	suite.Require().Error(err)
  1132  }
  1133  
  1134  func (suite *RPCTestSuite) TestEth_GetLogs_GetTopicsFromHistory() {
  1135  	_, receipt := deployTestContract(suite, suite.addr, senderAddr, testContractKind)
  1136  	param := make([]map[string]interface{}, 1)
  1137  	param[0] = make(map[string]interface{})
  1138  	param[0]["topics"] = []string{helloTopic, worldTopic}
  1139  	param[0]["fromBlock"] = receipt["blockNumber"].(string)
  1140  
  1141  	time.Sleep(time.Second * 5)
  1142  	rpcRes := Call(suite.T(), suite.addr, "eth_getLogs", param)
  1143  
  1144  	var logs []ethtypes.Log
  1145  	suite.Require().NoError(json.Unmarshal(rpcRes.Result, &logs))
  1146  	suite.Require().Equal(1, len(logs))
  1147  	suite.Require().Equal(2, len(logs[0].Topics))
  1148  	suite.Require().True(logs[0].Topics[0].Hex() == helloTopic)
  1149  	suite.Require().True(logs[0].Topics[1].Hex() == worldTopic)
  1150  
  1151  	// get block number from receipt
  1152  	blockNumber, err := hexutil.DecodeUint64(receipt["blockNumber"].(string))
  1153  	suite.Require().NoError(err)
  1154  
  1155  	// get current block height -> there is no logs from that height
  1156  	param[0]["fromBlock"] = hexutil.Uint64(blockNumber + 1).String()
  1157  
  1158  	rpcRes, err = CallWithError(suite.addr, "eth_getLogs", param)
  1159  	suite.Require().NoError(err)
  1160  	suite.Require().NoError(json.Unmarshal(rpcRes.Result, &logs))
  1161  	suite.Require().Zero(len(logs))
  1162  }*/
  1163  
  1164  func (suite *RPCTestSuite) TestEth_GetProof() {
  1165  
  1166  	initialBalance := suite.chain.SenderAccount().GetCoins()[0]
  1167  	commitBlock(suite)
  1168  	commitBlock(suite)
  1169  	rpcRes := Call(suite.T(), suite.addr, "eth_getProof", []interface{}{senderAddr.Hex(), []string{fmt.Sprint(addrAStoreKey)}, "latest"})
  1170  	suite.Require().NotNil(rpcRes)
  1171  
  1172  	var accRes types.AccountResult
  1173  	suite.Require().NoError(json.Unmarshal(rpcRes.Result, &accRes))
  1174  	suite.Require().Equal(senderAddr, accRes.Address)
  1175  	suite.Require().Equal(initialBalance.Amount.Int, accRes.Balance.ToInt())
  1176  	suite.Require().NotEmpty(accRes.AccountProof)
  1177  	suite.Require().NotEmpty(accRes.StorageProof)
  1178  
  1179  	// inexistentAddr -> zero value account result
  1180  	rpcRes, err := CallWithError(suite.addr, "eth_getProof", []interface{}{inexistentAddr.Hex(), []string{fmt.Sprint(addrAStoreKey)}, "latest"})
  1181  	suite.Require().NoError(err)
  1182  	suite.Require().NoError(json.Unmarshal(rpcRes.Result, &accRes))
  1183  	suite.Require().Equal(inexistentAddr, accRes.Address)
  1184  	suite.Require().True(sdk.ZeroDec().Int.Cmp(accRes.Balance.ToInt()) == 0)
  1185  
  1186  	// error check
  1187  	// miss argument
  1188  	_, err = CallWithError(suite.addr, "eth_getProof", []interface{}{hexAddr2.Hex(), []string{fmt.Sprint(addrAStoreKey)}})
  1189  	suite.Require().Error(err)
  1190  
  1191  	_, err = CallWithError(suite.addr, "eth_getProof", []interface{}{hexAddr2.Hex()})
  1192  	suite.Require().Error(err)
  1193  
  1194  	_, err = CallWithError(suite.addr, "eth_getProof", nil)
  1195  	suite.Require().Error(err)
  1196  }
  1197  
  1198  /*
  1199  func (suite *RPCTestSuite) TestEth_NewFilter() {
  1200  	param := make([]map[string]interface{}, 1)
  1201  	param[0] = make(map[string]interface{})
  1202  	// random topics
  1203  	param[0]["topics"] = []ethcmn.Hash{ethcmn.BytesToHash([]byte("random topics"))}
  1204  	rpcRes := Call(suite.T(), suite.addr, "eth_newFilter", param)
  1205  
  1206  	var ID string
  1207  	suite.Require().NoError(json.Unmarshal(rpcRes.Result, &ID))
  1208  	suite.Require().NotZero(ID)
  1209  
  1210  	// fromBlock: latest, toBlock: latest -> no error
  1211  	delete(param[0], "topics")
  1212  	param[0]["fromBlock"] = latestBlockNumber
  1213  	param[0]["toBlock"] = latestBlockNumber
  1214  	rpcRes, err := CallWithError(suite.addr, "eth_newFilter", param)
  1215  	suite.Require().NoError(err)
  1216  	suite.Require().NoError(json.Unmarshal(rpcRes.Result, &ID))
  1217  	suite.Require().NotZero(ID)
  1218  
  1219  	// fromBlock: nil, toBlock: latest -> no error
  1220  	delete(param[0], "fromBlock")
  1221  	rpcRes, err = CallWithError(suite.addr, "eth_newFilter", param)
  1222  	suite.Require().NoError(err)
  1223  	suite.Require().NoError(json.Unmarshal(rpcRes.Result, &ID))
  1224  	suite.Require().NotZero(ID)
  1225  
  1226  	// fromBlock: latest, toBlock: nil -> no error
  1227  	delete(param[0], "toBlock")
  1228  	param[0]["fromBlock"] = latestBlockNumber
  1229  	rpcRes, err = CallWithError(suite.addr, "eth_newFilter", param)
  1230  	suite.Require().NoError(err)
  1231  	suite.Require().NoError(json.Unmarshal(rpcRes.Result, &ID))
  1232  	suite.Require().NotZero(ID)
  1233  
  1234  	// fromBlock: pending, toBlock: pending -> no error
  1235  	param[0]["fromBlock"] = pendingBlockNumber
  1236  	param[0]["toBlock"] = pendingBlockNumber
  1237  	rpcRes, err = CallWithError(suite.addr, "eth_newFilter", param)
  1238  	suite.Require().NoError(err)
  1239  	suite.Require().NoError(json.Unmarshal(rpcRes.Result, &ID))
  1240  	suite.Require().NotZero(ID)
  1241  
  1242  	// fromBlock: latest, toBlock: pending -> no error
  1243  	param[0]["fromBlock"] = latestBlockNumber
  1244  	rpcRes, err = CallWithError(suite.addr, "eth_newFilter", param)
  1245  	suite.Require().NoError(err)
  1246  	suite.Require().NoError(json.Unmarshal(rpcRes.Result, &ID))
  1247  	suite.Require().NotZero(ID)
  1248  
  1249  	// toBlock > fromBlock -> no error
  1250  	param[0]["fromBlock"] = (*hexutil.Big)(big.NewInt(2)).String()
  1251  	param[0]["toBlock"] = (*hexutil.Big)(big.NewInt(3)).String()
  1252  	rpcRes, err = CallWithError(suite.addr, "eth_newFilter", param)
  1253  	suite.Require().NoError(err)
  1254  	suite.Require().NoError(json.Unmarshal(rpcRes.Result, &ID))
  1255  	suite.Require().NotZero(ID)
  1256  
  1257  	// error check
  1258  	// miss argument
  1259  	_, err = CallWithError(suite.addr, "eth_newFilter", nil)
  1260  	suite.Require().Error(err)
  1261  
  1262  	// fromBlock > toBlock -> error: invalid from and to block combination: from > to
  1263  	param[0]["fromBlock"] = (*hexutil.Big)(big.NewInt(3)).String()
  1264  	param[0]["toBlock"] = (*hexutil.Big)(big.NewInt(2)).String()
  1265  	rpcRes, err = CallWithError(suite.addr, "eth_newFilter", param)
  1266  	suite.Require().Error(err)
  1267  
  1268  	// fromBlock: pending, toBlock: latest
  1269  	param[0]["fromBlock"] = pendingBlockNumber
  1270  	param[0]["toBlock"] = latestBlockNumber
  1271  	rpcRes, err = CallWithError(suite.addr, "eth_newFilter", param)
  1272  	suite.Require().Error(err)
  1273  }
  1274  
  1275  func (suite *RPCTestSuite) TestEth_NewBlockFilter() {
  1276  	rpcRes := Call(suite.T(), suite.addr, "eth_newBlockFilter", nil)
  1277  
  1278  	var ID string
  1279  	suite.Require().NoError(json.Unmarshal(rpcRes.Result, &ID))
  1280  	suite.Require().NotZero(ID)
  1281  }
  1282  
  1283  func (suite *RPCTestSuite) TestEth_GetFilterChanges_BlockFilter() {
  1284  	rpcRes := Call(suite.T(), suite.addr, "eth_newBlockFilter", nil)
  1285  
  1286  	var ID string
  1287  	suite.Require().NoError(json.Unmarshal(rpcRes.Result, &ID))
  1288  
  1289  	// wait for block generation
  1290  	time.Sleep(5 * time.Second)
  1291  
  1292  	changesRes := Call(suite.T(), suite.addr, "eth_getFilterChanges", []interface{}{ID})
  1293  	var hashes []ethcmn.Hash
  1294  	suite.Require().NoError(json.Unmarshal(changesRes.Result, &hashes))
  1295  	suite.Require().GreaterOrEqual(len(hashes), 1)
  1296  
  1297  	// error check
  1298  	// miss argument
  1299  	_, err := CallWithError(suite.addr, "eth_getFilterChanges", nil)
  1300  	suite.Require().Error(err)
  1301  }
  1302  
  1303  func (suite *RPCTestSuite) TestEth_GetFilterChanges_NoLogs() {
  1304  	param := make([]map[string]interface{}, 1)
  1305  	param[0] = make(map[string]interface{})
  1306  	param[0]["topics"] = []ethcmn.Hash{ethcmn.BytesToHash([]byte("random topics"))}
  1307  
  1308  	rpcRes := Call(suite.T(), suite.addr, "eth_newFilter", param)
  1309  
  1310  	var ID string
  1311  	suite.Require().NoError(json.Unmarshal(rpcRes.Result, &ID))
  1312  
  1313  	changesRes := Call(suite.T(), suite.addr, "eth_getFilterChanges", []interface{}{ID})
  1314  
  1315  	var logs []ethtypes.Log
  1316  	suite.Require().NoError(json.Unmarshal(changesRes.Result, &logs))
  1317  	// no logs
  1318  	suite.Require().Empty(logs)
  1319  }
  1320  
  1321  func (suite *RPCTestSuite) TestEth_GetFilterChanges_WrongID() {
  1322  	// ID's length is 16
  1323  	inexistentID := "0x1234567890abcdef"
  1324  	_, err := CallWithError(suite.addr, "eth_getFilterChanges", []interface{}{inexistentID})
  1325  	suite.Require().Error(err)
  1326  }
  1327  
  1328  func (suite *RPCTestSuite) TestEth_GetFilterChanges_NoTopics() {
  1329  	// create a new filter with no topics and latest block height for "fromBlock"
  1330  	param := make([]map[string]interface{}, 1)
  1331  	param[0] = make(map[string]interface{})
  1332  	param[0]["fromBlock"] = latestBlockNumber
  1333  
  1334  	rpcRes := Call(suite.T(), suite.addr, "eth_newFilter", param)
  1335  	suite.Require().Nil(rpcRes.Error)
  1336  	var ID string
  1337  	suite.Require().NoError(json.Unmarshal(rpcRes.Result, &ID))
  1338  	suite.T().Logf("create filter successfully with ID %s\n", ID)
  1339  
  1340  	// deploy contract with emitting events
  1341  	_, _ = deployTestContract(suite, suite.addr, senderAddr, testContractKind)
  1342  
  1343  	// get filter changes
  1344  	changesRes := Call(suite.T(), suite.addr, "eth_getFilterChanges", []string{ID})
  1345  
  1346  	var logs []ethtypes.Log
  1347  	suite.Require().NoError(json.Unmarshal(changesRes.Result, &logs))
  1348  	suite.Require().Equal(1, len(logs))
  1349  }
  1350  
  1351  func (suite *RPCTestSuite) TestEth_GetFilterChanges_Addresses() {
  1352  	// TODO: logic bug, fix it later
  1353  	//// deploy contract with emitting events
  1354  	//_, receipt := deployTestContract(hexAddr1, testContractKind)
  1355  	//contractAddrHex := receipt["contractAddress"].(string)
  1356  	//blockHeight := receipt["blockNumber"].(string)
  1357  	//// create a filter
  1358  	//param := make([]map[string]interface{}, 1)
  1359  	//param[0] = make(map[string]interface{})
  1360  	//// focus on the contract by its address
  1361  	//param[0]["addresses"] = []string{contractAddrHex}
  1362  	//param[0]["topics"] = []string{helloTopic, worldTopic}
  1363  	//param[0]["fromBlock"] = blockHeight
  1364  	//rpcRes := Call(suite.T(), suite.addr, "eth_newFilter", param)
  1365  	//
  1366  	//var ID string
  1367  	//suite.Require().NoError(json.Unmarshal(rpcRes.Result, &ID))
  1368  	//suite.T().Logf("create filter focusing on contract %s successfully with ID %s\n", contractAddrHex, ID)
  1369  	//
  1370  	//// get filter changes
  1371  	//changesRes := Call(suite.T(), suite.addr, "eth_getFilterChanges", []string{ID})
  1372  	//
  1373  	//var logs []ethtypes.Log
  1374  	//suite.Require().NoError(json.Unmarshal(changesRes.Result, &logs))
  1375  	//suite.Require().Equal(1, len(logs))
  1376  }
  1377  
  1378  func (suite *RPCTestSuite) TestEth_GetFilterChanges_BlockHash() {
  1379  	// TODO: logic bug, fix it later
  1380  	//// deploy contract with emitting events
  1381  	//_, receipt := deployTestContract(hexAddr1, testContractKind)
  1382  	//blockHash := receipt["blockHash"].(string)
  1383  	//contractAddrHex := receipt["contractAddress"].(string)
  1384  	//// create a filter
  1385  	//param := make([]map[string]interface{}, 1)
  1386  	//param[0] = make(map[string]interface{})
  1387  	//// focus on the contract by its address
  1388  	//param[0]["blockHash"] = blockHash
  1389  	//param[0]["addresses"] = []string{contractAddrHex}
  1390  	//param[0]["topics"] = []string{helloTopic, worldTopic}
  1391  	//rpcRes := Call(suite.T(), suite.addr, "eth_newFilter", param)
  1392  	//
  1393  	//var ID string
  1394  	//suite.Require().NoError(json.Unmarshal(rpcRes.Result, &ID))
  1395  	//suite.T().Logf("create filter focusing on contract %s in the block with block hash %s successfully with ID %s\n", contractAddrHex, blockHash, ID)
  1396  	//
  1397  	//// get filter changes
  1398  	//changesRes := Call(suite.T(), suite.addr, "eth_getFilterChanges", []string{ID})
  1399  	//
  1400  	//var logs []ethtypes.Log
  1401  	//suite.Require().NoError(json.Unmarshal(changesRes.Result, &logs))
  1402  	//suite.Require().Equal(1, len(logs))
  1403  }
  1404  
  1405  // Tests topics case where there are topics in first two positions
  1406  func (suite *RPCTestSuite) TestEth_GetFilterChanges_Topics_AB() {
  1407  	param := make([]map[string]interface{}, 1)
  1408  	param[0] = make(map[string]interface{})
  1409  	// set topics in filter with A && B
  1410  	param[0]["topics"] = []string{helloTopic, worldTopic}
  1411  	param[0]["fromBlock"] = latestBlockNumber
  1412  
  1413  	// create new filter
  1414  	rpcRes := Call(suite.T(), suite.addr, "eth_newFilter", param)
  1415  
  1416  	var ID string
  1417  	suite.Require().NoError(json.Unmarshal(rpcRes.Result, &ID))
  1418  	suite.T().Logf("create filter successfully with ID %s\n", ID)
  1419  
  1420  	// deploy contract with emitting events
  1421  	_, _ = deployTestContract(suite, suite.addr, senderAddr, testContractKind)
  1422  
  1423  	// get filter changes
  1424  	changesRes := Call(suite.T(), suite.addr, "eth_getFilterChanges", []string{ID})
  1425  
  1426  	var logs []ethtypes.Log
  1427  	suite.Require().NoError(json.Unmarshal(changesRes.Result, &logs))
  1428  	suite.Require().Equal(1, len(logs))
  1429  }
  1430  
  1431  func (suite *RPCTestSuite) TestEth_GetFilterChanges_Topics_XB() {
  1432  	param := make([]map[string]interface{}, 1)
  1433  	param[0] = make(map[string]interface{})
  1434  	// set topics in filter with X && B
  1435  	param[0]["topics"] = []interface{}{nil, worldTopic}
  1436  	param[0]["fromBlock"] = latestBlockNumber
  1437  
  1438  	// create new filter
  1439  	rpcRes := Call(suite.T(), suite.addr, "eth_newFilter", param)
  1440  
  1441  	var ID string
  1442  	suite.Require().NoError(json.Unmarshal(rpcRes.Result, &ID))
  1443  	suite.T().Logf("create filter successfully with ID %s\n", ID)
  1444  
  1445  	// deploy contract with emitting events
  1446  	_, _ = deployTestContract(suite, suite.addr, senderAddr, testContractKind)
  1447  
  1448  	// get filter changes
  1449  	changesRes := Call(suite.T(), suite.addr, "eth_getFilterChanges", []string{ID})
  1450  
  1451  	var logs []ethtypes.Log
  1452  	suite.Require().NoError(json.Unmarshal(changesRes.Result, &logs))
  1453  	suite.Require().Equal(1, len(logs))
  1454  }
  1455  
  1456  //func (suite *RPCTestSuite)TestEth_GetFilterChanges_Topics_XXC() {
  1457  //	t.Skip()
  1458  //	// TODO: call test function, need tx receipts to determine contract address
  1459  //}
  1460  
  1461  func (suite *RPCTestSuite) TestEth_PendingTransactionFilter() {
  1462  	rpcRes := Call(suite.T(), suite.addr, "eth_newPendingTransactionFilter", nil)
  1463  
  1464  	var ID string
  1465  	suite.Require().NoError(json.Unmarshal(rpcRes.Result, &ID))
  1466  
  1467  	for i := 0; i < 5; i++ {
  1468  		_, _ = deployTestContract(suite, suite.addr, senderAddr, erc20ContractKind)
  1469  	}
  1470  
  1471  	time.Sleep(10 * time.Second)
  1472  
  1473  	// get filter changes
  1474  	changesRes := Call(suite.T(), suite.addr, "eth_getFilterChanges", []string{ID})
  1475  	suite.Require().NotNil(changesRes)
  1476  
  1477  	var txs []hexutil.Bytes
  1478  	suite.Require().NoError(json.Unmarshal(changesRes.Result, &txs))
  1479  
  1480  	suite.Require().True(len(txs) >= 2, "could not get any txs", "changesRes.Result", string(changesRes.Result))
  1481  }
  1482  
  1483  func (suite *RPCTestSuite) TestEth_UninstallFilter() {
  1484  	// create a new filter, get id
  1485  	rpcRes := Call(suite.T(), suite.addr, "eth_newBlockFilter", nil)
  1486  	var ID string
  1487  	suite.Require().NoError(json.Unmarshal(rpcRes.Result, &ID))
  1488  	suite.Require().NotZero(ID)
  1489  
  1490  	// based on id, uninstall filter
  1491  	rpcRes = Call(suite.T(), suite.addr, "eth_uninstallFilter", []string{ID})
  1492  	suite.Require().NotNil(rpcRes)
  1493  	var status bool
  1494  	suite.Require().NoError(json.Unmarshal(rpcRes.Result, &status))
  1495  	suite.Require().Equal(true, status)
  1496  
  1497  	// uninstall a non-existent filter
  1498  	rpcRes = Call(suite.T(), suite.addr, "eth_uninstallFilter", []string{ID})
  1499  	suite.Require().NotNil(rpcRes)
  1500  	suite.Require().NoError(json.Unmarshal(rpcRes.Result, &status))
  1501  	suite.Require().Equal(false, status)
  1502  
  1503  }
  1504  
  1505  func (suite *RPCTestSuite) TestEth_Subscribe_And_UnSubscribe() {
  1506  	// create websocket
  1507  	origin, url := "http://127.0.0.1:8546/", "ws://127.0.0.1:8546"
  1508  	ws, err := websocket.Dial(url, "", origin)
  1509  	suite.Require().NoError(err)
  1510  	defer func() {
  1511  		// close websocket
  1512  		err = ws.Close()
  1513  		suite.Require().NoError(err)
  1514  	}()
  1515  
  1516  	// send valid message
  1517  	validMessage := []byte(`{"id": 2, "method": "eth_subscribe", "params": ["newHeads"]}`)
  1518  	excuteValidMessage(suite.T(), ws, validMessage)
  1519  
  1520  	// send invalid message
  1521  	invalidMessage := []byte(`{"id": 2, "method": "eth_subscribe", "params": ["non-existent method"]}`)
  1522  	excuteInvalidMessage(suite.T(), ws, invalidMessage)
  1523  
  1524  	invalidMessage = []byte(`{"id": 2, "method": "eth_subscribe", "params": [""]}`)
  1525  	excuteInvalidMessage(suite.T(), ws, invalidMessage)
  1526  }
  1527  
  1528  func excuteValidMessage(t *testing.T, ws *websocket.Conn, message []byte) {
  1529  	fmt.Println("Send:", string(message))
  1530  	_, err := ws.Write(message)
  1531  	require.NoError(t, err)
  1532  
  1533  	msg := make([]byte, 10240)
  1534  	// receive subscription id
  1535  	n, err := ws.Read(msg)
  1536  	require.NoError(t, err)
  1537  	var res Response
  1538  	require.NoError(t, json.Unmarshal(msg[:n], &res))
  1539  	subscriptionId := string(res.Result)
  1540  
  1541  	// receive message three times
  1542  	for i := 0; i < 3; i++ {
  1543  		n, err = ws.Read(msg)
  1544  		require.NoError(t, err)
  1545  		fmt.Println("Receive:", string(msg[:n]))
  1546  	}
  1547  
  1548  	// cancel the subscription
  1549  	cancelMsg := fmt.Sprintf(`{"id": 2, "method": "eth_unsubscribe", "params": [%s]}`, subscriptionId)
  1550  	fmt.Println("Send:", cancelMsg)
  1551  	_, err = ws.Write([]byte(cancelMsg))
  1552  	require.NoError(t, err)
  1553  
  1554  	// receive the result of eth_unsubscribe
  1555  	n, err = ws.Read(msg)
  1556  	require.NoError(t, err)
  1557  	require.NoError(t, json.Unmarshal(msg[:n], &res))
  1558  	require.Equal(t, "true", string(res.Result))
  1559  }
  1560  
  1561  func excuteInvalidMessage(t *testing.T, ws *websocket.Conn, message []byte) {
  1562  	fmt.Println("Send:", string(message))
  1563  	_, err := ws.Write(message)
  1564  	require.NoError(t, err)
  1565  
  1566  	msg := make([]byte, 10240)
  1567  	// receive error msg
  1568  	n, err := ws.Read(msg)
  1569  	require.NoError(t, err)
  1570  
  1571  	var res Response
  1572  	require.NoError(t, json.Unmarshal(msg[:n], &res))
  1573  	require.Equal(t, -32600, res.Error.Code)
  1574  	require.Equal(t, 1, res.ID)
  1575  }
  1576  
  1577  func (suite *RPCTestSuite) TestWebsocket_PendingTransaction() {
  1578  	// create websocket
  1579  	origin, url := "http://127.0.0.1:8546/", "ws://127.0.0.1:8546"
  1580  	ws, err := websocket.Dial(url, "", origin)
  1581  	suite.Require().NoError(err)
  1582  	defer func() {
  1583  		// close websocket
  1584  		err = ws.Close()
  1585  		suite.Require().NoError(err)
  1586  	}()
  1587  
  1588  	// send message to call newPendingTransactions ws api
  1589  	_, err = ws.Write([]byte(`{"id": 2, "method": "eth_subscribe", "params": ["newPendingTransactions"]}`))
  1590  	suite.Require().NoError(err)
  1591  
  1592  	msg := make([]byte, 10240)
  1593  	// receive subscription id
  1594  	n, err := ws.Read(msg)
  1595  	suite.Require().NoError(err)
  1596  	var res Response
  1597  	suite.Require().NoError(json.Unmarshal(msg[:n], &res))
  1598  	subscriptionId := string(res.Result)
  1599  
  1600  	// send transactions
  1601  	var expectedHashList [3]ethcmn.Hash
  1602  	var wg sync.WaitGroup
  1603  	wg.Add(1)
  1604  	go func() {
  1605  		defer wg.Done()
  1606  		for i := 0; i < 3; i++ {
  1607  			param := make([]map[string]string, 1)
  1608  			param[0] = make(map[string]string)
  1609  			param[0]["from"] = hexAddr1.Hex()
  1610  			param[0]["data"] = "0x6080604052348015600f57600080fd5b5060117f775a94827b8fd9b519d36cd827093c664f93347070a554f65e4a6f56cd73889860405160405180910390a2603580604b6000396000f3fe6080604052600080fdfea165627a7a723058206cab665f0f557620554bb45adf266708d2bd349b8a4314bdff205ee8440e3c240029"
  1611  			param[0]["gasPrice"] = (*hexutil.Big)(defaultGasPrice.Amount.BigInt()).String()
  1612  			rpcRes := Call(suite.T(), suite.addr, "eth_sendTransaction", param)
  1613  
  1614  			var hash ethcmn.Hash
  1615  			suite.Require().NoError(json.Unmarshal(rpcRes.Result, &hash))
  1616  			expectedHashList[i] = hash
  1617  		}
  1618  	}()
  1619  	var actualHashList [3]ethcmn.Hash
  1620  	// receive message three times
  1621  	for i := 0; i < 3; i++ {
  1622  		n, err = ws.Read(msg)
  1623  		suite.Require().NoError(err)
  1624  		var notification websockets.SubscriptionNotification
  1625  		suite.Require().NoError(json.Unmarshal(msg[:n], &notification))
  1626  		actualHashList[i] = ethcmn.HexToHash(notification.Params.Result.(string))
  1627  	}
  1628  	wg.Wait()
  1629  	suite.Require().EqualValues(expectedHashList, actualHashList)
  1630  
  1631  	// cancel the subscription
  1632  	cancelMsg := fmt.Sprintf(`{"id": 2, "method": "eth_unsubscribe", "params": [%s]}`, subscriptionId)
  1633  	_, err = ws.Write([]byte(cancelMsg))
  1634  	suite.Require().NoError(err)
  1635  }
  1636  
  1637  //{} or nil          matches any topic list
  1638  //{A}                matches topic A in first position
  1639  //{{}, {B}}          matches any topic in first position AND B in second position
  1640  //{{A}, {B}}         matches topic A in first position AND B in second position
  1641  //{{A, B}, {C, D}}   matches topic (A OR B) in first position AND (C OR D) in second position
  1642  func (suite *RPCTestSuite) TestWebsocket_Logs(netAddr string) {
  1643  	t := suite.T()
  1644  	contractAddr1, contractAddr2, contractAddr3 := deployTestTokenContract(t, netAddr), deployTestTokenContract(t, netAddr), deployTestTokenContract(t, netAddr)
  1645  
  1646  	// init test cases
  1647  	tests := []struct {
  1648  		addressList string // input
  1649  		topicsList  string // input
  1650  		expected    int    // expected result
  1651  	}{
  1652  		// case 0: matches any contract address & any topics
  1653  		{"", "", 21},
  1654  		// case 1: matches one contract address & any topics
  1655  		{fmt.Sprintf(`"address":"%s"`, contractAddr1), "", 7},
  1656  		// case 2: matches two contract addressses & any topics
  1657  		{fmt.Sprintf(`"address":["%s","%s"]`, contractAddr1, contractAddr2), "", 14},
  1658  		// case 3: matches two contract addressses & one topic in first position
  1659  		{fmt.Sprintf(`"address":["%s","%s"]`, contractAddr1, contractAddr2), fmt.Sprintf(`"topics":["%s"]`, approveFuncHash), 6},
  1660  		// case 4: matches two contract addressses & one topic in third position
  1661  		{fmt.Sprintf(`"address":["%s","%s"]`, contractAddr1, contractAddr2), fmt.Sprintf(`"topics":[null, null, ["%s"]]`, recvAddr1Hash), 4},
  1662  		// case 5: matches two contract addressses & two topics in first、third position
  1663  		{fmt.Sprintf(`"address":["%s","%s"]`, contractAddr1, contractAddr2), fmt.Sprintf(`"topics":[["%s"], null, ["%s"]]`, approveFuncHash, recvAddr1Hash), 2},
  1664  		// case 6: matches two contract addressses & two topic lists in first、third position
  1665  		{fmt.Sprintf(`"address":["%s","%s"]`, contractAddr1, contractAddr2), fmt.Sprintf(`"topics":[["%s","%s"], null, ["%s","%s"]]`, approveFuncHash, transferFuncHash, recvAddr1Hash, recvAddr2Hash), 8},
  1666  	}
  1667  
  1668  	go func() {
  1669  		time.Sleep(time.Minute * 2)
  1670  		panic("the tasks have been running for too long time, over 2 minutes")
  1671  	}()
  1672  	// the approximate running time is one minute
  1673  	var wg sync.WaitGroup
  1674  	wg.Add(len(tests) + 1)
  1675  	for i, test := range tests {
  1676  		go verifyWebSocketRecvNum(suite.T(), &wg, i, test.addressList, test.topicsList, test.expected)
  1677  	}
  1678  	go sendTxs(suite.T(), netAddr, &wg, contractAddr1, contractAddr2, contractAddr3)
  1679  	wg.Wait()
  1680  }
  1681  
  1682  func deployTestTokenContract(t *testing.T, netAddr string) string {
  1683  	param := make([]map[string]string, 1)
  1684  	param[0] = map[string]string{
  1685  		"from":     hexAddr1.Hex(),
  1686  		"data":     ttokenContractByteCode,
  1687  		"gasPrice": (*hexutil.Big)(defaultGasPrice.Amount.BigInt()).String(),
  1688  	}
  1689  	rpcRes := Call(t, netAddr, "eth_sendTransaction", param)
  1690  	var hash ethcmn.Hash
  1691  	require.NoError(t, json.Unmarshal(rpcRes.Result, &hash))
  1692  	receipt := WaitForReceipt(t, netAddr, hash)
  1693  	require.NotNil(t, receipt)
  1694  	contractAddr, ok := receipt["contractAddress"].(string)
  1695  	require.True(t, ok)
  1696  	return contractAddr
  1697  }
  1698  
  1699  func verifyWebSocketRecvNum(t *testing.T, wg *sync.WaitGroup, index int, addressList, topicsList string, expected int) {
  1700  	defer wg.Done()
  1701  
  1702  	// create websocket
  1703  	origin, url := "http://127.0.0.1:8546/", "ws://127.0.0.1:8546"
  1704  	ws, err := websocket.Dial(url, "", origin)
  1705  	require.NoError(t, err)
  1706  	defer func() {
  1707  		// close websocket
  1708  		err := ws.Close()
  1709  		require.NoError(t, err)
  1710  	}()
  1711  
  1712  	// fulfill parameters
  1713  	param := assembleParameters(addressList, topicsList)
  1714  	_, err = ws.Write([]byte(param))
  1715  	require.NoError(t, err)
  1716  
  1717  	msg := make([]byte, 10240)
  1718  	// receive subscription id
  1719  	n, err := ws.Read(msg)
  1720  	var res Response
  1721  	require.NoError(t, err)
  1722  	require.NoError(t, json.Unmarshal(msg[:n], &res))
  1723  	require.Nil(t, res.Error)
  1724  	subscriptionId := string(res.Result)
  1725  	//log.Printf("test case %d: websocket %s is created successfully, expect receive %d logs \n", index, subscriptionId, expected)
  1726  
  1727  	for i := 0; i < expected; i++ {
  1728  		n, err = ws.Read(msg)
  1729  		require.NoError(t, err)
  1730  		var notification websockets.SubscriptionNotification
  1731  		require.NoError(t, json.Unmarshal(msg[:n], &notification))
  1732  	}
  1733  
  1734  	// cancel the subscription
  1735  	cancelMsg := fmt.Sprintf(`{"id": 2, "method": "eth_unsubscribe", "params": [%s]}`, subscriptionId)
  1736  	_, err = ws.Write([]byte(cancelMsg))
  1737  	require.NoError(t, err)
  1738  	//log.Printf("test case %d: webdocket %s receive %d logs, then close successfully", index, subscriptionId, expected)
  1739  }
  1740  */
  1741  
  1742  func assembleParameters(addressList string, topicsList string) string {
  1743  	var param string
  1744  	if addressList == "" {
  1745  		param = topicsList
  1746  	}
  1747  	if topicsList == "" {
  1748  		param = addressList
  1749  	}
  1750  	if addressList != "" && topicsList != "" {
  1751  		param = addressList + "," + topicsList
  1752  	}
  1753  	return fmt.Sprintf(`{"id": 2, "method": "eth_subscribe", "params": ["logs",{%s}]}`, param)
  1754  }
  1755  
  1756  func sendTxs(t *testing.T, netAddr string, wg *sync.WaitGroup, contractAddrs ...string) {
  1757  	dataList := []string{
  1758  		// 0. mint  4294967295coin -> 0x2cf4ea7df75b513509d95946b43062e26bd88035
  1759  		"0x40c10f190000000000000000000000002cf4ea7df75b513509d95946b43062e26bd8803500000000000000000000000000000000000000000000000000000000ffffffff",
  1760  		// 1. approve 12345678coin -> 0x9ad84c8630e0282f78e5479b46e64e17779e3cfb
  1761  		"0x095ea7b30000000000000000000000009ad84c8630e0282f78e5479b46e64e17779e3cfb0000000000000000000000000000000000000000000000000000000000bc614e",
  1762  		// 2. approve 12345678coin -> 0xc9c9b43322f5e1dc401252076fa4e699c9122cd6
  1763  		"0x095ea7b3000000000000000000000000c9c9b43322f5e1dc401252076fa4e699c9122cd60000000000000000000000000000000000000000000000000000000000bc614e",
  1764  		// 3. approve 12345678coin -> 0x2B5Cf24AeBcE90f0B8f80Bc42603157b27cFbf47
  1765  		"0x095ea7b30000000000000000000000002b5cf24aebce90f0b8f80bc42603157b27cfbf470000000000000000000000000000000000000000000000000000000000bc614e",
  1766  		// 4. transfer 1234coin    -> 0x9ad84c8630e0282f78e5479b46e64e17779e3cfb
  1767  		"0xa9059cbb0000000000000000000000009ad84c8630e0282f78e5479b46e64e17779e3cfb00000000000000000000000000000000000000000000000000000000000004d2",
  1768  		// 5. transfer 1234coin    -> 0xc9c9b43322f5e1dc401252076fa4e699c9122cd6
  1769  		"0xa9059cbb000000000000000000000000c9c9b43322f5e1dc401252076fa4e699c9122cd600000000000000000000000000000000000000000000000000000000000004d2",
  1770  		// 6. transfer 1234coin    -> 0x2B5Cf24AeBcE90f0B8f80Bc42603157b27cFbf47
  1771  		"0xa9059cbb0000000000000000000000002b5cf24aebce90f0b8f80bc42603157b27cfbf4700000000000000000000000000000000000000000000000000000000000004d2",
  1772  	}
  1773  	defer wg.Done()
  1774  	for _, contractAddr := range contractAddrs {
  1775  		for i := 0; i < 7; i++ {
  1776  			param := make([]map[string]string, 1)
  1777  			param[0] = make(map[string]string)
  1778  			param[0]["from"] = hexAddr1.Hex()
  1779  			param[0]["to"] = contractAddr
  1780  			param[0]["data"] = dataList[i]
  1781  			param[0]["gasPrice"] = (*hexutil.Big)(defaultGasPrice.Amount.BigInt()).String()
  1782  			rpcRes := Call(t, netAddr, "eth_sendTransaction", param)
  1783  			var hash ethcmn.Hash
  1784  			require.NoError(t, json.Unmarshal(rpcRes.Result, &hash))
  1785  
  1786  			time.Sleep(time.Second * 1)
  1787  		}
  1788  	}
  1789  }