github.com/bytom/bytom@v1.1.2-0.20221014091027-bbcba3df6075/protocol/bc/tx.go (about)

     1  package bc
     2  
     3  import (
     4  	"github.com/bytom/bytom/crypto/sha3pool"
     5  	"github.com/bytom/bytom/errors"
     6  )
     7  
     8  // Convenience routines for accessing entries of specific types by ID.
     9  var (
    10  	ErrEntryType    = errors.New("invalid entry type")
    11  	ErrMissingEntry = errors.New("missing entry")
    12  )
    13  
    14  // Tx is a wrapper for the entries-based representation of a transaction.
    15  type Tx struct {
    16  	*TxHeader
    17  	ID       Hash
    18  	Entries  map[Hash]Entry
    19  	InputIDs []Hash // 1:1 correspondence with TxData.Inputs
    20  
    21  	SpentOutputIDs []Hash
    22  }
    23  
    24  // SigHash ...
    25  func (tx *Tx) SigHash(n uint32) (hash Hash) {
    26  	hasher := sha3pool.Get256()
    27  	defer sha3pool.Put256(hasher)
    28  
    29  	tx.InputIDs[n].WriteTo(hasher)
    30  	tx.ID.WriteTo(hasher)
    31  	hash.ReadFrom(hasher)
    32  	return hash
    33  }
    34  
    35  // OriginalOutput try to get the output entry by given hash
    36  func (tx *Tx) OriginalOutput(id Hash) (*OriginalOutput, error) {
    37  	e, ok := tx.Entries[id]
    38  	if !ok || e == nil {
    39  		return nil, errors.Wrapf(ErrMissingEntry, "id %x", id.Bytes())
    40  	}
    41  
    42  	o, ok := e.(*OriginalOutput)
    43  	if !ok {
    44  		return nil, errors.Wrapf(ErrEntryType, "entry %x has unexpected type %T", id.Bytes(), e)
    45  	}
    46  	return o, nil
    47  }
    48  
    49  // Spend try to get the spend entry by given hash
    50  func (tx *Tx) Spend(id Hash) (*Spend, error) {
    51  	e, ok := tx.Entries[id]
    52  	if !ok || e == nil {
    53  		return nil, errors.Wrapf(ErrMissingEntry, "id %x", id.Bytes())
    54  	}
    55  
    56  	sp, ok := e.(*Spend)
    57  	if !ok {
    58  		return nil, errors.Wrapf(ErrEntryType, "entry %x has unexpected type %T", id.Bytes(), e)
    59  	}
    60  	return sp, nil
    61  }
    62  
    63  // Issuance try to get the issuance entry by given hash
    64  func (tx *Tx) Issuance(id Hash) (*Issuance, error) {
    65  	e, ok := tx.Entries[id]
    66  	if !ok || e == nil {
    67  		return nil, errors.Wrapf(ErrMissingEntry, "id %x", id.Bytes())
    68  	}
    69  
    70  	iss, ok := e.(*Issuance)
    71  	if !ok {
    72  		return nil, errors.Wrapf(ErrEntryType, "entry %x has unexpected type %T", id.Bytes(), e)
    73  	}
    74  	return iss, nil
    75  }
    76  
    77  // VetoInput try to get the veto entry by given hash
    78  func (tx *Tx) VetoInput(id Hash) (*VetoInput, error) {
    79  	e, ok := tx.Entries[id]
    80  	if !ok || e == nil {
    81  		return nil, errors.Wrapf(ErrMissingEntry, "id %x", id.Bytes())
    82  	}
    83  
    84  	sp, ok := e.(*VetoInput)
    85  	if !ok {
    86  		return nil, errors.Wrapf(ErrEntryType, "entry %x has unexpected type %T", id.Bytes(), e)
    87  	}
    88  	return sp, nil
    89  }
    90  
    91  // VoteOutput try to get the vote output entry by given hash
    92  func (tx *Tx) VoteOutput(id Hash) (*VoteOutput, error) {
    93  	e, ok := tx.Entries[id]
    94  	if !ok || e == nil {
    95  		return nil, errors.Wrapf(ErrMissingEntry, "id %x", id.Bytes())
    96  	}
    97  
    98  	o, ok := e.(*VoteOutput)
    99  	if !ok {
   100  		return nil, errors.Wrapf(ErrEntryType, "entry %x has unexpected type %T", id.Bytes(), e)
   101  	}
   102  	return o, nil
   103  }