OSDN Git Service

Merge branch 'master' of https://github.com/Bytom/bytom-btmhash
[bytom/bytom.git] / protocol / bc / tx.go
1 package bc
2
3 import (
4         "github.com/bytom/crypto/sha3pool"
5         "github.com/bytom/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         // IDs of reachable entries of various kinds
16         NonceIDs       []Hash
17         SpentOutputIDs []Hash
18 }
19
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
32 var (
33         ErrEntryType    = errors.New("invalid entry type")
34         ErrMissingEntry = errors.New("missing entry")
35 )
36
37 func (tx *Tx) Output(id Hash) (*Output, 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.(*Output)
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 func (tx *Tx) Spend(id Hash) (*Spend, error) {
50         e, ok := tx.Entries[id]
51         if !ok || e == nil {
52                 return nil, errors.Wrapf(ErrMissingEntry, "id %x", id.Bytes())
53         }
54         sp, ok := e.(*Spend)
55         if !ok {
56                 return nil, errors.Wrapf(ErrEntryType, "entry %x has unexpected type %T", id.Bytes(), e)
57         }
58         return sp, nil
59 }
60
61 func (tx *Tx) Issuance(id Hash) (*Issuance, error) {
62         e, ok := tx.Entries[id]
63         if !ok || e == nil {
64                 return nil, errors.Wrapf(ErrMissingEntry, "id %x", id.Bytes())
65         }
66         iss, ok := e.(*Issuance)
67         if !ok {
68                 return nil, errors.Wrapf(ErrEntryType, "entry %x has unexpected type %T", id.Bytes(), e)
69         }
70         return iss, nil
71 }
72
73 func (tx *Tx) Nonce(id Hash) (*Nonce, error) {
74         e, ok := tx.Entries[id]
75         if !ok || e == nil {
76                 return nil, errors.Wrapf(ErrMissingEntry, "id %x", id.Bytes())
77         }
78         nonce, ok := e.(*Nonce)
79         if !ok {
80                 return nil, errors.Wrapf(ErrEntryType, "entry %x has unexpected type %T", id.Bytes(), e)
81         }
82         return nonce, nil
83 }