func (a *AddressProva) String() string {
	return a.EncodeAddress()
}
String returns a human-readable string for the Prova address type.
This is equivalent to calling EncodeAddress, but is provided so the type can
be used as a fmt.Stringer.
package provautil
import (
	"encoding/binary"
	"encoding/hex"
	"errors"
	"github.com/bitgo/prova/btcec"
	"github.com/bitgo/prova/chaincfg"
	"github.com/bitgo/prova/provautil/base58"
	"github.com/btcsuite/golangcrypto/ripemd160"
)
var (
	ErrChecksumMismatch = errors.New("checksum mismatch")
	ErrUnknownAddressType = errors.New("unknown address type")
	ErrAddressCollision = errors.New("address collision")
)
func encodeProvaAddress(keyIDs []btcec.KeyID, hash160 []byte, netID byte) string {
	data := make([]byte, len(keyIDs)*btcec.KeyIDSize+ripemd160.Size)
	copy(data[0:], hash160)
	offset := ripemd160.Size
	for _, keyID := range keyIDs {
		binary.LittleEndian.PutUint32(data[offset:], uint32(keyID))
		offset += btcec.KeyIDSize
	}
	return base58.CheckEncode(data, netID)
}
type Address interface {
	String() string
	EncodeAddress() string
	ScriptAddress() []byte
	ScriptKeyIDs() []btcec.KeyID
	IsForNet(*chaincfg.Params) bool
}
func DecodeAddress(addr string, defaultNet *chaincfg.Params) (Address, error) {
	decoded, netID, err := base58.CheckDecode(addr)
	if err != nil {
		if err == base58.ErrChecksum {
			return nil, ErrChecksumMismatch
		}
		return nil, errors.New("decoded address is of unknown format")
	}
	if chaincfg.IsProvaAddrID(netID) {
		decodedLen := len(decoded)
		mininumKeyIdsCount := 2
		maximumKeyIdsCount := 19
		if decodedLen < ripemd160.Size+(mininumKeyIdsCount*btcec.KeyIDSize) {
			return nil, errors.New("decoded address is of unknown size")
		}
		if decodedLen > ripemd160.Size+(maximumKeyIdsCount*btcec.KeyIDSize) {
			return nil, errors.New("decoded address exceeds maximum size")
		}
		if (decodedLen-ripemd160.Size)%btcec.KeyIDSize != 0 {
			return nil, errors.New("decoded address has invalid size")
		}
		return newAddressProvaFromBytes(decoded, netID)
	}
	return nil, errors.New("decoded address is of unknown size")
}
type AddressProva struct {
	keyIDs []btcec.KeyID
	hash   [ripemd160.Size]byte
	netID  byte
}
func NewAddressProva(pkHash []byte, keyIDs []btcec.KeyID, net *chaincfg.Params) (*AddressProva, error) {
	return newAddressProva(pkHash, keyIDs, net.ProvaAddrID)
}
func newAddressProva(pkHash []byte, keyIDs []btcec.KeyID, netID byte) (*AddressProva, error) {
	if len(pkHash) != ripemd160.Size {
		return nil, errors.New("pkHash must be 20 bytes")
	}
	if len(keyIDs) < 2 {
		return nil, errors.New("keyIDs must have length at least 2")
	}
	if len(keyIDs) > 19 {
		return nil, errors.New("keyIDs must have length at most 19")
	}
	addr := &AddressProva{netID: netID}
	copy(addr.hash[:], pkHash)
	numKeyIDs := len(keyIDs)
	addr.keyIDs = make([]btcec.KeyID, numKeyIDs, numKeyIDs)
	copy(addr.keyIDs, keyIDs)
	return addr, nil
}
func newAddressProvaFromBytes(data []byte, netID byte) (*AddressProva, error) {
	keyIDs := []btcec.KeyID{}
	keyIDSize := btcec.KeyIDSize
	offset := ripemd160.Size
	for i := offset; i <= len(data)-keyIDSize; i += keyIDSize {
		id := btcec.KeyIDFromAddressBuffer(data[i : i+keyIDSize])
		keyIDs = append(keyIDs, id)
	}
	return newAddressProva(data[0:offset], keyIDs, netID)
}
func (a *AddressProva) EncodeAddress() string {
	return encodeProvaAddress(a.keyIDs[:], a.hash[:], a.netID)
}
func (a *AddressProva) ScriptAddress() []byte {
	return a.hash[:]
}
func (a *AddressProva) ScriptKeyIDs() []btcec.KeyID {
	return a.keyIDs[:]
}
func (a *AddressProva) IsForNet(net *chaincfg.Params) bool {
	return a.netID == net.ProvaAddrID
}