+++ /dev/null
-package types
-
-import (
- "fmt"
- "io"
-
- "github.com/vapor/encoding/blockchain"
- "github.com/vapor/errors"
- "github.com/vapor/protocol/bc"
-)
-
-// serflag variables for input types.
-const (
- IssuanceInputType uint8 = iota
- SpendInputType
- CoinbaseInputType
- ClainPeginInputType
-)
-
-type (
- // TxInput is the top level struct of tx input.
- TxInput struct {
- AssetVersion uint64
- TypedInput
- CommitmentSuffix []byte
- WitnessSuffix []byte
- Peginwitness [][]byte
- }
-
- // TypedInput return the txinput type.
- TypedInput interface {
- InputType() uint8
- }
-)
-
-var errBadAssetID = errors.New("asset ID does not match other issuance parameters")
-
-// AssetAmount return the asset id and amount of the txinput.
-func (t *TxInput) AssetAmount() bc.AssetAmount {
- switch inp := t.TypedInput.(type) {
- case *IssuanceInput:
- assetID := inp.AssetID()
- return bc.AssetAmount{
- AssetId: &assetID,
- Amount: inp.Amount,
- }
- case *SpendInput:
- return inp.AssetAmount
- case *ClaimInput:
- return inp.AssetAmount
- }
- return bc.AssetAmount{}
-}
-
-// AssetID return the assetID of the txinput
-func (t *TxInput) AssetID() bc.AssetID {
- switch inp := t.TypedInput.(type) {
- case *IssuanceInput:
- return inp.AssetID()
- case *SpendInput:
- return *inp.AssetId
- case *ClaimInput:
- return *inp.AssetId
-
- }
- return bc.AssetID{}
-}
-
-// Amount return the asset amount of the txinput
-func (t *TxInput) Amount() uint64 {
- switch inp := t.TypedInput.(type) {
- case *IssuanceInput:
- return inp.Amount
- case *SpendInput:
- return inp.Amount
- case *ClaimInput:
- return inp.Amount
- }
- return 0
-}
-
-// ControlProgram return the control program of the spend input
-func (t *TxInput) ControlProgram() []byte {
- if si, ok := t.TypedInput.(*SpendInput); ok {
- return si.ControlProgram
- }
- return nil
-}
-
-// IssuanceProgram return the control program of the issuance input
-func (t *TxInput) IssuanceProgram() []byte {
- if ii, ok := t.TypedInput.(*IssuanceInput); ok {
- return ii.IssuanceProgram
- }
- return nil
-}
-
-// AssetDefinition return the asset definition of the issuance input
-func (t *TxInput) AssetDefinition() []byte {
- if ii, ok := t.TypedInput.(*IssuanceInput); ok {
- return ii.AssetDefinition
- }
- return nil
-}
-
-// Arguments get the args for the input
-func (t *TxInput) Arguments() [][]byte {
- switch inp := t.TypedInput.(type) {
- case *IssuanceInput:
- return inp.Arguments
- case *SpendInput:
- return inp.Arguments
- case *ClaimInput:
- return inp.Arguments
- }
- return nil
-}
-
-// SetArguments set the args for the input
-func (t *TxInput) SetArguments(args [][]byte) {
- switch inp := t.TypedInput.(type) {
- case *IssuanceInput:
- inp.Arguments = args
- case *SpendInput:
- inp.Arguments = args
- case *ClaimInput:
- inp.Arguments = args
- }
-}
-
-// SpentOutputID calculate the hash of spended output
-func (t *TxInput) SpentOutputID() (o bc.Hash, err error) {
- if si, ok := t.TypedInput.(*SpendInput); ok {
- o, err = ComputeOutputID(&si.SpendCommitment)
- }
- return o, err
-}
-
-func (t *TxInput) readFrom(r *blockchain.Reader) (err error) {
- if t.AssetVersion, err = blockchain.ReadVarint63(r); err != nil {
- return err
- }
-
- if t.Peginwitness, err = blockchain.ReadVarstrList(r); err != nil {
- return err
- }
- var assetID bc.AssetID
- t.CommitmentSuffix, err = blockchain.ReadExtensibleString(r, func(r *blockchain.Reader) error {
- if t.AssetVersion != 1 {
- return nil
- }
- var icType [1]byte
- if _, err = io.ReadFull(r, icType[:]); err != nil {
- return errors.Wrap(err, "reading input commitment type")
- }
- switch icType[0] {
- case IssuanceInputType:
- ii := new(IssuanceInput)
- t.TypedInput = ii
-
- if ii.Nonce, err = blockchain.ReadVarstr31(r); err != nil {
- return err
- }
- if _, err = assetID.ReadFrom(r); err != nil {
- return err
- }
- if ii.Amount, err = blockchain.ReadVarint63(r); err != nil {
- return err
- }
-
- case SpendInputType:
- si := new(SpendInput)
- t.TypedInput = si
- if si.SpendCommitmentSuffix, err = si.SpendCommitment.readFrom(r, 1); err != nil {
- return err
- }
- case ClainPeginInputType:
- ci := new(ClaimInput)
- t.TypedInput = ci
- if ci.SpendCommitmentSuffix, err = ci.SpendCommitment.readFrom(r, 1); err != nil {
- return err
- }
- case CoinbaseInputType:
- ci := new(CoinbaseInput)
- t.TypedInput = ci
- if ci.Arbitrary, err = blockchain.ReadVarstr31(r); err != nil {
- return err
- }
- default:
- return fmt.Errorf("unsupported input type %d", icType[0])
- }
- return nil
- })
- if err != nil {
- return err
- }
-
- t.WitnessSuffix, err = blockchain.ReadExtensibleString(r, func(r *blockchain.Reader) error {
- if t.AssetVersion != 1 {
- return nil
- }
-
- switch inp := t.TypedInput.(type) {
- case *IssuanceInput:
- if inp.AssetDefinition, err = blockchain.ReadVarstr31(r); err != nil {
- return err
- }
- if inp.VMVersion, err = blockchain.ReadVarint63(r); err != nil {
- return err
- }
- if inp.IssuanceProgram, err = blockchain.ReadVarstr31(r); err != nil {
- return err
- }
- if inp.AssetID() != assetID {
- return errBadAssetID
- }
- if inp.Arguments, err = blockchain.ReadVarstrList(r); err != nil {
- return err
- }
-
- case *SpendInput:
- if inp.Arguments, err = blockchain.ReadVarstrList(r); err != nil {
- return err
- }
- case *ClaimInput:
- if inp.Arguments, err = blockchain.ReadVarstrList(r); err != nil {
- return err
- }
- }
- return nil
- })
-
- return err
-}
-
-func (t *TxInput) writeTo(w io.Writer) error {
- if _, err := blockchain.WriteVarint63(w, t.AssetVersion); err != nil {
- return errors.Wrap(err, "writing asset version")
- }
-
- if _, err := blockchain.WriteVarstrList(w, t.Peginwitness); err != nil {
- return errors.Wrap(err, "writing pegin witness")
- }
- if _, err := blockchain.WriteExtensibleString(w, t.CommitmentSuffix, t.writeInputCommitment); err != nil {
- return errors.Wrap(err, "writing input commitment")
- }
-
- _, err := blockchain.WriteExtensibleString(w, t.WitnessSuffix, t.writeInputWitness)
- return errors.Wrap(err, "writing input witness")
-}
-
-func (t *TxInput) writeInputCommitment(w io.Writer) (err error) {
- if t.AssetVersion != 1 {
- return nil
- }
-
- switch inp := t.TypedInput.(type) {
- case *IssuanceInput:
- if _, err = w.Write([]byte{IssuanceInputType}); err != nil {
- return err
- }
- if _, err = blockchain.WriteVarstr31(w, inp.Nonce); err != nil {
- return err
- }
- assetID := t.AssetID()
- if _, err = assetID.WriteTo(w); err != nil {
- return err
- }
- _, err = blockchain.WriteVarint63(w, inp.Amount)
- return err
-
- case *SpendInput:
- if _, err = w.Write([]byte{SpendInputType}); err != nil {
- return err
- }
- return inp.SpendCommitment.writeExtensibleString(w, inp.SpendCommitmentSuffix, t.AssetVersion)
- case *ClaimInput:
- if _, err = w.Write([]byte{ClainPeginInputType}); err != nil {
- return err
- }
- return inp.SpendCommitment.writeExtensibleString(w, inp.SpendCommitmentSuffix, t.AssetVersion)
- case *CoinbaseInput:
- if _, err = w.Write([]byte{CoinbaseInputType}); err != nil {
- return err
- }
- if _, err = blockchain.WriteVarstr31(w, inp.Arbitrary); err != nil {
- return errors.Wrap(err, "writing coinbase arbitrary")
- }
- }
- return nil
-}
-
-func (t *TxInput) writeInputWitness(w io.Writer) error {
- if t.AssetVersion != 1 {
- return nil
- }
- switch inp := t.TypedInput.(type) {
- case *IssuanceInput:
- if _, err := blockchain.WriteVarstr31(w, inp.AssetDefinition); err != nil {
- return err
- }
- if _, err := blockchain.WriteVarint63(w, inp.VMVersion); err != nil {
- return err
- }
- if _, err := blockchain.WriteVarstr31(w, inp.IssuanceProgram); err != nil {
- return err
- }
- _, err := blockchain.WriteVarstrList(w, inp.Arguments)
- return err
-
- case *SpendInput:
- _, err := blockchain.WriteVarstrList(w, inp.Arguments)
- return err
- case *ClaimInput:
- _, err := blockchain.WriteVarstrList(w, inp.Arguments)
-
- return err
- }
- return nil
-}