func AddressBytes(redeem []byte) []byte {
	h := sha256.Sum256(redeem)
	ripeHash := ripemd160.New()
	if _, err := ripeHash.Write(h[:]); err != nil {
		log.Fatal(err)
	}
	return ripeHash.Sum(nil)
}
AddressBytes returns ripeme160(sha256(redeem)) (address of redeem script).
package address
import (
	"crypto/sha256"
	"errors"
	"fmt"
	"log"
	"github.com/bitgoin/address/base58"
	"github.com/bitgoin/address/btcec"
	"golang.org/x/crypto/ripemd160"
)
var (
	secp256k1 = btcec.S256()
)
type Params struct {
	DumpedPrivateKeyHeader []byte
	AddressHeader          []byte
	P2SHHeader             []byte
	HDPrivateKeyID         []byte
	HDPublicKeyID          []byte
}
type PublicKey struct {
	*btcec.PublicKey
	isCompressed bool
	param        *Params
}
type PrivateKey struct {
	*btcec.PrivateKey
	PublicKey *PublicKey
}
func NewPublicKey(pubKeyByte []byte, param *Params) (*PublicKey, error) {
	key, err := btcec.ParsePubKey(pubKeyByte, secp256k1)
	if err != nil {
		return nil, err
	}
	isCompressed := false
	if len(pubKeyByte) == btcec.PubKeyBytesLenCompressed {
		isCompressed = true
	}
	return &PublicKey{
		PublicKey:    key,
		isCompressed: isCompressed,
		param:        param,
	}, nil
}
func FromWIF(wif string, param *Params) (*PrivateKey, error) {
	pb, err := base58.Decode(wif)
	if err != nil {
		return nil, err
	}
	ok := false
	for _, h := range param.DumpedPrivateKeyHeader {
		if pb[0] == h {
			ok = true
		}
	}
	if !ok {
		return nil, errors.New("wif is invalid")
	}
	isCompressed := false
	if len(pb) == btcec.PrivKeyBytesLen+2 && pb[btcec.PrivKeyBytesLen+1] == 0x01 {
		pb = pb[:len(pb)-1]
		isCompressed = true
		log.Println("compressed")
	}
	priv, pub := btcec.PrivKeyFromBytes(secp256k1, pb[1:])
	return &PrivateKey{
		PrivateKey: priv,
		PublicKey: &PublicKey{
			PublicKey:    pub,
			isCompressed: isCompressed,
			param:        param,
		},
	}, nil
}
func NewPrivateKey(pb []byte, param *Params) *PrivateKey {
	priv, pub := btcec.PrivKeyFromBytes(secp256k1, pb)
	return &PrivateKey{
		PrivateKey: priv,
		PublicKey: &PublicKey{
			PublicKey:    pub,
			isCompressed: true,
			param:        param,
		},
	}
}
func Generate(param *Params) (*PrivateKey, error) {
	prikey, err := btcec.NewPrivateKey(secp256k1)
	if err != nil {
		return nil, err
	}
	key := &PrivateKey{
		PublicKey: &PublicKey{
			PublicKey:    prikey.PubKey(),
			isCompressed: true,
			param:        param,
		},
		PrivateKey: prikey,
	}
	return key, nil
}
func (priv *PrivateKey) Sign(hash []byte) ([]byte, error) {
	sig, err := priv.PrivateKey.Sign(hash)
	if err != nil {
		return nil, err
	}
	return sig.Serialize(), nil
}
func (priv *PrivateKey) WIFAddress() string {
	p := priv.Serialize()
	if priv.PublicKey.isCompressed {
		p = append(p, 0x1)
	}
	p = append(p, 0x0)
	copy(p[1:], p[:len(p)-1])
	p[0] = priv.PublicKey.param.DumpedPrivateKeyHeader[0]
	return base58.Encode(p)
}
func (pub *PublicKey) Serialize() []byte {
	if pub.isCompressed {
		return pub.SerializeCompressed()
	}
	return pub.SerializeUncompressed()
}
func (pub *PublicKey) AddressBytes() []byte {
	shadPublicKeyBytes := sha256.Sum256(pub.Serialize())
	ripeHash := ripemd160.New()
	if _, err := ripeHash.Write(shadPublicKeyBytes[:]); err != nil {
		log.Fatal(err)
	}
	return ripeHash.Sum(nil)
}
func (pub *PublicKey) Address() string {
	ripeHashedBytes := pub.AddressBytes()
	ripeHashedBytes = append(pub.param.AddressHeader, ripeHashedBytes...)
	return base58.Encode(ripeHashedBytes)
}
func DecodeAddress(addr string) ([]byte, error) {
	pb, err := base58.Decode(addr)
	if err != nil {
		return nil, err
	}
	return pb[1:], nil
}
func (pub *PublicKey) Verify(signature []byte, data []byte) error {
	sig, err := btcec.ParseSignature(signature, secp256k1)
	if err != nil {
		return err
	}
	valid := sig.Verify(data, pub.PublicKey)
	if !valid {
		return fmt.Errorf("signature is invalid")
	}
	return nil
}