This modifies DecodeAddressV0 to reject any attempts to decode strings that are larger than the max possible size early since there is no reason to waste time and memory doing the base 58 decode when it is guaranteed to be invalid anyway. It also adds an associated test to ensure proper functionality.
1420 lines
55 KiB
Go
1420 lines
55 KiB
Go
// Copyright (c) 2021 The Decred developers
|
|
// Use of this source code is governed by an ISC
|
|
// license that can be found in the LICENSE file.
|
|
|
|
package stdaddr
|
|
|
|
import (
|
|
"bytes"
|
|
"encoding/hex"
|
|
"errors"
|
|
"testing"
|
|
|
|
"github.com/decred/base58"
|
|
"github.com/decred/dcrd/crypto/ripemd160"
|
|
"github.com/decred/dcrd/dcrec/edwards/v2"
|
|
"github.com/decred/dcrd/dcrec/secp256k1/v4"
|
|
)
|
|
|
|
// mockAddrParams implements the AddressParams interface and is used throughout
|
|
// the tests to mock multiple networks.
|
|
type mockAddrParams struct {
|
|
pubKeyID [2]byte
|
|
pkhEcdsaID [2]byte
|
|
pkhEd25519ID [2]byte
|
|
pkhSchnorrID [2]byte
|
|
scriptHashID [2]byte
|
|
privKeyID [2]byte
|
|
}
|
|
|
|
// AddrIDPubKeyV0 returns the magic prefix bytes associated with the mock params
|
|
// for version 0 pay-to-pubkey addresses.
|
|
//
|
|
// This is part of the AddressParams interface.
|
|
func (p *mockAddrParams) AddrIDPubKeyV0() [2]byte {
|
|
return p.pubKeyID
|
|
}
|
|
|
|
// AddrIDPubKeyHashECDSAV0 returns the magic prefix bytes associated with the
|
|
// mock params for version 0 pay-to-pubkey-hash addresses where the underlying
|
|
// pubkey is secp256k1 and the signature algorithm is ECDSA.
|
|
//
|
|
// This is part of the AddressParams interface.
|
|
func (p *mockAddrParams) AddrIDPubKeyHashECDSAV0() [2]byte {
|
|
return p.pkhEcdsaID
|
|
}
|
|
|
|
// AddrIDPubKeyHashEd25519V0 returns the magic prefix bytes associated with the
|
|
// mock params for version 0 pay-to-pubkey-hash addresses where the underlying
|
|
// pubkey and signature algorithm are Ed25519.
|
|
//
|
|
// This is part of the AddressParams interface.
|
|
func (p *mockAddrParams) AddrIDPubKeyHashEd25519V0() [2]byte {
|
|
return p.pkhEd25519ID
|
|
}
|
|
|
|
// AddrIDPubKeyHashSchnorrV0 returns the magic prefix bytes associated with the
|
|
// mock params for version 0 pay-to-pubkey-hash addresses where the underlying
|
|
// pubkey is secp256k1 and the signature algorithm is Schnorr.
|
|
//
|
|
// This is part of the AddressParams interface.
|
|
func (p *mockAddrParams) AddrIDPubKeyHashSchnorrV0() [2]byte {
|
|
return p.pkhSchnorrID
|
|
}
|
|
|
|
// AddrIDScriptHashV0 returns the magic prefix bytes associated with the mock
|
|
// params for version 0 pay-to-script-hash addresses.
|
|
//
|
|
// This is part of the AddressParams interface.
|
|
func (p *mockAddrParams) AddrIDScriptHashV0() [2]byte {
|
|
return p.scriptHashID
|
|
}
|
|
|
|
// mockMainNetParams returns mock mainnet address parameters to use throughout
|
|
// the tests. They match the Decred mainnet params as of the time this comment
|
|
// was written.
|
|
func mockMainNetParams() *mockAddrParams {
|
|
return &mockAddrParams{
|
|
pubKeyID: [2]byte{0x13, 0x86}, // starts with Dk
|
|
pkhEcdsaID: [2]byte{0x07, 0x3f}, // starts with Ds
|
|
pkhEd25519ID: [2]byte{0x07, 0x1f}, // starts with De
|
|
pkhSchnorrID: [2]byte{0x07, 0x01}, // starts with DS
|
|
scriptHashID: [2]byte{0x07, 0x1a}, // starts with Dc
|
|
privKeyID: [2]byte{0x22, 0xde}, // starts with Pm
|
|
}
|
|
}
|
|
|
|
// mockTestNetParams returns mock testnet address parameters to use throughout
|
|
// the tests. They match the Decred testnet params as of the time this comment
|
|
// was written.
|
|
func mockTestNetParams() *mockAddrParams {
|
|
return &mockAddrParams{
|
|
pubKeyID: [2]byte{0x28, 0xf7}, // starts with Tk
|
|
pkhEcdsaID: [2]byte{0x0f, 0x21}, // starts with Ts
|
|
pkhEd25519ID: [2]byte{0x0f, 0x01}, // starts with Te
|
|
pkhSchnorrID: [2]byte{0x0e, 0xe3}, // starts with TS
|
|
scriptHashID: [2]byte{0x0e, 0xfc}, // starts with Tc
|
|
privKeyID: [2]byte{0x23, 0x0e}, // starts with Pt
|
|
}
|
|
}
|
|
|
|
// mockRegNetParams returns mock regression test address parameters to use
|
|
// throughout the tests. They match the Decred regnet params as of the time
|
|
// this comment was written.
|
|
func mockRegNetParams() *mockAddrParams {
|
|
return &mockAddrParams{
|
|
pubKeyID: [2]byte{0x25, 0xe5}, // starts with Rk
|
|
pkhEcdsaID: [2]byte{0x0e, 0x00}, // starts with Rs
|
|
pkhEd25519ID: [2]byte{0x0d, 0xe0}, // starts with Re
|
|
pkhSchnorrID: [2]byte{0x0d, 0xc2}, // starts with RS
|
|
scriptHashID: [2]byte{0x0d, 0xdb}, // starts with Rc
|
|
privKeyID: [2]byte{0x22, 0xfe}, // starts with Pr
|
|
}
|
|
}
|
|
|
|
// hexToBytes converts the passed hex string into bytes and will panic if there
|
|
// is an error. This is only provided for the hard-coded constants so errors in
|
|
// the source code can be detected. It will only (and must only) be called with
|
|
// hard-coded values.
|
|
func hexToBytes(s string) []byte {
|
|
b, err := hex.DecodeString(s)
|
|
if err != nil {
|
|
panic("invalid hex in source file: " + s)
|
|
}
|
|
return b
|
|
}
|
|
|
|
// TestAddresses ensures that address-related APIs work as intended including
|
|
// that they are properly encoded and decoded, that they produce the expected
|
|
// payment-related scripts, and that error paths fail as expected. For
|
|
// addresses that implement the stake address interface, the stake-related
|
|
// scripts are also tested.
|
|
func TestAddresses(t *testing.T) {
|
|
mainNetParams := mockMainNetParams()
|
|
testNetParams := mockTestNetParams()
|
|
regNetParams := mockRegNetParams()
|
|
|
|
type newAddrFn func() (Address, error)
|
|
tests := []struct {
|
|
name string // test description
|
|
makeAddr newAddrFn // function to construct new address via API
|
|
makeErr error // expected error from new address function
|
|
addr string // expected address and address to decode
|
|
net AddressParams // params for network
|
|
decodeErr error // expected error from decode
|
|
version uint16 // expected scripts version
|
|
payScript string // hex-encoded expected payment script
|
|
voteScript string // hex-encoded expected voting rights script
|
|
rewardAmount int64 // reward commitment amount
|
|
voteFeeLimit int64 // reward commitment vote fee limit
|
|
revFeeLimit int64 // reward commitment revoke fee limit
|
|
rewardScript string // hex-encoded expected reward commitment script
|
|
changeScript string // hex-encoded expected stake change script
|
|
commitScript string // hex-encoded expected vote commitment script
|
|
revokeScript string // hex-encoded expected revoke commitment script
|
|
trsyScript string // hex-encoded expected pay from treasury script
|
|
pubKey string // hex-encoded expected public key
|
|
}{{
|
|
// ---------------------------------------------------------------------
|
|
// Misc decoding error tests.
|
|
// ---------------------------------------------------------------------
|
|
|
|
name: "bad checksum",
|
|
addr: "TsmWaPM77WSyA3aiQ2Q1KnwGDVWvEkhip23",
|
|
net: testNetParams,
|
|
decodeErr: ErrBadAddressChecksum,
|
|
}, {
|
|
name: "parse valid mainnet address with testnet rejected",
|
|
addr: "DsUZxxoHJSty8DCfwfartwTYbuhmVct7tJu",
|
|
net: testNetParams,
|
|
decodeErr: ErrUnsupportedAddress,
|
|
}, {
|
|
name: "mainnet p2pk with no data for pubkey",
|
|
addr: "Aiz5jz1s",
|
|
net: mainNetParams,
|
|
decodeErr: ErrUnsupportedAddress,
|
|
}, {
|
|
name: "invalid base58 (l not in base58 alphabet)",
|
|
addr: "DsUZxxoHlSty8DCfwfartwTYbuhmVct7tJu",
|
|
net: mainNetParams,
|
|
decodeErr: ErrUnsupportedAddress,
|
|
}, {
|
|
// ---------------------------------------------------------------------
|
|
// Negative P2PK ECDSA secp256k1 tests.
|
|
// ---------------------------------------------------------------------
|
|
|
|
name: "mainnet p2pk-ecdsa-secp256k1 uncompressed (0x04) rejected via constructor",
|
|
makeAddr: func() (Address, error) {
|
|
pkHex := "0464c44653d6567eff5753c5d24a682ddc2b2cadfe1b0c6433b163" +
|
|
"74dace6778f0b87ca4279b565d2130ce59f75bfbb2b88da794143d7cfd3" +
|
|
"e80808a1fa3203904"
|
|
pk := hexToBytes(pkHex)
|
|
return NewAddressPubKeyEcdsaSecp256k1Raw(0, pk, mainNetParams)
|
|
},
|
|
makeErr: ErrInvalidPubKeyFormat,
|
|
}, {
|
|
name: "mainnet p2pk-ecdsa-secp256k1 uncompressed (0x04) rejected via decode",
|
|
addr: "HiQeNVx8PNYP8ysyunUoicyNdfRUrEu1kzPE6v5gECBHBYgDzXCg8BsDGjmaHCpV97ytaQGHz5XDMJgJVHjv9YeSXWkHfwmBJj",
|
|
net: mainNetParams,
|
|
decodeErr: ErrUnsupportedAddress,
|
|
}, {
|
|
name: "mainnet p2pk-ecdsa-secp256k1 hybrid (0x06) rejected via constructor",
|
|
makeAddr: func() (Address, error) {
|
|
pkHex := "0664c44653d6567eff5753c5d24a682ddc2b2cadfe1b0c6433b163" +
|
|
"74dace6778f0b87ca4279b565d2130ce59f75bfbb2b88da794143d7cfd3" +
|
|
"e80808a1fa3203904"
|
|
pk := hexToBytes(pkHex)
|
|
return NewAddressPubKeyEcdsaSecp256k1Raw(0, pk, mainNetParams)
|
|
},
|
|
makeErr: ErrInvalidPubKeyFormat,
|
|
}, {
|
|
name: "mainnet p2pk-ecdsa-secp256k1 hybrid (0x07) rejected via constructor",
|
|
makeAddr: func() (Address, error) {
|
|
pkHex := "07348d8aeb4253ca52456fe5da94ab1263bfee16bb8192497f6663" +
|
|
"89ca964f84798375129d7958843b14258b905dc94faed324dd8a9d67ffa" +
|
|
"c8cc0a85be84bac5d"
|
|
pk := hexToBytes(pkHex)
|
|
return NewAddressPubKeyEcdsaSecp256k1Raw(0, pk, mainNetParams)
|
|
},
|
|
makeErr: ErrInvalidPubKeyFormat,
|
|
}, {
|
|
name: "p2pk-ecdsa-secp256k1 unsupported script version",
|
|
makeAddr: func() (Address, error) {
|
|
pkHex := "028f53838b7639563f27c94845549a41e5146bcd52e7fef0ea6da143a02b0fe2ed"
|
|
pk := hexToBytes(pkHex)
|
|
return NewAddressPubKeyEcdsaSecp256k1Raw(9999, pk, mainNetParams)
|
|
},
|
|
makeErr: ErrUnsupportedScriptVersion,
|
|
}, {
|
|
name: "p2pk-ecdsa-secp256k1 unsupported script version via concrete constructor",
|
|
makeAddr: func() (Address, error) {
|
|
pkHex := "028f53838b7639563f27c94845549a41e5146bcd52e7fef0ea6da143a02b0fe2ed"
|
|
pk, err := secp256k1.ParsePubKey(hexToBytes(pkHex))
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return NewAddressPubKeyEcdsaSecp256k1(9999, pk, mainNetParams)
|
|
},
|
|
makeErr: ErrUnsupportedScriptVersion,
|
|
}, {
|
|
name: "p2pk-ecdsa-secp256k1 malformed pubkey",
|
|
makeAddr: func() (Address, error) {
|
|
pkHex := "028f53838b7639563f27c94845549a41e5146bcd52e7fef0ea6da143a02b0fe2"
|
|
pk := hexToBytes(pkHex)
|
|
return NewAddressPubKeyEcdsaSecp256k1Raw(0, pk, mainNetParams)
|
|
},
|
|
makeErr: ErrInvalidPubKey,
|
|
}, {
|
|
name: "p2pk-ecdsa-secp256k1 malformed pubkey via decode",
|
|
addr: "3tWTcxjUnAKTzHh8pHPYpSsUKVbTvziNGHtbBFQkY12khQWuW83p",
|
|
net: mainNetParams,
|
|
decodeErr: ErrUnsupportedAddress,
|
|
}, {
|
|
// ---------------------------------------------------------------------
|
|
// Positive P2PK ECDSA secp256k1 tests.
|
|
// ---------------------------------------------------------------------
|
|
|
|
name: "mainnet p2pk-ecdsa-secp256k1 compressed (0x02)",
|
|
makeAddr: func() (Address, error) {
|
|
pkHex := "028f53838b7639563f27c94845549a41e5146bcd52e7fef0ea6da143a02b0fe2ed"
|
|
pk := hexToBytes(pkHex)
|
|
return NewAddressPubKeyEcdsaSecp256k1Raw(0, pk, mainNetParams)
|
|
},
|
|
makeErr: nil,
|
|
addr: "DkM3ZigNyiwHrsXRjkDQ8t8tW6uKGW9g61qEkG3bMqQPQWYEf5X3J",
|
|
net: mainNetParams,
|
|
decodeErr: nil,
|
|
version: 0,
|
|
payScript: "21028f53838b7639563f27c94845549a41e5146bcd52e7fef0ea6da143a02b0fe2edac",
|
|
pubKey: "028f53838b7639563f27c94845549a41e5146bcd52e7fef0ea6da143a02b0fe2ed",
|
|
}, {
|
|
name: "mainnet p2pk-ecdsa-secp256k1 compressed (0x03)",
|
|
makeAddr: func() (Address, error) {
|
|
pkHex := "03e925aafc1edd44e7c7f1ea4fb7d265dc672f204c3d0c81930389c10b81fb75de"
|
|
pk := hexToBytes(pkHex)
|
|
return NewAddressPubKeyEcdsaSecp256k1Raw(0, pk, mainNetParams)
|
|
},
|
|
makeErr: nil,
|
|
addr: "DkRM4ZcdejbYRu4AbcEdfDLzU9w1ZTqPXatXvL1g8Q77ibDjz7gwF",
|
|
net: mainNetParams,
|
|
decodeErr: nil,
|
|
version: 0,
|
|
payScript: "2103e925aafc1edd44e7c7f1ea4fb7d265dc672f204c3d0c81930389c10b81fb75deac",
|
|
pubKey: "03e925aafc1edd44e7c7f1ea4fb7d265dc672f204c3d0c81930389c10b81fb75de",
|
|
}, {
|
|
name: "mainnet p2pk-ecdsa-secp256k1 compressed via concrete constructor",
|
|
makeAddr: func() (Address, error) {
|
|
pkHex := "028f53838b7639563f27c94845549a41e5146bcd52e7fef0ea6da143a02b0fe2ed"
|
|
pk, err := secp256k1.ParsePubKey(hexToBytes(pkHex))
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return NewAddressPubKeyEcdsaSecp256k1(0, pk, mainNetParams)
|
|
},
|
|
makeErr: nil,
|
|
addr: "DkM3ZigNyiwHrsXRjkDQ8t8tW6uKGW9g61qEkG3bMqQPQWYEf5X3J",
|
|
net: mainNetParams,
|
|
decodeErr: nil,
|
|
version: 0,
|
|
payScript: "21028f53838b7639563f27c94845549a41e5146bcd52e7fef0ea6da143a02b0fe2edac",
|
|
pubKey: "028f53838b7639563f27c94845549a41e5146bcd52e7fef0ea6da143a02b0fe2ed",
|
|
}, {
|
|
name: "mainnet p2pk-ecdsa-secp256k1 compressed from uncompressed via concrete constructor",
|
|
makeAddr: func() (Address, error) {
|
|
pkHex := "0464c44653d6567eff5753c5d24a682ddc2b2cadfe1b0c6433b163" +
|
|
"74dace6778f0b87ca4279b565d2130ce59f75bfbb2b88da794143d7cfd3" +
|
|
"e80808a1fa3203904"
|
|
pk, err := secp256k1.ParsePubKey(hexToBytes(pkHex))
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return NewAddressPubKeyEcdsaSecp256k1(0, pk, mainNetParams)
|
|
},
|
|
makeErr: nil,
|
|
addr: "DkM3EyZ546GghVSkvzb6J47PvGDyntqiDtFgipQhNj78Xm2mUYRpf",
|
|
net: mainNetParams,
|
|
decodeErr: nil,
|
|
version: 0,
|
|
payScript: "210264c44653d6567eff5753c5d24a682ddc2b2cadfe1b0c6433b16374dace6778f0ac",
|
|
pubKey: "0264c44653d6567eff5753c5d24a682ddc2b2cadfe1b0c6433b16374dace6778f0",
|
|
}, {
|
|
name: "testnet p2pk-ecdsa-secp256k1 compressed (0x02)",
|
|
makeAddr: func() (Address, error) {
|
|
pkHex := "026a40c403e74670c4de7656a09caa2353d4b383a9ce66eef51e1220eacf4be06e"
|
|
pk := hexToBytes(pkHex)
|
|
return NewAddressPubKeyEcdsaSecp256k1Raw(0, pk, testNetParams)
|
|
},
|
|
makeErr: nil,
|
|
addr: "TkKmMiY5iDh4U3KkSopYgkU1AzhAcQZiSoVhYhFymZHGMi9LM9Fdt",
|
|
net: testNetParams,
|
|
decodeErr: nil,
|
|
version: 0,
|
|
payScript: "21026a40c403e74670c4de7656a09caa2353d4b383a9ce66eef51e1220eacf4be06eac",
|
|
pubKey: "026a40c403e74670c4de7656a09caa2353d4b383a9ce66eef51e1220eacf4be06e",
|
|
}, {
|
|
name: "testnet p2pk-ecdsa-secp256k1 compressed (0x03)",
|
|
makeAddr: func() (Address, error) {
|
|
pkHex := "030844ee70d8384d5250e9bb3a6a73d4b5bec770e8b31d6a0ae9fb739009d91af5"
|
|
pk := hexToBytes(pkHex)
|
|
return NewAddressPubKeyEcdsaSecp256k1Raw(0, pk, testNetParams)
|
|
},
|
|
makeErr: nil,
|
|
addr: "TkQ3RrFierkUUbgipYwgeVfV8ch3fktfrDamGyDYESPBXMaVNNmWG",
|
|
net: testNetParams,
|
|
decodeErr: nil,
|
|
version: 0,
|
|
payScript: "21030844ee70d8384d5250e9bb3a6a73d4b5bec770e8b31d6a0ae9fb739009d91af5ac",
|
|
pubKey: "030844ee70d8384d5250e9bb3a6a73d4b5bec770e8b31d6a0ae9fb739009d91af5",
|
|
}, {
|
|
name: "testnet p2pk-ecdsa-secp256k1 compressed via concrete constructor",
|
|
makeAddr: func() (Address, error) {
|
|
pkHex := "026a40c403e74670c4de7656a09caa2353d4b383a9ce66eef51e1220eacf4be06e"
|
|
pk, err := secp256k1.ParsePubKey(hexToBytes(pkHex))
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return NewAddressPubKeyEcdsaSecp256k1(0, pk, testNetParams)
|
|
},
|
|
makeErr: nil,
|
|
addr: "TkKmMiY5iDh4U3KkSopYgkU1AzhAcQZiSoVhYhFymZHGMi9LM9Fdt",
|
|
net: testNetParams,
|
|
decodeErr: nil,
|
|
version: 0,
|
|
payScript: "21026a40c403e74670c4de7656a09caa2353d4b383a9ce66eef51e1220eacf4be06eac",
|
|
pubKey: "026a40c403e74670c4de7656a09caa2353d4b383a9ce66eef51e1220eacf4be06e",
|
|
}, {
|
|
name: "testnet p2pk-ecdsa-secp256k1 compressed from uncompressed via concrete constructor",
|
|
makeAddr: func() (Address, error) {
|
|
pkHex := "046a40c403e74670c4de7656a09caa2353d4b383a9ce66eef51e12" +
|
|
"20eacf4be06ed548c8c16fb5eb9007cb94220b3bb89491d5a1fd2d77867" +
|
|
"fca64217acecf2244"
|
|
pk, err := secp256k1.ParsePubKey(hexToBytes(pkHex))
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return NewAddressPubKeyEcdsaSecp256k1(0, pk, testNetParams)
|
|
},
|
|
makeErr: nil,
|
|
addr: "TkKmMiY5iDh4U3KkSopYgkU1AzhAcQZiSoVhYhFymZHGMi9LM9Fdt",
|
|
net: testNetParams,
|
|
decodeErr: nil,
|
|
version: 0,
|
|
payScript: "21026a40c403e74670c4de7656a09caa2353d4b383a9ce66eef51e1220eacf4be06eac",
|
|
pubKey: "026a40c403e74670c4de7656a09caa2353d4b383a9ce66eef51e1220eacf4be06e",
|
|
}, {
|
|
name: "regnet p2pk-ecdsa-secp256k1 compressed (0x02)",
|
|
addr: "Rk41kKgrecrxQ8bLg8GJm1feMPBFtFeb4rG56tDfMdAtvPy4HneyR",
|
|
net: regNetParams,
|
|
decodeErr: nil,
|
|
version: 0,
|
|
payScript: "21026a40c403e74670c4de7656a09caa2353d4b383a9ce66eef51e1220eacf4be06eac",
|
|
pubKey: "026a40c403e74670c4de7656a09caa2353d4b383a9ce66eef51e1220eacf4be06e",
|
|
}, {
|
|
name: "regnet p2pk-ecdsa-secp256k1 compressed (0x03)",
|
|
addr: "Rk8HpTQVbFvNQgxK3sPSiks8K1B8wbyYUGM8qABDpWGp63Q5mnG52",
|
|
net: regNetParams,
|
|
decodeErr: nil,
|
|
version: 0,
|
|
payScript: "21030844ee70d8384d5250e9bb3a6a73d4b5bec770e8b31d6a0ae9fb739009d91af5ac",
|
|
pubKey: "030844ee70d8384d5250e9bb3a6a73d4b5bec770e8b31d6a0ae9fb739009d91af5",
|
|
}, {
|
|
// ---------------------------------------------------------------------
|
|
// Negative P2PK Ed25519 tests.
|
|
// ---------------------------------------------------------------------
|
|
|
|
name: "p2pk-ed25519 unsupported script version",
|
|
makeAddr: func() (Address, error) {
|
|
pkHex := "cecc1507dc1ddd7295951c290888f095adb9044d1b73d696e6df065d683bd4fc"
|
|
pk := hexToBytes(pkHex)
|
|
return NewAddressPubKeyEd25519Raw(9999, pk, mainNetParams)
|
|
},
|
|
makeErr: ErrUnsupportedScriptVersion,
|
|
}, {
|
|
name: "p2pk-ed25519 unsupported script version via concrete constructor",
|
|
makeAddr: func() (Address, error) {
|
|
pkHex := "cecc1507dc1ddd7295951c290888f095adb9044d1b73d696e6df065d683bd4fc"
|
|
pk, err := edwards.ParsePubKey(hexToBytes(pkHex))
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return NewAddressPubKeyEd25519(9999, pk, mainNetParams)
|
|
},
|
|
makeErr: ErrUnsupportedScriptVersion,
|
|
}, {
|
|
name: "p2pk-ed25519 malformed pubkey",
|
|
makeAddr: func() (Address, error) {
|
|
return NewAddressPubKeyEd25519Raw(0, nil, mainNetParams)
|
|
},
|
|
makeErr: ErrInvalidPubKey,
|
|
}, {
|
|
name: "p2pk-ed25519 malformed pubkey (only 31 bytes) via decode",
|
|
addr: "3tWUQtEa3P4SDQwjER81wkTxe4kiYLgNAso3pt2X5k3NFHRVQeNv",
|
|
net: mainNetParams,
|
|
decodeErr: ErrUnsupportedAddress,
|
|
}, {
|
|
// ---------------------------------------------------------------------
|
|
// Positive P2PK Ed25519 tests.
|
|
// ---------------------------------------------------------------------
|
|
|
|
name: "mainnet p2pk-ed25519",
|
|
makeAddr: func() (Address, error) {
|
|
// From pubkey for privkey 0x00...01.
|
|
pkHex := "cecc1507dc1ddd7295951c290888f095adb9044d1b73d696e6df065d683bd4fc"
|
|
pk := hexToBytes(pkHex)
|
|
return NewAddressPubKeyEd25519Raw(0, pk, mainNetParams)
|
|
},
|
|
makeErr: nil,
|
|
addr: "DkM5zR8tqWNAHngZQDTyAeqzabZxMKrkSbCFULDhmvySn3uHmm221",
|
|
net: mainNetParams,
|
|
decodeErr: nil,
|
|
version: 0,
|
|
payScript: "20cecc1507dc1ddd7295951c290888f095adb9044d1b73d696e6df065d683bd4fc51be",
|
|
pubKey: "cecc1507dc1ddd7295951c290888f095adb9044d1b73d696e6df065d683bd4fc",
|
|
}, {
|
|
name: "mainnet p2pk-ed25519 via concrete constructor",
|
|
makeAddr: func() (Address, error) {
|
|
// From pubkey for privkey 0x00...01.
|
|
pkHex := "cecc1507dc1ddd7295951c290888f095adb9044d1b73d696e6df065d683bd4fc"
|
|
pk, err := edwards.ParsePubKey(hexToBytes(pkHex))
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return NewAddressPubKeyEd25519(0, pk, mainNetParams)
|
|
},
|
|
makeErr: nil,
|
|
addr: "DkM5zR8tqWNAHngZQDTyAeqzabZxMKrkSbCFULDhmvySn3uHmm221",
|
|
net: mainNetParams,
|
|
decodeErr: nil,
|
|
version: 0,
|
|
payScript: "20cecc1507dc1ddd7295951c290888f095adb9044d1b73d696e6df065d683bd4fc51be",
|
|
pubKey: "cecc1507dc1ddd7295951c290888f095adb9044d1b73d696e6df065d683bd4fc",
|
|
}, {
|
|
name: "testnet p2pk-ed25519",
|
|
makeAddr: func() (Address, error) {
|
|
// From pubkey for privkey 0x00...01.
|
|
pkHex := "cecc1507dc1ddd7295951c290888f095adb9044d1b73d696e6df065d683bd4fc"
|
|
pk := hexToBytes(pkHex)
|
|
return NewAddressPubKeyEd25519Raw(0, pk, testNetParams)
|
|
},
|
|
makeErr: nil,
|
|
addr: "TkKp4jynaSAyyV5FooNX3UBGzeXhxYq7e96YtjbRS5XEaar5zFom4",
|
|
net: testNetParams,
|
|
decodeErr: nil,
|
|
version: 0,
|
|
payScript: "20cecc1507dc1ddd7295951c290888f095adb9044d1b73d696e6df065d683bd4fc51be",
|
|
pubKey: "cecc1507dc1ddd7295951c290888f095adb9044d1b73d696e6df065d683bd4fc",
|
|
}, {
|
|
name: "testnet p2pk-ed25519 via concrete constructor",
|
|
makeAddr: func() (Address, error) {
|
|
// From pubkey for privkey 0x00...01.
|
|
pkHex := "cecc1507dc1ddd7295951c290888f095adb9044d1b73d696e6df065d683bd4fc"
|
|
pk, err := edwards.ParsePubKey(hexToBytes(pkHex))
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return NewAddressPubKeyEd25519(0, pk, testNetParams)
|
|
},
|
|
makeErr: nil,
|
|
addr: "TkKp4jynaSAyyV5FooNX3UBGzeXhxYq7e96YtjbRS5XEaar5zFom4",
|
|
net: testNetParams,
|
|
decodeErr: nil,
|
|
version: 0,
|
|
payScript: "20cecc1507dc1ddd7295951c290888f095adb9044d1b73d696e6df065d683bd4fc51be",
|
|
pubKey: "cecc1507dc1ddd7295951c290888f095adb9044d1b73d696e6df065d683bd4fc",
|
|
}, {
|
|
name: "regnet p2pk-ed25519",
|
|
makeAddr: func() (Address, error) {
|
|
// From pubkey for privkey 0x00...01.
|
|
pkHex := "cecc1507dc1ddd7295951c290888f095adb9044d1b73d696e6df065d683bd4fc"
|
|
pk := hexToBytes(pkHex)
|
|
return NewAddressPubKeyEd25519Raw(0, pk, regNetParams)
|
|
},
|
|
makeErr: nil,
|
|
addr: "Rk44TM8ZWqLsuaLr37pH7jNvB31oEPuzGBrvSvZ729Qs9GfoiBryE",
|
|
net: regNetParams,
|
|
decodeErr: nil,
|
|
version: 0,
|
|
payScript: "20cecc1507dc1ddd7295951c290888f095adb9044d1b73d696e6df065d683bd4fc51be",
|
|
pubKey: "cecc1507dc1ddd7295951c290888f095adb9044d1b73d696e6df065d683bd4fc",
|
|
}, {
|
|
// ---------------------------------------------------------------------
|
|
// Negative P2PK Schnorr secp256k1 tests.
|
|
// ---------------------------------------------------------------------
|
|
|
|
name: "mainnet p2pk-schnorr-secp256k1 uncompressed (0x04) rejected via constructor",
|
|
makeAddr: func() (Address, error) {
|
|
pkHex := "0464c44653d6567eff5753c5d24a682ddc2b2cadfe1b0c6433b163" +
|
|
"74dace6778f0b87ca4279b565d2130ce59f75bfbb2b88da794143d7cfd3" +
|
|
"e80808a1fa3203904"
|
|
pk := hexToBytes(pkHex)
|
|
return NewAddressPubKeySchnorrSecp256k1Raw(0, pk, mainNetParams)
|
|
},
|
|
makeErr: ErrInvalidPubKeyFormat,
|
|
}, {
|
|
name: "mainnet p2pk-schnorr-secp256k1 uncompressed (0x04) rejected via decode",
|
|
addr: "HiQjU9uCJtiQD7osQuYHWJRFiBCTuqtaTw8QFMtMgAW2ny4nUENeXDiV5VxfVZrK6PZynKPDpL7bwc6XLFNpV8k7ePDJmkkVCh",
|
|
net: mainNetParams,
|
|
decodeErr: ErrUnsupportedAddress,
|
|
}, {
|
|
name: "mainnet p2pk-schnorr-secp256k1 hybrid (0x06) rejected via constructor",
|
|
makeAddr: func() (Address, error) {
|
|
pkHex := "0664c44653d6567eff5753c5d24a682ddc2b2cadfe1b0c6433b163" +
|
|
"74dace6778f0b87ca4279b565d2130ce59f75bfbb2b88da794143d7cfd3" +
|
|
"e80808a1fa3203904"
|
|
pk := hexToBytes(pkHex)
|
|
return NewAddressPubKeySchnorrSecp256k1Raw(0, pk, mainNetParams)
|
|
},
|
|
makeErr: ErrInvalidPubKeyFormat,
|
|
}, {
|
|
name: "mainnet p2pk-schnorr-secp256k1 hybrid (0x07) rejected via constructor",
|
|
makeAddr: func() (Address, error) {
|
|
pkHex := "07348d8aeb4253ca52456fe5da94ab1263bfee16bb8192497f6663" +
|
|
"89ca964f84798375129d7958843b14258b905dc94faed324dd8a9d67ffa" +
|
|
"c8cc0a85be84bac5d"
|
|
pk := hexToBytes(pkHex)
|
|
return NewAddressPubKeySchnorrSecp256k1Raw(0, pk, mainNetParams)
|
|
},
|
|
makeErr: ErrInvalidPubKeyFormat,
|
|
}, {
|
|
name: "p2pk-schnorr-secp256k1 unsupported script version",
|
|
makeAddr: func() (Address, error) {
|
|
pkHex := "028f53838b7639563f27c94845549a41e5146bcd52e7fef0ea6da143a02b0fe2ed"
|
|
pk := hexToBytes(pkHex)
|
|
return NewAddressPubKeySchnorrSecp256k1Raw(9999, pk, mainNetParams)
|
|
},
|
|
makeErr: ErrUnsupportedScriptVersion,
|
|
}, {
|
|
name: "p2pk-schnorr-secp256k1 unsupported script version via concrete constructor",
|
|
makeAddr: func() (Address, error) {
|
|
pkHex := "028f53838b7639563f27c94845549a41e5146bcd52e7fef0ea6da143a02b0fe2ed"
|
|
pk, err := secp256k1.ParsePubKey(hexToBytes(pkHex))
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return NewAddressPubKeySchnorrSecp256k1(9999, pk, mainNetParams)
|
|
},
|
|
makeErr: ErrUnsupportedScriptVersion,
|
|
}, {
|
|
name: "p2pk-schnorr-secp256k1 malformed pubkey",
|
|
makeAddr: func() (Address, error) {
|
|
pkHex := "028f53838b7639563f27c94845549a41e5146bcd52e7fef0ea6da143a02b0fe2"
|
|
pk := hexToBytes(pkHex)
|
|
return NewAddressPubKeySchnorrSecp256k1Raw(0, pk, mainNetParams)
|
|
},
|
|
makeErr: ErrInvalidPubKey,
|
|
}, {
|
|
name: "p2pk-schnorr-secp256k1 malformed pubkey via decode",
|
|
addr: "3tWUW3oD87XtmFVGnLX4Z3Hdesm2qRvvN8H5kq3yXxJumCxbvCpo",
|
|
net: mainNetParams,
|
|
decodeErr: ErrUnsupportedAddress,
|
|
}, {
|
|
// ---------------------------------------------------------------------
|
|
// Positive P2PK Schnorr secp256k1 tests.
|
|
// ---------------------------------------------------------------------
|
|
|
|
name: "mainnet p2pk-schnorr-secp256k1 compressed (0x02)",
|
|
addr: "DkM7TD2qsne9DKo4uA2ZNt3XhejYVwT5mmQWtUXtjdPhRHXTSKxN4",
|
|
net: mainNetParams,
|
|
decodeErr: nil,
|
|
version: 0,
|
|
payScript: "21028f53838b7639563f27c94845549a41e5146bcd52e7fef0ea6da143a02b0fe2ed52be",
|
|
pubKey: "028f53838b7639563f27c94845549a41e5146bcd52e7fef0ea6da143a02b0fe2ed",
|
|
}, {
|
|
name: "mainnet p2pk-schnorr-secp256k1 compressed (0x03)",
|
|
addr: "DkRQx3y6YoJPnMKom23nuDFdfhmEnu8oDLTp4YVyWC6RjND19UxHk",
|
|
net: mainNetParams,
|
|
decodeErr: nil,
|
|
version: 0,
|
|
payScript: "2103e925aafc1edd44e7c7f1ea4fb7d265dc672f204c3d0c81930389c10b81fb75de52be",
|
|
pubKey: "03e925aafc1edd44e7c7f1ea4fb7d265dc672f204c3d0c81930389c10b81fb75de",
|
|
}, {
|
|
name: "mainnet p2pk-schnorr-secp256k1 compressed via concrete constructor",
|
|
makeAddr: func() (Address, error) {
|
|
pkHex := "028f53838b7639563f27c94845549a41e5146bcd52e7fef0ea6da143a02b0fe2ed"
|
|
pk, err := secp256k1.ParsePubKey(hexToBytes(pkHex))
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return NewAddressPubKeySchnorrSecp256k1(0, pk, mainNetParams)
|
|
},
|
|
makeErr: nil,
|
|
addr: "DkM7TD2qsne9DKo4uA2ZNt3XhejYVwT5mmQWtUXtjdPhRHXTSKxN4",
|
|
net: mainNetParams,
|
|
decodeErr: nil,
|
|
version: 0,
|
|
payScript: "21028f53838b7639563f27c94845549a41e5146bcd52e7fef0ea6da143a02b0fe2ed52be",
|
|
pubKey: "028f53838b7639563f27c94845549a41e5146bcd52e7fef0ea6da143a02b0fe2ed",
|
|
}, {
|
|
name: "mainnet p2pk-schnorr-secp256k1 compressed from uncompressed via concrete constructor",
|
|
makeAddr: func() (Address, error) {
|
|
pkHex := "048f53838b7639563f27c94845549a41e5146bcd52e7fef0ea6da1" +
|
|
"43a02b0fe2ed91badd9f6403cc485dc3d5ca83ee8917dca57414866b083" +
|
|
"087c1c83b7a8e3304"
|
|
pk, err := secp256k1.ParsePubKey(hexToBytes(pkHex))
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return NewAddressPubKeySchnorrSecp256k1(0, pk, mainNetParams)
|
|
},
|
|
makeErr: nil,
|
|
addr: "DkM7TD2qsne9DKo4uA2ZNt3XhejYVwT5mmQWtUXtjdPhRHXTSKxN4",
|
|
net: mainNetParams,
|
|
decodeErr: nil,
|
|
version: 0,
|
|
payScript: "21028f53838b7639563f27c94845549a41e5146bcd52e7fef0ea6da143a02b0fe2ed52be",
|
|
pubKey: "028f53838b7639563f27c94845549a41e5146bcd52e7fef0ea6da143a02b0fe2ed",
|
|
}, {
|
|
name: "testnet p2pk-schnorr-secp256k1 compressed (0x02)",
|
|
addr: "TkKqFCtYcHPupVbPcDdhvkNeNYXPqqs88Z4ygukH9MGaNV8e1WWhX",
|
|
net: testNetParams,
|
|
decodeErr: nil,
|
|
version: 0,
|
|
payScript: "21026a40c403e74670c4de7656a09caa2353d4b383a9ce66eef51e1220eacf4be06e52be",
|
|
pubKey: "026a40c403e74670c4de7656a09caa2353d4b383a9ce66eef51e1220eacf4be06e",
|
|
}, {
|
|
name: "testnet p2pk-schnorr-secp256k1 compressed (0x03)",
|
|
addr: "TkQ7KLcBYvTKq3xMyxkqtVa8LAXGuCC5XyA3RBhqcENVY8ZiDjuAB",
|
|
net: testNetParams,
|
|
decodeErr: nil,
|
|
version: 0,
|
|
payScript: "21030844ee70d8384d5250e9bb3a6a73d4b5bec770e8b31d6a0ae9fb739009d91af552be",
|
|
pubKey: "030844ee70d8384d5250e9bb3a6a73d4b5bec770e8b31d6a0ae9fb739009d91af5",
|
|
}, {
|
|
name: "regnet p2pk-schnorr-secp256k1 compressed (0x02)",
|
|
addr: "Rk45dp3KYgZokaryqY5U11aHYw1V7gwzkbqMF6hxjRACwAxDivM6N",
|
|
net: regNetParams,
|
|
decodeErr: nil,
|
|
version: 0,
|
|
payScript: "21026a40c403e74670c4de7656a09caa2353d4b383a9ce66eef51e1220eacf4be06e52be",
|
|
pubKey: "026a40c403e74670c4de7656a09caa2353d4b383a9ce66eef51e1220eacf4be06e",
|
|
}, {
|
|
name: "regnet p2pk-schnorr-secp256k1 compressed (0x03)",
|
|
addr: "Rk8MhwkxVKdDm9DxDHCbxkmmWZ1NB3GxA1vQyNfXCJG86pPPnnn9M",
|
|
net: regNetParams,
|
|
decodeErr: nil,
|
|
version: 0,
|
|
payScript: "21030844ee70d8384d5250e9bb3a6a73d4b5bec770e8b31d6a0ae9fb739009d91af552be",
|
|
pubKey: "030844ee70d8384d5250e9bb3a6a73d4b5bec770e8b31d6a0ae9fb739009d91af5",
|
|
}, {
|
|
// ---------------------------------------------------------------------
|
|
// Negative P2PKH ECDSA secp256k1 tests.
|
|
// ---------------------------------------------------------------------
|
|
|
|
name: "p2pkh-ecdsa-secp256k1 wrong hash length",
|
|
makeAddr: func() (Address, error) {
|
|
hash := hexToBytes("000ef030107fd26e0b6bf40512bca2ceb1dd80adaa")
|
|
return NewAddressPubKeyHashEcdsaSecp256k1(0, hash, mainNetParams)
|
|
},
|
|
makeErr: ErrInvalidHashLen,
|
|
}, {
|
|
name: "p2pkh-ecdsa-secp256k1 unsupported script version",
|
|
makeAddr: func() (Address, error) {
|
|
hash := hexToBytes("2789d58cfa0957d206f025c2af056fc8a77cebb0")
|
|
return NewAddressPubKeyHashEcdsaSecp256k1(9999, hash, mainNetParams)
|
|
},
|
|
makeErr: ErrUnsupportedScriptVersion,
|
|
}, {
|
|
// ---------------------------------------------------------------------
|
|
// Positive P2PKH ECDSA secp256k1 tests.
|
|
// ---------------------------------------------------------------------
|
|
|
|
name: "mainnet p2pkh-ecdsa-secp256k1",
|
|
makeAddr: func() (Address, error) {
|
|
hash := hexToBytes("2789d58cfa0957d206f025c2af056fc8a77cebb0")
|
|
return NewAddressPubKeyHashEcdsaSecp256k1(0, hash, mainNetParams)
|
|
},
|
|
makeErr: nil,
|
|
addr: "DsUZxxoHJSty8DCfwfartwTYbuhmVct7tJu",
|
|
net: mainNetParams,
|
|
decodeErr: nil,
|
|
version: 0,
|
|
payScript: "76a9142789d58cfa0957d206f025c2af056fc8a77cebb088ac",
|
|
voteScript: "ba76a9142789d58cfa0957d206f025c2af056fc8a77cebb088ac",
|
|
rewardAmount: 1e8,
|
|
revFeeLimit: 16777216,
|
|
rewardScript: "6a1e2789d58cfa0957d206f025c2af056fc8a77cebb000e1f505000000000058",
|
|
changeScript: "bd76a9142789d58cfa0957d206f025c2af056fc8a77cebb088ac",
|
|
commitScript: "bb76a9142789d58cfa0957d206f025c2af056fc8a77cebb088ac",
|
|
revokeScript: "bc76a9142789d58cfa0957d206f025c2af056fc8a77cebb088ac",
|
|
trsyScript: "c376a9142789d58cfa0957d206f025c2af056fc8a77cebb088ac",
|
|
}, {
|
|
name: "mainnet p2pkh-ecdsa-secp256k1 2",
|
|
makeAddr: func() (Address, error) {
|
|
hash := hexToBytes("229ebac30efd6a69eec9c1a48e048b7c975c25f2")
|
|
return NewAddressPubKeyHashEcdsaSecp256k1(0, hash, mainNetParams)
|
|
},
|
|
makeErr: nil,
|
|
addr: "DsU7xcg53nxaKLLcAUSKyRndjG78Z2VZnX9",
|
|
net: mainNetParams,
|
|
decodeErr: nil,
|
|
version: 0,
|
|
payScript: "76a914229ebac30efd6a69eec9c1a48e048b7c975c25f288ac",
|
|
voteScript: "ba76a914229ebac30efd6a69eec9c1a48e048b7c975c25f288ac",
|
|
rewardAmount: 9556193632,
|
|
revFeeLimit: 33554432,
|
|
rewardScript: "6a1e229ebac30efd6a69eec9c1a48e048b7c975c25f260f19739020000000059",
|
|
changeScript: "bd76a914229ebac30efd6a69eec9c1a48e048b7c975c25f288ac",
|
|
commitScript: "bb76a914229ebac30efd6a69eec9c1a48e048b7c975c25f288ac",
|
|
revokeScript: "bc76a914229ebac30efd6a69eec9c1a48e048b7c975c25f288ac",
|
|
trsyScript: "c376a914229ebac30efd6a69eec9c1a48e048b7c975c25f288ac",
|
|
}, {
|
|
name: "testnet p2pkh-ecdsa-secp256k1",
|
|
makeAddr: func() (Address, error) {
|
|
hash := hexToBytes("f15da1cb8d1bcb162c6ab446c95757a6e791c916")
|
|
return NewAddressPubKeyHashEcdsaSecp256k1(0, hash, testNetParams)
|
|
},
|
|
makeErr: nil,
|
|
addr: "Tso2MVTUeVrjHTBFedFhiyM7yVTbieqp91h",
|
|
net: testNetParams,
|
|
decodeErr: nil,
|
|
version: 0,
|
|
payScript: "76a914f15da1cb8d1bcb162c6ab446c95757a6e791c91688ac",
|
|
voteScript: "ba76a914f15da1cb8d1bcb162c6ab446c95757a6e791c91688ac",
|
|
rewardAmount: 2428220961,
|
|
revFeeLimit: 16777216,
|
|
rewardScript: "6a1ef15da1cb8d1bcb162c6ab446c95757a6e791c91621b6bb90000000000058",
|
|
changeScript: "bd76a914f15da1cb8d1bcb162c6ab446c95757a6e791c91688ac",
|
|
commitScript: "bb76a914f15da1cb8d1bcb162c6ab446c95757a6e791c91688ac",
|
|
revokeScript: "bc76a914f15da1cb8d1bcb162c6ab446c95757a6e791c91688ac",
|
|
trsyScript: "c376a914f15da1cb8d1bcb162c6ab446c95757a6e791c91688ac",
|
|
}, {
|
|
name: "regnet p2pkh-sep256k1-ecdsa",
|
|
makeAddr: func() (Address, error) {
|
|
hash := hexToBytes("f15da1cb8d1bcb162c6ab446c95757a6e791c916")
|
|
return NewAddressPubKeyHashEcdsaSecp256k1(0, hash, regNetParams)
|
|
},
|
|
makeErr: nil,
|
|
addr: "RsWM2w5LPJip56uxcZ1Scq7Tcbg97EfiwPA",
|
|
net: regNetParams,
|
|
decodeErr: nil,
|
|
version: 0,
|
|
payScript: "76a914f15da1cb8d1bcb162c6ab446c95757a6e791c91688ac",
|
|
voteScript: "ba76a914f15da1cb8d1bcb162c6ab446c95757a6e791c91688ac",
|
|
rewardAmount: 2428220961,
|
|
revFeeLimit: 16777216,
|
|
rewardScript: "6a1ef15da1cb8d1bcb162c6ab446c95757a6e791c91621b6bb90000000000058",
|
|
changeScript: "bd76a914f15da1cb8d1bcb162c6ab446c95757a6e791c91688ac",
|
|
commitScript: "bb76a914f15da1cb8d1bcb162c6ab446c95757a6e791c91688ac",
|
|
revokeScript: "bc76a914f15da1cb8d1bcb162c6ab446c95757a6e791c91688ac",
|
|
trsyScript: "c376a914f15da1cb8d1bcb162c6ab446c95757a6e791c91688ac",
|
|
}, {
|
|
// ---------------------------------------------------------------------
|
|
// Negative P2PKH ed25519 tests.
|
|
// ---------------------------------------------------------------------
|
|
|
|
name: "p2pkh-ed25519 wrong hash length",
|
|
makeAddr: func() (Address, error) {
|
|
hash := hexToBytes("000ef030107fd26e0b6bf40512bca2ceb1dd80adaa")
|
|
return NewAddressPubKeyHashEd25519(0, hash, mainNetParams)
|
|
},
|
|
makeErr: ErrInvalidHashLen,
|
|
}, {
|
|
name: "p2pkh-ed25519 unsupported script version",
|
|
makeAddr: func() (Address, error) {
|
|
hash := hexToBytes("0ef030107fd26e0b6bf40512bca2ceb1dd80adaa")
|
|
return NewAddressPubKeyHashEd25519(9999, hash, mainNetParams)
|
|
},
|
|
makeErr: ErrUnsupportedScriptVersion,
|
|
}, {
|
|
// ---------------------------------------------------------------------
|
|
// Positive P2PKH Ed25519 tests.
|
|
// ---------------------------------------------------------------------
|
|
|
|
name: "mainnet p2pkh-ed25519",
|
|
makeAddr: func() (Address, error) {
|
|
// From pubkey for privkey 0x00...01.
|
|
hash := hexToBytes("456d8ee57a4b9121987b4ecab8c3bcb5797e8a53")
|
|
return NewAddressPubKeyHashEd25519(0, hash, mainNetParams)
|
|
},
|
|
makeErr: nil,
|
|
addr: "DeeUhrRoTp4DftsqddVW96yMGMW4sgQFYUE",
|
|
net: mainNetParams,
|
|
decodeErr: nil,
|
|
version: 0,
|
|
payScript: "76a914456d8ee57a4b9121987b4ecab8c3bcb5797e8a538851be",
|
|
}, {
|
|
name: "mainnet p2pkh-ed25519 2",
|
|
makeAddr: func() (Address, error) {
|
|
// From pubkey for privkey 0x00...02.
|
|
hash := hexToBytes("09788a8dcb216efa354e487d57d76255b1af4320")
|
|
return NewAddressPubKeyHashEd25519(0, hash, mainNetParams)
|
|
},
|
|
makeErr: nil,
|
|
addr: "DeZ1gU2ta8auk5et79R74GYR3pnF31KXbFo",
|
|
net: mainNetParams,
|
|
decodeErr: nil,
|
|
version: 0,
|
|
payScript: "76a91409788a8dcb216efa354e487d57d76255b1af43208851be",
|
|
}, {
|
|
name: "testnet p2pkh-ed25519",
|
|
makeAddr: func() (Address, error) {
|
|
// From pubkey for privkey 0x00...01.
|
|
hash := hexToBytes("456d8ee57a4b9121987b4ecab8c3bcb5797e8a53")
|
|
return NewAddressPubKeyHashEd25519(0, hash, testNetParams)
|
|
},
|
|
makeErr: nil,
|
|
addr: "TeeXvqZJrc7KnFZCT27fHfzcrTTzSF1aSRG",
|
|
net: testNetParams,
|
|
decodeErr: nil,
|
|
version: 0,
|
|
payScript: "76a914456d8ee57a4b9121987b4ecab8c3bcb5797e8a538851be",
|
|
}, {
|
|
name: "regnet p2pkh-ed25519",
|
|
makeAddr: func() (Address, error) {
|
|
// From pubkey for privkey 0x00...01.
|
|
hash := hexToBytes("456d8ee57a4b9121987b4ecab8c3bcb5797e8a53")
|
|
return NewAddressPubKeyHashEd25519(0, hash, regNetParams)
|
|
},
|
|
makeErr: nil,
|
|
addr: "ReMrcHBAbQyQZuHuQwsQBXkxVZgXpnbqX72",
|
|
net: regNetParams,
|
|
decodeErr: nil,
|
|
version: 0,
|
|
payScript: "76a914456d8ee57a4b9121987b4ecab8c3bcb5797e8a538851be",
|
|
}, {
|
|
// ---------------------------------------------------------------------
|
|
// Negative P2PKH Schnorr secp256k1 tests.
|
|
// ---------------------------------------------------------------------
|
|
|
|
name: "p2pkh-schnorr-secp256k1 wrong hash length",
|
|
makeAddr: func() (Address, error) {
|
|
hash := hexToBytes("000ef030107fd26e0b6bf40512bca2ceb1dd80adaa")
|
|
return NewAddressPubKeyHashSchnorrSecp256k1(0, hash, mainNetParams)
|
|
},
|
|
makeErr: ErrInvalidHashLen,
|
|
}, {
|
|
name: "p2pkh-schnorr-secp256k1 unsupported script version",
|
|
makeAddr: func() (Address, error) {
|
|
hash := hexToBytes("0ef030107fd26e0b6bf40512bca2ceb1dd80adaa")
|
|
return NewAddressPubKeyHashSchnorrSecp256k1(9999, hash, mainNetParams)
|
|
},
|
|
makeErr: ErrUnsupportedScriptVersion,
|
|
}, {
|
|
// ---------------------------------------------------------------------
|
|
// Positive P2PKH Schnorr secp256k1 tests.
|
|
// ---------------------------------------------------------------------
|
|
|
|
name: "mainnet p2pkh-schnorr-secp256k1",
|
|
makeAddr: func() (Address, error) {
|
|
hash := hexToBytes("2789d58cfa0957d206f025c2af056fc8a77cebb0")
|
|
return NewAddressPubKeyHashSchnorrSecp256k1(0, hash, mainNetParams)
|
|
},
|
|
makeErr: nil,
|
|
addr: "DSXcZv4oSRiEoWL2a9aD8sgfptRo1YEXNKj",
|
|
net: mainNetParams,
|
|
decodeErr: nil,
|
|
version: 0,
|
|
payScript: "76a9142789d58cfa0957d206f025c2af056fc8a77cebb08852be",
|
|
}, {
|
|
name: "mainnet p2pkh-schnorr-secp256k1 2",
|
|
makeAddr: func() (Address, error) {
|
|
hash := hexToBytes("229ebac30efd6a69eec9c1a48e048b7c975c25f2")
|
|
return NewAddressPubKeyHashSchnorrSecp256k1(0, hash, mainNetParams)
|
|
},
|
|
makeErr: nil,
|
|
addr: "DSXAZZwbBmmqzdTxnxRgDN1kxEqA4xJfufA",
|
|
net: mainNetParams,
|
|
decodeErr: nil,
|
|
version: 0,
|
|
payScript: "76a914229ebac30efd6a69eec9c1a48e048b7c975c25f28852be",
|
|
}, {
|
|
name: "testnet p2pkh-schnorr-secp256k1",
|
|
makeAddr: func() (Address, error) {
|
|
hash := hexToBytes("f15da1cb8d1bcb162c6ab446c95757a6e791c916")
|
|
return NewAddressPubKeyHashSchnorrSecp256k1(0, hash, testNetParams)
|
|
},
|
|
makeErr: nil,
|
|
addr: "TSr4xSiznUfzxkJcH7F3xuaFCUBdEb5Jfzg",
|
|
net: testNetParams,
|
|
decodeErr: nil,
|
|
version: 0,
|
|
payScript: "76a914f15da1cb8d1bcb162c6ab446c95757a6e791c9168852be",
|
|
}, {
|
|
name: "regnet p2pkh-sep256k1-schnorr",
|
|
makeAddr: func() (Address, error) {
|
|
hash := hexToBytes("f15da1cb8d1bcb162c6ab446c95757a6e791c916")
|
|
return NewAddressPubKeyHashSchnorrSecp256k1(0, hash, regNetParams)
|
|
},
|
|
makeErr: nil,
|
|
addr: "RSZPdtLrXHY5kQ3KF2znrmLaqaQAdB3CRu7",
|
|
net: regNetParams,
|
|
decodeErr: nil,
|
|
version: 0,
|
|
payScript: "76a914f15da1cb8d1bcb162c6ab446c95757a6e791c9168852be",
|
|
}, {
|
|
// ---------------------------------------------------------------------
|
|
// Negative P2SH tests.
|
|
// ---------------------------------------------------------------------
|
|
|
|
name: "p2sh wrong hash length",
|
|
makeAddr: func() (Address, error) {
|
|
hash := hexToBytes("00f815b036d9bbbce5e9f2a00abd1bf3dc91e95510")
|
|
return NewAddressScriptHashFromHash(0, hash, mainNetParams)
|
|
},
|
|
makeErr: ErrInvalidHashLen,
|
|
}, {
|
|
name: "p2sh from script hash unsupported script version",
|
|
makeAddr: func() (Address, error) {
|
|
hash := hexToBytes("f815b036d9bbbce5e9f2a00abd1bf3dc91e95510")
|
|
return NewAddressScriptHashFromHash(9999, hash, mainNetParams)
|
|
},
|
|
makeErr: ErrUnsupportedScriptVersion,
|
|
}, {
|
|
name: "p2sh from redeem script unsupported script version",
|
|
makeAddr: func() (Address, error) {
|
|
script := hexToBytes("a914f0b4e85100aee1a996f22915eb3c3f764d53779a87")
|
|
return NewAddressScriptHash(9999, script, mainNetParams)
|
|
},
|
|
makeErr: ErrUnsupportedScriptVersion,
|
|
}, {
|
|
// ---------------------------------------------------------------------
|
|
// Positive P2SH tests.
|
|
// ---------------------------------------------------------------------
|
|
|
|
name: "mainnet p2sh",
|
|
makeAddr: func() (Address, error) {
|
|
script := hexToBytes("512103aa43f0a6c15730d886cc1f0342046d2017548" +
|
|
"3d90d7ccb657f90c489111d794c51ae")
|
|
return NewAddressScriptHash(0, script, mainNetParams)
|
|
},
|
|
makeErr: nil,
|
|
addr: "DcuQKx8BES9wU7C6Q5VmLBjw436r27hayjS",
|
|
net: mainNetParams,
|
|
decodeErr: nil,
|
|
version: 0,
|
|
payScript: "a914f0b4e85100aee1a996f22915eb3c3f764d53779a87",
|
|
rewardAmount: 1e8,
|
|
revFeeLimit: 16777216,
|
|
rewardScript: "6a1ef0b4e85100aee1a996f22915eb3c3f764d53779a00e1f505000000800058",
|
|
voteScript: "baa914f0b4e85100aee1a996f22915eb3c3f764d53779a87",
|
|
changeScript: "bda914f0b4e85100aee1a996f22915eb3c3f764d53779a87",
|
|
commitScript: "bba914f0b4e85100aee1a996f22915eb3c3f764d53779a87",
|
|
revokeScript: "bca914f0b4e85100aee1a996f22915eb3c3f764d53779a87",
|
|
trsyScript: "c3a914f0b4e85100aee1a996f22915eb3c3f764d53779a87",
|
|
}, {
|
|
name: "mainnet p2sh 2",
|
|
makeAddr: func() (Address, error) {
|
|
hash := hexToBytes("c7da5095683436f4435fc4e7163dcafda1a2d007")
|
|
return NewAddressScriptHashFromHash(0, hash, mainNetParams)
|
|
},
|
|
makeErr: nil,
|
|
addr: "DcqgK4N4Ccucu2Sq4VDAdu4wH4LASLhzLVp",
|
|
net: mainNetParams,
|
|
decodeErr: nil,
|
|
version: 0,
|
|
payScript: "a914c7da5095683436f4435fc4e7163dcafda1a2d00787",
|
|
voteScript: "baa914c7da5095683436f4435fc4e7163dcafda1a2d00787",
|
|
rewardAmount: 9556193632,
|
|
revFeeLimit: 33554432,
|
|
rewardScript: "6a1ec7da5095683436f4435fc4e7163dcafda1a2d00760f19739020000800059",
|
|
changeScript: "bda914c7da5095683436f4435fc4e7163dcafda1a2d00787",
|
|
commitScript: "bba914c7da5095683436f4435fc4e7163dcafda1a2d00787",
|
|
revokeScript: "bca914c7da5095683436f4435fc4e7163dcafda1a2d00787",
|
|
trsyScript: "c3a914c7da5095683436f4435fc4e7163dcafda1a2d00787",
|
|
}, {
|
|
name: "testnet p2sh",
|
|
makeAddr: func() (Address, error) {
|
|
hash := hexToBytes("36c1ca10a8a6a4b5d4204ac970853979903aa284")
|
|
return NewAddressScriptHashFromHash(0, hash, testNetParams)
|
|
},
|
|
makeErr: nil,
|
|
addr: "TccWLgcquqvwrfBocq5mcK5kBiyw8MvyvCi",
|
|
net: testNetParams,
|
|
decodeErr: nil,
|
|
version: 0,
|
|
payScript: "a91436c1ca10a8a6a4b5d4204ac970853979903aa28487",
|
|
voteScript: "baa91436c1ca10a8a6a4b5d4204ac970853979903aa28487",
|
|
rewardAmount: 2428220961,
|
|
revFeeLimit: 16777216,
|
|
rewardScript: "6a1e36c1ca10a8a6a4b5d4204ac970853979903aa28421b6bb90000000800058",
|
|
changeScript: "bda91436c1ca10a8a6a4b5d4204ac970853979903aa28487",
|
|
commitScript: "bba91436c1ca10a8a6a4b5d4204ac970853979903aa28487",
|
|
revokeScript: "bca91436c1ca10a8a6a4b5d4204ac970853979903aa28487",
|
|
trsyScript: "c3a91436c1ca10a8a6a4b5d4204ac970853979903aa28487",
|
|
}, {
|
|
name: "regnet p2sh",
|
|
makeAddr: func() (Address, error) {
|
|
hash := hexToBytes("36c1ca10a8a6a4b5d4204ac970853979903aa284")
|
|
return NewAddressScriptHashFromHash(0, hash, regNetParams)
|
|
},
|
|
makeErr: nil,
|
|
addr: "RcKq28Eheeo2eJvWakqWWAr5pqCUWykwDHe",
|
|
net: regNetParams,
|
|
decodeErr: nil,
|
|
version: 0,
|
|
payScript: "a91436c1ca10a8a6a4b5d4204ac970853979903aa28487",
|
|
voteScript: "baa91436c1ca10a8a6a4b5d4204ac970853979903aa28487",
|
|
rewardAmount: 2428220961,
|
|
revFeeLimit: 16777216,
|
|
rewardScript: "6a1e36c1ca10a8a6a4b5d4204ac970853979903aa28421b6bb90000000800058",
|
|
changeScript: "bda91436c1ca10a8a6a4b5d4204ac970853979903aa28487",
|
|
commitScript: "bba91436c1ca10a8a6a4b5d4204ac970853979903aa28487",
|
|
revokeScript: "bca91436c1ca10a8a6a4b5d4204ac970853979903aa28487",
|
|
trsyScript: "c3a91436c1ca10a8a6a4b5d4204ac970853979903aa28487",
|
|
}}
|
|
|
|
for _, test := range tests {
|
|
// Create address from test constructor and ensure it produces the
|
|
// expected encoded address when the constructor is specified.
|
|
if test.makeAddr != nil {
|
|
addr, err := test.makeAddr()
|
|
if !errors.Is(err, test.makeErr) {
|
|
t.Errorf("%s: mismatched err -- got %v, want %v", test.name, err,
|
|
test.makeErr)
|
|
continue
|
|
}
|
|
if err != nil {
|
|
continue
|
|
}
|
|
|
|
// Ensure encoding the address is the same as the original.
|
|
encoded := addr.String()
|
|
if encoded != test.addr {
|
|
t.Errorf("%s: unexpected address -- got %v, want %v", test.name,
|
|
encoded, test.addr)
|
|
continue
|
|
}
|
|
}
|
|
|
|
// Decode address and ensure the expected error is received.
|
|
decodedAddr, err := DecodeAddress(test.addr, test.net)
|
|
if !errors.Is(err, test.decodeErr) {
|
|
t.Errorf("%s: mismatched err -- got %v, want %v", test.name, err,
|
|
test.decodeErr)
|
|
continue
|
|
}
|
|
if err != nil {
|
|
continue
|
|
}
|
|
|
|
// Ensure the payment script version and contents are the expected
|
|
// values.
|
|
wantPayScript, err := hex.DecodeString(test.payScript)
|
|
if err != nil {
|
|
t.Errorf("%s: unexpected hex decode err: %v", test.name, err)
|
|
continue
|
|
}
|
|
gotPayScriptVersion, gotPayScript := decodedAddr.PaymentScript()
|
|
if gotPayScriptVersion != test.version {
|
|
t.Errorf("%s: mismatched payment script version -- got %d, want %d",
|
|
test.name, gotPayScriptVersion, test.version)
|
|
continue
|
|
}
|
|
if !bytes.Equal(gotPayScript, wantPayScript) {
|
|
t.Errorf("%s: mismatched payment script -- got %x, want %x",
|
|
test.name, gotPayScript, wantPayScript)
|
|
continue
|
|
}
|
|
|
|
// Ensure stake-specific interface results produce the expected values.
|
|
if stakeAddr, ok := decodedAddr.(StakeAddress); ok {
|
|
// Ensure the voting rights script version and contents are the
|
|
// expected values.
|
|
wantScript, err := hex.DecodeString(test.voteScript)
|
|
if err != nil {
|
|
t.Errorf("%s: unexpected hex decode err: %v", test.name, err)
|
|
continue
|
|
}
|
|
gotScriptVer, gotScript := stakeAddr.VotingRightsScript()
|
|
if gotScriptVer != test.version {
|
|
t.Errorf("%s: mismatched voting rights script version -- got "+
|
|
"%d, want %d", test.name, gotScriptVer,
|
|
test.version)
|
|
continue
|
|
}
|
|
if !bytes.Equal(gotScript, wantScript) {
|
|
t.Errorf("%s: mismatched voting rights script -- got %x, want %x",
|
|
test.name, gotScript, wantScript)
|
|
continue
|
|
}
|
|
|
|
// Ensure the reward commitment script version and contents are the
|
|
// expected values.
|
|
wantScript, err = hex.DecodeString(test.rewardScript)
|
|
if err != nil {
|
|
t.Errorf("%s: unexpected hex decode err: %v", test.name, err)
|
|
continue
|
|
}
|
|
gotScriptVer, gotScript = stakeAddr.RewardCommitmentScript(
|
|
test.rewardAmount, test.voteFeeLimit, test.revFeeLimit)
|
|
if gotScriptVer != test.version {
|
|
t.Errorf("%s: mismatched reward cmt script version -- got %d, "+
|
|
"want %d", test.name, gotScriptVer, test.version)
|
|
continue
|
|
}
|
|
if !bytes.Equal(gotScript, wantScript) {
|
|
t.Errorf("%s: mismatched reward cmt script -- got %x, want %x",
|
|
test.name, gotScript, wantScript)
|
|
continue
|
|
}
|
|
|
|
// Ensure the stake change script version and contents are the
|
|
// expected values.
|
|
wantScript, err = hex.DecodeString(test.changeScript)
|
|
if err != nil {
|
|
t.Errorf("%s: unexpected hex decode err: %v", test.name, err)
|
|
continue
|
|
}
|
|
gotScriptVer, gotScript = stakeAddr.StakeChangeScript()
|
|
if gotScriptVer != test.version {
|
|
t.Errorf("%s: mismatched change script version -- got %d, "+
|
|
"want %d", test.name, gotScriptVer, test.version)
|
|
continue
|
|
}
|
|
if !bytes.Equal(gotScript, wantScript) {
|
|
t.Errorf("%s: mismatched change script -- got %x, want %x",
|
|
test.name, gotScript, wantScript)
|
|
continue
|
|
}
|
|
|
|
// Ensure the vote commitment script version and contents are the
|
|
// expected values.
|
|
wantScript, err = hex.DecodeString(test.commitScript)
|
|
if err != nil {
|
|
t.Errorf("%s: unexpected hex decode err: %v", test.name, err)
|
|
continue
|
|
}
|
|
gotScriptVer, gotScript = stakeAddr.PayVoteCommitmentScript()
|
|
if gotScriptVer != test.version {
|
|
t.Errorf("%s: mismatched vote commit script version -- got %d, "+
|
|
"want %d", test.name, gotScriptVer, test.version)
|
|
continue
|
|
}
|
|
if !bytes.Equal(gotScript, wantScript) {
|
|
t.Errorf("%s: mismatched vote commit script -- got %x, want %x",
|
|
test.name, gotScript, wantScript)
|
|
continue
|
|
}
|
|
|
|
// Ensure the revoke commitment script version and contents are the
|
|
// expected values.
|
|
wantScript, err = hex.DecodeString(test.revokeScript)
|
|
if err != nil {
|
|
t.Errorf("%s: unexpected hex decode err: %v", test.name, err)
|
|
continue
|
|
}
|
|
gotScriptVer, gotScript = stakeAddr.PayRevokeCommitmentScript()
|
|
if gotScriptVer != test.version {
|
|
t.Errorf("%s: mismatched revoke cmt script version -- got %d, "+
|
|
"want %d", test.name, gotScriptVer, test.version)
|
|
continue
|
|
}
|
|
if !bytes.Equal(gotScript, wantScript) {
|
|
t.Errorf("%s: mismatched revoke cmt script -- got %x, want %x",
|
|
test.name, gotScript, wantScript)
|
|
continue
|
|
}
|
|
|
|
// Ensure the pay from treasury script version and contents are the
|
|
// expected values.
|
|
wantScript, err = hex.DecodeString(test.trsyScript)
|
|
if err != nil {
|
|
t.Errorf("%s: unexpected hex decode err: %v", test.name, err)
|
|
continue
|
|
}
|
|
gotScriptVer, gotScript = stakeAddr.PayFromTreasuryScript()
|
|
if gotScriptVer != test.version {
|
|
t.Errorf("%s: mismatched treasury change script version -- "+
|
|
"got %d, want %d", test.name, gotScriptVer, test.version)
|
|
continue
|
|
}
|
|
if !bytes.Equal(gotScript, wantScript) {
|
|
t.Errorf("%s: mismatched treasury change script -- got %x, "+
|
|
"want %x", test.name, gotScript, wantScript)
|
|
continue
|
|
}
|
|
}
|
|
|
|
// Ensure encoding the address is the same as the original.
|
|
encoded := decodedAddr.String()
|
|
if encoded != test.addr {
|
|
t.Errorf("%s: decoding and encoding produced different addresses "+
|
|
"-- got %v, want %v", test.name, encoded, test.addr)
|
|
continue
|
|
}
|
|
|
|
// Ensure the method to get the serialized public key for the addresses
|
|
// that support it returns the expected value.
|
|
if pubKeyer, ok := decodedAddr.(SerializedPubKeyer); ok {
|
|
wantPubKey, err := hex.DecodeString(test.pubKey)
|
|
if err != nil {
|
|
t.Errorf("%s: unexpected hex decode err: %v", test.name, err)
|
|
continue
|
|
}
|
|
gotPubKey := pubKeyer.SerializedPubKey()
|
|
if !bytes.Equal(gotPubKey, wantPubKey) {
|
|
t.Errorf("%s: mismatched public key -- got %x, want %x",
|
|
test.name, gotPubKey, wantPubKey)
|
|
continue
|
|
}
|
|
}
|
|
|
|
// Ensure the AddressPubKeyHash method for the address types that
|
|
// support it returns the expected address.
|
|
var pkhAddr Address
|
|
var wantPkhAddr string
|
|
switch a := decodedAddr.(type) {
|
|
case *AddressPubKeyEcdsaSecp256k1V0:
|
|
id := test.net.AddrIDPubKeyHashECDSAV0()
|
|
wantPkhAddr = base58.CheckEncode(Hash160(a.serializedPubKey), id)
|
|
pkhAddr = a.AddressPubKeyHash()
|
|
|
|
case *AddressPubKeyEd25519V0:
|
|
id := test.net.AddrIDPubKeyHashEd25519V0()
|
|
wantPkhAddr = base58.CheckEncode(Hash160(a.serializedPubKey), id)
|
|
pkhAddr = a.AddressPubKeyHash()
|
|
|
|
case *AddressPubKeySchnorrSecp256k1V0:
|
|
id := test.net.AddrIDPubKeyHashSchnorrV0()
|
|
wantPkhAddr = base58.CheckEncode(Hash160(a.serializedPubKey), id)
|
|
pkhAddr = a.AddressPubKeyHash()
|
|
}
|
|
if pkhAddr != nil {
|
|
gotAddr := pkhAddr.String()
|
|
if gotAddr != wantPkhAddr {
|
|
t.Errorf("%s: mismatched pkh address -- got %s, want %s",
|
|
test.name, gotAddr, wantPkhAddr)
|
|
}
|
|
}
|
|
|
|
// Ensure the Hash160 method for the addresses that support it returns
|
|
// the expected value.
|
|
if h160er, ok := decodedAddr.(Hash160er); ok {
|
|
decodedBytes := base58.Decode(test.addr)
|
|
wantH160 := decodedBytes[2 : 2+ripemd160.Size]
|
|
if gotH160 := h160er.Hash160()[:]; !bytes.Equal(gotH160, wantH160) {
|
|
t.Errorf("%s: mismatched hash160 -- got %x, want %x", test.name,
|
|
gotH160, wantH160)
|
|
return
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// TestDecodeAddressV0Corners ensures that some additional errors that are
|
|
// specific to decoding version 0 addresses directly, as opposed to via the
|
|
// generic API, work as intended. This is necessary because the generic address
|
|
// decoding function contains additional logic to avoid even attempting to
|
|
// decode addresses which can't possibly be one of the supported version 0
|
|
// address types, while the version 0 decoding logic specifically attempts to
|
|
// decode the address in order to provide more detailed errors.
|
|
func TestDecodeAddressV0Corners(t *testing.T) {
|
|
mainNetParams := mockMainNetParams()
|
|
|
|
tests := []struct {
|
|
name string // test description
|
|
addr string // expected address and address to decode
|
|
net AddressParams // params for network
|
|
decodeErr error // expected error from decode
|
|
}{{
|
|
// ---------------------------------------------------------------------
|
|
// Misc decoding error tests.
|
|
// ---------------------------------------------------------------------
|
|
|
|
name: "mainnet p2pk with no data for pubkey",
|
|
addr: "Aiz5jz1s",
|
|
net: mainNetParams,
|
|
decodeErr: ErrMalformedAddressData,
|
|
}, {
|
|
name: "invalid base58 (l not in base58 alphabet)",
|
|
addr: "DsUZxxoHlSty8DCfwfartwTYbuhmVct7tJu",
|
|
net: mainNetParams,
|
|
decodeErr: ErrMalformedAddress,
|
|
}, {
|
|
name: "exceeds max version 0 address size",
|
|
addr: "5HLcANeEU3u2pxrCZFmLoyY4bAH7sgEuiTGcionhA7tzHdecFmgg1LJk",
|
|
net: mainNetParams,
|
|
decodeErr: ErrMalformedAddress,
|
|
}, {
|
|
// ---------------------------------------------------------------------
|
|
// Negative P2PK ECDSA secp256k1 tests.
|
|
// ---------------------------------------------------------------------
|
|
|
|
name: "mainnet p2pk-ecdsa-secp256k1 uncompressed (0x04) rejected via decode",
|
|
addr: "HiQeNVx8PNYP8ysyunUoicyNdfRUrEu1kzPE6v5gECBHBYgDzXCg8BsDGjmaHCpV97ytaQGHz5XDMJgJVHjv9YeSXWkHfwmBJj",
|
|
net: mainNetParams,
|
|
decodeErr: ErrMalformedAddress,
|
|
}, {
|
|
name: "p2pk-ecdsa-secp256k1 malformed pubkey via decode",
|
|
addr: "3tWTcxjUnAKTzHh8pHPYpSsUKVbTvziNGHtbBFQkY12khQWuW83p",
|
|
net: mainNetParams,
|
|
decodeErr: ErrMalformedAddressData,
|
|
}, {
|
|
// ---------------------------------------------------------------------
|
|
// Negative P2PK Ed25519 tests.
|
|
// ---------------------------------------------------------------------
|
|
|
|
name: "p2pk-ed25519 malformed pubkey (only 31 bytes) via decode",
|
|
addr: "3tWUQtEa3P4SDQwjER81wkTxe4kiYLgNAso3pt2X5k3NFHRVQeNv",
|
|
net: mainNetParams,
|
|
decodeErr: ErrMalformedAddressData,
|
|
}, {
|
|
// ---------------------------------------------------------------------
|
|
// Negative P2PK Schnorr secp256k1 tests.
|
|
// ---------------------------------------------------------------------
|
|
|
|
name: "mainnet p2pk-schnorr-secp256k1 uncompressed (0x04) rejected via decode",
|
|
addr: "HiQjU9uCJtiQD7osQuYHWJRFiBCTuqtaTw8QFMtMgAW2ny4nUENeXDiV5VxfVZrK6PZynKPDpL7bwc6XLFNpV8k7ePDJmkkVCh",
|
|
net: mainNetParams,
|
|
decodeErr: ErrMalformedAddress,
|
|
}, {
|
|
name: "p2pk-schnorr-secp256k1 malformed pubkey via decode",
|
|
addr: "3tWUW3oD87XtmFVGnLX4Z3Hdesm2qRvvN8H5kq3yXxJumCxbvCpo",
|
|
net: mainNetParams,
|
|
decodeErr: ErrMalformedAddressData,
|
|
}}
|
|
|
|
for _, test := range tests {
|
|
_, err := DecodeAddressV0(test.addr, test.net)
|
|
if !errors.Is(err, test.decodeErr) {
|
|
t.Errorf("%s: mismatched err -- got %v, want %v", test.name, err,
|
|
test.decodeErr)
|
|
continue
|
|
}
|
|
}
|
|
}
|
|
|
|
// TestProbablyV0Base58Addr ensures the function that determines if an address
|
|
// is probably a base58 address works as intended by checking off by ones and
|
|
// ensuring all allowed characters in the modified base58 alphabet are accepted.
|
|
func TestProbablyV0Base58Addr(t *testing.T) {
|
|
tests := []struct {
|
|
name string // test description
|
|
str string // string to test
|
|
want bool // expected result
|
|
}{{
|
|
name: "all allowed base58 chars part 1",
|
|
str: "123456789ABCDEFGHJKLMNPQRSTUVWXYZab",
|
|
want: true,
|
|
}, {
|
|
name: "all allowed base58 chars part 2",
|
|
str: "QRSTUVWXYZabcdefghijkmnopqrstuvwxyz",
|
|
want: true,
|
|
}, {
|
|
name: "invalid base58 (0 not in base58 alphabet, one less than '1')",
|
|
str: "DsUZxxoH0Sty8DCfwfartwTYbuhmVct7tJu",
|
|
want: false,
|
|
}, {
|
|
name: "invalid base58 ({ not in base58 alphabet, one more than 'z')",
|
|
str: "DsUZxxoH{Sty8DCfwfartwTYbuhmVct7tJu",
|
|
want: false,
|
|
}, {
|
|
name: "invalid base58 (I not in base58 alphabet)",
|
|
str: "DsUZxxoHISty8DCfwfartwTYbuhmVct7tJu",
|
|
want: false,
|
|
}, {
|
|
name: "invalid base58 (O not in base58 alphabet)",
|
|
str: "DsUZxxoHOSty8DCfwfartwTYbuhmVct7tJu",
|
|
want: false,
|
|
}, {
|
|
name: "invalid base58 (l not in base58 alphabet)",
|
|
str: "DsUZxxoHlSty8DCfwfartwTYbuhmVct7tJu",
|
|
want: false,
|
|
}, {
|
|
name: "invalid base58 (: not in base58 alphabet, one more than '9')",
|
|
str: "DsUZxxoH:Sty8DCfwfartwTYbuhmVct7tJu",
|
|
want: false,
|
|
}, {
|
|
name: "invalid base58 (@ not in base58 alphabet, one less than 'A')",
|
|
str: "DsUZxxoH@Sty8DCfwfartwTYbuhmVct7tJu",
|
|
want: false,
|
|
}, {
|
|
name: "invalid base58 ([ not in base58 alphabet, one more than 'Z')",
|
|
str: "DsUZxxoH[Sty8DCfwfartwTYbuhmVct7tJu",
|
|
want: false,
|
|
}, {
|
|
name: "invalid base58 (` not in base58 alphabet, one less than 'a')",
|
|
str: "DsUZxxoH`Sty8DCfwfartwTYbuhmVct7tJu",
|
|
want: false,
|
|
}}
|
|
|
|
for _, test := range tests {
|
|
got := probablyV0Base58Addr(test.str)
|
|
if got != test.want {
|
|
t.Errorf("%q: unexpected result -- got %v, want %v", test.name, got,
|
|
test.want)
|
|
continue
|
|
}
|
|
}
|
|
}
|