-
Notifications
You must be signed in to change notification settings - Fork 1
/
exec.go
159 lines (135 loc) · 6.5 KB
/
exec.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
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
// Copyright Fuzamei Corp. 2018 All Rights Reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package executor
import (
"encoding/hex"
"github.com/assetcloud/chain/account"
"github.com/assetcloud/chain/common"
"github.com/assetcloud/chain/common/address"
"github.com/assetcloud/chain/types"
ty "github.com/assetcloud/plugin/plugin/dapp/privacy/types"
)
// Exec_Public2Privacy execute public to privacy
func (p *privacy) Exec_Public2Privacy(payload *ty.Public2Privacy, tx *types.Transaction, index int) (*types.Receipt, error) {
accDB, err := p.createAccountDB(payload.GetAssetExec(), payload.GetTokenname())
if err != nil {
privacylog.Error("Exec_pub2priv_newAccountDB", "exec", payload.GetAssetExec(),
"symbol", payload.GetTokenname(), "err", err)
return nil, err
}
txhashstr := hex.EncodeToString(tx.Hash())
from := tx.From()
receipt, err := accDB.ExecWithdraw(address.ExecAddress(string(tx.Execer)), from, payload.Amount)
if err != nil {
privacylog.Error("PrivacyTrading Exec", "txhash", txhashstr, "ExecWithdraw error ", err)
return nil, err
}
txhash := common.ToHex(tx.Hash())
output := payload.GetOutput().GetKeyoutput()
//因为只有包含当前交易的block被执行完成之后,同步到相应的钱包之后,
//才能将相应的utxo作为input,进行支付,所以此处不需要进行将KV设置到
//executor中的临时数据库中,只需要将kv返回给blockchain就行
//即:一个块中产生的UTXO是不能够在同一个高度进行支付的
for index, keyOutput := range output {
key := CalcPrivacyOutputKey(payload.AssetExec, payload.Tokenname, keyOutput.Amount, txhash, index)
value := types.Encode(keyOutput)
receipt.KV = append(receipt.KV, &types.KeyValue{Key: key, Value: value})
}
privacylog.Debug("testkey", "output", payload.GetOutput().Keyoutput)
receiptLogs := p.buildPrivacyReceiptLog(payload.GetAssetExec(), payload.GetTokenname(), payload.GetOutput())
execlog := &types.ReceiptLog{Ty: ty.TyLogPrivacyOutput, Log: types.Encode(receiptLogs)}
receipt.Logs = append(receipt.Logs, execlog)
//////////////////debug code begin///////////////
privacylog.Debug("PrivacyTrading Exec", "ActionPublic2Privacy txhash", txhashstr, "receipt is", receipt)
//////////////////debug code end///////////////
return receipt, nil
}
// Exec_Privacy2Privacy execute privacy to privacy transaction
func (p *privacy) Exec_Privacy2Privacy(payload *ty.Privacy2Privacy, tx *types.Transaction, index int) (*types.Receipt, error) {
txhashstr := hex.EncodeToString(tx.Hash())
receipt := &types.Receipt{KV: make([]*types.KeyValue, 0)}
privacyInput := payload.Input
for _, keyInput := range privacyInput.Keyinput {
value := []byte{keyImageSpentAlready}
key := calcPrivacyKeyImageKey(payload.AssetExec, payload.Tokenname, keyInput.KeyImage)
stateDB := p.GetStateDB()
stateDB.Set(key, value)
receipt.KV = append(receipt.KV, &types.KeyValue{Key: key, Value: value})
}
execlog := &types.ReceiptLog{Ty: ty.TyLogPrivacyInput, Log: types.Encode(payload.GetInput())}
receipt.Logs = append(receipt.Logs, execlog)
txhash := common.ToHex(tx.Hash())
output := payload.GetOutput().GetKeyoutput()
for index, keyOutput := range output {
key := CalcPrivacyOutputKey(payload.AssetExec, payload.Tokenname, keyOutput.Amount, txhash, index)
value := types.Encode(keyOutput)
receipt.KV = append(receipt.KV, &types.KeyValue{Key: key, Value: value})
}
receiptLogs := p.buildPrivacyReceiptLog(payload.GetAssetExec(), payload.GetTokenname(), payload.GetOutput())
execlog = &types.ReceiptLog{Ty: ty.TyLogPrivacyOutput, Log: types.Encode(receiptLogs)}
receipt.Logs = append(receipt.Logs, execlog)
receipt.Ty = types.ExecOk
//////////////////debug code begin///////////////
privacylog.Debug("PrivacyTrading Exec", "ActionPrivacy2Privacy txhash", txhashstr, "receipt is", receipt)
//////////////////debug code end///////////////
return receipt, nil
}
// Exec_Privacy2Public execute privacy to public transaction
func (p *privacy) Exec_Privacy2Public(payload *ty.Privacy2Public, tx *types.Transaction, index int) (*types.Receipt, error) {
accDB, err := p.createAccountDB(payload.GetAssetExec(), payload.GetTokenname())
if err != nil {
privacylog.Error("Exec_pub2priv_newAccountDB", "exec", payload.GetAssetExec(),
"symbol", payload.GetTokenname(), "err", err)
return nil, err
}
txhashstr := hex.EncodeToString(tx.Hash())
receipt, err := accDB.ExecDeposit(payload.To, address.ExecAddress(string(tx.Execer)), payload.Amount)
if err != nil {
privacylog.Error("PrivacyTrading Exec", "ActionPrivacy2Public txhash", txhashstr, "ExecDeposit error ", err)
return nil, err
}
privacyInput := payload.Input
for _, keyInput := range privacyInput.Keyinput {
value := []byte{keyImageSpentAlready}
key := calcPrivacyKeyImageKey(payload.AssetExec, payload.Tokenname, keyInput.KeyImage)
stateDB := p.GetStateDB()
stateDB.Set(key, value)
receipt.KV = append(receipt.KV, &types.KeyValue{Key: key, Value: value})
}
execlog := &types.ReceiptLog{Ty: ty.TyLogPrivacyInput, Log: types.Encode(payload.GetInput())}
receipt.Logs = append(receipt.Logs, execlog)
txhash := common.ToHex(tx.Hash())
output := payload.GetOutput().GetKeyoutput()
for index, keyOutput := range output {
key := CalcPrivacyOutputKey(payload.AssetExec, payload.Tokenname, keyOutput.Amount, txhash, index)
value := types.Encode(keyOutput)
receipt.KV = append(receipt.KV, &types.KeyValue{Key: key, Value: value})
}
receiptLog := p.buildPrivacyReceiptLog(payload.GetAssetExec(), payload.GetTokenname(), payload.GetOutput())
execlog = &types.ReceiptLog{Ty: ty.TyLogPrivacyOutput, Log: types.Encode(receiptLog)}
receipt.Logs = append(receipt.Logs, execlog)
receipt.Ty = types.ExecOk
//////////////////debug code begin///////////////
privacylog.Debug("PrivacyTrading Exec", "ActionPrivacy2Privacy txhash", txhashstr, "receipt is", receipt)
//////////////////debug code end///////////////
return receipt, nil
}
func (p *privacy) createAccountDB(exec, symbol string) (*account.DB, error) {
cfg := p.GetAPI().GetConfig()
if exec == "" || exec == cfg.GetCoinExec() {
return p.GetCoinsAccount(), nil
}
return account.NewAccountDB(cfg, exec, symbol, p.GetStateDB())
}
func (p *privacy) buildPrivacyReceiptLog(assetExec, assetSymbol string, output *ty.PrivacyOutput) *ty.ReceiptPrivacyOutput {
if assetExec == "" {
assetExec = p.GetAPI().GetConfig().GetCoinExec()
}
receipt := &ty.ReceiptPrivacyOutput{
AssetExec: assetExec,
AssetSymbol: assetSymbol,
Keyoutput: output.Keyoutput,
}
return receipt
}