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