github.com/gochain-io/gochain@v2.2.26+incompatible/core/types/transaction.go (about) 1 // Copyright 2014 The go-ethereum Authors 2 // This file is part of the go-ethereum library. 3 // 4 // The go-ethereum library is free software: you can redistribute it and/or modify 5 // it under the terms of the GNU Lesser General Public License as published by 6 // the Free Software Foundation, either version 3 of the License, or 7 // (at your option) any later version. 8 // 9 // The go-ethereum library is distributed in the hope that it will be useful, 10 // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 // GNU Lesser General Public License for more details. 13 // 14 // You should have received a copy of the GNU Lesser General Public License 15 // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>. 16 17 package types 18 19 import ( 20 "container/heap" 21 "context" 22 "errors" 23 "io" 24 "math/big" 25 "sync/atomic" 26 27 "github.com/gochain-io/gochain/common" 28 "github.com/gochain-io/gochain/common/hexutil" 29 "github.com/gochain-io/gochain/crypto" 30 "github.com/gochain-io/gochain/rlp" 31 ) 32 33 //go:generate gencodec -type txdata -field-override txdataMarshaling -out gen_tx_json.go 34 35 var ( 36 ErrInvalidSig = errors.New("invalid transaction v, r, s values") 37 errNoSigner = errors.New("missing signing methods") 38 ) 39 40 type Transaction struct { 41 data txdata 42 // caches 43 hash atomic.Value 44 size atomic.Value 45 from atomic.Value 46 } 47 48 type txdata struct { 49 AccountNonce uint64 `json:"nonce" gencodec:"required"` 50 Price *big.Int `json:"gasPrice" gencodec:"required"` 51 GasLimit uint64 `json:"gas" gencodec:"required"` 52 Recipient *common.Address `json:"to" rlp:"nil"` // nil means contract creation 53 Amount *big.Int `json:"value" gencodec:"required"` 54 Payload []byte `json:"input" gencodec:"required"` 55 56 // Signature values 57 V *big.Int `json:"v" gencodec:"required"` 58 R *big.Int `json:"r" gencodec:"required"` 59 S *big.Int `json:"s" gencodec:"required"` 60 61 // This is only used when marshaling to JSON. 62 Hash *common.Hash `json:"hash" rlp:"-"` 63 } 64 65 type txdataMarshaling struct { 66 AccountNonce hexutil.Uint64 67 Price *hexutil.Big 68 GasLimit hexutil.Uint64 69 Amount *hexutil.Big 70 Payload hexutil.Bytes 71 V *hexutil.Big 72 R *hexutil.Big 73 S *hexutil.Big 74 } 75 76 func NewTransaction(nonce uint64, to common.Address, amount *big.Int, gasLimit uint64, gasPrice *big.Int, data []byte) *Transaction { 77 return newTransaction(nonce, &to, amount, gasLimit, gasPrice, data) 78 } 79 80 func NewContractCreation(nonce uint64, amount *big.Int, gasLimit uint64, gasPrice *big.Int, data []byte) *Transaction { 81 return newTransaction(nonce, nil, amount, gasLimit, gasPrice, data) 82 } 83 84 func newTransaction(nonce uint64, to *common.Address, amount *big.Int, gasLimit uint64, gasPrice *big.Int, data []byte) *Transaction { 85 if len(data) > 0 { 86 data = common.CopyBytes(data) 87 } 88 d := txdata{ 89 AccountNonce: nonce, 90 Recipient: to, 91 Payload: data, 92 Amount: new(big.Int), 93 GasLimit: gasLimit, 94 Price: new(big.Int), 95 V: new(big.Int), 96 R: new(big.Int), 97 S: new(big.Int), 98 } 99 if amount != nil { 100 d.Amount.Set(amount) 101 } 102 if gasPrice != nil { 103 d.Price.Set(gasPrice) 104 } 105 106 return &Transaction{data: d} 107 } 108 109 // ChainId returns which chain id this transaction was signed for (if at all) 110 func (tx *Transaction) ChainId() *big.Int { 111 return deriveChainId(tx.data.V) 112 } 113 114 // Protected returns whether the transaction is protected from replay protection. 115 func (tx *Transaction) Protected() bool { 116 return isProtectedV(tx.data.V) 117 } 118 119 func isProtectedV(V *big.Int) bool { 120 if V.BitLen() <= 8 { 121 v := V.Uint64() 122 return v != 27 && v != 28 123 } 124 // anything not 27 or 28 is considered protected 125 return true 126 } 127 128 // EncodeRLP implements rlp.Encoder 129 func (tx *Transaction) EncodeRLP(w io.Writer) error { 130 return rlp.Encode(w, &tx.data) 131 } 132 133 // DecodeRLP implements rlp.Decoder 134 func (tx *Transaction) DecodeRLP(s *rlp.Stream) error { 135 _, size, _ := s.Kind() 136 err := s.Decode(&tx.data) 137 if err == nil { 138 tx.size.Store(common.StorageSize(rlp.ListSize(size))) 139 } 140 141 return err 142 } 143 144 // MarshalJSON encodes the web3 RPC transaction format. 145 func (tx *Transaction) MarshalJSON() ([]byte, error) { 146 hash := tx.Hash() 147 data := tx.data 148 data.Hash = &hash 149 return data.MarshalJSON() 150 } 151 152 // UnmarshalJSON decodes the web3 RPC transaction format. 153 func (tx *Transaction) UnmarshalJSON(input []byte) error { 154 var dec txdata 155 if err := dec.UnmarshalJSON(input); err != nil { 156 return err 157 } 158 159 withSignature := dec.V.Sign() != 0 || dec.R.Sign() != 0 || dec.S.Sign() != 0 160 if withSignature { 161 var V byte 162 if isProtectedV(dec.V) { 163 chainID := deriveChainId(dec.V).Uint64() 164 V = byte(dec.V.Uint64() - 35 - 2*chainID) 165 } else { 166 V = byte(dec.V.Uint64() - 27) 167 } 168 if !crypto.ValidateSignatureValues(V, dec.R, dec.S, false) { 169 return ErrInvalidSig 170 } 171 } 172 173 *tx = Transaction{data: dec} 174 return nil 175 } 176 177 func (tx *Transaction) Data() []byte { return common.CopyBytes(tx.data.Payload) } 178 func (tx *Transaction) Gas() uint64 { return tx.data.GasLimit } 179 func (tx *Transaction) GasPrice() *big.Int { return new(big.Int).Set(tx.data.Price) } 180 func (tx *Transaction) CmpGasPriceTx(tx2 *Transaction) int { return tx.data.Price.Cmp(tx2.data.Price) } 181 func (tx *Transaction) CmpGasPrice(i *big.Int) int { return tx.data.Price.Cmp(i) } 182 func (tx *Transaction) Value() *big.Int { return new(big.Int).Set(tx.data.Amount) } 183 func (tx *Transaction) Nonce() uint64 { return tx.data.AccountNonce } 184 func (tx *Transaction) CheckNonce() bool { return true } 185 186 // To returns the recipient address of the transaction. 187 // It returns nil if the transaction is a contract creation. 188 func (tx *Transaction) To() *common.Address { 189 if tx.data.Recipient == nil { 190 return nil 191 } 192 to := *tx.data.Recipient 193 return &to 194 } 195 196 // Hash hashes the RLP encoding of tx. 197 // It uniquely identifies the transaction. 198 func (tx *Transaction) Hash() common.Hash { 199 if hash := tx.hash.Load(); hash != nil { 200 return hash.(common.Hash) 201 } 202 v := rlpHash(tx) 203 tx.hash.Store(v) 204 return v 205 } 206 207 // Size returns the true RLP encoded storage size of the transaction, either by 208 // encoding and returning it, or returning a previsouly cached value. 209 func (tx *Transaction) Size() common.StorageSize { 210 if size := tx.size.Load(); size != nil { 211 return size.(common.StorageSize) 212 } 213 c := writeCounter(0) 214 rlp.Encode(&c, &tx.data) 215 tx.size.Store(common.StorageSize(c)) 216 return common.StorageSize(c) 217 } 218 219 // AsMessage returns the transaction as a core.Message. 220 // 221 // AsMessage requires a signer to derive the sender. 222 // 223 // XXX Rename message to something less arbitrary? 224 func (tx *Transaction) AsMessage(ctx context.Context, s Signer) (*Message, error) { 225 from, err := Sender(s, tx) 226 if err != nil { 227 return nil, err 228 } 229 msg := &Message{ 230 nonce: tx.data.AccountNonce, 231 gasLimit: tx.data.GasLimit, 232 gasPrice: tx.data.Price, 233 to: tx.data.Recipient, 234 amount: tx.data.Amount, 235 data: tx.data.Payload, 236 checkNonce: true, 237 from: from, 238 } 239 return msg, nil 240 } 241 242 // WithSignature returns a new transaction with the given signature. 243 // This signature needs to be formatted as described in the yellow paper (v+27). 244 func (tx *Transaction) WithSignature(signer Signer, sig []byte) (*Transaction, error) { 245 r, s, v, err := signer.SignatureValues(tx, sig) 246 if err != nil { 247 return nil, err 248 } 249 cpy := &Transaction{data: tx.data} 250 cpy.data.R, cpy.data.S, cpy.data.V = r, s, v 251 return cpy, nil 252 } 253 254 // Cost returns amount + gasprice * gaslimit. 255 func (tx *Transaction) Cost() *big.Int { 256 total := new(big.Int).Mul(tx.data.Price, new(big.Int).SetUint64(tx.data.GasLimit)) 257 total.Add(total, tx.data.Amount) 258 return total 259 } 260 261 func (tx *Transaction) RawSignatureValues() (*big.Int, *big.Int, *big.Int) { 262 return tx.data.V, tx.data.R, tx.data.S 263 } 264 265 // Transactions is a Transaction slice type for basic sorting. 266 type Transactions []*Transaction 267 268 // Len returns the length of s. 269 func (s Transactions) Len() int { return len(s) } 270 271 // Swap swaps the i'th and the j'th element in s. 272 func (s Transactions) Swap(i, j int) { s[i], s[j] = s[j], s[i] } 273 274 // GetRlp implements Rlpable and returns the i'th element of s in rlp. 275 func (s Transactions) GetRlp(i int) []byte { 276 enc, _ := rlp.EncodeToBytes(s[i]) 277 return enc 278 } 279 280 // TxByNonce implements the sort interface to allow sorting a list of transactions 281 // by their nonces. This is usually only useful for sorting transactions from a 282 // single account, otherwise a nonce comparison doesn't make much sense. 283 type TxByNonce Transactions 284 285 func (s TxByNonce) Len() int { return len(s) } 286 func (s TxByNonce) Less(i, j int) bool { return s[i].data.AccountNonce < s[j].data.AccountNonce } 287 func (s TxByNonce) Swap(i, j int) { s[i], s[j] = s[j], s[i] } 288 289 // TxByPrice implements both the sort and the heap interface, making it useful 290 // for all at once sorting as well as individually adding and removing elements. 291 type TxByPrice Transactions 292 293 func (s TxByPrice) Len() int { return len(s) } 294 func (s TxByPrice) Less(i, j int) bool { return s[i].data.Price.Cmp(s[j].data.Price) > 0 } 295 func (s TxByPrice) Swap(i, j int) { s[i], s[j] = s[j], s[i] } 296 297 func (s *TxByPrice) Push(x interface{}) { 298 *s = append(*s, x.(*Transaction)) 299 } 300 301 func (s *TxByPrice) Pop() interface{} { 302 old := *s 303 n := len(old) 304 x := old[n-1] 305 *s = old[0 : n-1] 306 return x 307 } 308 309 // TransactionsByPriceAndNonce represents a set of transactions that can return 310 // transactions in a profit-maximizing sorted order, while supporting removing 311 // entire batches of transactions for non-executable accounts. 312 type TransactionsByPriceAndNonce struct { 313 txs map[common.Address]Transactions // Per account nonce-sorted list of transactions 314 heads TxByPrice // Next transaction for each unique account (price heap) 315 signer Signer // Signer for the set of transactions 316 } 317 318 // NewTransactionsByPriceAndNonce creates a transaction set that can retrieve 319 // price sorted transactions in a nonce-honouring way. 320 // 321 // Note, the input map is reowned so the caller should not interact any more with 322 // if after providing it to the constructor. 323 func NewTransactionsByPriceAndNonce(signer Signer, txs map[common.Address]Transactions) *TransactionsByPriceAndNonce { 324 // Initialize a price based heap with the head transactions 325 heads := make(TxByPrice, 0, len(txs)) 326 for from, accTxs := range txs { 327 if len(accTxs) > 0 { 328 heads = append(heads, accTxs[0]) 329 // Ensure the sender address is from the signer 330 acc, _ := Sender(signer, accTxs[0]) 331 txs[acc] = accTxs[1:] 332 if from != acc { 333 delete(txs, from) 334 } 335 } 336 } 337 heap.Init(&heads) 338 339 // Assemble and return the transaction set 340 return &TransactionsByPriceAndNonce{ 341 txs: txs, 342 heads: heads, 343 signer: signer, 344 } 345 } 346 347 // Peek returns the next transaction by price. 348 func (t *TransactionsByPriceAndNonce) Peek() *Transaction { 349 if len(t.heads) == 0 { 350 return nil 351 } 352 return t.heads[0] 353 } 354 355 // Shift replaces the current best head with the next one from the same account. 356 func (t *TransactionsByPriceAndNonce) Shift() { 357 acc, _ := Sender(t.signer, t.heads[0]) 358 if txs, ok := t.txs[acc]; ok && len(txs) > 0 { 359 t.heads[0], t.txs[acc] = txs[0], txs[1:] 360 heap.Fix(&t.heads, 0) 361 } else { 362 heap.Pop(&t.heads) 363 } 364 } 365 366 // Pop removes the best transaction, *not* replacing it with the next one from 367 // the same account. This should be used when a transaction cannot be executed 368 // and hence all subsequent ones should be discarded from the same account. 369 func (t *TransactionsByPriceAndNonce) Pop() { 370 heap.Pop(&t.heads) 371 } 372 373 // Message is a fully derived transaction and implements core.Message 374 // 375 // NOTE: In a future PR this will be removed. 376 type Message struct { 377 to *common.Address 378 from common.Address 379 nonce uint64 380 amount *big.Int 381 gasLimit uint64 382 gasPrice *big.Int 383 data []byte 384 checkNonce bool 385 } 386 387 func NewMessage(from common.Address, to *common.Address, nonce uint64, amount *big.Int, gasLimit uint64, gasPrice *big.Int, data []byte, checkNonce bool) *Message { 388 return &Message{ 389 from: from, 390 to: to, 391 nonce: nonce, 392 amount: amount, 393 gasLimit: gasLimit, 394 gasPrice: gasPrice, 395 data: data, 396 checkNonce: checkNonce, 397 } 398 } 399 400 func (m *Message) From() common.Address { return m.from } 401 func (m *Message) To() *common.Address { return m.to } 402 func (m *Message) GasPrice() *big.Int { return m.gasPrice } 403 func (m *Message) Value() *big.Int { return m.amount } 404 func (m *Message) Gas() uint64 { return m.gasLimit } 405 func (m *Message) Nonce() uint64 { return m.nonce } 406 func (m *Message) Data() []byte { return m.data } 407 func (m *Message) CheckNonce() bool { return m.checkNonce }