github.com/0chain/gosdk@v1.17.11/zcncore/ethwallet_base_test.go (about) 1 package zcncore 2 3 import ( 4 "context" 5 "math/big" 6 "sync" 7 "testing" 8 9 "github.com/ethereum/go-ethereum/common" 10 "github.com/ethereum/go-ethereum/consensus/ethash" 11 "github.com/ethereum/go-ethereum/core" 12 "github.com/ethereum/go-ethereum/core/rawdb" 13 "github.com/ethereum/go-ethereum/core/types" 14 "github.com/ethereum/go-ethereum/crypto" 15 "github.com/ethereum/go-ethereum/eth" 16 "github.com/ethereum/go-ethereum/eth/ethconfig" 17 "github.com/ethereum/go-ethereum/ethclient" 18 "github.com/ethereum/go-ethereum/node" 19 "github.com/ethereum/go-ethereum/params" 20 "github.com/stretchr/testify/require" 21 ) 22 23 var ( 24 testKey, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291") 25 testAddr = crypto.PubkeyToAddress(testKey.PublicKey) 26 testBalance = big.NewInt(2e15) 27 ) 28 29 func TestTokensConversion(t *testing.T) { 30 t.Run("Tokens to Eth", func(t *testing.T) { 31 ethTokens := TokensToEth(4337488392000000000) 32 require.Equal(t, 4.337488392, ethTokens) 33 }) 34 35 t.Run("Eth to tokens", func(t *testing.T) { 36 ethTokens := EthToTokens(4.337488392) 37 require.Equal(t, int64(4337488392000000000), ethTokens) 38 }) 39 40 t.Run("GTokens to Eth", func(t *testing.T) { 41 ethTokens := GTokensToEth(10000000) 42 require.Equal(t, 0.01, ethTokens) 43 }) 44 45 t.Run("Eth to GTokens", func(t *testing.T) { 46 ethTokens := GEthToTokens(4.337488392) 47 require.Equal(t, int64(4337488392), ethTokens) 48 }) 49 } 50 51 func TestValidEthAddress(t *testing.T) { 52 t.Run("Valid Eth wallet, but no balance", func(t *testing.T) { 53 _config.chain.EthNode = "test" 54 backend, _ := newTestBackend(t) 55 client, _ := backend.Attach() 56 defer backend.Close() 57 defer client.Close() 58 59 realClient := ethclient.NewClient(client) 60 getEthClient = func() (*ethclient.Client, error) { 61 return realClient, nil 62 } 63 64 res, err := IsValidEthAddress("0x531f9349ed2Fe5c526B47fa7841D35c90482e6cF") 65 require.Nil(t, err, "") 66 require.False(t, res, "") 67 }) 68 69 t.Run("Valid Eth wallet", func(t *testing.T) { 70 _config.chain.EthNode = "test" 71 backend, _ := newTestBackend(t) 72 client, _ := backend.Attach() 73 defer backend.Close() 74 defer client.Close() 75 76 realClient := ethclient.NewClient(client) 77 err := sendTransaction(realClient) 78 require.Nil(t, err) 79 80 getEthClient = func() (*ethclient.Client, error) { 81 return realClient, nil 82 } 83 84 res, err := IsValidEthAddress(testAddr.String()) 85 require.Nil(t, err, "") 86 require.True(t, res, "") 87 }) 88 89 t.Run("Invalid Eth wallet", func(t *testing.T) { 90 _config.chain.EthNode = "test" 91 backend, _ := newTestBackend(t) 92 client, _ := backend.Attach() 93 defer backend.Close() 94 defer client.Close() 95 96 realClient := ethclient.NewClient(client) 97 getEthClient = func() (*ethclient.Client, error) { 98 return realClient, nil 99 } 100 101 res, err := IsValidEthAddress("testAddr.String()") 102 require.NotNil(t, err, "") 103 require.False(t, res, "") 104 }) 105 } 106 107 func TestGetWalletAddrFromEthMnemonic(t *testing.T) { 108 t.Run("Success", func(t *testing.T) { 109 _config.chain.EthNode = "test" 110 mnemonic := "expect domain water near beauty bag pond clap chronic chronic length leisure" 111 res, err := GetWalletAddrFromEthMnemonic(mnemonic) 112 require.Nil(t, err, "") 113 require.Equal(t, res, "{\"ID\":\"0x531f9349ed2Fe5c526B47fa7841D35c90482e6cF\",\"PrivateKey\":\"b68bbd97a2b46b3fb2e38db771ec38935231f0b95733a4021d61601c658bc541\"}") 114 }) 115 116 t.Run("Wrong", func(t *testing.T) { 117 _config.chain.EthNode = "test" 118 mnemonic := "this is wrong mnemonic" 119 _, err := GetWalletAddrFromEthMnemonic(mnemonic) 120 require.NotNil(t, err, "") 121 }) 122 } 123 124 func TestGetEthBalance(t *testing.T) { 125 t.Run("Success", func(t *testing.T) { 126 _config.chain.EthNode = "test" 127 backend, _ := newTestBackend(t) 128 client, _ := backend.Attach() 129 defer backend.Close() 130 defer client.Close() 131 132 realClient := ethclient.NewClient(client) 133 err := sendTransaction(realClient) 134 require.Nil(t, err) 135 136 getEthClient = func() (*ethclient.Client, error) { 137 return realClient, nil 138 } 139 140 tcb := &MockBalanceCallback{} 141 tcb.wg = &sync.WaitGroup{} 142 tcb.wg.Add(1) 143 err = GetEthBalance(testAddr.String(), tcb) 144 if err != nil { 145 tcb.wg.Done() 146 } 147 tcb.wg.Wait() 148 149 require.Nil(t, err, "") 150 require.True(t, tcb.value > 0, "") 151 require.True(t, tcb.status == StatusSuccess, "") 152 require.True(t, tcb.info == "") 153 }) 154 } 155 156 func TestCheckEthHashStatus(t *testing.T) { 157 t.Run("Pending transaction", func(t *testing.T) { 158 _config.chain.EthNode = "test" 159 backend, _ := newTestBackend(t) 160 client, _ := backend.Attach() 161 defer backend.Close() 162 defer client.Close() 163 164 realClient := ethclient.NewClient(client) 165 err := sendTransaction(realClient) 166 require.Nil(t, err) 167 168 getEthClient = func() (*ethclient.Client, error) { 169 return realClient, nil 170 } 171 result := CheckEthHashStatus("0x05aa8890d4778e292f837dd36b59a50931c175f4648c3d8157525f5454475cf7") 172 require.True(t, result < 0, "") 173 }) 174 } 175 176 func TestSuggestEthGasPrice(t *testing.T) { 177 t.Run("suggest gas price success", func(t *testing.T) { 178 _config.chain.EthNode = "test" 179 backend, _ := newTestBackend(t) 180 client, _ := backend.Attach() 181 defer backend.Close() 182 defer client.Close() 183 184 realClient := ethclient.NewClient(client) 185 getEthClient = func() (*ethclient.Client, error) { 186 return realClient, nil 187 } 188 gas, err := SuggestEthGasPrice() 189 require.Nil(t, err) 190 require.True(t, gas > 0) 191 }) 192 } 193 194 func TestTransferEthTokens(t *testing.T) { 195 t.Run("success transfer", func(t *testing.T) { 196 _config.chain.EthNode = "test" 197 backend, _ := newTestBackend(t) 198 client, _ := backend.Attach() 199 defer backend.Close() 200 defer client.Close() 201 202 realClient := ethclient.NewClient(client) 203 getEthClient = func() (*ethclient.Client, error) { 204 return realClient, nil 205 } 206 207 hash, err := TransferEthTokens("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291", 1000000000000, 10000) 208 require.Nil(t, err) 209 require.EqualValues(t, hash, "0x43eba8525933e34908e766de93176d810e8582e886052708d44d9db157803aec") 210 }) 211 } 212 213 type MockBalanceCallback struct { 214 wg *sync.WaitGroup 215 status int 216 value int64 217 info string 218 } 219 220 func (balCall *MockBalanceCallback) OnBalanceAvailable(status int, value int64, info string) { 221 defer balCall.wg.Done() 222 223 balCall.status = status 224 balCall.value = value 225 balCall.info = info 226 } 227 228 func newTestBackend(t *testing.T) (*node.Node, []*types.Block) { 229 // Generate test chain. 230 genesis, blocks := generateTestChain() 231 // Create node 232 n, err := node.New(&node.Config{}) 233 if err != nil { 234 t.Fatalf("can't create new node: %v", err) 235 } 236 // Create Ethereum Service 237 config := ðconfig.Config{Genesis: genesis} 238 config.Ethash.PowMode = ethash.ModeFake 239 ethservice, err := eth.New(n, config) 240 if err != nil { 241 t.Fatalf("can't create new ethereum service: %v", err) 242 } 243 // Import the test chain. 244 if err := n.Start(); err != nil { 245 t.Fatalf("can't start test node: %v", err) 246 } 247 if _, err := ethservice.BlockChain().InsertChain(blocks[1:]); err != nil { 248 t.Fatalf("can't import test blocks: %v", err) 249 } 250 return n, blocks 251 } 252 253 func generateTestChain() (*core.Genesis, []*types.Block) { 254 db := rawdb.NewMemoryDatabase() 255 config := params.AllEthashProtocolChanges 256 genesis := &core.Genesis{ 257 Config: config, 258 Alloc: core.GenesisAlloc{testAddr: {Balance: testBalance}}, 259 ExtraData: []byte("test genesis"), 260 Timestamp: 9000, 261 } 262 // BaseFee: big.NewInt(params.InitialBaseFee), 263 generate := func(i int, g *core.BlockGen) { 264 g.OffsetTime(5) 265 g.SetExtra([]byte("test")) 266 } 267 gblock := genesis.ToBlock() 268 genesis.Commit(db) //nolint: errcheck 269 engine := ethash.NewFaker() 270 blocks, _ := core.GenerateChain(config, gblock, engine, db, 1, generate) 271 blocks = append([]*types.Block{gblock}, blocks...) 272 return genesis, blocks 273 } 274 275 func sendTransaction(ec *ethclient.Client) error { 276 // Retrieve chainID 277 chainID, err := ec.ChainID(context.Background()) 278 if err != nil { 279 return err 280 } 281 // Create transaction 282 tx := types.NewTransaction(0, common.Address{1}, big.NewInt(1), 22000, big.NewInt(1), nil) 283 signer := types.LatestSignerForChainID(chainID) 284 signature, err := crypto.Sign(signer.Hash(tx).Bytes(), testKey) 285 if err != nil { 286 return err 287 } 288 signedTx, err := tx.WithSignature(signer, signature) 289 if err != nil { 290 return err 291 } 292 // Send transaction 293 return ec.SendTransaction(context.Background(), signedTx) 294 }