/
message.go
173 lines (159 loc) · 4.38 KB
/
message.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
160
161
162
163
164
165
166
167
168
169
170
171
172
173
package w3types
import (
"encoding/json"
"math/big"
"github.com/ethereum/go-ethereum"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common/hexutil"
"github.com/ethereum/go-ethereum/core/types"
)
var addr0 = common.Address{}
// Message represents a transaction without the signature.
//
// If no input data is given, but Func is not null, the input data is
// automatically encoded from the given Func and Args arguments by many
// functions that accept a Message struct as an argument.
type Message struct {
From common.Address // Sender
To *common.Address // Recipient
Nonce uint64
GasPrice *big.Int
GasFeeCap *big.Int
GasTipCap *big.Int
Gas uint64
Value *big.Int
Input []byte // Input data
AccessList types.AccessList
Func Func // Func to encode
Args []any // Arguments for Func
}
// Set sets msg to the given Message and returns it.
func (msg *Message) Set(msg2 *Message) *Message {
msg.From = msg2.From
msg.To = msg2.To
msg.Nonce = msg2.Nonce
msg.GasPrice = msg2.GasPrice
msg.GasFeeCap = msg2.GasFeeCap
msg.GasTipCap = msg2.GasTipCap
msg.Gas = msg2.Gas
msg.Value = msg2.Value
msg.Input = msg2.Input
msg.AccessList = msg2.AccessList
msg.Func = msg2.Func
msg.Args = msg2.Args
return msg
}
// SetTx sets msg to the [types.Transaction] tx and returns msg.
func (msg *Message) SetTx(tx *types.Transaction, signer types.Signer) (*Message, error) {
from, err := signer.Sender(tx)
if err != nil {
return nil, err
}
msg.From = from
msg.To = tx.To()
msg.Nonce = tx.Nonce()
msg.GasPrice = tx.GasPrice()
msg.GasFeeCap = tx.GasFeeCap()
msg.GasTipCap = tx.GasTipCap()
msg.Gas = tx.Gas()
msg.Value = tx.Value()
msg.Input = tx.Data()
msg.AccessList = tx.AccessList()
return msg, nil
}
// MustSetTx is like [SetTx] but panics if the sender retrieval fails.
func (msg *Message) MustSetTx(tx *types.Transaction, signer types.Signer) *Message {
msg, err := msg.SetTx(tx, signer)
if err != nil {
panic(err)
}
return msg
}
// SetCallMsg sets msg to the [ethereum.CallMsg] callMsg and returns msg.
func (msg *Message) SetCallMsg(callMsg ethereum.CallMsg) *Message {
msg.From = callMsg.From
msg.To = callMsg.To
msg.Gas = callMsg.Gas
msg.GasPrice = callMsg.GasPrice
msg.GasFeeCap = callMsg.GasFeeCap
msg.GasTipCap = callMsg.GasTipCap
msg.Value = callMsg.Value
msg.Input = callMsg.Data
msg.AccessList = callMsg.AccessList
return msg
}
type message struct {
From *common.Address `json:"from,omitempty"`
To *common.Address `json:"to,omitempty"`
Nonce hexutil.Uint64 `json:"nonce,omitempty"`
GasPrice *hexutil.Big `json:"gasPrice,omitempty"`
GasFeeCap *hexutil.Big `json:"gasFeeCap,omitempty"`
GasTipCap *hexutil.Big `json:"gasTipCap,omitempty"`
Gas hexutil.Uint64 `json:"gas,omitempty"`
Value *hexutil.Big `json:"value,omitempty"`
Input hexutil.Bytes `json:"data,omitempty"`
AccessList types.AccessList `json:"accessList,omitempty"`
}
// MarshalJSON implements the [json.Marshaler].
func (msg *Message) MarshalJSON() ([]byte, error) {
var enc message
if msg.From != addr0 {
enc.From = &msg.From
}
enc.To = msg.To
enc.Nonce = hexutil.Uint64(msg.Nonce)
if msg.GasPrice != nil {
enc.GasPrice = (*hexutil.Big)(msg.GasPrice)
}
if msg.GasFeeCap != nil {
enc.GasFeeCap = (*hexutil.Big)(msg.GasFeeCap)
}
if msg.GasTipCap != nil {
enc.GasTipCap = (*hexutil.Big)(msg.GasTipCap)
}
if msg.Gas > 0 {
enc.Gas = hexutil.Uint64(msg.Gas)
}
if msg.Value != nil {
enc.Value = (*hexutil.Big)(msg.Value)
}
if len(msg.Input) > 0 {
enc.Input = msg.Input
}
if len(msg.AccessList) > 0 {
enc.AccessList = msg.AccessList
}
return json.Marshal(&enc)
}
// UnmarshalJSON implements the [json.Unmarshaler].
func (msg *Message) UnmarshalJSON(data []byte) error {
var dec message
if err := json.Unmarshal(data, &dec); err != nil {
return err
}
if dec.From != nil {
msg.From = *dec.From
}
msg.To = dec.To
msg.Nonce = uint64(dec.Nonce)
if dec.GasPrice != nil {
msg.GasPrice = (*big.Int)(dec.GasPrice)
}
if dec.GasFeeCap != nil {
msg.GasFeeCap = (*big.Int)(dec.GasFeeCap)
}
if dec.GasTipCap != nil {
msg.GasTipCap = (*big.Int)(dec.GasTipCap)
}
msg.Gas = uint64(dec.Gas)
if dec.Value != nil {
msg.Value = (*big.Int)(dec.Value)
}
if len(dec.Input) > 0 {
msg.Input = dec.Input
}
if len(dec.AccessList) > 0 {
msg.AccessList = dec.AccessList
}
return nil
}