package chain import ( "crypto/ecdsa" "encoding/hex" "testing" crypto "github.com/nspcc-dev/neofs-crypto" "github.com/nspcc-dev/neofs-crypto/test" "github.com/stretchr/testify/require" ) func TestAddress(t *testing.T) { var ( multiSigVerificationScript = "512103c02a93134f98d9c78ec54b1b1f97fc64cd81360f53a293f41e4ad54aac3c57172103fea219d4ccfd7641cebbb2439740bb4bd7c4730c1abd6ca1dc44386533816df952ae" multiSigAddress = "ANbvKqa2SfgTUkq43NRUhCiyxPrpUPn7S3" normalVerificationScript = "2102a33413277a319cc6fd4c54a2feb9032eba668ec587f307e319dc48733087fa61ac" normalAddress = "AcraNnCuPKnUYtPYyrACRCVJhLpvskbfhu" ) t.Run("check multi-sig address", func(t *testing.T) { data, err := hex.DecodeString(multiSigVerificationScript) require.NoError(t, err) require.Equal(t, multiSigAddress, Address(data)) }) t.Run("check normal address", func(t *testing.T) { data, err := hex.DecodeString(normalVerificationScript) require.NoError(t, err) require.Equal(t, normalAddress, Address(data)) }) } func TestVerificationScript(t *testing.T) { t.Run("check normal", func(t *testing.T) { pkString := "02a33413277a319cc6fd4c54a2feb9032eba668ec587f307e319dc48733087fa61" pkBytes, err := hex.DecodeString(pkString) require.NoError(t, err) pk := crypto.UnmarshalPublicKey(pkBytes) expect, err := hex.DecodeString( "21" + pkString + // PUSHBYTES33 "ac", // CHECKSIG ) require.Equal(t, expect, VerificationScript(pk)) }) t.Run("check multisig", func(t *testing.T) { pk1String := "03c02a93134f98d9c78ec54b1b1f97fc64cd81360f53a293f41e4ad54aac3c5717" pk2String := "03fea219d4ccfd7641cebbb2439740bb4bd7c4730c1abd6ca1dc44386533816df9" pk1Bytes, err := hex.DecodeString(pk1String) require.NoError(t, err) pk1 := crypto.UnmarshalPublicKey(pk1Bytes) pk2Bytes, err := hex.DecodeString(pk2String) require.NoError(t, err) pk2 := crypto.UnmarshalPublicKey(pk2Bytes) expect, err := hex.DecodeString( "51" + // one address "21" + pk1String + // PUSHBYTES33 "21" + pk2String + // PUSHBYTES33 "52" + // 2 PublicKeys "ae", // CHECKMULTISIG ) require.Equal(t, expect, VerificationScript(pk1, pk2)) }) } func TestKeysToAddress(t *testing.T) { t.Run("check normal", func(t *testing.T) { pkString := "02a33413277a319cc6fd4c54a2feb9032eba668ec587f307e319dc48733087fa61" pkBytes, err := hex.DecodeString(pkString) require.NoError(t, err) pk := crypto.UnmarshalPublicKey(pkBytes) expect := "AcraNnCuPKnUYtPYyrACRCVJhLpvskbfhu" actual := KeysToAddress(pk) require.Equal(t, expect, actual) require.NoError(t, IsAddress(actual)) }) t.Run("check multisig", func(t *testing.T) { pk1String := "03c02a93134f98d9c78ec54b1b1f97fc64cd81360f53a293f41e4ad54aac3c5717" pk2String := "03fea219d4ccfd7641cebbb2439740bb4bd7c4730c1abd6ca1dc44386533816df9" pk1Bytes, err := hex.DecodeString(pk1String) require.NoError(t, err) pk1 := crypto.UnmarshalPublicKey(pk1Bytes) pk2Bytes, err := hex.DecodeString(pk2String) require.NoError(t, err) pk2 := crypto.UnmarshalPublicKey(pk2Bytes) expect := "ANbvKqa2SfgTUkq43NRUhCiyxPrpUPn7S3" actual := KeysToAddress(pk1, pk2) require.Equal(t, expect, actual) require.NoError(t, IsAddress(actual)) }) } func TestFetchPublicKeys(t *testing.T) { var ( multiSigVerificationScript = "512103c02a93134f98d9c78ec54b1b1f97fc64cd81360f53a293f41e4ad54aac3c57172103fea219d4ccfd7641cebbb2439740bb4bd7c4730c1abd6ca1dc44386533816df952ae" normalVerificationScript = "2102a33413277a319cc6fd4c54a2feb9032eba668ec587f307e319dc48733087fa61ac" pk1String = "03c02a93134f98d9c78ec54b1b1f97fc64cd81360f53a293f41e4ad54aac3c5717" pk2String = "03fea219d4ccfd7641cebbb2439740bb4bd7c4730c1abd6ca1dc44386533816df9" pk3String = "02a33413277a319cc6fd4c54a2feb9032eba668ec587f307e319dc48733087fa61" ) t.Run("shouls not fail", func(t *testing.T) { wrongVS, err := hex.DecodeString(multiSigVerificationScript) require.NoError(t, err) wrongVS[len(wrongVS)-1] = 0x1 wrongPK, err := hex.DecodeString(multiSigVerificationScript) require.NoError(t, err) wrongPK[2] = 0x1 var testCases = []struct { name string value []byte }{ {name: "empty VerificationScript"}, { name: "wrong size VerificationScript", value: []byte{0x1}, }, { name: "wrong VerificationScript type", value: wrongVS, }, { name: "wrong public key in VerificationScript", value: wrongPK, }, } for i := range testCases { tt := testCases[i] t.Run(tt.name, func(t *testing.T) { var keys []*ecdsa.PublicKey require.NotPanics(t, func() { keys = FetchPublicKeys(tt.value) }) require.Nil(t, keys) }) } }) t.Run("check multi-sig address", func(t *testing.T) { data, err := hex.DecodeString(multiSigVerificationScript) require.NoError(t, err) pk1Bytes, err := hex.DecodeString(pk1String) require.NoError(t, err) pk2Bytes, err := hex.DecodeString(pk2String) require.NoError(t, err) pk1 := crypto.UnmarshalPublicKey(pk1Bytes) pk2 := crypto.UnmarshalPublicKey(pk2Bytes) keys := FetchPublicKeys(data) require.Len(t, keys, 2) require.Equal(t, keys[0], pk1) require.Equal(t, keys[1], pk2) }) t.Run("check normal address", func(t *testing.T) { data, err := hex.DecodeString(normalVerificationScript) require.NoError(t, err) pkBytes, err := hex.DecodeString(pk3String) require.NoError(t, err) pk := crypto.UnmarshalPublicKey(pkBytes) keys := FetchPublicKeys(data) require.Len(t, keys, 1) require.Equal(t, keys[0], pk) }) t.Run("generate 10 keys VerificationScript and try parse it", func(t *testing.T) { var ( count = 10 expect = make([]*ecdsa.PublicKey, 0, count) ) for i := 0; i < count; i++ { key := test.DecodeKey(i) expect = append(expect, &key.PublicKey) } vs := VerificationScript(expect...) actual := FetchPublicKeys(vs) require.Equal(t, expect, actual) }) } func TestReversedScriptHashToAddress(t *testing.T) { var testCases = []struct { name string value string expect string }{ { name: "first", expect: "APfiG5imQgn8dzTTfaDfqHnxo3QDUkF69A", value: "5696acd07f0927fd5f01946828638c9e2c90c5dc", }, { name: "second", expect: "AK2nJJpJr6o664CWJKi1QRXjqeic2zRp8y", value: "23ba2703c53263e8d6e522dc32203339dcd8eee9", }, } for i := range testCases { tt := testCases[i] t.Run(tt.name, func(t *testing.T) { actual, err := ReversedScriptHashToAddress(tt.value) require.NoError(t, err) require.Equal(t, tt.expect, actual) require.NoError(t, IsAddress(actual)) }) } } func TestReverseBytes(t *testing.T) { var testCases = []struct { name string value []byte expect []byte }{ {name: "empty"}, { name: "single byte", expect: []byte{0x1}, value: []byte{0x1}, }, { name: "two bytes", expect: []byte{0x2, 0x1}, value: []byte{0x1, 0x2}, }, { name: "three bytes", expect: []byte{0x3, 0x2, 0x1}, value: []byte{0x1, 0x2, 0x3}, }, { name: "five bytes", expect: []byte{0x5, 0x4, 0x3, 0x2, 0x1}, value: []byte{0x1, 0x2, 0x3, 0x4, 0x5}, }, { name: "eight bytes", expect: []byte{0x8, 0x7, 0x6, 0x5, 0x4, 0x3, 0x2, 0x1}, value: []byte{0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8}, }, } for i := range testCases { tt := testCases[i] t.Run(tt.name, func(t *testing.T) { actual := ReverseBytes(tt.value) require.Equal(t, tt.expect, actual) }) } }