From 60d4bed78fffbf8d6ba94d5391b5b48249144cb7 Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Tue, 18 Mar 2014 20:18:44 -0500 Subject: [PATCH] Modify DecodeAddress to accept serialized pubkeys. This commit modifies DecodeAddress to accept and decode pay-to-pubkey addresses (raw serialized public keys). Since the resulting Address needs to have a network associated with it, and a raw serialized public key does not encode the network with it, a new parameter has been added which requires the caller to specify a default network to use when decoding addresses. In the case the address has a network encoded with it such as for pay-to-pubkey-hash and pay-to-script-hash addresses, the network will be decoded from the address and the resulting Address instance will have that network associated with it. When the address does NOT have a network encoded with it, such as a pay-to-pubkey address, the provided default network will be associated with the returned Address instance. Also, the tests have been updated to test the new functionality. ok @owainga and @jrick. --- address.go | 17 +++- address_test.go | 228 +++++++++++++++++++++++----------------------- test_coverage.txt | 55 +++++------ 3 files changed, 156 insertions(+), 144 deletions(-) diff --git a/address.go b/address.go index f410468..bb4d891 100644 --- a/address.go +++ b/address.go @@ -118,10 +118,23 @@ type Address interface { // DecodeAddress decodes the string encoding of an address and returns // the Address if addr is a valid encoding for a known address type. -func DecodeAddress(addr string) (Address, error) { - decoded := Base58Decode(addr) +// +// The bitcoin network the address is associated with is extracted if possible. +// When the address does not encode the network, such as in the case of a raw +// public key, the address will be associated with the passed defaultNet. +func DecodeAddress(addr string, defaultNet btcwire.BitcoinNet) (Address, error) { + // Serialized public keys are either 65 bytes (130 hex chars) if + // uncompressed/hybrid or 33 bytes (66 hex chars) if compressed. + if len(addr) == 130 || len(addr) == 66 { + serializedPubKey, err := hex.DecodeString(addr) + if err != nil { + return nil, err + } + return NewAddressPubKey(serializedPubKey, defaultNet) + } // Switch on decoded length to determine the type. + decoded := Base58Decode(addr) switch len(decoded) { case 1 + ripemd160.Size + 4: // P2PKH or P2SH // Parse the network and hash type (pubkey hash vs script diff --git a/address_test.go b/address_test.go index 439946f..3b855c9 100644 --- a/address_test.go +++ b/address_test.go @@ -8,6 +8,7 @@ import ( "bytes" "code.google.com/p/go.crypto/ripemd160" "encoding/hex" + "fmt" "github.com/conformal/btcutil" "github.com/conformal/btcwire" "reflect" @@ -19,20 +20,20 @@ const invalidNet = btcwire.BitcoinNet(0xffffffff) func TestAddresses(t *testing.T) { tests := []struct { - name string - addr string - valid bool - canDecode bool - result btcutil.Address - f func() (btcutil.Address, error) - net btcwire.BitcoinNet + name string + addr string + encoded string + valid bool + result btcutil.Address + f func() (btcutil.Address, error) + net btcwire.BitcoinNet }{ // Positive P2PKH tests. { - name: "mainnet p2pkh", - addr: "1MirQ9bwyQcGVJPwKUgapu5ouK2E2Ey4gX", - valid: true, - canDecode: true, + name: "mainnet p2pkh", + addr: "1MirQ9bwyQcGVJPwKUgapu5ouK2E2Ey4gX", + encoded: "1MirQ9bwyQcGVJPwKUgapu5ouK2E2Ey4gX", + valid: true, result: btcutil.TstAddressPubKeyHash( [ripemd160.Size]byte{ 0xe3, 0x4c, 0xce, 0x70, 0xc8, 0x63, 0x73, 0x27, 0x3e, 0xfc, @@ -47,10 +48,10 @@ func TestAddresses(t *testing.T) { net: btcwire.MainNet, }, { - name: "mainnet p2pkh 2", - addr: "12MzCDwodF9G1e7jfwLXfR164RNtx4BRVG", - valid: true, - canDecode: true, + name: "mainnet p2pkh 2", + addr: "12MzCDwodF9G1e7jfwLXfR164RNtx4BRVG", + encoded: "12MzCDwodF9G1e7jfwLXfR164RNtx4BRVG", + valid: true, result: btcutil.TstAddressPubKeyHash( [ripemd160.Size]byte{ 0x0e, 0xf0, 0x30, 0x10, 0x7f, 0xd2, 0x6e, 0x0b, 0x6b, 0xf4, @@ -65,10 +66,10 @@ func TestAddresses(t *testing.T) { net: btcwire.MainNet, }, { - name: "testnet p2pkh", - addr: "mrX9vMRYLfVy1BnZbc5gZjuyaqH3ZW2ZHz", - valid: true, - canDecode: true, + name: "testnet p2pkh", + addr: "mrX9vMRYLfVy1BnZbc5gZjuyaqH3ZW2ZHz", + encoded: "mrX9vMRYLfVy1BnZbc5gZjuyaqH3ZW2ZHz", + valid: true, result: btcutil.TstAddressPubKeyHash( [ripemd160.Size]byte{ 0x78, 0xb3, 0x16, 0xa0, 0x86, 0x47, 0xd5, 0xb7, 0x72, 0x83, @@ -85,10 +86,10 @@ func TestAddresses(t *testing.T) { // Negative P2PKH tests. { - name: "p2pkh wrong byte identifier/net", - addr: "MrX9vMRYLfVy1BnZbc5gZjuyaqH3ZW2ZHz", - valid: false, - canDecode: true, + name: "p2pkh wrong byte identifier/net", + addr: "MrX9vMRYLfVy1BnZbc5gZjuyaqH3ZW2ZHz", + encoded: "MrX9vMRYLfVy1BnZbc5gZjuyaqH3ZW2ZHz", + valid: false, f: func() (btcutil.Address, error) { pkHash := []byte{ 0x78, 0xb3, 0x16, 0xa0, 0x86, 0x47, 0xd5, 0xb7, 0x72, 0x83, @@ -97,10 +98,9 @@ func TestAddresses(t *testing.T) { }, }, { - name: "p2pkh wrong hash length", - addr: "", - valid: false, - canDecode: true, + name: "p2pkh wrong hash length", + addr: "", + valid: false, f: func() (btcutil.Address, error) { pkHash := []byte{ 0x00, 0x0e, 0xf0, 0x30, 0x10, 0x7f, 0xd2, 0x6e, 0x0b, 0x6b, @@ -110,10 +110,9 @@ func TestAddresses(t *testing.T) { }, }, { - name: "p2pkh bad checksum", - addr: "1MirQ9bwyQcGVJPwKUgapu5ouK2E2Ey4gY", - valid: false, - canDecode: true, + name: "p2pkh bad checksum", + addr: "1MirQ9bwyQcGVJPwKUgapu5ouK2E2Ey4gY", + valid: false, }, // Positive P2SH tests. @@ -121,10 +120,10 @@ func TestAddresses(t *testing.T) { // Taken from transactions: // output: 3c9018e8d5615c306d72397f8f5eef44308c98fb576a88e030c25456b4f3a7ac // input: 837dea37ddc8b1e3ce646f1a656e79bbd8cc7f558ac56a169626d649ebe2a3ba. - name: "mainnet p2sh", - addr: "3QJmV3qfvL9SuYo34YihAf3sRCW3qSinyC", - valid: true, - canDecode: true, + name: "mainnet p2sh", + addr: "3QJmV3qfvL9SuYo34YihAf3sRCW3qSinyC", + encoded: "3QJmV3qfvL9SuYo34YihAf3sRCW3qSinyC", + valid: true, result: btcutil.TstAddressScriptHash( [ripemd160.Size]byte{ 0xf8, 0x15, 0xb0, 0x36, 0xd9, 0xbb, 0xbc, 0xe5, 0xe9, 0xf2, @@ -161,10 +160,10 @@ func TestAddresses(t *testing.T) { // Taken from transactions: // output: b0539a45de13b3e0403909b8bd1a555b8cbe45fd4e3f3fda76f3a5f52835c29d // input: (not yet redeemed at time test was written) - name: "mainnet p2sh 2", - addr: "3NukJ6fYZJ5Kk8bPjycAnruZkE5Q7UW7i8", - valid: true, - canDecode: true, + name: "mainnet p2sh 2", + addr: "3NukJ6fYZJ5Kk8bPjycAnruZkE5Q7UW7i8", + encoded: "3NukJ6fYZJ5Kk8bPjycAnruZkE5Q7UW7i8", + valid: true, result: btcutil.TstAddressScriptHash( [ripemd160.Size]byte{ 0xe8, 0xc3, 0x00, 0xc8, 0x79, 0x86, 0xef, 0xa8, 0x4c, 0x37, @@ -180,10 +179,10 @@ func TestAddresses(t *testing.T) { }, { // Taken from bitcoind base58_keys_valid. - name: "testnet p2sh", - addr: "2NBFNJTktNa7GZusGbDbGKRZTxdK9VVez3n", - valid: true, - canDecode: true, + name: "testnet p2sh", + addr: "2NBFNJTktNa7GZusGbDbGKRZTxdK9VVez3n", + encoded: "2NBFNJTktNa7GZusGbDbGKRZTxdK9VVez3n", + valid: true, result: btcutil.TstAddressScriptHash( [ripemd160.Size]byte{ 0xc5, 0x79, 0x34, 0x2c, 0x2c, 0x4c, 0x92, 0x20, 0x20, 0x5e, @@ -200,10 +199,9 @@ func TestAddresses(t *testing.T) { // Negative P2SH tests. { - name: "p2sh wrong hash length", - addr: "", - valid: false, - canDecode: true, + name: "p2sh wrong hash length", + addr: "", + valid: false, f: func() (btcutil.Address, error) { hash := []byte{ 0x00, 0xf8, 0x15, 0xb0, 0x36, 0xd9, 0xbb, 0xbc, 0xe5, 0xe9, @@ -213,10 +211,9 @@ func TestAddresses(t *testing.T) { }, }, { - name: "p2sh wrong byte identifier/net", - addr: "0NBFNJTktNa7GZusGbDbGKRZTxdK9VVez3n", - valid: false, - canDecode: true, + name: "p2sh wrong byte identifier/net", + addr: "0NBFNJTktNa7GZusGbDbGKRZTxdK9VVez3n", + valid: false, f: func() (btcutil.Address, error) { hash := []byte{ 0xc5, 0x79, 0x34, 0x2c, 0x2c, 0x4c, 0x92, 0x20, 0x20, 0x5e, @@ -227,10 +224,10 @@ func TestAddresses(t *testing.T) { // Positive P2PK tests. { - name: "mainnet p2pk compressed (0x02)", - addr: "13CG6SJ3yHUXo4Cr2RY4THLLJrNFuG3gUg", - valid: true, - canDecode: false, + name: "mainnet p2pk compressed (0x02)", + addr: "02192d74d0cb94344c9569c2e77901573d8d7903c3ebec3a957724895dca52c6b4", + encoded: "13CG6SJ3yHUXo4Cr2RY4THLLJrNFuG3gUg", + valid: true, result: btcutil.TstAddressPubKey( []byte{ 0x02, 0x19, 0x2d, 0x74, 0xd0, 0xcb, 0x94, 0x34, 0x4c, 0x95, @@ -249,10 +246,10 @@ func TestAddresses(t *testing.T) { net: btcwire.MainNet, }, { - name: "mainnet p2pk compressed (0x03)", - addr: "15sHANNUBSh6nDp8XkDPmQcW6n3EFwmvE6", - valid: true, - canDecode: false, + name: "mainnet p2pk compressed (0x03)", + addr: "03b0bd634234abbb1ba1e986e884185c61cf43e001f9137f23c2c409273eb16e65", + encoded: "15sHANNUBSh6nDp8XkDPmQcW6n3EFwmvE6", + valid: true, result: btcutil.TstAddressPubKey( []byte{ 0x03, 0xb0, 0xbd, 0x63, 0x42, 0x34, 0xab, 0xbb, 0x1b, 0xa1, @@ -271,10 +268,11 @@ func TestAddresses(t *testing.T) { net: btcwire.MainNet, }, { - name: "mainnet p2pk uncompressed (0x04)", - addr: "12cbQLTFMXRnSzktFkuoG3eHoMeFtpTu3S", - valid: true, - canDecode: false, + name: "mainnet p2pk uncompressed (0x04)", + addr: "0411db93e1dcdb8a016b49840f8c53bc1eb68a382e97b1482ecad7b148a6909a5cb2" + + "e0eaddfb84ccf9744464f82e160bfa9b8b64f9d4c03f999b8643f656b412a3", + encoded: "12cbQLTFMXRnSzktFkuoG3eHoMeFtpTu3S", + valid: true, result: btcutil.TstAddressPubKey( []byte{ 0x04, 0x11, 0xdb, 0x93, 0xe1, 0xdc, 0xdb, 0x8a, 0x01, 0x6b, @@ -299,10 +297,11 @@ func TestAddresses(t *testing.T) { net: btcwire.MainNet, }, { - name: "mainnet p2pk hybrid (0x06)", - addr: "1Ja5rs7XBZnK88EuLVcFqYGMEbBitzchmX", - valid: true, - canDecode: false, + name: "mainnet p2pk hybrid (0x06)", + addr: "06192d74d0cb94344c9569c2e77901573d8d7903c3ebec3a957724895dca52c6b4" + + "0d45264838c0bd96852662ce6a847b197376830160c6d2eb5e6a4c44d33f453e", + encoded: "1Ja5rs7XBZnK88EuLVcFqYGMEbBitzchmX", + valid: true, result: btcutil.TstAddressPubKey( []byte{ 0x06, 0x19, 0x2d, 0x74, 0xd0, 0xcb, 0x94, 0x34, 0x4c, 0x95, @@ -327,10 +326,11 @@ func TestAddresses(t *testing.T) { net: btcwire.MainNet, }, { - name: "mainnet p2pk hybrid (0x07)", - addr: "1ExqMmf6yMxcBMzHjbj41wbqYuqoX6uBLG", - valid: true, - canDecode: false, + name: "mainnet p2pk hybrid (0x07)", + addr: "07b0bd634234abbb1ba1e986e884185c61cf43e001f9137f23c2c409273eb16e65" + + "37a576782eba668a7ef8bd3b3cfb1edb7117ab65129b8a2e681f3c1e0908ef7b", + encoded: "1ExqMmf6yMxcBMzHjbj41wbqYuqoX6uBLG", + valid: true, result: btcutil.TstAddressPubKey( []byte{ 0x07, 0xb0, 0xbd, 0x63, 0x42, 0x34, 0xab, 0xbb, 0x1b, 0xa1, @@ -355,10 +355,10 @@ func TestAddresses(t *testing.T) { net: btcwire.MainNet, }, { - name: "testnet p2pk compressed (0x02)", - addr: "mhiDPVP2nJunaAgTjzWSHCYfAqxxrxzjmo", - valid: true, - canDecode: false, + name: "testnet p2pk compressed (0x02)", + addr: "02192d74d0cb94344c9569c2e77901573d8d7903c3ebec3a957724895dca52c6b4", + encoded: "mhiDPVP2nJunaAgTjzWSHCYfAqxxrxzjmo", + valid: true, result: btcutil.TstAddressPubKey( []byte{ 0x02, 0x19, 0x2d, 0x74, 0xd0, 0xcb, 0x94, 0x34, 0x4c, 0x95, @@ -377,10 +377,10 @@ func TestAddresses(t *testing.T) { net: btcwire.TestNet3, }, { - name: "testnet p2pk compressed (0x03)", - addr: "mkPETRTSzU8MZLHkFKBmbKppxmdw9qT42t", - valid: true, - canDecode: false, + name: "testnet p2pk compressed (0x03)", + addr: "03b0bd634234abbb1ba1e986e884185c61cf43e001f9137f23c2c409273eb16e65", + encoded: "mkPETRTSzU8MZLHkFKBmbKppxmdw9qT42t", + valid: true, result: btcutil.TstAddressPubKey( []byte{ 0x03, 0xb0, 0xbd, 0x63, 0x42, 0x34, 0xab, 0xbb, 0x1b, 0xa1, @@ -399,10 +399,11 @@ func TestAddresses(t *testing.T) { net: btcwire.TestNet3, }, { - name: "testnet p2pk uncompressed (0x04)", - addr: "mh8YhPYEAYs3E7EVyKtB5xrcfMExkkdEMF", - valid: true, - canDecode: false, + name: "testnet p2pk uncompressed (0x04)", + addr: "0411db93e1dcdb8a016b49840f8c53bc1eb68a382e97b1482ecad7b148a6909a5" + + "cb2e0eaddfb84ccf9744464f82e160bfa9b8b64f9d4c03f999b8643f656b412a3", + encoded: "mh8YhPYEAYs3E7EVyKtB5xrcfMExkkdEMF", + valid: true, result: btcutil.TstAddressPubKey( []byte{ 0x04, 0x11, 0xdb, 0x93, 0xe1, 0xdc, 0xdb, 0x8a, 0x01, 0x6b, @@ -427,10 +428,11 @@ func TestAddresses(t *testing.T) { net: btcwire.TestNet3, }, { - name: "testnet p2pk hybrid (0x06)", - addr: "my639vCVzbDZuEiX44adfTUg6anRomZLEP", - valid: true, - canDecode: false, + name: "testnet p2pk hybrid (0x06)", + addr: "06192d74d0cb94344c9569c2e77901573d8d7903c3ebec3a957724895dca52c6b" + + "40d45264838c0bd96852662ce6a847b197376830160c6d2eb5e6a4c44d33f453e", + encoded: "my639vCVzbDZuEiX44adfTUg6anRomZLEP", + valid: true, result: btcutil.TstAddressPubKey( []byte{ 0x06, 0x19, 0x2d, 0x74, 0xd0, 0xcb, 0x94, 0x34, 0x4c, 0x95, @@ -455,10 +457,11 @@ func TestAddresses(t *testing.T) { net: btcwire.TestNet3, }, { - name: "testnet p2pk hybrid (0x07)", - addr: "muUnepk5nPPrxUTuTAhRqrpAQuSWS5fVii", - valid: true, - canDecode: false, + name: "testnet p2pk hybrid (0x07)", + addr: "07b0bd634234abbb1ba1e986e884185c61cf43e001f9137f23c2c409273eb16e6" + + "537a576782eba668a7ef8bd3b3cfb1edb7117ab65129b8a2e681f3c1e0908ef7b", + encoded: "muUnepk5nPPrxUTuTAhRqrpAQuSWS5fVii", + valid: true, result: btcutil.TstAddressPubKey( []byte{ 0x07, 0xb0, 0xbd, 0x63, 0x42, 0x34, 0xab, 0xbb, 0x1b, 0xa1, @@ -485,33 +488,29 @@ func TestAddresses(t *testing.T) { } for _, test := range tests { - var decoded btcutil.Address - var err error - if test.canDecode { - // Decode addr and compare error against valid. - decoded, err = btcutil.DecodeAddress(test.addr) - if (err == nil) != test.valid { - t.Errorf("%v: decoding test failed", test.name) - return - } - } else { - // The address can't be decoded directly, so instead - // call the creation function. - decoded, err = test.f() - if (err == nil) != test.valid { - t.Errorf("%v: creation test failed", test.name) - return - } + // Decode addr and compare error against valid. + decoded, err := btcutil.DecodeAddress(test.addr, test.net) + if (err == nil) != test.valid { + t.Errorf("%v: decoding test failed: %v", test.name, err) + return } - // If decoding succeeded, encode again and compare against the original. if err == nil { - encoded := decoded.EncodeAddress() + // Ensure the stringer returns the same address as the + // original. + if decodedStringer, ok := decoded.(fmt.Stringer); ok { + if test.addr != decodedStringer.String() { + t.Errorf("%v: String on decoded value does not match expected value: %v != %v", + test.name, test.addr, decodedStringer.String()) + return + } + } - // Compare encoded addr against the original encoding. - if test.addr != encoded { + // Encode again and compare against the original. + encoded := decoded.EncodeAddress() + if test.encoded != encoded { t.Errorf("%v: decoding and encoding produced different addressess: %v != %v", - test.name, test.addr, encoded) + test.name, test.encoded, encoded) return } @@ -537,8 +536,7 @@ func TestAddresses(t *testing.T) { return } - // Check networks. This check always succeeds for non-P2PKH and - // non-P2SH addresses as both nets will be Go's default zero value. + // Ensure the address is for the expected network. if !decoded.IsForNet(test.net) { t.Errorf("%v: calculated network does not match expected", test.name) diff --git a/test_coverage.txt b/test_coverage.txt index f1b56d7..87af8cb 100644 --- a/test_coverage.txt +++ b/test_coverage.txt @@ -1,6 +1,5 @@ github.com/conformal/btcutil/base58.go Base58Decode 100.00% (20/20) -github.com/conformal/btcutil/address.go DecodeAddr 100.00% (18/18) github.com/conformal/btcutil/base58.go Base58Encode 100.00% (15/15) github.com/conformal/btcutil/addrconvs.go DecodeAddress 100.00% (14/14) github.com/conformal/btcutil/block.go Block.Tx 100.00% (12/12) @@ -9,50 +8,52 @@ github.com/conformal/btcutil/block.go Block.TxShas 100.00% (10/10) github.com/conformal/btcutil/address.go encodeAddress 100.00% (9/9) github.com/conformal/btcutil/addrconvs.go EncodeAddress 100.00% (8/8) github.com/conformal/btcutil/addrconvs.go EncodeScriptHash 100.00% (8/8) -github.com/conformal/btcutil/address.go NewAddressScriptHashFromHash 100.00% (7/7) github.com/conformal/btcutil/addrconvs.go encodeHashWithNetId 100.00% (7/7) -github.com/conformal/btcutil/address.go NewAddressPubKeyHash 100.00% (7/7) github.com/conformal/btcutil/tx.go NewTxFromBytes 100.00% (7/7) github.com/conformal/btcutil/block.go NewBlockFromBytes 100.00% (7/7) -github.com/conformal/btcutil/address.go AddressPubKeyHash.EncodeAddress 100.00% (5/5) github.com/conformal/btcutil/block.go Block.Sha 100.00% (5/5) -github.com/conformal/btcutil/address.go AddressScriptHash.EncodeAddress 100.00% (5/5) github.com/conformal/btcutil/tx.go Tx.Sha 100.00% (5/5) -github.com/conformal/btcutil/address.go AddressPubKey.EncodeAddress 100.00% (5/5) github.com/conformal/btcutil/block.go Block.TxSha 100.00% (4/4) -github.com/conformal/btcutil/address.go checkBitcoinNet 100.00% (3/3) github.com/conformal/btcutil/hash160.go calcHash 100.00% (2/2) github.com/conformal/btcutil/address.go NewAddressScriptHash 100.00% (2/2) -github.com/conformal/btcutil/hash160.go Hash160 100.00% (1/1) -github.com/conformal/btcutil/address.go AddressPubKeyHash.ScriptAddress 100.00% (1/1) -github.com/conformal/btcutil/address.go AddressPubKeyHash.Net 100.00% (1/1) -github.com/conformal/btcutil/address.go AddressScriptHash.ScriptAddress 100.00% (1/1) -github.com/conformal/btcutil/address.go AddressScriptHash.Net 100.00% (1/1) -github.com/conformal/btcutil/block.go OutOfRangeError.Error 100.00% (1/1) -github.com/conformal/btcutil/address.go AddressPubKey.ScriptAddress 100.00% (1/1) -github.com/conformal/btcutil/address.go AddressPubKey.Net 100.00% (1/1) -github.com/conformal/btcutil/address.go AddressPubKey.String 100.00% (1/1) +github.com/conformal/btcutil/block.go NewBlock 100.00% (1/1) +github.com/conformal/btcutil/tx.go NewTx 100.00% (1/1) +github.com/conformal/btcutil/address.go AddressScriptHash.String 100.00% (1/1) +github.com/conformal/btcutil/tx.go Tx.SetIndex 100.00% (1/1) github.com/conformal/btcutil/block.go Block.MsgBlock 100.00% (1/1) +github.com/conformal/btcutil/block.go NewBlockFromBlockAndBytes 100.00% (1/1) +github.com/conformal/btcutil/address.go AddressScriptHash.ScriptAddress 100.00% (1/1) +github.com/conformal/btcutil/address.go AddressPubKeyHash.ScriptAddress 100.00% (1/1) +github.com/conformal/btcutil/address.go AddressPubKeyHash.EncodeAddress 100.00% (1/1) github.com/conformal/btcutil/block.go Block.Height 100.00% (1/1) github.com/conformal/btcutil/block.go Block.SetHeight 100.00% (1/1) -github.com/conformal/btcutil/block.go NewBlock 100.00% (1/1) -github.com/conformal/btcutil/block.go NewBlockFromBlockAndBytes 100.00% (1/1) -github.com/conformal/btcutil/tx.go Tx.MsgTx 100.00% (1/1) +github.com/conformal/btcutil/address.go AddressPubKey.EncodeAddress 100.00% (1/1) +github.com/conformal/btcutil/address.go AddressPubKey.ScriptAddress 100.00% (1/1) github.com/conformal/btcutil/tx.go Tx.Index 100.00% (1/1) -github.com/conformal/btcutil/tx.go Tx.SetIndex 100.00% (1/1) -github.com/conformal/btcutil/tx.go NewTx 100.00% (1/1) +github.com/conformal/btcutil/address.go AddressPubKey.String 100.00% (1/1) +github.com/conformal/btcutil/tx.go Tx.MsgTx 100.00% (1/1) +github.com/conformal/btcutil/address.go AddressScriptHash.EncodeAddress 100.00% (1/1) +github.com/conformal/btcutil/hash160.go Hash160 100.00% (1/1) +github.com/conformal/btcutil/address.go AddressPubKeyHash.String 100.00% (1/1) +github.com/conformal/btcutil/block.go OutOfRangeError.Error 100.00% (1/1) +github.com/conformal/btcutil/address.go DecodeAddr 95.65% (22/23) github.com/conformal/btcutil/appdata.go appDataDir 92.00% (23/25) -github.com/conformal/btcutil/address.go NewAddressPubKey 91.67% (11/12) +github.com/conformal/btcutil/address.go NewAddressPubKeyHash 91.67% (11/12) +github.com/conformal/btcutil/address.go NewAddressScriptHashFromHash 91.67% (11/12) github.com/conformal/btcutil/addrconvs.go EncodePrivateKey 90.91% (20/22) -github.com/conformal/btcutil/block.go Block.TxLoc 88.89% (8/9) github.com/conformal/btcutil/block.go Block.Bytes 88.89% (8/9) +github.com/conformal/btcutil/block.go Block.TxLoc 88.89% (8/9) github.com/conformal/btcutil/address.go AddressPubKey.serialize 85.71% (6/7) +github.com/conformal/btcutil/address.go NewAddressPubKey 83.33% (15/18) +github.com/conformal/btcutil/address.go checkBitcoinNet 83.33% (5/6) github.com/conformal/btcutil/addrconvs.go DecodePrivateKey 82.61% (19/23) -github.com/conformal/btcutil/address.go AddressPubKey.AddressPubKeyHash 0.00% (0/2) +github.com/conformal/btcutil/address.go AddressPubKeyHash.IsForNet 60.00% (3/5) +github.com/conformal/btcutil/address.go AddressPubKey.IsForNet 60.00% (3/5) +github.com/conformal/btcutil/address.go AddressScriptHash.IsForNet 60.00% (3/5) +github.com/conformal/btcutil/certgen.go NewTLSCertPair 0.00% (0/50) +github.com/conformal/btcutil/address.go AddressPubKey.AddressPubKeyHash 0.00% (0/3) github.com/conformal/btcutil/address.go AddressPubKey.Format 0.00% (0/1) github.com/conformal/btcutil/address.go AddressPubKey.SetFormat 0.00% (0/1) -github.com/conformal/btcutil/address.go AddressScriptHash.String 0.00% (0/1) -github.com/conformal/btcutil/address.go AddressPubKeyHash.String 0.00% (0/1) github.com/conformal/btcutil/appdata.go AppDataDir 0.00% (0/1) -github.com/conformal/btcutil ------------------------------- 94.21% (309/328) +github.com/conformal/btcutil ------------------------------- 80.15% (323/403)