func (env *Envelope) GenerateReceipt() *Receipt {
	receipt := &Receipt{
		Type: env.Type,
		Hash: env.Hash(),
	}
	return receipt
}
Generate a transaction Receipt containing the Tx hash.
Returned by ABCI methods.
package txs
import (
	"crypto/sha256"
	"encoding/json"
	"fmt"
	"github.com/gallactic/gallactic/crypto"
	e "github.com/gallactic/gallactic/errors"
	"github.com/gallactic/gallactic/txs/tx"
	amino "github.com/tendermint/go-amino"
)
type Envelope struct {
	ChainID     string             `json:"chainId"`
	Type        tx.Type            `json:"type"`
	Tx          tx.Tx              `json:"tx"`
	Signatories []crypto.Signatory `json:"signatories,omitempty"`
	hash        []byte
}
func Enclose(chainId string, tx tx.Tx) *Envelope {
	return &Envelope{
		ChainID: chainId,
		Type:    tx.Type(),
		Tx:      tx,
	}
}
func (env Envelope) signBytes() ([]byte, error) {
	env.Signatories = nil
	bs, err := json.Marshal(env)
	if err != nil {
		return nil, fmt.Errorf("could not generate canonical SignBytes for tx %v: %v", env, err)
	}
	return bs, nil
}
func (env *Envelope) Hash() []byte {
	if env.hash != nil {
		return env.hash
	}
	if env.Signatories == nil {
		return nil
	}
	bs, err := env.Encode()
	if err != nil {
		return nil
	}
	h := sha256.Sum256(bs)  
	env.hash = h[:]
	return env.hash
}
func (env *Envelope) String() string {
	return fmt.Sprintf("Envelop{TxHash: %X; Tx: %v}", env.Hash(), env.Tx)
}
func (env *Envelope) Verify() error {
	if len(env.Signatories) == 0 {
		return e.Errorf(e.ErrInvalidSignature, "Transaction envelope contains no signatories")
	}
	inputs := env.Tx.Signers()
	if len(inputs) != len(env.Signatories) {
		return e.Errorf(e.ErrInvalidSignature, "Number of inputs (= %v) should equal number of signatories (= %v)",
			len(inputs), len(env.Signatories))
	}
	signBytes, err := env.signBytes()
	if err != nil {
		return e.Errorf(e.ErrInvalidSignature, "Could not generate SignBytes: %v", err)
	}
	for i, s := range env.Signatories {
		if !inputs[i].Address.Verify(s.PublicKey) {
			return e.Errorf(e.ErrInvalidSignature, "Address %v can not be verified", inputs[i].Address)
		}
		if !s.PublicKey.Verify(signBytes, s.Signature) {
			return e.Errorf(e.ErrInvalidSignature, "Invalid signature in signatory %v", inputs[i].Address)
		}
	}
	return nil
}
func (env *Envelope) Sign(signers ...crypto.Signer) error {
	env.Signatories = env.Signatories[:0]
	signBytes, err := env.signBytes()
	if err != nil {
		return err
	}
	signerMap := make(map[crypto.Address]crypto.Signer)
	for _, signer := range signers {
		signerMap[signer.Address()] = signer
	}
	for _, input := range env.Tx.Signers() {
		signer, ok := signerMap[input.Address]
		if !ok {
			return e.Errorf(e.ErrInvalidSignature, "Account to sign %v not passed to Sign", input)
		}
		signature, err := signer.Sign(signBytes)
		if err != nil {
			return err
		}
		publicKey := signer.PublicKey()
		env.Signatories = append(env.Signatories, crypto.Signatory{
			PublicKey: publicKey,
			Signature: signature,
		})
	}
	return nil
}