OSDN Git Service

feat: add cross-chain output (#56)
[bytom/vapor.git] / protocol / bc / tx.go
1 package bc
2
3 import (
4         "github.com/vapor/crypto/sha3pool"
5         "github.com/vapor/errors"
6 )
7
8 // Tx is a wrapper for the entries-based representation of a transaction.
9 type Tx struct {
10         *TxHeader
11         ID       Hash
12         Entries  map[Hash]Entry
13         InputIDs []Hash // 1:1 correspondence with TxData.Inputs
14
15         SpentOutputIDs []Hash
16         GasInputIDs    []Hash
17 }
18
19 // SigHash ...
20 func (tx *Tx) SigHash(n uint32) (hash Hash) {
21         hasher := sha3pool.Get256()
22         defer sha3pool.Put256(hasher)
23
24         tx.InputIDs[n].WriteTo(hasher)
25         tx.ID.WriteTo(hasher)
26         hash.ReadFrom(hasher)
27         return hash
28 }
29
30 // Convenience routines for accessing entries of specific types by ID.
31 var (
32         ErrEntryType    = errors.New("invalid entry type")
33         ErrMissingEntry = errors.New("missing entry")
34 )
35
36 // IntraChainOutput try to get the intra-chain output entry by given hash
37 func (tx *Tx) IntraChainOutput(id Hash) (*IntraChainOutput, error) {
38         e, ok := tx.Entries[id]
39         if !ok || e == nil {
40                 return nil, errors.Wrapf(ErrMissingEntry, "id %x", id.Bytes())
41         }
42         o, ok := e.(*IntraChainOutput)
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 // CrossChainOutput try to get the cross-chain output entry by given hash
50 func (tx *Tx) CrossChainOutput(id Hash) (*CrossChainOutput, error) {
51         e, ok := tx.Entries[id]
52         if !ok || e == nil {
53                 return nil, errors.Wrapf(ErrMissingEntry, "id %x", id.Bytes())
54         }
55         o, ok := e.(*CrossChainOutput)
56         if !ok {
57                 return nil, errors.Wrapf(ErrEntryType, "entry %x has unexpected type %T", id.Bytes(), e)
58         }
59         return o, nil
60 }
61
62 // Spend try to get the spend entry by given hash
63 func (tx *Tx) Spend(id Hash) (*Spend, error) {
64         e, ok := tx.Entries[id]
65         if !ok || e == nil {
66                 return nil, errors.Wrapf(ErrMissingEntry, "id %x", id.Bytes())
67         }
68         sp, ok := e.(*Spend)
69         if !ok {
70                 return nil, errors.Wrapf(ErrEntryType, "entry %x has unexpected type %T", id.Bytes(), e)
71         }
72         return sp, nil
73 }
74
75 // Issuance try to get the issuance entry by given hash
76 func (tx *Tx) Issuance(id Hash) (*Issuance, error) {
77         e, ok := tx.Entries[id]
78         if !ok || e == nil {
79                 return nil, errors.Wrapf(ErrMissingEntry, "id %x", id.Bytes())
80         }
81         iss, ok := e.(*Issuance)
82         if !ok {
83                 return nil, errors.Wrapf(ErrEntryType, "entry %x has unexpected type %T", id.Bytes(), e)
84         }
85         return iss, nil
86 }