lbcutil/addrconvs.go

79 lines
2.4 KiB
Go

package btcutil
import (
"bytes"
"code.google.com/p/go.crypto/ripemd160"
"errors"
"github.com/conformal/btcwire"
)
// ErrAddrUnknownNet describes an error where the address identifier
// byte is not recognized as belonging to neither the Bitcoin MainNet nor
// TestNet.
var ErrAddrUnknownNet = errors.New("unrecognized network identifier byte")
// ErrMalformedAddress describes an error where an address is improperly
// formatted, either due to an incorrect length of the hashed pubkey or
// a non-matching checksum.
var ErrMalformedAddress = errors.New("malformed address")
// Constants used to specify which network a payment address belongs
// to. Mainnet address cannot be used on the Testnet, and vice versa.
const (
// MainNetAddr is the address identifier for MainNet
MainNetAddr = 0x00
// TestNetAddr is the address identifier for TestNet
TestNetAddr = 0x6f
)
// EncodeAddress takes a 20-byte raw payment address (hash160 of the
// uncompressed pubkey) and a network identifying byte and encodes the
// payment address in a human readable string.
func EncodeAddress(addrHash []byte, netID byte) (encoded string, err error) {
if len(addrHash) != ripemd160.Size {
return "", ErrMalformedAddress
}
if netID != MainNetAddr && netID != TestNetAddr {
return "", ErrAddrUnknownNet
}
tosum := append([]byte{netID}, addrHash...)
cksum := btcwire.DoubleSha256(tosum)
a := append([]byte{netID}, addrHash...)
a = append(a, cksum[:4]...)
return Base58Encode(a), nil
}
// DecodeAddress decodes a human readable payment address string
// returning the 20-byte decoded address, along with the network
// identifying byte.
func DecodeAddress(addr string) (addrHash []byte, netID byte, err error) {
decoded := Base58Decode(addr)
// Length of decoded address must be 20 bytes + 1 byte for a network
// identifier byte + 4 bytes of checksum.
if len(decoded) != ripemd160.Size+5 {
return nil, 0x00, ErrMalformedAddress
}
netID = decoded[0]
if netID != MainNetAddr && netID != TestNetAddr {
return nil, 0x00, ErrAddrUnknownNet
}
addrHash = decoded[1:21]
// Checksum is first four bytes of double SHA256 of the network byte
// and addrHash. Verify this matches the final 4 bytes of the decoded
// address.
tosum := append([]byte{netID}, addrHash...)
cksum := btcwire.DoubleSha256(tosum)[:4]
if !bytes.Equal(cksum, decoded[len(decoded)-4:]) {
return nil, 0x00, ErrMalformedAddress
}
return addrHash, netID, nil
}