OSDN Git Service

9b00d3904e11541fb1016ed69e6cb595c781a582
[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 // Entry try to get the  entry by given hash
63 func (tx *Tx) Entry(id Hash) (Entry, error) {
64         e, ok := tx.Entries[id]
65         if !ok || e == nil {
66                 return nil, errors.Wrapf(ErrMissingEntry, "id %x", id.Bytes())
67         }
68         return e, nil
69 }
70
71 // Spend try to get the spend entry by given hash
72 func (tx *Tx) Spend(id Hash) (*Spend, error) {
73         e, ok := tx.Entries[id]
74         if !ok || e == nil {
75                 return nil, errors.Wrapf(ErrMissingEntry, "id %x", id.Bytes())
76         }
77         sp, ok := e.(*Spend)
78         if !ok {
79                 return nil, errors.Wrapf(ErrEntryType, "entry %x has unexpected type %T", id.Bytes(), e)
80         }
81         return sp, nil
82 }
83
84 // Issuance try to get the issuance entry by given hash
85 func (tx *Tx) Issuance(id Hash) (*Issuance, error) {
86         e, ok := tx.Entries[id]
87         if !ok || e == nil {
88                 return nil, errors.Wrapf(ErrMissingEntry, "id %x", id.Bytes())
89         }
90         iss, ok := e.(*Issuance)
91         if !ok {
92                 return nil, errors.Wrapf(ErrEntryType, "entry %x has unexpected type %T", id.Bytes(), e)
93         }
94         return iss, nil
95 }
96
97 // VoteOutput try to get the vote output entry by given hash
98 func (tx *Tx) VoteOutput(id Hash) (*VoteOutput, error) {
99         e, ok := tx.Entries[id]
100         if !ok || e == nil {
101                 return nil, errors.Wrapf(ErrMissingEntry, "id %x", id.Bytes())
102         }
103         o, ok := e.(*VoteOutput)
104         if !ok {
105                 return nil, errors.Wrapf(ErrEntryType, "entry %x has unexpected type %T", id.Bytes(), e)
106         }
107         return o, nil
108 }