-
Notifications
You must be signed in to change notification settings - Fork 11
/
transaction.go
89 lines (70 loc) · 1.96 KB
/
transaction.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
package elastosTransaction
import (
"encoding/hex"
"errors"
owcrypt "github.com/blocktree/go-owcrypt"
)
type Vin struct {
TxID string
Vout uint16
Address string
}
type Vout struct {
AssetID string
Amount uint64
Address string
}
type TxHash struct {
Address string
Hash string
}
func CreateEmptyRawTransactionAndHash(vins []Vin, vouts []Vout) (string, []TxHash, error) {
if vins == nil || len(vins) == 0 || vouts == nil || len(vouts) == 0 {
return "", nil, errors.New("Miss inputs or outputs!")
}
tx, err := NewTransaction(vins, vouts)
if err != nil {
return "", nil, err
}
emptyTrans, hash := tx.GetEmptyAndHash()
txHashes := []TxHash{}
loop:
for _, in := range vins {
for _, txHash := range txHashes {
if txHash.Address == in.Address {
continue loop
}
}
txHashes = append(txHashes, TxHash{Address: in.Address, Hash: hex.EncodeToString(hash)})
}
return hex.EncodeToString(emptyTrans), txHashes, nil
}
func SignRawTransaction(hash string, privateKey []byte) ([]byte, error) {
hashByte, err := hex.DecodeString(hash)
if err != nil {
return nil, errors.New("Invalid transaction hash!")
}
signature,_, retCode := owcrypt.Signature(privateKey, nil, hashByte, owcrypt.ECC_CURVE_SECP256R1)
if retCode != owcrypt.SUCCESS {
return nil, errors.New("Failed to sign transaction!")
}
return signature, nil
}
func VerifyAndCombineRawTransaction(emptyTrans string, sigPubs []SigPub) (bool, string) {
txBytes, err := hex.DecodeString(emptyTrans)
if err != nil {
return false, ""
}
hash := owcrypt.Hash(txBytes, 0, owcrypt.HASH_ALG_SHA256)
for _, sp := range sigPubs {
publicKey := owcrypt.PointDecompress(sp.PublicKey, owcrypt.ECC_CURVE_SECP256R1)[1:]
if owcrypt.SUCCESS != owcrypt.Verify(publicKey, nil, hash, sp.Signature, owcrypt.ECC_CURVE_SECP256R1) {
return false, ""
}
}
sigRaw, err := Sigpubs(sigPubs).ToBytes()
if err != nil {
return false, ""
}
return true, hex.EncodeToString(append(txBytes, sigRaw...))
}