From bcb009075bd5f825e57381fab5c135b0eb140953 Mon Sep 17 00:00:00 2001 From: Josh Rickmar Date: Sun, 20 Apr 2014 15:01:48 -0500 Subject: [PATCH] Add method to access P2PKH and P2SH hash arrays. This change adds the Hash160 methods to AddressPubKeyHash and AddressScriptHash so the hash may be accessed as an array, rather than a byte slice with the ScriptAddress method of the Address interface. In situations where arrays are more appropiate than slices (such as for map keys), accessing the array directly this way can significantly improve performance by reducing copying into local arrays. --- address.go | 14 ++++++++++++++ address_test.go | 18 +++++++++++++++++- test_coverage.txt | 22 ++++++++++++---------- 3 files changed, 43 insertions(+), 11 deletions(-) diff --git a/address.go b/address.go index c194d74..a4fd126 100644 --- a/address.go +++ b/address.go @@ -250,6 +250,13 @@ func (a *AddressPubKeyHash) String() string { return a.EncodeAddress() } +// Hash160 returns the underlying array of the pubkey hash. This can be useful +// when an array is more appropiate than a slice (for example, when used as map +// keys). +func (a *AddressPubKeyHash) Hash160() *[ripemd160.Size]byte { + return &a.hash +} + // AddressScriptHash is an Address for a pay-to-script-hash (P2SH) // transaction. type AddressScriptHash struct { @@ -331,6 +338,13 @@ func (a *AddressScriptHash) String() string { return a.EncodeAddress() } +// Hash160 returns the underlying array of the script hash. This can be useful +// when an array is more appropiate than a slice (for example, when used as map +// keys). +func (a *AddressScriptHash) Hash160() *[ripemd160.Size]byte { + return &a.hash +} + // PubKeyFormat describes what format to use for a pay-to-pubkey address. type PubKeyFormat int diff --git a/address_test.go b/address_test.go index 3b855c9..7fe4ac4 100644 --- a/address_test.go +++ b/address_test.go @@ -529,12 +529,28 @@ func TestAddresses(t *testing.T) { saddr, _ = hex.DecodeString(d.String()) } - // Check script address. + // Check script address, as well as the Hash160 method for P2PKH and + // P2SH addresses. if !bytes.Equal(saddr, decoded.ScriptAddress()) { t.Errorf("%v: script addresses do not match:\n%x != \n%x", test.name, saddr, decoded.ScriptAddress()) return } + switch a := decoded.(type) { + case *btcutil.AddressPubKeyHash: + if h := a.Hash160()[:]; !bytes.Equal(saddr, h) { + t.Errorf("%v: hashes do not match:\n%x != \n%x", + test.name, saddr, h) + return + } + + case *btcutil.AddressScriptHash: + if h := a.Hash160()[:]; !bytes.Equal(saddr, h) { + t.Errorf("%v: hashes do not match:\n%x != \n%x", + test.name, saddr, h) + return + } + } // Ensure the address is for the expected network. if !decoded.IsForNet(test.net) { diff --git a/test_coverage.txt b/test_coverage.txt index ac55a98..af66f2c 100644 --- a/test_coverage.txt +++ b/test_coverage.txt @@ -3,29 +3,31 @@ github.com/conformal/btcutil/base58.go Base58Decode 100.00% (20/20) github.com/conformal/btcutil/base58.go Base58Encode 100.00% (15/15) github.com/conformal/btcutil/block.go Block.Tx 100.00% (12/12) github.com/conformal/btcutil/block.go Block.Transactions 100.00% (11/11) -github.com/conformal/btcutil/amount.go NewAmount 100.00% (9/9) github.com/conformal/btcutil/address.go encodeAddress 100.00% (9/9) +github.com/conformal/btcutil/amount.go NewAmount 100.00% (9/9) github.com/conformal/btcutil/amount.go AmountUnit.String 100.00% (8/8) github.com/conformal/btcutil/block.go NewBlockFromBytes 100.00% (7/7) github.com/conformal/btcutil/tx.go NewTxFromBytes 100.00% (7/7) github.com/conformal/btcutil/tx.go Tx.Sha 100.00% (5/5) -github.com/conformal/btcutil/address.go checkBitcoinNet 100.00% (5/5) github.com/conformal/btcutil/block.go Block.Sha 100.00% (5/5) +github.com/conformal/btcutil/address.go checkBitcoinNet 100.00% (5/5) +github.com/conformal/btcutil/hash160.go calcHash 100.00% (2/2) github.com/conformal/btcutil/amount.go Amount.Format 100.00% (2/2) github.com/conformal/btcutil/address.go NewAddressScriptHash 100.00% (2/2) -github.com/conformal/btcutil/hash160.go calcHash 100.00% (2/2) -github.com/conformal/btcutil/block.go Block.MsgBlock 100.00% (1/1) +github.com/conformal/btcutil/block.go OutOfRangeError.Error 100.00% (1/1) github.com/conformal/btcutil/address.go AddressPubKeyHash.EncodeAddress 100.00% (1/1) github.com/conformal/btcutil/address.go AddressPubKeyHash.ScriptAddress 100.00% (1/1) +github.com/conformal/btcutil/address.go AddressPubKeyHash.Hash160 100.00% (1/1) github.com/conformal/btcutil/address.go AddressScriptHash.EncodeAddress 100.00% (1/1) github.com/conformal/btcutil/address.go AddressScriptHash.ScriptAddress 100.00% (1/1) github.com/conformal/btcutil/address.go AddressScriptHash.String 100.00% (1/1) +github.com/conformal/btcutil/address.go AddressScriptHash.Hash160 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/address.go AddressPubKey.String 100.00% (1/1) github.com/conformal/btcutil/amount.go Amount.ToUnit 100.00% (1/1) github.com/conformal/btcutil/amount.go Amount.String 100.00% (1/1) -github.com/conformal/btcutil/block.go OutOfRangeError.Error 100.00% (1/1) +github.com/conformal/btcutil/block.go Block.MsgBlock 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) @@ -38,8 +40,8 @@ github.com/conformal/btcutil/tx.go NewTx 100.00% (1/1) github.com/conformal/btcutil/address.go AddressPubKeyHash.String 100.00% (1/1) github.com/conformal/btcutil/address.go DecodeAddress 95.65% (22/23) github.com/conformal/btcutil/appdata.go appDataDir 92.00% (23/25) -github.com/conformal/btcutil/address.go NewAddressScriptHashFromHash 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/address.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) @@ -47,13 +49,13 @@ github.com/conformal/btcutil/address.go AddressPubKey.serialize 85.71% (6/7) github.com/conformal/btcutil/address.go DecodePrivateKey 83.33% (20/24) github.com/conformal/btcutil/address.go NewAddressPubKey 83.33% (15/18) github.com/conformal/btcutil/block.go Block.TxSha 75.00% (3/4) -github.com/conformal/btcutil/address.go AddressPubKey.IsForNet 60.00% (3/5) -github.com/conformal/btcutil/address.go AddressPubKeyHash.IsForNet 60.00% (3/5) github.com/conformal/btcutil/address.go AddressScriptHash.IsForNet 60.00% (3/5) +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/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/appdata.go AppDataDir 0.00% (0/1) github.com/conformal/btcutil/address.go AddressPubKey.SetFormat 0.00% (0/1) -github.com/conformal/btcutil/address.go AddressPubKey.Format 0.00% (0/1) -github.com/conformal/btcutil ------------------------------- 78.78% (297/377) +github.com/conformal/btcutil ------------------------------- 78.89% (299/379)