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

     1  package types
     2  
     3  import (
     4  	"fmt"
     5  	"io"
     6  
     7  	"github.com/bytom/bytom/crypto/sha3pool"
     8  	"github.com/bytom/bytom/encoding/blockchain"
     9  	"github.com/bytom/bytom/errors"
    10  	"github.com/bytom/bytom/protocol/bc"
    11  )
    12  
    13  // OutputCommitment contains the commitment data for a transaction output.
    14  type OutputCommitment struct {
    15  	bc.AssetAmount
    16  	VMVersion      uint64
    17  	ControlProgram []byte
    18  }
    19  
    20  func (oc *OutputCommitment) writeExtensibleString(w io.Writer, suffix []byte, assetVersion uint64) error {
    21  	_, err := blockchain.WriteExtensibleString(w, suffix, func(w io.Writer) error {
    22  		return oc.writeContents(w, suffix, assetVersion)
    23  	})
    24  	return err
    25  }
    26  
    27  func (oc *OutputCommitment) writeContents(w io.Writer, suffix []byte, assetVersion uint64) (err error) {
    28  	if assetVersion == 1 {
    29  		if _, err = oc.AssetAmount.WriteTo(w); err != nil {
    30  			return errors.Wrap(err, "writing asset amount")
    31  		}
    32  		if _, err = blockchain.WriteVarint63(w, oc.VMVersion); err != nil {
    33  			return errors.Wrap(err, "writing vm version")
    34  		}
    35  		if _, err = blockchain.WriteVarstr31(w, oc.ControlProgram); err != nil {
    36  			return errors.Wrap(err, "writing control program")
    37  		}
    38  	}
    39  	if len(suffix) > 0 {
    40  		_, err = w.Write(suffix)
    41  	}
    42  	return errors.Wrap(err, "writing suffix")
    43  }
    44  
    45  func (oc *OutputCommitment) readFrom(r *blockchain.Reader, assetVersion uint64) (suffix []byte, err error) {
    46  	return blockchain.ReadExtensibleString(r, func(r *blockchain.Reader) error {
    47  		if assetVersion == 1 {
    48  			if err := oc.AssetAmount.ReadFrom(r); err != nil {
    49  				return errors.Wrap(err, "reading asset+amount")
    50  			}
    51  			oc.VMVersion, err = blockchain.ReadVarint63(r)
    52  			if err != nil {
    53  				return errors.Wrap(err, "reading VM version")
    54  			}
    55  			if oc.VMVersion != 1 {
    56  				return fmt.Errorf("unrecognized VM version %d for asset version 1", oc.VMVersion)
    57  			}
    58  			oc.ControlProgram, err = blockchain.ReadVarstr31(r)
    59  			return errors.Wrap(err, "reading control program")
    60  		}
    61  		return nil
    62  	})
    63  }
    64  
    65  // Hash convert suffix && assetVersion to bc.Hash
    66  func (oc *OutputCommitment) Hash(suffix []byte, assetVersion uint64) (outputhash bc.Hash) {
    67  	h := sha3pool.Get256()
    68  	defer sha3pool.Put256(h)
    69  	oc.writeExtensibleString(h, suffix, assetVersion)
    70  	outputhash.ReadFrom(h)
    71  	return outputhash
    72  }