OSDN Git Service

0702e4ced421f714a65339ff5aada17b8f5ffad5
[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         MainchainOutputIDs []Hash
17         GasInputIDs        []Hash
18 }
19
20 // SigHash ...
21 func (tx *Tx) SigHash(n uint32) (hash Hash) {
22         hasher := sha3pool.Get256()
23         defer sha3pool.Put256(hasher)
24
25         tx.InputIDs[n].WriteTo(hasher)
26         tx.ID.WriteTo(hasher)
27         hash.ReadFrom(hasher)
28         return hash
29 }
30
31 // Convenience routines for accessing entries of specific types by ID.
32 var (
33         ErrEntryType    = errors.New("invalid entry type")
34         ErrMissingEntry = errors.New("missing entry")
35 )
36
37 // IntraChainOutput try to get the intra-chain output entry by given hash
38 func (tx *Tx) IntraChainOutput(id Hash) (*IntraChainOutput, error) {
39         e, ok := tx.Entries[id]
40         if !ok || e == nil {
41                 return nil, errors.Wrapf(ErrMissingEntry, "id %x", id.Bytes())
42         }
43         o, ok := e.(*IntraChainOutput)
44         if !ok {
45                 return nil, errors.Wrapf(ErrEntryType, "entry %x has unexpected type %T", id.Bytes(), e)
46         }
47         return o, nil
48 }
49
50 // CrossChainOutput try to get the cross-chain output entry by given hash
51 func (tx *Tx) CrossChainOutput(id Hash) (*CrossChainOutput, error) {
52         e, ok := tx.Entries[id]
53         if !ok || e == nil {
54                 return nil, errors.Wrapf(ErrMissingEntry, "id %x", id.Bytes())
55         }
56         o, ok := e.(*CrossChainOutput)
57         if !ok {
58                 return nil, errors.Wrapf(ErrEntryType, "entry %x has unexpected type %T", id.Bytes(), e)
59         }
60         return o, nil
61 }
62
63 // Entry try to get the  entry by given hash
64 func (tx *Tx) Entry(id Hash) (Entry, error) {
65         e, ok := tx.Entries[id]
66         if !ok || e == nil {
67                 return nil, errors.Wrapf(ErrMissingEntry, "id %x", id.Bytes())
68         }
69         return e, nil
70 }
71
72 // Spend try to get the spend entry by given hash
73 func (tx *Tx) Spend(id Hash) (*Spend, error) {
74         e, ok := tx.Entries[id]
75         if !ok || e == nil {
76                 return nil, errors.Wrapf(ErrMissingEntry, "id %x", id.Bytes())
77         }
78         sp, ok := e.(*Spend)
79         if !ok {
80                 return nil, errors.Wrapf(ErrEntryType, "entry %x has unexpected type %T", id.Bytes(), e)
81         }
82         return sp, nil
83 }
84
85 // VetoInput try to get the veto entry by given hash
86 func (tx *Tx) VetoInput(id Hash) (*VetoInput, error) {
87         e, ok := tx.Entries[id]
88         if !ok || e == nil {
89                 return nil, errors.Wrapf(ErrMissingEntry, "id %x", id.Bytes())
90         }
91         sp, ok := e.(*VetoInput)
92         if !ok {
93                 return nil, errors.Wrapf(ErrEntryType, "entry %x has unexpected type %T", id.Bytes(), e)
94         }
95         return sp, nil
96 }
97
98 // VoteOutput try to get the vote output entry by given hash
99 func (tx *Tx) VoteOutput(id Hash) (*VoteOutput, error) {
100         e, ok := tx.Entries[id]
101         if !ok || e == nil {
102                 return nil, errors.Wrapf(ErrMissingEntry, "id %x", id.Bytes())
103         }
104         o, ok := e.(*VoteOutput)
105         if !ok {
106                 return nil, errors.Wrapf(ErrEntryType, "entry %x has unexpected type %T", id.Bytes(), e)
107         }
108         return o, nil
109 }