diff --git a/address.go b/address.go index a16528c..d1b29cb 100644 --- a/address.go +++ b/address.go @@ -69,19 +69,22 @@ func (a *A25) Set58(s []byte) error { func (a *A25) ComputeChecksum() (c [4]byte) { copy(c[:], a.doubleSHA256()) return -} /* {{header|Go}} */ +} -// AddressFromPrivKey takes a private key string and returns a Bitcoin address -func AddressFromPrivKey(privKey string) string { - pubKey := PrivateKey(privKey).PubKey() - return Address(pubKey).EncodeAddress() +// AddressFromPrivateKey takes a private key string and returns a Bitcoin address +func AddressFromPrivateKey(privateKey string) (string, error) { + pubKey := PrivateKey(privateKey).PubKey() + address, err := Address(pubKey) + if err != nil { + return "", err + } + return address.EncodeAddress(), nil } // Address gets a bsvutil.LegacyAddressPubKeyHash -func Address(publicKey *bsvec.PublicKey) (address *bsvutil.LegacyAddressPubKeyHash) { +func Address(publicKey *bsvec.PublicKey) (*bsvutil.LegacyAddressPubKeyHash, error) { publicKeyHash := bsvutil.Hash160(publicKey.SerializeCompressed()) - address, _ = bsvutil.NewLegacyAddressPubKeyHash(publicKeyHash, &chaincfg.MainNetParams) - return + return bsvutil.NewLegacyAddressPubKeyHash(publicKeyHash, &chaincfg.MainNetParams) } // ValidA58 validates a base58 encoded bitcoin address. An address is valid @@ -89,7 +92,7 @@ func Address(publicKey *bsvec.PublicKey) (address *bsvutil.LegacyAddressPubKeyHa // and the checksum validates. Return value ok will be true for valid // addresses. If ok is false, the address is invalid and the error value // may indicate why. -func ValidA58(a58 []byte) (ok bool, err error) { +func ValidA58(a58 []byte) (bool, error) { var a A25 if err := a.Set58(a58); err != nil { return false, err diff --git a/address_test.go b/address_test.go index 08198bf..5b5225d 100644 --- a/address_test.go +++ b/address_test.go @@ -1,17 +1,60 @@ package bitcoin import ( + "fmt" "testing" ) -// Test address -const address = "1KCEAmVS6FFggtc7W9as7sEENvjt7DqMi2" - +// TestValidA58 will test the method ValidA58() func TestValidA58(t *testing.T) { - valid, err := ValidA58([]byte(address)) + t.Parallel() + + // Create the list of tests + var tests = []struct { + input string + expectedValid bool + expectedError bool + }{ + {"1KCEAmVS6FFggtc7W9as7sEENvjt7DqMi2", true, false}, + {"1KCEAmVS6FFggtc7W9as7sEENvjt7DqMi", false, false}, + {"1KCEAmV", false, false}, + {"", false, false}, + {"0", false, true}, + } + + // Run tests + for _, test := range tests { + if valid, err := ValidA58([]byte(test.input)); err != nil && !test.expectedError { + t.Errorf("%s Failed: [%s] inputted and error not expected but got: %s", t.Name(), test.input, err.Error()) + } else if err == nil && test.expectedError { + t.Errorf("%s Failed: [%s] inputted and error was expected", t.Name(), test.input) + } else if valid && !test.expectedValid { + t.Errorf("%s Failed: [%s] inputted and was valid but should NOT be valid", t.Name(), test.input) + } else if !valid && test.expectedValid { + t.Errorf("%s Failed: [%s] inputted and was invalid but should be valid", t.Name(), test.input) + } + } +} + +// ExampleValidA58 example using ValidA58() +func ExampleValidA58() { + valid, err := ValidA58([]byte("1KCEAmVS6FFggtc7W9as7sEENvjt7DqMi2")) + if err != nil { + fmt.Printf("error occurred: %s", err.Error()) + return + } else if !valid { + fmt.Printf("address is not valid: %s", "1KCEAmVS6FFggtc7W9as7sEENvjt7DqMi2") + return + } else { + fmt.Printf("address is valid!") + } + // Output:address is valid! +} - if !valid { - t.Error("Failed to validate address", err) +// BenchmarkValidA58 benchmarks the method ValidA58() +func BenchmarkValidA58(b *testing.B) { + for i := 0; i < b.N; i++ { + _, _ = ValidA58([]byte("1KCEAmVS6FFggtc7W9as7sEENvjt7DqMi2")) } }