-
Notifications
You must be signed in to change notification settings - Fork 17
/
transaction_output.go
137 lines (111 loc) · 3.33 KB
/
transaction_output.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
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
package structures
import (
"bytes"
"encoding/binary"
"encoding/gob"
"fmt"
"log"
"strings"
"github.com/gelembjuk/oursql/lib/utils"
)
// TXOutput represents a transaction output
type TXCurrrencyOutput struct {
Value float64
PubKeyHash []byte
}
// Simplified output format. To use externally
// It has all info in human readable format
// this can be used to display info abut outputs wihout references to transaction object
type TXOutputIndependent struct {
Value float64
DestPubKeyHash []byte
SendPubKeyHash []byte
TXID []byte
OIndex int
IsBase bool
BlockHash []byte
}
type TXOutputIndependentList []TXOutputIndependent
// Lock signs the output
func (out *TXCurrrencyOutput) Lock(address []byte) {
pubKeyHash, err := utils.AddresBToPubKeyHash(address)
if err != nil {
// send to noone !
// TODO some better behavior needed here
out.PubKeyHash = []byte{}
}
out.PubKeyHash = pubKeyHash
}
// Lock signs the output
func (out TXCurrrencyOutput) HasOutAddress() bool {
return len(out.PubKeyHash) > 0
}
// IsLockedWithKey checks if the output can be used by the owner of the pubkey
func (out *TXCurrrencyOutput) IsLockedWithKey(pubKeyHash []byte) bool {
return bytes.Compare(out.PubKeyHash, pubKeyHash) == 0
}
// Same as IsLockedWithKey but for simpler structure
func (out *TXOutputIndependent) IsLockedWithKey(pubKeyHash []byte) bool {
return bytes.Compare(out.DestPubKeyHash, pubKeyHash) == 0
}
// build independed transaction from normal output
func (out *TXOutputIndependent) LoadFromSimple(sout TXCurrrencyOutput, txid []byte, ind int, sender []byte, iscoinbase bool, blockHash []byte) {
out.OIndex = ind
out.DestPubKeyHash = sout.PubKeyHash
out.SendPubKeyHash = sender
out.Value = sout.Value
out.TXID = txid
out.IsBase = iscoinbase
out.BlockHash = blockHash
}
// NewTXOutput create a new TXOutput
func NewTXOutput(value float64, address string) *TXCurrrencyOutput {
txo := &TXCurrrencyOutput{value, nil}
txo.Lock([]byte(address))
return txo
}
// TXOutputs collects TXOutput
type TXOutputs struct {
Outputs []TXCurrrencyOutput
}
// Serialize serializes TXOutputs
func (outs TXOutputs) Serialize() []byte {
var buff bytes.Buffer
enc := gob.NewEncoder(&buff)
err := enc.Encode(outs)
if err != nil {
log.Panic(err)
}
return buff.Bytes()
}
// DeserializeOutputs deserializes TXOutputs
func DeserializeOutputs(data []byte) TXOutputs {
var outputs TXOutputs
dec := gob.NewDecoder(bytes.NewReader(data))
err := dec.Decode(&outputs)
if err != nil {
log.Panic(err)
}
return outputs
}
func (output TXCurrrencyOutput) String() string {
lines := []string{}
lines = append(lines, fmt.Sprintf(" Value: %f", output.Value))
lines = append(lines, fmt.Sprintf(" Script: %x", output.PubKeyHash))
return strings.Join(lines, "\n")
}
func (output TXCurrrencyOutput) ToBytes() ([]byte, error) {
buff := new(bytes.Buffer)
err := binary.Write(buff, binary.BigEndian, output.Value)
if err != nil {
return nil, err
}
err = binary.Write(buff, binary.BigEndian, output.PubKeyHash)
if err != nil {
return nil, err
}
return buff.Bytes(), nil
}
func (a TXOutputIndependentList) Len() int { return len(a) }
func (a TXOutputIndependentList) Swap(i, j int) { a[i], a[j] = a[j], a[i] }
func (a TXOutputIndependentList) Less(i, j int) bool { return a[i].Value < a[j].Value }