package tx import ( crypto "github.com/tendermint/go-crypto" data "github.com/tendermint/go-data" keys "github.com/tendermint/go-crypto/keys" ) const ( typeOneSig = byte(0x01) typeMultiSig = byte(0x02) nameOneSig = "sig" nameMultiSig = "multi" ) var _ keys.Signable = Sig{} var TxMapper data.Mapper func init() { TxMapper = data.NewMapper(Sig{}). RegisterInterface(&OneSig{}, nameOneSig, typeOneSig). RegisterInterface(&MultiSig{}, nameMultiSig, typeMultiSig) } /* DO NOT USE this interface. It is public by necessity but should never be used directly outside of this package. Only use Sig, never SigInner */ type SigInner interface { SignBytes() []byte Sign(pubkey crypto.PubKey, sig crypto.Signature) error Signers() ([]crypto.PubKey, error) } // Sig is what is exported, and handles serialization type Sig struct { SigInner } // TxBytes func (s Sig) TxBytes() ([]byte, error) { return data.ToWire(s) } // WrapSig goes from concrete implementation to "interface" struct func WrapSig(pk SigInner) Sig { if wrap, ok := pk.(Sig); ok { pk = wrap.Unwrap() } return Sig{pk} } // Unwrap recovers the concrete interface safely (regardless of levels of embeds) func (p Sig) Unwrap() SigInner { pk := p.SigInner for wrap, ok := pk.(Sig); ok; wrap, ok = pk.(Sig) { pk = wrap.SigInner } return pk } func (p Sig) MarshalJSON() ([]byte, error) { return TxMapper.ToJSON(p.Unwrap()) } func (p *Sig) UnmarshalJSON(data []byte) (err error) { parsed, err := TxMapper.FromJSON(data) if err == nil && parsed != nil { p.SigInner = parsed.(SigInner) } return }