func (p *Payment) WitnessScriptHash() (string, error) {
	if p.WitnessHash == nil || len(p.WitnessHash) == 0 {
		return "", errors.New("payment's witnessHash can't be empty or nil")
	}
	version := byte(0x00)
	payload := &address.Bech32{p.Network.Bech32, version, p.WitnessHash}
	addr, err := address.ToBech32(payload)
	if err != nil {
		return "", err
	}
	return addr, nil
}
WitnessScriptHash is a method of the Payment struct to derive a base58 p2wsh address
package payment
import (
	"crypto/sha256"
	"errors"
	"fmt"
	"hash"
	"github.com/btcsuite/btcd/btcec"
	"github.com/btcsuite/btcd/txscript"
	"github.com/btcsuite/btcutil/base58"
	"github.com/vulpemventures/go-elements/address"
	"github.com/vulpemventures/go-elements/network"
	"golang.org/x/crypto/ripemd160"
)
type Payment struct {
	Hash          []byte
	WitnessHash   []byte
	Script        []byte
	WitnessScript []byte
	Redeem        *Payment
	PublicKey     *btcec.PublicKey
	BlindingKey   *btcec.PublicKey
	Network       *network.Network
}
func FromPublicKey(
	pubkey *btcec.PublicKey,
	net *network.Network,
	blindingKey *btcec.PublicKey,
) *Payment {
	var tmpNet *network.Network
	if net == nil {
		tmpNet = &network.Liquid
	} else {
		tmpNet = net
	}
	publicKeyBytes := pubkey.SerializeCompressed()
	pkHash := Hash160(publicKeyBytes)
	script := buildScript(pkHash, "p2pkh")
	witnessScript := buildScript(pkHash, "p2wpkh")
	return &Payment{
		Hash:          pkHash,
		WitnessHash:   pkHash,
		Script:        script,
		WitnessScript: witnessScript,
		Network:       tmpNet,
		PublicKey:     pubkey,
		BlindingKey:   blindingKey,
	}
}
func FromPublicKeys(
	pubkeys []*btcec.PublicKey,
	nrequired int,
	net *network.Network,
	blindingKey *btcec.PublicKey,
) (*Payment, error) {
	if len(pubkeys) < nrequired {
		errorMsg := fmt.Sprintf("unable to generate multisig script with "+
			"%d required signatures when there are only %d public "+
			"keys available", nrequired, len(pubkeys))
		return nil, errors.New(errorMsg)
	}
	var tmpNet *network.Network
	if net == nil {
		tmpNet = &network.Liquid
	} else {
		tmpNet = net
	}
	builder := txscript.NewScriptBuilder().AddInt64(int64(nrequired))
	for _, key := range pubkeys {
		builder.AddData(key.SerializeCompressed())
	}
	builder.AddInt64(int64(len(pubkeys)))
	builder.AddOp(txscript.OP_CHECKMULTISIG)
	multiSigScript, err := builder.Script()
	if err != nil {
		return nil, err
	}
	redeem, err := FromScript(multiSigScript, tmpNet, blindingKey)
	if err != nil {
		return nil, err
	}
	return FromPayment(redeem)
}
func FromPayment(payment *Payment) (*Payment, error) {
	if payment.Script == nil || len(payment.Script) == 0 {
		return nil, errors.New("payment's script can't be empty or nil")
	}
	redeem := payment.copy()
	scriptToHash := make([]byte, 0)
	if len(redeem.WitnessScript) > 0 {
		scriptToHash = redeem.WitnessScript
	} else {
		scriptToHash = redeem.Script
	}
	scriptHash := Hash160(scriptToHash)
	witnessScriptHash := sha256.Sum256(scriptToHash)
	script := buildScript(scriptHash, "p2sh")
	witnessScript := buildScript(witnessScriptHash[:], "p2wsh")
	return &Payment{
		Hash:          scriptHash,
		WitnessHash:   witnessScriptHash[:],
		Script:        script,
		WitnessScript: witnessScript,
		Redeem:        redeem,
		Network:       redeem.Network,
		BlindingKey:   redeem.BlindingKey,
	}, nil
}
func FromScript(
	script []byte,
	net *network.Network,
	blindingKey *btcec.PublicKey,
) (*Payment, error) {
	if script == nil || len(script) == 0 {
		return nil, errors.New("payment's script can't be empty or nil")
	}
	var tmpNet *network.Network
	if net == nil {
		tmpNet = &network.Liquid
	} else {
		tmpNet = net
	}
	scriptHash := make([]byte, 0)
	witnessScriptHash := make([]byte, 0)
	_script := make([]byte, 0)
	witnessScript := make([]byte, 0)
	switch address.GetScriptType(script) {
	case address.P2WpkhScript:
		scriptHash = append(scriptHash, script[2:]...)
		_script = buildScript(scriptHash, "p2pkh")
		witnessScriptHash = append(scriptHash, script[2:]...)
		witnessScript = script
	case address.P2WshScript:
		witnessScriptHash = append(scriptHash, script[2:]...)
		witnessScript = script
	case address.P2ShScript:
		scriptHash = append(scriptHash, script[2:len(script)-1]...)
		_script = script
	case address.P2PkhScript:
		scriptHash = append(scriptHash, script[3:len(script)-2]...)
		_script = script
	default:
		_script = script
	}
	return &Payment{
		Hash:          scriptHash,
		WitnessHash:   witnessScriptHash,
		Script:        _script,
		WitnessScript: witnessScript,
		Network:       tmpNet,
		BlindingKey:   blindingKey,
	}, nil
}
func (p *Payment) PubKeyHash() (string, error) {
	if p.Hash == nil || len(p.Hash) == 0 {
		return "", errors.New("payment's hash can't be empty or nil")
	}
	payload := &address.Base58{p.Network.PubKeyHash, p.Hash}
	addr := address.ToBase58(payload)
	return addr, nil
}
func (p *Payment) ConfidentialPubKeyHash() (string, error) {
	if p.Hash == nil || len(p.Hash) == 0 {
		return "", errors.New("payment's hash can't be empty or nil")
	}
	if p.BlindingKey == nil {
		return "", errors.New("payment's blinding key can't be nil")
	}
	prefix := [1]byte{p.Network.PubKeyHash}
	confidentialAddress := append(
		append(
			prefix[:],
			p.BlindingKey.SerializeCompressed()...,
		),
		p.Hash...,
	)
	return base58.CheckEncode(confidentialAddress, p.Network.Confidential), nil
}
func (p *Payment) ScriptHash() (string, error) {
	if p.Hash == nil || len(p.Hash) == 0 {
		return "", errors.New("payment's hash can't be empty or nil")
	}
	payload := &address.Base58{p.Network.ScriptHash, p.Hash}
	addr := address.ToBase58(payload)
	return addr, nil
}
func (p *Payment) ConfidentialScriptHash() (string, error) {
	if p.Hash == nil || len(p.Hash) == 0 {
		return "", errors.New("payment's hash can't be empty or nil")
	}
	if p.BlindingKey == nil {
		return "", errors.New("payment's blinding key can't be nil")
	}
	prefix := [1]byte{p.Network.ScriptHash}
	confidentialAddress := append(
		append(
			prefix[:],
			p.BlindingKey.SerializeCompressed()...,
		),
		p.Hash...,
	)
	return base58.CheckEncode(confidentialAddress, p.Network.Confidential), nil
}
func (p *Payment) WitnessPubKeyHash() (string, error) {
	if p.WitnessHash == nil || len(p.WitnessHash) == 0 {
		return "", errors.New("payment's hash can't be empty or nil")
	}
	version := byte(0x00)
	payload := &address.Bech32{p.Network.Bech32, version, p.WitnessHash}
	addr, err := address.ToBech32(payload)
	if err != nil {
		return "", nil
	}
	return addr, nil
}
func (p *Payment) ConfidentialWitnessPubKeyHash() (string, error) {
	if p.WitnessHash == nil || len(p.WitnessHash) == 0 {
		return "", errors.New("payment's hash can't be empty or nil")
	}
	version := byte(0x00)
	payload := &address.Blech32{
		p.Network.Blech32,
		version,
		p.BlindingKey.SerializeCompressed(),
		p.WitnessHash,
	}
	addr, err := address.ToBlech32(payload)
	if err != nil {
		return "", nil
	}
	return addr, nil
}