github.com/cerberus-wallet/blockbook@v0.3.2/bchain/coins/nuls/nulsparser_test.go (about) 1 package nuls 2 3 import ( 4 "blockbook/bchain" 5 "blockbook/bchain/coins/btc" 6 "encoding/hex" 7 "encoding/json" 8 "math/big" 9 "reflect" 10 "testing" 11 12 "github.com/ethereum/go-ethereum/common/hexutil" 13 "github.com/martinboehm/btcutil/hdkeychain" 14 ) 15 16 var ( 17 testTx1, testTx2 bchain.Tx 18 19 testTxPacked1 = "0001e240daadfbe7931e000000007b22686578223a22222c2274786964223a223030323036626231323431303861356664393865383238623138316666303162393237633063366234373764343531326266656638346366353266306663326136613161222c2276657273696f6e223a312c226c6f636b74696d65223a302c2276696e223a5b7b22636f696e62617365223a22222c2274786964223a223030323035343537616230373033623164313034363264343334373034386330626233353634653430663537616531663632353136393539343364653161633831306130222c22766f7574223a302c22736372697074536967223a7b22686578223a22227d2c2273657175656e6365223a302c22616464726573736573223a5b224e736535334d77524c424a31575555365365644d485141466643507442377734225d7d5d2c22766f7574223a5b7b2256616c7565536174223a3339393939393030303030302c2276616c7565223a302c226e223a302c227363726970745075624b6579223a7b22686578223a224e7365347a705a4873557555376835796d7632387063476277486a75336a6f56222c22616464726573736573223a5b224e7365347a705a4873557555376835796d7632387063476277486a75336a6f56225d7d7d5d2c22626c6f636b74696d65223a313535323335373834343137357d" 20 testTxPacked2 = "0007c91adaadfbb89946000000007b22686578223a22222c2274786964223a223030323037386139386633383163373134613036386436303565346265316565323139353438353736313165303938616262636333663530633536383066386164326535222c2276657273696f6e223a312c226c6f636b74696d65223a302c2276696e223a5b7b22636f696e62617365223a22222c2274786964223a223030323037613430646334623661633430376434396133633333616137353462623466303565343565353763323438313162313437653762663363616630363361383233222c22766f7574223a312c22736372697074536967223a7b22686578223a22227d2c2273657175656e6365223a302c22616464726573736573223a5b224e73653131397a326f53444a596b466b786d775944695974506642654e6b7169225d7d5d2c22766f7574223a5b7b2256616c7565536174223a3430303030303030303030302c2276616c7565223a302c226e223a302c227363726970745075624b6579223a7b22686578223a224e736534696b6a45383867324267734e7773737754646b53776953724b6a6a53222c22616464726573736573223a5b224e736534696b6a45383867324267734e7773737754646b53776953724b6a6a53225d7d7d2c7b2256616c7565536174223a373238363536353537303030302c2276616c7565223a302c226e223a312c227363726970745075624b6579223a7b22686578223a224e73653131397a326f53444a596b466b786d775944695974506642654e6b7169222c22616464726573736573223a5b224e73653131397a326f53444a596b466b786d775944695974506642654e6b7169225d7d7d5d2c22626c6f636b74696d65223a313535323335373435393535357d" 21 ) 22 23 func init() { 24 testTx1 = bchain.Tx{ 25 Hex: "", 26 Blocktime: 1552357844175, 27 Txid: "00206bb124108a5fd98e828b181ff01b927c0c6b477d4512bfef84cf52f0fc2a6a1a", 28 LockTime: 0, 29 Version: 1, 30 Vin: []bchain.Vin{ 31 { 32 Txid: "00205457ab0703b1d10462d4347048c0bb3564e40f57ae1f6251695943de1ac810a0", 33 Vout: 0, 34 Sequence: 0, 35 Addresses: []string{ 36 "Nse53MwRLBJ1WUU6SedMHQAFfCPtB7w4", 37 }, 38 }, 39 }, 40 Vout: []bchain.Vout{ 41 { 42 ValueSat: *big.NewInt(399999000000), 43 N: 0, 44 JsonValue: json.Number("0"), 45 ScriptPubKey: bchain.ScriptPubKey{ 46 Hex: "Nse4zpZHsUuU7h5ymv28pcGbwHju3joV", 47 Addresses: []string{ 48 "Nse4zpZHsUuU7h5ymv28pcGbwHju3joV", 49 }, 50 }, 51 }, 52 }, 53 //CoinSpecificData: []string{}, 54 } 55 56 testTx2 = bchain.Tx{ 57 Hex: "", 58 Blocktime: 1552357459555, 59 Txid: "002078a98f381c714a068d605e4be1ee21954857611e098abbcc3f50c5680f8ad2e5", 60 LockTime: 0, 61 Version: 1, 62 Vin: []bchain.Vin{ 63 { 64 Txid: "00207a40dc4b6ac407d49a3c33aa754bb4f05e45e57c24811b147e7bf3caf063a823", 65 Vout: 1, 66 Sequence: 0, 67 Addresses: []string{ 68 "Nse119z2oSDJYkFkxmwYDiYtPfBeNkqi", 69 }, 70 }, 71 }, 72 Vout: []bchain.Vout{ 73 { 74 ValueSat: *big.NewInt(400000000000), 75 N: 0, 76 JsonValue: json.Number("0"), 77 ScriptPubKey: bchain.ScriptPubKey{ 78 Hex: "Nse4ikjE88g2BgsNwsswTdkSwiSrKjjS", 79 Addresses: []string{ 80 "Nse4ikjE88g2BgsNwsswTdkSwiSrKjjS", 81 }, 82 }, 83 }, 84 { 85 ValueSat: *big.NewInt(7286565570000), 86 N: 1, 87 JsonValue: json.Number("0"), 88 ScriptPubKey: bchain.ScriptPubKey{ 89 Hex: "Nse119z2oSDJYkFkxmwYDiYtPfBeNkqi", 90 Addresses: []string{ 91 "Nse119z2oSDJYkFkxmwYDiYtPfBeNkqi", 92 }, 93 }, 94 }, 95 }, 96 //CoinSpecificData: []string{}, 97 } 98 } 99 100 func TestGetAddrDescFromAddress(t *testing.T) { 101 type args struct { 102 address string 103 } 104 tests := []struct { 105 name string 106 args args 107 want string 108 wantErr bool 109 }{ 110 { 111 name: "P2PKH", 112 args: args{address: "Nse4j39uEMuxx5j577h3K2MDLAQ64JZN"}, 113 want: "042301ac78cd3eb193287e2c59e4cbd765c5c47d432c2fa1", 114 wantErr: false, 115 }, 116 { 117 name: "P2PKH", 118 args: args{address: "Nse2e7U7nmGT8UHsvQ7JfksLtWwoLwrd"}, 119 want: "0423018a90e66a64318f6af6d673487a6560f5686fd26a2e", 120 wantErr: false, 121 }, 122 { 123 name: "P2PKH", 124 args: args{address: "NsdvMEP57nzxmBa5z18rx9sQsLgUfNtw"}, 125 want: "04230124422cfe426573e476fd45d7c2a43a75a0b6b8c478", 126 wantErr: false, 127 }, 128 } 129 parser := NewNulsParser(GetChainParams("main"), &btc.Configuration{}) 130 131 for _, tt := range tests { 132 t.Run(tt.name, func(t *testing.T) { 133 got, err := parser.GetAddrDescFromAddress(tt.args.address) 134 if (err != nil) != tt.wantErr { 135 t.Errorf("GetAddrDescFromAddress() error = %v, wantErr %v", err, tt.wantErr) 136 return 137 } 138 h := hex.EncodeToString(got) 139 if !reflect.DeepEqual(h, tt.want) { 140 t.Errorf("GetAddrDescFromAddress() = %v, want %v", h, tt.want) 141 } 142 }) 143 } 144 } 145 146 func TestGetAddrDescFromVout(t *testing.T) { 147 type args struct { 148 vout bchain.Vout 149 } 150 tests := []struct { 151 name string 152 args args 153 want string 154 wantErr bool 155 }{ 156 { 157 name: "P2PK", 158 args: args{vout: bchain.Vout{ScriptPubKey: bchain.ScriptPubKey{Hex: "Nse4j39uEMuxx5j577h3K2MDLAQ64JZN"}}}, 159 want: "042301ac78cd3eb193287e2c59e4cbd765c5c47d432c2fa1", 160 wantErr: false, 161 }, 162 { 163 name: "P2PK", 164 args: args{vout: bchain.Vout{ScriptPubKey: bchain.ScriptPubKey{Hex: "Nse2e7U7nmGT8UHsvQ7JfksLtWwoLwrd"}}}, 165 want: "0423018a90e66a64318f6af6d673487a6560f5686fd26a2e", 166 wantErr: false, 167 }, 168 { 169 name: "P2PK", 170 args: args{vout: bchain.Vout{ScriptPubKey: bchain.ScriptPubKey{Hex: "NsdvMEP57nzxmBa5z18rx9sQsLgUfNtw"}}}, 171 want: "04230124422cfe426573e476fd45d7c2a43a75a0b6b8c478", 172 wantErr: false, 173 }, 174 } 175 parser := NewNulsParser(GetChainParams("main"), &btc.Configuration{}) 176 177 for _, tt := range tests { 178 t.Run(tt.name, func(t *testing.T) { 179 got, err := parser.GetAddrDescFromVout(&tt.args.vout) 180 if (err != nil) != tt.wantErr { 181 t.Errorf("GetAddrDescFromVout() error = %v, wantErr %v", err, tt.wantErr) 182 return 183 } 184 h := hex.EncodeToString(got) 185 if !reflect.DeepEqual(h, tt.want) { 186 t.Errorf("GetAddrDescFromVout() = %v, want %v", h, tt.want) 187 } 188 }) 189 } 190 } 191 192 func TestGetAddressesFromAddrDesc(t *testing.T) { 193 type args struct { 194 script string 195 } 196 tests := []struct { 197 name string 198 args args 199 want []string 200 want2 bool 201 wantErr bool 202 }{ 203 { 204 name: "P2PKH", 205 args: args{script: "042301ac78cd3eb193287e2c59e4cbd765c5c47d432c2fa1"}, 206 want: []string{"Nse4j39uEMuxx5j577h3K2MDLAQ64JZN"}, 207 want2: true, 208 wantErr: false, 209 }, 210 { 211 name: "P2PKH", 212 args: args{script: "0423018a90e66a64318f6af6d673487a6560f5686fd26a2e"}, 213 want: []string{"Nse2e7U7nmGT8UHsvQ7JfksLtWwoLwrd"}, 214 want2: true, 215 wantErr: false, 216 }, 217 { 218 name: "P2PKH", 219 args: args{script: "04230124422cfe426573e476fd45d7c2a43a75a0b6b8c478"}, 220 want: []string{"NsdvMEP57nzxmBa5z18rx9sQsLgUfNtw"}, 221 want2: true, 222 wantErr: false, 223 }, 224 } 225 226 parser := NewNulsParser(GetChainParams("main"), &btc.Configuration{}) 227 228 for _, tt := range tests { 229 t.Run(tt.name, func(t *testing.T) { 230 b, _ := hex.DecodeString(tt.args.script) 231 got, got2, err := parser.GetAddressesFromAddrDesc(b) 232 if (err != nil) != tt.wantErr { 233 t.Errorf("GetAddressesFromAddrDesc() error = %v, wantErr %v", err, tt.wantErr) 234 return 235 } 236 if !reflect.DeepEqual(got, tt.want) { 237 t.Errorf("GetAddressesFromAddrDesc() = %v, want %v", got, tt.want) 238 } 239 if !reflect.DeepEqual(got2, tt.want2) { 240 t.Errorf("GetAddressesFromAddrDesc() = %v, want %v", got2, tt.want2) 241 } 242 }) 243 } 244 } 245 246 func TestPackTx(t *testing.T) { 247 type args struct { 248 tx bchain.Tx 249 height uint32 250 blockTime int64 251 parser *NulsParser 252 } 253 tests := []struct { 254 name string 255 args args 256 want string 257 wantErr bool 258 }{ 259 { 260 name: "test-1", 261 args: args{ 262 tx: testTx1, 263 height: 123456, 264 blockTime: 1552357844175, 265 parser: NewNulsParser(GetChainParams("main"), &btc.Configuration{}), 266 }, 267 want: testTxPacked1, 268 wantErr: false, 269 }, 270 { 271 name: "test-2", 272 args: args{ 273 tx: testTx2, 274 height: 510234, 275 blockTime: 1552357459555, 276 parser: NewNulsParser(GetChainParams("main"), &btc.Configuration{}), 277 }, 278 want: testTxPacked2, 279 wantErr: false, 280 }, 281 } 282 for _, tt := range tests { 283 t.Run(tt.name, func(t *testing.T) { 284 got, err := tt.args.parser.PackTx(&tt.args.tx, tt.args.height, tt.args.blockTime) 285 if (err != nil) != tt.wantErr { 286 t.Errorf("packTx() error = %v, wantErr %v", err, tt.wantErr) 287 return 288 } 289 h := hex.EncodeToString(got) 290 if !reflect.DeepEqual(h, tt.want) { 291 t.Errorf("packTx() = %v, want %v", h, tt.want) 292 } 293 }) 294 } 295 } 296 297 func TestUnpackTx(t *testing.T) { 298 type args struct { 299 packedTx string 300 parser *NulsParser 301 } 302 tests := []struct { 303 name string 304 args args 305 want *bchain.Tx 306 want1 uint32 307 wantErr bool 308 }{ 309 { 310 name: "test-1", 311 args: args{ 312 packedTx: testTxPacked1, 313 parser: NewNulsParser(GetChainParams("main"), &btc.Configuration{}), 314 }, 315 want: &testTx1, 316 want1: 123456, 317 wantErr: false, 318 }, 319 { 320 name: "test-2", 321 args: args{ 322 packedTx: testTxPacked2, 323 parser: NewNulsParser(GetChainParams("main"), &btc.Configuration{}), 324 }, 325 want: &testTx2, 326 want1: 510234, 327 wantErr: false, 328 }, 329 } 330 for _, tt := range tests { 331 t.Run(tt.name, func(t *testing.T) { 332 b, _ := hex.DecodeString(tt.args.packedTx) 333 got, got1, err := tt.args.parser.UnpackTx(b) 334 if (err != nil) != tt.wantErr { 335 t.Errorf("unpackTx() error = %v, wantErr %v", err, tt.wantErr) 336 return 337 } 338 if !reflect.DeepEqual(got, tt.want) { 339 t.Errorf("unpackTx() got = %+v, want %+v", got, tt.want) 340 } 341 if got1 != tt.want1 { 342 t.Errorf("unpackTx() got1 = %v, want %v", got1, tt.want1) 343 } 344 }) 345 } 346 } 347 348 func TestDeriveAddressDescriptorsFromTo(t *testing.T) { 349 350 parser := NewNulsParser(GetChainParams("main"), &btc.Configuration{}) 351 352 // test xpub xprv math ,and get private key 353 xprv := "xprv9yEvwSfPanK5gLYVnYvNyF2CEWJx1RsktQtKDeT6jnCnqASBiPCvFYHFSApXv39bZbF6hRaha1kWQBVhN1xjo7NHuhAn5uUfzy79TBuGiHh" 354 xpub := "xpub6CEHLxCHR9sNtpcxtaTPLNxvnY9SQtbcFdov22riJ7jmhxmLFvXAoLbjHSzwXwNNuxC1jUP6tsHzFV9rhW9YKELfmR9pJaKFaM8C3zMPgjw" 355 extKey, err := hdkeychain.NewKeyFromString(xprv, parser.Params.Base58CksumHasher) 356 if err != nil { 357 t.Errorf("DeriveAddressDescriptorsFromTo() error = %v", err) 358 return 359 } 360 changeExtKey, err := extKey.Child(0) 361 if err != nil { 362 t.Errorf("DeriveAddressDescriptorsFromTo() error = %v", err) 363 return 364 } 365 366 key1, _ := changeExtKey.Child(0) 367 priKey1, _ := key1.ECPrivKey() 368 wantPriKey1 := "0x995c98115809359eb57a5e179558faddd55ef88f88e5cf58617a5f9f3d6bb3a1" 369 if !reflect.DeepEqual(hexutil.MustDecode(wantPriKey1), priKey1.Serialize()) { 370 t.Errorf("DeriveAddressDescriptorsFromTo() %v, want %v", wantPriKey1, hexutil.Encode(priKey1.Serialize())) 371 return 372 } 373 pubKey1, _ := key1.ECPubKey() 374 wantPubKey1 := "0x028855d37e8b1d2760289ea51996df05f3297d86fae4e113aea696a0f02a420ae2" 375 if !reflect.DeepEqual(hexutil.MustDecode(wantPubKey1), pubKey1.SerializeCompressed()) { 376 t.Errorf("DeriveAddressDescriptorsFromTo() %v, want %v", wantPubKey1, hexutil.Encode(pubKey1.SerializeCompressed())) 377 return 378 } 379 380 key2, _ := changeExtKey.Child(1) 381 priKey2, _ := key2.ECPrivKey() 382 wantPriKey2 := "0x0f65dee42d3c974c1a4bcc79f141be89715dc8d6406faa9ad4f1f55ca95fabc8" 383 if !reflect.DeepEqual(hexutil.MustDecode(wantPriKey2), priKey2.Serialize()) { 384 t.Errorf("DeriveAddressDescriptorsFromTo() %v, want %v", wantPriKey2, hexutil.Encode(priKey2.Serialize())) 385 return 386 } 387 pubKey2, _ := key2.ECPubKey() 388 wantPubKey2 := "0x0216f460ea59194464a6c981560e3f52899203496ed8a20f8f9a57a9225d841293" 389 if !reflect.DeepEqual(hexutil.MustDecode(wantPubKey2), pubKey2.SerializeCompressed()) { 390 t.Errorf("DeriveAddressDescriptorsFromTo() %v, want %v", wantPubKey2, hexutil.Encode(pubKey2.SerializeCompressed())) 391 return 392 } 393 394 key3, _ := changeExtKey.Child(2) 395 priKey3, _ := key3.ECPrivKey() 396 wantPriKey3 := "0x6fd98d1d9c3f3ac1ff61bbf3f20e89f00ffa8d43a554f2a7d73fd464b6666f45" 397 if !reflect.DeepEqual(hexutil.MustDecode(wantPriKey3), priKey3.Serialize()) { 398 t.Errorf("DeriveAddressDescriptorsFromTo() %v, want %v", wantPriKey3, hexutil.Encode(priKey3.Serialize())) 399 return 400 } 401 pubKey3, _ := key3.ECPubKey() 402 wantPubKey3 := "0x0327ef15c2eaf99365610d6ef89d9ad1e89d1ddf888fc0ec7eb8a94d97153ee482" 403 if !reflect.DeepEqual(hexutil.MustDecode(wantPubKey3), pubKey3.SerializeCompressed()) { 404 t.Errorf("DeriveAddressDescriptorsFromTo() %v, want %v", wantPubKey3, hexutil.Encode(pubKey3.SerializeCompressed())) 405 return 406 } 407 408 key4, _ := changeExtKey.Child(3) 409 priKey4, _ := key4.ECPrivKey() 410 wantPriKey4 := "0x21412d9e33aba493faf4bc7d408ed5290bea5b36a7beec554b858051f8d4bff3" 411 if !reflect.DeepEqual(hexutil.MustDecode(wantPriKey4), priKey4.Serialize()) { 412 t.Errorf("DeriveAddressDescriptorsFromTo() %v, want %v", wantPriKey4, hexutil.Encode(priKey4.Serialize())) 413 return 414 } 415 pubKey4, _ := key4.ECPubKey() 416 wantPubKey4 := "0x02a73aebd08c6f70fa97f616b1c0b63756efe9eb070a14628de3d850b2b970a9a7" 417 if !reflect.DeepEqual(hexutil.MustDecode(wantPubKey4), pubKey4.SerializeCompressed()) { 418 t.Errorf("DeriveAddressDescriptorsFromTo() %v, want %v", wantPubKey4, hexutil.Encode(pubKey4.SerializeCompressed())) 419 return 420 } 421 422 key5, _ := changeExtKey.Child(4) 423 priKey5, _ := key5.ECPrivKey() 424 wantPriKey5 := "0xdc3d290e32a4e0f38bc26c25a78ceb1c8779110883d9cb0be54629043c1f8724" 425 if !reflect.DeepEqual(hexutil.MustDecode(wantPriKey5), priKey5.Serialize()) { 426 t.Errorf("DeriveAddressDescriptorsFromTo() %v, want %v", wantPriKey5, hexutil.Encode(priKey5.Serialize())) 427 return 428 } 429 pubKey5, _ := key5.ECPubKey() 430 wantPubKey5 := "0x02f87eb70b985a857d7238bc9423dab7d5930f3fcfc2118ccac0634a9342b9d324" 431 if !reflect.DeepEqual(hexutil.MustDecode(wantPubKey5), pubKey5.SerializeCompressed()) { 432 t.Errorf("DeriveAddressDescriptorsFromTo() %v, want %v", wantPubKey5, hexutil.Encode(pubKey5.SerializeCompressed())) 433 return 434 } 435 436 type args struct { 437 xpub string 438 change uint32 439 fromIndex uint32 440 toIndex uint32 441 } 442 tests := []struct { 443 name string 444 args args 445 want []string 446 wantErr bool 447 }{ 448 { 449 name: "test-xpub", 450 args: args{ 451 xpub: xpub, 452 change: 0, 453 fromIndex: 0, 454 toIndex: 5, 455 }, 456 want: []string{ 457 "NsdtwhD8hb8H72J7FyQpGta2sqLngrXZ", 458 "Nse51sBAzRTVtm48wYQLb4TH7MGAHAER", 459 "NsdvoFSwfh1oW238SFM6p5wL4J834Gv2", 460 "Nse4wVWsJ4v3jPcpE4vRkAiZLFyQSNKd", 461 "Nse5NzUcZybsvFQeNgqfuWmmmwCfhdxF", 462 }, 463 wantErr: false, 464 }, 465 { 466 name: "test-xprv", 467 args: args{ 468 xpub: xprv, 469 change: 0, 470 fromIndex: 0, 471 toIndex: 5, 472 }, 473 want: []string{ 474 "NsdtwhD8hb8H72J7FyQpGta2sqLngrXZ", 475 "Nse51sBAzRTVtm48wYQLb4TH7MGAHAER", 476 "NsdvoFSwfh1oW238SFM6p5wL4J834Gv2", 477 "Nse4wVWsJ4v3jPcpE4vRkAiZLFyQSNKd", 478 "Nse5NzUcZybsvFQeNgqfuWmmmwCfhdxF", 479 }, 480 wantErr: false, 481 }, 482 } 483 484 for _, tt := range tests { 485 t.Run(tt.name, func(t *testing.T) { 486 got, err := parser.DeriveAddressDescriptorsFromTo(tt.args.xpub, tt.args.change, tt.args.fromIndex, tt.args.toIndex) 487 if (err != nil) != tt.wantErr { 488 t.Errorf("DeriveAddressDescriptorsFromTo() error = %v, wantErr %v", err, tt.wantErr) 489 return 490 } 491 if len(got) != len(tt.want) { 492 t.Errorf("DeriveAddressDescriptorsFromTo() result count = %v, want %v", len(got), len(tt.want)) 493 return 494 } 495 496 for i, add := range tt.want { 497 addStrs, ok, error := parser.GetAddressesFromAddrDesc(got[i]) 498 if !ok || error != nil { 499 t.Errorf("DeriveAddressDescriptorsFromTo() fail %v - %v , %v", i, ok, error) 500 return 501 } 502 if len(addStrs) != 1 { 503 t.Errorf("DeriveAddressDescriptorsFromTo() len(adds) != 1, %v", addStrs) 504 return 505 } 506 if !reflect.DeepEqual(addStrs[0], add) { 507 t.Errorf("DeriveAddressDescriptorsFromTo() of index %v = %v, want %v", i, addStrs, add) 508 return 509 } 510 } 511 }) 512 } 513 514 }