-
Notifications
You must be signed in to change notification settings - Fork 9
/
transaction_output.go
128 lines (103 loc) · 3.07 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
package structures
import (
"bytes"
"encoding/binary"
"encoding/gob"
"fmt"
"log"
"strings"
"github.com/gelembjuk/democoin/lib/utils"
)
// TXOutput represents a transaction output
type TXOutput 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 *TXOutput) Lock(address []byte) {
pubKeyHash := utils.Base58Decode(address)
pubKeyHash = pubKeyHash[1 : len(pubKeyHash)-4]
out.PubKeyHash = pubKeyHash
}
// IsLockedWithKey checks if the output can be used by the owner of the pubkey
func (out *TXOutput) 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 TXOutput, 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) *TXOutput {
txo := &TXOutput{value, nil}
txo.Lock([]byte(address))
return txo
}
// TXOutputs collects TXOutput
type TXOutputs struct {
Outputs []TXOutput
}
// 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 TXOutput) 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 TXOutput) 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 }