func MakeLogicSigAccountDelegated(program []byte, args [][]byte, signer ed25519.PrivateKey) (lsa LogicSigAccount, err error) {
	var ma MultisigAccount
	lsig, err := MakeLogicSig(program, args, signer, ma)
	if err != nil {
		return
	}
	signerAccount, err := AccountFromPrivateKey(signer)
	if err != nil {
		return
	}
	lsa = LogicSigAccount{
		Lsig: lsig,
		SigningKey: signerAccount.PublicKey,
	}
	return
}
MakeLogicSigAccountDelegated creates a new delegated LogicSigAccount. This
type of LogicSig has the authority to sign transactions on behalf of another
account, called the delegating account. If the delegating account is a
multisig account, use MakeLogicSigAccountDelegated instead.

The parameter signer is the private key of the delegating account.
package crypto
import (
	"crypto/sha512"
	"errors"
	"fmt"
	"golang.org/x/crypto/ed25519"
	"github.com/algorand/go-algorand-sdk/types"
)
const msigAddrPrefix = "MultisigAddr"
type Account struct {
	PublicKey  ed25519.PublicKey
	PrivateKey ed25519.PrivateKey
	Address    types.Address
}
func init() {
	addrLen := len(types.Address{})
	pkLen := ed25519.PublicKeySize
	if addrLen != pkLen {
		panic("address and public key are different sizes")
	}
}
func GenerateAccount() (kp Account) {
	pk, sk, err := ed25519.GenerateKey(nil)
	if err != nil {
		panic(err)
	}
	var a types.Address
	n := copy(a[:], pk)
	if n != ed25519.PublicKeySize {
		panic("generated public key is the wrong size")
	}
	kp.PublicKey = pk
	kp.PrivateKey = sk
	kp.Address = a
	return
}
func AccountFromPrivateKey(sk ed25519.PrivateKey) (account Account, err error) {
	if len(sk) != ed25519.PrivateKeySize {
		err = errInvalidPrivateKey
		return
	}
	account.PrivateKey = make(ed25519.PrivateKey, len(sk))
	copy(account.PrivateKey, sk)
	account.PublicKey = sk.Public().(ed25519.PublicKey)
	if len(account.PublicKey) != ed25519.PublicKeySize {
		err = errors.New("generated public key is the wrong size")
		return
	}
	copy(account.Address[:], account.PublicKey)
	return
}
type MultisigAccount struct {
	Version uint8
	Threshold uint8
	Pks []ed25519.PublicKey
}
func MultisigAccountWithParams(version uint8, threshold uint8, addrs []types.Address) (ma MultisigAccount, err error) {
	ma.Version = version
	ma.Threshold = threshold
	ma.Pks = make([]ed25519.PublicKey, len(addrs))
	for i := 0; i < len(addrs); i++ {
		ma.Pks[i] = addrs[i][:]
	}
	err = ma.Validate()
	return
}
func MultisigAccountFromSig(sig types.MultisigSig) (ma MultisigAccount, err error) {
	ma.Version = sig.Version
	ma.Threshold = sig.Threshold
	ma.Pks = make([]ed25519.PublicKey, len(sig.Subsigs))
	for i := 0; i < len(sig.Subsigs); i++ {
		c := make([]byte, len(sig.Subsigs[i].Key))
		copy(c, sig.Subsigs[i].Key)
		ma.Pks[i] = c
	}
	err = ma.Validate()
	return
}
func (ma MultisigAccount) Address() (addr types.Address, err error) {
	err = ma.Validate()
	if err != nil {
		return
	}
	buffer := append([]byte(msigAddrPrefix), byte(ma.Version), byte(ma.Threshold))
	for _, pki := range ma.Pks {
		buffer = append(buffer, pki[:]...)
	}
	return sha512.Sum512_256(buffer), nil
}
func (ma MultisigAccount) Validate() (err error) {
	if ma.Version != 1 {
		err = errMsigUnknownVersion
		return
	}
	if ma.Threshold == 0 || len(ma.Pks) == 0 || int(ma.Threshold) > len(ma.Pks) {
		err = errMsigInvalidThreshold
		return
	}
	return
}
func (ma MultisigAccount) Blank() bool {
	if ma.Version != 0 {
		return false
	}
	if ma.Threshold != 0 {
		return false
	}
	if ma.Pks != nil {
		return false
	}
	return true
}
func LogicSigAddress(lsig types.LogicSig) types.Address {
	toBeSigned := programToSign(lsig.Logic)
	checksum := sha512.Sum512_256(toBeSigned)
	var addr types.Address
	n := copy(addr[:], checksum[:])
	if n != ed25519.PublicKeySize {
		panic(fmt.Sprintf("Generated public key has length of %d, expected %d", n, ed25519.PublicKeySize))
	}
	return addr
}
type LogicSigAccount struct {
	_struct struct{} `codec:",omitempty,omitemptyarray"`
	Lsig types.LogicSig `codec:"lsig"`
	SigningKey ed25519.PublicKey `codec:"sigkey"`
}
func MakeLogicSigAccountEscrow(program []byte, args [][]byte) LogicSigAccount {
	return LogicSigAccount{
		Lsig: types.LogicSig{
			Logic: program,
			Args:  args,
		},
	}
}