github.com/Bytom/bytom@v1.1.2-0.20210127130405-ae40204c0b09/protocol/bc/types/txoutput.go (about)

     1  package types
     2  
     3  import (
     4  	"io"
     5  
     6  	"github.com/bytom/bytom/encoding/blockchain"
     7  	"github.com/bytom/bytom/errors"
     8  	"github.com/bytom/bytom/protocol/bc"
     9  )
    10  
    11  // TxOutput is the top level struct of tx output.
    12  type TxOutput struct {
    13  	AssetVersion uint64
    14  	OutputCommitment
    15  	// Unconsumed suffixes of the commitment and witness extensible strings.
    16  	CommitmentSuffix []byte
    17  }
    18  
    19  // NewTxOutput create a new output struct
    20  func NewTxOutput(assetID bc.AssetID, amount uint64, controlProgram []byte) *TxOutput {
    21  	return &TxOutput{
    22  		AssetVersion: 1,
    23  		OutputCommitment: OutputCommitment{
    24  			AssetAmount: bc.AssetAmount{
    25  				AssetId: &assetID,
    26  				Amount:  amount,
    27  			},
    28  			VMVersion:      1,
    29  			ControlProgram: controlProgram,
    30  		},
    31  	}
    32  }
    33  
    34  func (to *TxOutput) readFrom(r *blockchain.Reader) (err error) {
    35  	if to.AssetVersion, err = blockchain.ReadVarint63(r); err != nil {
    36  		return errors.Wrap(err, "reading asset version")
    37  	}
    38  
    39  	if to.CommitmentSuffix, err = to.OutputCommitment.readFrom(r, to.AssetVersion); err != nil {
    40  		return errors.Wrap(err, "reading output commitment")
    41  	}
    42  
    43  	// read and ignore the (empty) output witness
    44  	_, err = blockchain.ReadVarstr31(r)
    45  	return errors.Wrap(err, "reading output witness")
    46  }
    47  
    48  func (to *TxOutput) writeTo(w io.Writer) error {
    49  	if _, err := blockchain.WriteVarint63(w, to.AssetVersion); err != nil {
    50  		return errors.Wrap(err, "writing asset version")
    51  	}
    52  
    53  	if err := to.writeCommitment(w); err != nil {
    54  		return errors.Wrap(err, "writing output commitment")
    55  	}
    56  
    57  	if _, err := blockchain.WriteVarstr31(w, nil); err != nil {
    58  		return errors.Wrap(err, "writing witness")
    59  	}
    60  	return nil
    61  }
    62  
    63  func (to *TxOutput) writeCommitment(w io.Writer) error {
    64  	return to.OutputCommitment.writeExtensibleString(w, to.CommitmentSuffix, to.AssetVersion)
    65  }
    66  
    67  // ComputeOutputID assembles an output entry given a spend commitment and
    68  // computes and returns its corresponding entry ID.
    69  func ComputeOutputID(sc *SpendCommitment) (h bc.Hash, err error) {
    70  	defer func() {
    71  		if r, ok := recover().(error); ok {
    72  			err = r
    73  		}
    74  	}()
    75  	src := &bc.ValueSource{
    76  		Ref:      &sc.SourceID,
    77  		Value:    &sc.AssetAmount,
    78  		Position: sc.SourcePosition,
    79  	}
    80  	o := bc.NewOutput(src, &bc.Program{VmVersion: sc.VMVersion, Code: sc.ControlProgram}, 0)
    81  
    82  	h = bc.EntryID(o)
    83  	return h, nil
    84  }