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

     1  package tests
     2  
     3  import (
     4  	"encoding/json"
     5  	"fmt"
     6  
     7  	"github.com/ethereum/go-ethereum/common"
     8  	ethcmn "github.com/ethereum/go-ethereum/common"
     9  	"github.com/ethereum/go-ethereum/common/hexutil"
    10  	ethcrypto "github.com/ethereum/go-ethereum/crypto"
    11  )
    12  
    13  func (suite *RPCTestSuite) TestPersonal_NewAccount() {
    14  	// create an new mnemonics randomly on the node
    15  	rpcRes := Call(suite.T(), suite.addr, "personal_newAccount", []string{defaultPassWd})
    16  	var addr common.Address
    17  	suite.Require().NoError(json.Unmarshal(rpcRes.Result, &addr))
    18  	addrCounter++
    19  
    20  	rpcRes = Call(suite.T(), suite.addr, "personal_listAccounts", nil)
    21  	var res []common.Address
    22  	suite.Require().NoError(json.Unmarshal(rpcRes.Result, &res))
    23  	suite.Require().Equal(1, len(res))
    24  	suite.Require().True(res[0] == addr)
    25  }
    26  
    27  func (suite *RPCTestSuite) TestPersonal_Sign() {
    28  	rpcRes := Call(suite.T(), suite.addr, "personal_sign", []interface{}{hexutil.Bytes{0x88}, hexutil.Bytes(senderAddr[:]), ""})
    29  
    30  	var res hexutil.Bytes
    31  	suite.Require().NoError(json.Unmarshal(rpcRes.Result, &res))
    32  	suite.Require().Equal(65, len(res))
    33  	// TODO: check that signature is same as with geth, requires importing a key
    34  
    35  	// error with inexistent addr
    36  	inexistentAddr := common.BytesToAddress([]byte{0})
    37  	_, err := CallWithError(suite.addr, "personal_sign", []interface{}{hexutil.Bytes{0x88}, inexistentAddr, ""})
    38  	suite.Require().Error(err)
    39  }
    40  
    41  func (suite *RPCTestSuite) TestPersonal_ImportRawKey() {
    42  	privkey, err := ethcrypto.GenerateKey()
    43  	suite.Require().NoError(err)
    44  
    45  	// parse priv key to hex
    46  	hexPriv := common.Bytes2Hex(ethcrypto.FromECDSA(privkey))
    47  	rpcRes := Call(suite.T(), suite.addr, "personal_importRawKey", []string{hexPriv, defaultPassWd})
    48  
    49  	var resAddr common.Address
    50  	suite.Require().NoError(json.Unmarshal(rpcRes.Result, &resAddr))
    51  
    52  	addr := ethcrypto.PubkeyToAddress(privkey.PublicKey)
    53  
    54  	suite.Require().True(addr == resAddr)
    55  
    56  	addrCounter++
    57  
    58  	// error check with wrong hex format of privkey
    59  	rpcRes, err = CallWithError(suite.addr, "personal_importRawKey", []string{fmt.Sprintf("%sg", hexPriv), defaultPassWd})
    60  	suite.Require().Error(err)
    61  }
    62  
    63  func (suite *RPCTestSuite) TestPersonal_ImportRawKey_Duplicate() {
    64  	privkey, err := ethcrypto.GenerateKey()
    65  	suite.Require().NoError(err)
    66  	// parse priv key to hex, then add the key
    67  	hexPriv := common.Bytes2Hex(ethcrypto.FromECDSA(privkey))
    68  	rpcRes := Call(suite.T(), suite.addr, "personal_importRawKey", []string{hexPriv, defaultPassWd})
    69  	var resAddr common.Address
    70  	suite.Require().NoError(json.Unmarshal(rpcRes.Result, &resAddr))
    71  	suite.Require().True(ethcrypto.PubkeyToAddress(privkey.PublicKey) == resAddr)
    72  	addrCounter++
    73  
    74  	// record the key-list length
    75  	rpcRes = Call(suite.T(), suite.addr, "personal_listAccounts", nil)
    76  	var list []common.Address
    77  	suite.Require().NoError(json.Unmarshal(rpcRes.Result, &list))
    78  	originLen := len(list)
    79  
    80  	// add the same key again
    81  	rpcRes = Call(suite.T(), suite.addr, "personal_importRawKey", []string{hexPriv, defaultPassWd})
    82  	var newResAddr common.Address
    83  	suite.Require().NoError(json.Unmarshal(rpcRes.Result, &newResAddr))
    84  	suite.Require().Equal(resAddr, newResAddr)
    85  
    86  	// check the actual key-list length changed or not
    87  	rpcRes = Call(suite.T(), suite.addr, "personal_listAccounts", nil)
    88  	suite.Require().NoError(json.Unmarshal(rpcRes.Result, &list))
    89  	suite.Require().Equal(originLen, len(list))
    90  }
    91  
    92  func (suite *RPCTestSuite) TestPersonal_EcRecover() {
    93  	data := hexutil.Bytes{0x88}
    94  	rpcRes := Call(suite.T(), suite.addr, "personal_sign", []interface{}{data, hexutil.Bytes(senderAddr[:]), ""})
    95  
    96  	var res hexutil.Bytes
    97  	suite.Require().NoError(json.Unmarshal(rpcRes.Result, &res))
    98  	suite.Require().Equal(65, len(res))
    99  
   100  	rpcRes = Call(suite.T(), suite.addr, "personal_ecRecover", []interface{}{data, res})
   101  	var ecrecoverRes common.Address
   102  	suite.Require().NoError(json.Unmarshal(rpcRes.Result, &ecrecoverRes))
   103  	suite.Require().Equal(senderAddr.Bytes(), ecrecoverRes[:])
   104  
   105  	// error check for ecRecover
   106  	// wrong length of sig
   107  	rpcRes, err := CallWithError(suite.addr, "personal_ecRecover", []interface{}{data, res[1:]})
   108  	suite.Require().Error(err)
   109  
   110  	// wrong RecoveryIDOffset -> nether 27 nor 28
   111  	res[ethcrypto.RecoveryIDOffset] = 29
   112  	rpcRes, err = CallWithError(suite.addr, "personal_ecRecover", []interface{}{data, res})
   113  	suite.Require().Error(err)
   114  
   115  	// fail in SigToPub
   116  	sigInvalid := make(hexutil.Bytes, 65)
   117  	for i := 0; i < 64; i++ {
   118  		sigInvalid[i] = 0
   119  	}
   120  	sigInvalid[64] = 27
   121  	rpcRes, err = CallWithError(suite.addr, "personal_ecRecover", []interface{}{data, sigInvalid})
   122  	suite.Require().Error(err)
   123  }
   124  
   125  func (suite *RPCTestSuite) TestPersonal_UnlockAccount() {
   126  	// create a new account
   127  	rpcRes := Call(suite.T(), suite.addr, "personal_newAccount", []string{defaultPassWd})
   128  	var addr common.Address
   129  	suite.Require().NoError(json.Unmarshal(rpcRes.Result, &addr))
   130  
   131  	addrCounter++
   132  
   133  	newPassWd := "87654321"
   134  	// try to sign with different password -> failed
   135  	_, err := CallWithError(suite.addr, "personal_sign", []interface{}{hexutil.Bytes{0x88}, addr, newPassWd})
   136  	suite.Require().Error(err)
   137  
   138  	// unlock the address with the new password
   139  	rpcRes = Call(suite.T(), suite.addr, "personal_unlockAccount", []interface{}{addr, newPassWd})
   140  	var unlocked bool
   141  	suite.Require().NoError(json.Unmarshal(rpcRes.Result, &unlocked))
   142  	suite.Require().True(unlocked)
   143  
   144  	// try to sign with the new password -> successfully
   145  	rpcRes, err = CallWithError(suite.addr, "personal_sign", []interface{}{hexutil.Bytes{0x88}, addr, newPassWd})
   146  	suite.Require().NoError(err)
   147  	var res hexutil.Bytes
   148  	suite.Require().NoError(json.Unmarshal(rpcRes.Result, &res))
   149  	suite.Require().Equal(65, len(res))
   150  
   151  	// error check
   152  	// inexistent addr
   153  	inexistentAddr := common.BytesToAddress([]byte{0})
   154  	_, err = CallWithError(suite.addr, "personal_unlockAccount", []interface{}{hexutil.Bytes{0x88}, inexistentAddr, newPassWd})
   155  	suite.Require().Error(err)
   156  }
   157  
   158  func (suite *RPCTestSuite) TestPersonal_LockAccount() {
   159  	// create a new account
   160  	rpcRes := Call(suite.T(), suite.addr, "personal_newAccount", []string{defaultPassWd})
   161  	var addr common.Address
   162  	suite.Require().NoError(json.Unmarshal(rpcRes.Result, &addr))
   163  
   164  	addrCounter++
   165  
   166  	// unlock the account above first
   167  	rpcRes = Call(suite.T(), suite.addr, "personal_unlockAccount", []interface{}{addr, defaultPassWd})
   168  	var unlocked bool
   169  	suite.Require().NoError(json.Unmarshal(rpcRes.Result, &unlocked))
   170  	suite.Require().True(unlocked)
   171  
   172  	// lock the account
   173  	rpcRes = Call(suite.T(), suite.addr, "personal_lockAccount", []interface{}{addr})
   174  	var locked bool
   175  	suite.Require().NoError(json.Unmarshal(rpcRes.Result, &locked))
   176  	suite.Require().True(locked)
   177  
   178  	// try to sign, should be locked -> fail to sign
   179  	_, err := CallWithError(suite.addr, "personal_sign", []interface{}{hexutil.Bytes{0x88}, addr, defaultPassWd})
   180  	suite.Require().Error(err)
   181  
   182  	// error check
   183  	// lock an inexistent account
   184  	inexistentAddr := common.BytesToAddress([]byte{0})
   185  	rpcRes = Call(suite.T(), suite.addr, "personal_lockAccount", []interface{}{inexistentAddr})
   186  	suite.Require().NoError(json.Unmarshal(rpcRes.Result, &locked))
   187  	suite.Require().False(locked)
   188  }
   189  
   190  func (suite *RPCTestSuite) TestPersonal_SendTransaction_Transfer() {
   191  	params := make([]interface{}, 2)
   192  	params[0] = map[string]string{
   193  		"from":  senderAddr.Hex(),
   194  		"to":    receiverAddr.Hex(),
   195  		"value": "0x16345785d8a0000", // 0.1
   196  	}
   197  	params[1] = defaultPassWd
   198  
   199  	rpcRes := Call(suite.T(), suite.addr, "personal_sendTransaction", params)
   200  	var hash ethcmn.Hash
   201  	suite.Require().NoError(json.Unmarshal(rpcRes.Result, &hash))
   202  
   203  	commitBlock(suite)
   204  	commitBlock(suite)
   205  
   206  	receipt := WaitForReceipt(suite.T(), suite.addr, hash)
   207  	suite.Require().NotNil(receipt)
   208  	suite.Require().Equal("0x1", receipt["status"].(string))
   209  }
   210  
   211  func (suite *RPCTestSuite) TestPersonal_SendTransaction_DeployContract() {
   212  	params := make([]interface{}, 2)
   213  	params[0] = map[string]string{
   214  		"from":     senderAddr.Hex(),
   215  		"data":     "0x6080604052348015600f57600080fd5b5060117f775a94827b8fd9b519d36cd827093c664f93347070a554f65e4a6f56cd73889860405160405180910390a2603580604b6000396000f3fe6080604052600080fdfea165627a7a723058206cab665f0f557620554bb45adf266708d2bd349b8a4314bdff205ee8440e3c240029",
   216  		"gasPrice": (*hexutil.Big)(defaultGasPrice.Amount.BigInt()).String(),
   217  	}
   218  	params[1] = defaultPassWd
   219  
   220  	rpcRes := Call(suite.T(), suite.addr, "personal_sendTransaction", params)
   221  	var hash ethcmn.Hash
   222  	suite.Require().NoError(json.Unmarshal(rpcRes.Result, &hash))
   223  
   224  	commitBlock(suite)
   225  	commitBlock(suite)
   226  
   227  	receipt := WaitForReceipt(suite.T(), suite.addr, hash)
   228  	suite.Require().NotNil(receipt)
   229  	suite.Require().Equal("0x1", receipt["status"].(string))
   230  }