-
Notifications
You must be signed in to change notification settings - Fork 0
/
common.go
145 lines (124 loc) · 3.49 KB
/
common.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
package types
import (
"bytes"
"encoding/hex"
"fmt"
"github.com/ci123chain/ci123chain/pkg/abci/codec"
types2 "github.com/ci123chain/ci123chain/pkg/abci/types"
sdkerrors "github.com/ci123chain/ci123chain/pkg/abci/types/errors"
"github.com/ci123chain/ci123chain/pkg/cryptosuite"
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/rlp"
)
type CommonTx struct {
From types2.AccAddress `json:"from"`
Nonce uint64 `json:"nonce"`
Gas uint64 `json:"gas"`
Msgs []types2.Msg `json:"msgs"`
PubKey []byte `json:"pub_key"`
Signature []byte `json:"signature"`
}
func NewCommonTx(from types2.AccAddress, nonce, gas uint64, msgs []types2.Msg) *CommonTx {
return &CommonTx{
From: from,
Nonce: nonce,
Gas: gas,
Msgs: msgs,
}
}
func (tx CommonTx) ValidateBasic() error {
if tx.From.Empty() {
return ErrInvalidParam("empty from address")
}
// TODO Currently we don't support a gas system.
if len(tx.Msgs) == 0 {
return ErrInvalidParam("empty messagees")
}
if len(tx.Signature) == 0 {
return ErrInvalidParam("message with no signature")
}
return nil
}
func (tx *CommonTx) SetSignature(sig []byte) {
tx.Signature = sig
}
func (tx *CommonTx) GetSignature() []byte {
return tx.Signature
}
func (tx *CommonTx) SetPubKey(pub []byte) {
tx.PubKey = pub
}
func (msg *CommonTx) GetSignBytes() []byte{
ntx := *msg
ntx.SetSignature(nil)
hexstr := hex.EncodeToString(ntx.Bytes())
return cryptosuite.Hash([]byte(hexstr))
}
func (msg *CommonTx) Bytes() []byte {
bytes, err := GetCodec().MarshalBinaryBare(msg)
if err != nil {
panic(err)
}
return bytes
}
func (msg *CommonTx) GetGas() uint64 {
return msg.Gas
}
func (msg *CommonTx) GetNonce() uint64 {
return msg.Nonce
}
func (msg *CommonTx) GetMsgs() []types2.Msg{
return msg.Msgs
}
func (msg *CommonTx) GetFromAddress() types2.AccAddress{
return msg.From
}
func SignCommonTx(from types2.AccAddress, nonce, gas uint64, msgs []types2.Msg, priv string, cdc *codec.Codec) ([]byte, error){
tx := NewCommonTx(from, nonce, gas, msgs)
if priv == "" {
return cdc.MarshalBinaryBare(tx)
}
var signature []byte
privPub, err := hex.DecodeString(priv)
eth := cryptosuite.NewEccK1()
if !IsValidPrivateKey(from, privPub){
return nil, ErrInvalidParam("invalid private_key, the private key does not match the from account")
}
signature, err = eth.Sign(privPub, tx.GetSignBytes())
if err != nil {
return nil, err
}
tx.SetSignature(signature)
return cdc.MarshalBinaryBare(tx)
}
// DefaultTxDecoder logic for standard transfer decoding
func DefaultTxDecoder(cdc *codec.Codec) types2.TxDecoder {
return func(txBytes []byte) (types2.Tx, error) {
var transfer *CommonTx
err := codec.GetLegacyAminoByCodec(cdc).UnmarshalBinaryBare(txBytes, &transfer)
if err != nil || transfer == nil {
var pbTx PbTx
err = GetEncodingConfig().Marshaler.UnmarshalBinaryBare(txBytes, &pbTx)
if err != nil || len(pbTx.GetMsgs()) < 1 {
var ethTx *MsgEthereumTx
err := rlp.DecodeBytes(txBytes, ðTx)
if err != nil {
return nil, sdkerrors.Wrap(sdkerrors.ErrInternal, fmt.Sprintf("decode msg failed: %v", err.Error()))
}
return ethTx, nil
}
return &pbTx, nil
}
return transfer, nil
}
}
func IsValidPrivateKey(from types2.AccAddress,identity []byte) bool {
key := crypto.ToECDSAUnsafe(identity)
by1 := crypto.PubkeyToAddress(key.PublicKey).Bytes()
by2 := from.Bytes()
if bytes.Equal(by1, by2) {
return true
}else {
return false
}
}