github.com/amazechain/amc@v0.1.3/common/transaction/transaction.go (about) 1 // Copyright 2022 The AmazeChain Authors 2 // This file is part of the AmazeChain library. 3 // 4 // The AmazeChain 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 AmazeChain 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 AmazeChain library. If not, see <http://www.gnu.org/licenses/>. 16 17 package transaction 18 19 import ( 20 "bytes" 21 "fmt" 22 "github.com/amazechain/amc/utils" 23 "github.com/holiman/uint256" 24 "google.golang.org/protobuf/proto" 25 "math/big" 26 "sync/atomic" 27 "time" 28 29 "github.com/amazechain/amc/api/protocol/types_pb" 30 "github.com/amazechain/amc/common/types" 31 ) 32 33 var ( 34 ErrGasFeeCapTooLow = fmt.Errorf("fee cap less than base fee") 35 ErrUnmarshalHash = fmt.Errorf("hash verify falied") 36 ) 37 38 // Transaction types. 39 const ( 40 LegacyTxType = iota 41 AccessListTxType 42 DynamicFeeTxType 43 ) 44 45 type TxData interface { 46 txType() byte // returns the type ID 47 copy() TxData // creates a deep copy and initializes all fields 48 49 chainID() *uint256.Int 50 accessList() AccessList 51 data() []byte 52 gas() uint64 53 gasPrice() *uint256.Int 54 gasTipCap() *uint256.Int 55 gasFeeCap() *uint256.Int 56 value() *uint256.Int 57 nonce() uint64 58 to() *types.Address 59 from() *types.Address 60 sign() []byte 61 hash() types.Hash 62 63 rawSignatureValues() (v, r, s *uint256.Int) 64 setSignatureValues(chainID, v, r, s *uint256.Int) 65 66 //Marshal() ([]byte, error) 67 //MarshalTo(data []byte) (n int, err error) 68 //Unmarshal(data []byte) error 69 //Size() int 70 } 71 72 // Transactions implements DerivableList for transactions. 73 type Transactions []*Transaction 74 75 // Len returns the length of s. 76 func (s Transactions) Len() int { return len(s) } 77 78 // EncodeIndex encodes the i'th transaction to w. Note that this does not check for errors 79 // because we assume that *Transaction will only ever contain valid txs that were either 80 // constructed by decoding or via public API in this package. 81 func (s Transactions) EncodeIndex(i int, w *bytes.Buffer) { 82 tx := s[i] 83 proto, _ := tx.Marshal() 84 w.Write(proto) 85 } 86 87 type Transaction struct { 88 inner TxData // Consensus contents of a transaction 89 time time.Time // Time first seen locally (spam avoidance) 90 91 // caches 92 hash atomic.Value 93 size atomic.Value 94 from atomic.Value 95 } 96 97 // NewTx creates a new transaction. 98 func NewTx(inner TxData) *Transaction { 99 tx := new(Transaction) 100 tx.setDecoded(inner.copy(), 0) 101 return tx 102 } 103 104 func txDataFromProtoMessage(message proto.Message) (TxData, error) { 105 var ( 106 pbTx *types_pb.Transaction 107 ok bool 108 inner TxData 109 ) 110 111 if pbTx, ok = message.(*types_pb.Transaction); !ok { 112 return nil, fmt.Errorf("aa") 113 } 114 115 switch pbTx.Type { 116 case LegacyTxType: 117 var itx LegacyTx 118 if nil != pbTx.To { 119 itx.To = utils.ConvertH160ToPAddress(pbTx.To) 120 if *itx.To == (types.Address{}) { 121 itx.To = nil 122 } 123 } 124 itx.From = utils.ConvertH160ToPAddress(pbTx.From) 125 itx.Sign = pbTx.Sign 126 itx.Nonce = pbTx.Nonce 127 itx.Gas = pbTx.Gas 128 itx.GasPrice = utils.ConvertH256ToUint256Int(pbTx.GasPrice) 129 itx.Value = utils.ConvertH256ToUint256Int(pbTx.Value) 130 if nil != pbTx.V { 131 itx.V = utils.ConvertH256ToUint256Int(pbTx.V) 132 } 133 if nil != pbTx.R { 134 itx.R = utils.ConvertH256ToUint256Int(pbTx.R) 135 } 136 if nil != pbTx.S { 137 itx.S = utils.ConvertH256ToUint256Int(pbTx.S) 138 } 139 itx.Data = pbTx.Data 140 inner = &itx 141 case AccessListTxType: 142 var altt AccessListTx 143 altt.ChainID = uint256.NewInt(pbTx.ChainID) 144 altt.Nonce = pbTx.Nonce 145 altt.Gas = pbTx.Gas 146 altt.GasPrice = utils.ConvertH256ToUint256Int(pbTx.GasPrice) 147 altt.Value = utils.ConvertH256ToUint256Int(pbTx.Value) 148 if nil != pbTx.V { 149 altt.V = utils.ConvertH256ToUint256Int(pbTx.V) 150 } 151 if nil != pbTx.R { 152 altt.R = utils.ConvertH256ToUint256Int(pbTx.R) 153 } 154 if nil != pbTx.S { 155 altt.S = utils.ConvertH256ToUint256Int(pbTx.S) 156 } 157 altt.Data = pbTx.Data 158 if nil != pbTx.To { 159 altt.To = utils.ConvertH160ToPAddress(pbTx.To) 160 if *altt.To == (types.Address{}) { 161 altt.To = nil 162 } 163 } 164 //altt.To = utils.ConvertH160ToPAddress(pbTx.To) 165 altt.From = utils.ConvertH160ToPAddress(pbTx.From) 166 altt.Sign = pbTx.Sign 167 inner = &altt 168 case DynamicFeeTxType: 169 var dftt DynamicFeeTx 170 dftt.ChainID = uint256.NewInt(pbTx.ChainID) 171 dftt.Nonce = pbTx.Nonce 172 dftt.Gas = pbTx.Gas 173 dftt.GasFeeCap = utils.ConvertH256ToUint256Int(pbTx.FeePerGas) 174 dftt.GasTipCap = utils.ConvertH256ToUint256Int(pbTx.PriorityFeePerGas) 175 dftt.Value = utils.ConvertH256ToUint256Int(pbTx.Value) 176 if nil != pbTx.V { 177 dftt.V = utils.ConvertH256ToUint256Int(pbTx.V) 178 } 179 if nil != pbTx.R { 180 dftt.R = utils.ConvertH256ToUint256Int(pbTx.R) 181 } 182 if nil != pbTx.S { 183 dftt.S = utils.ConvertH256ToUint256Int(pbTx.S) 184 } 185 dftt.Data = pbTx.Data 186 if nil != pbTx.To { 187 dftt.To = utils.ConvertH160ToPAddress(pbTx.To) 188 if *dftt.To == (types.Address{}) { 189 dftt.To = nil 190 } 191 } 192 193 //dftt.To = utils.ConvertH160ToPAddress(pbTx.To) 194 dftt.From = utils.ConvertH160ToPAddress(pbTx.From) 195 dftt.Sign = pbTx.Sign 196 inner = &dftt 197 } 198 199 // todo 200 protoHash := utils.ConvertH256ToHash(pbTx.Hash) 201 innerHash := inner.hash() 202 if bytes.Compare(protoHash[:], innerHash[:]) != 0 { 203 //return nil, ErrUnmarshalHash 204 } 205 206 return inner, nil 207 } 208 209 func FromProtoMessage(message proto.Message) (*Transaction, error) { 210 inner, err := txDataFromProtoMessage(message) 211 if err != nil { 212 return nil, err 213 } 214 return NewTx(inner), nil 215 } 216 217 func (tx *Transaction) ToProtoMessage() proto.Message { 218 var pbTx types_pb.Transaction 219 pbTx.Type = uint64(tx.inner.txType()) 220 221 switch t := tx.inner.(type) { 222 case *AccessListTx: 223 pbTx.ChainID = t.ChainID.Uint64() 224 pbTx.Nonce = tx.Nonce() 225 pbTx.Gas = tx.Gas() 226 pbTx.GasPrice = utils.ConvertUint256IntToH256(tx.GasPrice()) 227 pbTx.Value = utils.ConvertUint256IntToH256(tx.Value()) 228 pbTx.Data = tx.Data() 229 pbTx.From = utils.ConvertAddressToH160(*tx.From()) 230 pbTx.Sign = t.Sign 231 case *LegacyTx: 232 pbTx.Nonce = tx.Nonce() 233 pbTx.Gas = tx.Gas() 234 pbTx.GasPrice = utils.ConvertUint256IntToH256(tx.GasPrice()) 235 pbTx.Value = utils.ConvertUint256IntToH256(tx.Value()) 236 pbTx.Data = tx.Data() 237 //pbTx.To = utils.ConvertAddressToH160(*tx.To()) 238 pbTx.From = utils.ConvertAddressToH160(*tx.From()) 239 pbTx.Sign = t.Sign 240 case *DynamicFeeTx: 241 pbTx.ChainID = t.ChainID.Uint64() 242 pbTx.Nonce = tx.Nonce() 243 pbTx.Gas = tx.Gas() 244 pbTx.GasPrice = utils.ConvertUint256IntToH256(tx.GasPrice()) 245 pbTx.Value = utils.ConvertUint256IntToH256(tx.Value()) 246 pbTx.Data = tx.Data() 247 //pbTx.To = utils.ConvertAddressToH160(*tx.To()) 248 pbTx.From = utils.ConvertAddressToH160(*tx.From()) 249 pbTx.Sign = t.Sign 250 pbTx.FeePerGas = utils.ConvertUint256IntToH256(t.GasFeeCap) 251 pbTx.PriorityFeePerGas = utils.ConvertUint256IntToH256(t.GasTipCap) 252 } 253 if tx.To() != nil { 254 pbTx.To = utils.ConvertAddressToH160(*tx.To()) 255 } 256 257 pbTx.Hash = utils.ConvertHashToH256(tx.Hash()) 258 259 v, r, s := tx.RawSignatureValues() 260 if nil != v { 261 pbTx.V = utils.ConvertUint256IntToH256(v) 262 } 263 if nil != r { 264 pbTx.R = utils.ConvertUint256IntToH256(r) 265 } 266 if nil != s { 267 pbTx.S = utils.ConvertUint256IntToH256(s) 268 } 269 270 return &pbTx 271 } 272 273 func (tx *Transaction) setDecoded(inner TxData, size int) { 274 tx.inner = inner 275 tx.time = time.Now() 276 //if size > 0 { 277 // tx.size.Store(common.StorageSize(size)) 278 //} 279 } 280 281 func (tx *Transaction) RawSignatureValues() (v, r, s *uint256.Int) { 282 return tx.inner.rawSignatureValues() 283 } 284 285 // WithSignature todo 286 func (tx *Transaction) WithSignatureValues(v, r, s *uint256.Int) (*Transaction, error) { 287 //todo 288 tx.inner.setSignatureValues(uint256.NewInt(100100100), v, r, s) 289 return tx, nil 290 } 291 292 func (tx Transaction) Marshal() ([]byte, error) { 293 var pbTx types_pb.Transaction 294 pbTx.Type = uint64(tx.inner.txType()) 295 296 switch t := tx.inner.(type) { 297 case *AccessListTx: 298 pbTx.ChainID = t.ChainID.Uint64() 299 pbTx.Nonce = tx.Nonce() 300 pbTx.Gas = tx.Gas() 301 pbTx.GasPrice = utils.ConvertUint256IntToH256(tx.GasPrice()) 302 pbTx.Value = utils.ConvertUint256IntToH256(tx.Value()) 303 pbTx.Data = tx.Data() 304 pbTx.From = utils.ConvertAddressToH160(*tx.From()) 305 pbTx.Sign = t.Sign 306 case *LegacyTx: 307 pbTx.Nonce = tx.Nonce() 308 pbTx.Gas = tx.Gas() 309 pbTx.GasPrice = utils.ConvertUint256IntToH256(tx.GasPrice()) 310 pbTx.Value = utils.ConvertUint256IntToH256(tx.Value()) 311 pbTx.Data = tx.Data() 312 //pbTx.To = utils.ConvertAddressToH160(*tx.To()) 313 pbTx.From = utils.ConvertAddressToH160(*tx.From()) 314 pbTx.Sign = t.Sign 315 case *DynamicFeeTx: 316 pbTx.ChainID = t.ChainID.Uint64() 317 pbTx.Nonce = tx.Nonce() 318 pbTx.Gas = tx.Gas() 319 pbTx.GasPrice = utils.ConvertUint256IntToH256(tx.GasPrice()) 320 pbTx.Value = utils.ConvertUint256IntToH256(tx.Value()) 321 pbTx.Data = tx.Data() 322 //pbTx.To = utils.ConvertAddressToH160(*tx.To()) 323 pbTx.From = utils.ConvertAddressToH160(*tx.From()) 324 pbTx.Sign = t.Sign 325 pbTx.FeePerGas = utils.ConvertUint256IntToH256(t.GasFeeCap) 326 pbTx.PriorityFeePerGas = utils.ConvertUint256IntToH256(t.GasTipCap) 327 } 328 if tx.To() != nil { 329 pbTx.To = utils.ConvertAddressToH160(*tx.To()) 330 } 331 v, r, s := tx.RawSignatureValues() 332 if nil != v { 333 pbTx.V = utils.ConvertUint256IntToH256(v) 334 } 335 if nil != r { 336 pbTx.R = utils.ConvertUint256IntToH256(r) 337 } 338 if nil != s { 339 pbTx.S = utils.ConvertUint256IntToH256(s) 340 } 341 return proto.Marshal(&pbTx) 342 } 343 344 func (tx *Transaction) MarshalTo(data []byte) (n int, err error) { 345 b, err := tx.Marshal() 346 if err != nil { 347 return 0, err 348 } 349 350 copy(data, b) 351 return len(b), nil 352 } 353 354 func (tx *Transaction) Unmarshal(data []byte) error { 355 var pbTx types_pb.Transaction 356 var err error 357 var inner TxData 358 err = proto.Unmarshal(data, &pbTx) 359 if err != nil { 360 return err 361 } 362 363 inner, err = txDataFromProtoMessage(&pbTx) 364 if err != nil { 365 return err 366 } 367 368 tx.setDecoded(inner, 0) 369 return err 370 } 371 372 func (tx *Transaction) Type() uint8 { 373 return tx.inner.txType() 374 } 375 376 func (tx *Transaction) ChainId() *uint256.Int { 377 return tx.inner.chainID() 378 } 379 380 func (tx *Transaction) Data() []byte { 381 return tx.inner.data() 382 } 383 384 func (tx *Transaction) AccessList() AccessList { 385 return tx.inner.accessList() 386 } 387 388 func (tx *Transaction) Gas() uint64 { 389 return tx.inner.gas() 390 } 391 392 func (tx *Transaction) GasPrice() *uint256.Int { 393 return tx.inner.gasPrice() 394 } 395 396 func (tx *Transaction) GasTipCap() *uint256.Int { 397 return tx.inner.gasTipCap() 398 } 399 400 func (tx *Transaction) GasFeeCap() *uint256.Int { 401 return tx.inner.gasFeeCap() 402 } 403 404 func (tx *Transaction) Value() *uint256.Int { 405 return tx.inner.value() 406 } 407 408 func (tx *Transaction) Nonce() uint64 { 409 return tx.inner.nonce() 410 } 411 412 func (tx *Transaction) To() *types.Address { 413 return copyAddressPtr(tx.inner.to()) 414 } 415 416 func (tx *Transaction) From() *types.Address { 417 return tx.inner.from() 418 } 419 420 func (tx *Transaction) SetFrom(addr types.Address) { 421 switch t := tx.inner.(type) { 422 case *AccessListTx: 423 t.From = &addr 424 case *LegacyTx: 425 t.From = &addr 426 case *DynamicFeeTx: 427 t.From = &addr 428 } 429 } 430 431 func (tx *Transaction) SetNonce(nonce uint64) { 432 switch t := tx.inner.(type) { 433 case *AccessListTx: 434 t.Nonce = nonce 435 case *LegacyTx: 436 t.Nonce = nonce 437 case *DynamicFeeTx: 438 t.Nonce = nonce 439 } 440 } 441 442 func (tx *Transaction) Sign() []byte { 443 return tx.inner.sign() 444 } 445 446 func (tx *Transaction) Cost() *uint256.Int { 447 price := tx.inner.gasPrice() 448 gas := uint256.NewInt(tx.inner.gas()) 449 total := new(uint256.Int).Mul(price, gas) 450 total = total.Add(total, tx.Value()) 451 return total 452 } 453 454 func (tx *Transaction) Hash() types.Hash { 455 if hash := tx.hash.Load(); hash != nil { 456 return hash.(types.Hash) 457 } 458 h := tx.inner.hash() 459 tx.hash.Store(h) 460 return h 461 } 462 463 // GasFeeCapCmp compares the fee cap of two transactions. 464 func (tx *Transaction) GasFeeCapCmp(other *Transaction) int { 465 return tx.inner.gasFeeCap().Cmp(other.inner.gasFeeCap()) 466 } 467 468 // EffectiveGasTipIntCmp compares the effective gasTipCap of a transaction to the given gasTipCap. 469 func (tx *Transaction) EffectiveGasTipIntCmp(other *uint256.Int, baseFee *uint256.Int) int { 470 if baseFee == nil { 471 return tx.GasTipCapIntCmp(other) 472 } 473 return tx.EffectiveGasTipValue(baseFee).Cmp(other) 474 } 475 476 // GasTipCapCmp compares the gasTipCap of two transactions. 477 func (tx *Transaction) GasTipCapCmp(other *Transaction) int { 478 return tx.inner.gasTipCap().Cmp(other.inner.gasTipCap()) 479 } 480 481 // GasFeeCapIntCmp compares the fee cap of the transaction against the given fee cap. 482 func (tx *Transaction) GasFeeCapIntCmp(other *uint256.Int) int { 483 return tx.inner.gasFeeCap().Cmp(other) 484 } 485 486 // GasTipCapIntCmp compares the gasTipCap of the transaction against the given gasTipCap. 487 func (tx *Transaction) GasTipCapIntCmp(other *uint256.Int) int { 488 return tx.inner.gasTipCap().Cmp(other) 489 } 490 491 // EffectiveGasTipValue is identical to EffectiveGasTip, but does not return an 492 // error in case the effective gasTipCap is negative 493 func (tx *Transaction) EffectiveGasTipValue(baseFee *uint256.Int) *uint256.Int { 494 effectiveTip, _ := tx.EffectiveGasTip(baseFee) 495 return effectiveTip 496 } 497 498 // EffectiveGasTipCmp compares the effective gasTipCap of two transactions assuming the given base fee. 499 func (tx *Transaction) EffectiveGasTipCmp(other *Transaction, baseFee *uint256.Int) int { 500 if baseFee == nil { 501 return tx.GasTipCapCmp(other) 502 } 503 return tx.EffectiveGasTipValue(baseFee).Cmp(other.EffectiveGasTipValue(baseFee)) 504 } 505 506 // EffectiveGasTip returns the effective miner gasTipCap for the given base fee. 507 // Note: if the effective gasTipCap is negative, this method returns both error 508 // the actual negative value, _and_ ErrGasFeeCapTooLow 509 func (tx *Transaction) EffectiveGasTip(baseFee *uint256.Int) (*uint256.Int, error) { 510 if baseFee == nil { 511 return tx.GasTipCap(), nil 512 } 513 var err error 514 gasFeeCap := tx.GasFeeCap() 515 if gasFeeCap.Cmp(baseFee) == -1 { 516 err = ErrGasFeeCapTooLow 517 } 518 return uint256Min(tx.GasTipCap(), new(uint256.Int).Sub(gasFeeCap, baseFee)), err 519 } 520 521 func uint256Min(x, y *uint256.Int) *uint256.Int { 522 if x.Cmp(y) == 1 { 523 return x 524 } 525 return y 526 } 527 528 func isProtectedV(V *big.Int) bool { 529 if V.BitLen() <= 8 { 530 v := V.Uint64() 531 return v != 27 && v != 28 && v != 1 && v != 0 532 } 533 // anything not 27 or 28 is considered protected 534 return true 535 } 536 537 // Protected says whether the transaction is replay-protected. 538 func (tx *Transaction) Protected() bool { 539 switch tx := tx.inner.(type) { 540 case *LegacyTx: 541 return tx.V.ToBig() != nil && isProtectedV(tx.V.ToBig()) 542 default: 543 return true 544 } 545 } 546 547 // WithSignature returns a new transaction with the given signature. 548 // This signature needs to be in the [R || S || V] format where V is 0 or 1. 549 func (tx *Transaction) WithSignature(signer Signer, sig []byte) (*Transaction, error) { 550 r, s, v, err := signer.SignatureValues(tx, sig) 551 if err != nil { 552 return nil, err 553 } 554 cpy := tx.inner.copy() 555 var chainID *uint256.Int 556 if signer.ChainID() == nil { 557 chainID = nil 558 } else { 559 chainID, _ = uint256.FromBig(signer.ChainID()) 560 } 561 562 v1, _ := uint256.FromBig(v) 563 r1, _ := uint256.FromBig(r) 564 s1, _ := uint256.FromBig(s) 565 cpy.setSignatureValues(chainID, v1, r1, s1) 566 return &Transaction{inner: cpy, time: tx.time}, nil 567 } 568 569 //type Transaction struct { 570 // to types.Address 571 // from types.Address 572 // nonce uint64 573 // amount uint256.Int 574 // gasLimit uint64 575 // gasPrice uint256.Int 576 // gasFeeCap uint256.Int 577 // payload []byte 578 //} 579 580 //func (t *Transaction) ToProtoMessage() proto.Message { 581 // pbTx := types_pb.Transaction{ 582 // From: types.Address(t.from), 583 // To: types.Address(t.to), 584 // Value: t.amount, 585 // Data: t.payload, 586 // Nonce: t.nonce, 587 // S: nil, 588 // V: nil, 589 // R: nil, 590 // } 591 // 592 // return &pbTx 593 //} 594 595 func copyAddressPtr(a *types.Address) *types.Address { 596 if a == nil { 597 return nil 598 } 599 cpy := *a 600 return &cpy 601 } 602 603 // Message is a fully derived transaction and implements core.Message 604 type Message struct { 605 to *types.Address 606 from types.Address 607 nonce uint64 608 amount uint256.Int 609 gasLimit uint64 610 gasPrice uint256.Int 611 feeCap uint256.Int 612 tip uint256.Int 613 data []byte 614 accessList AccessList 615 checkNonce bool 616 isFree bool 617 } 618 619 func NewMessage(from types.Address, to *types.Address, nonce uint64, amount *uint256.Int, gasLimit uint64, gasPrice *uint256.Int, feeCap, tip *uint256.Int, data []byte, accessList AccessList, checkNonce bool, isFree bool) Message { 620 m := Message{ 621 from: from, 622 to: to, 623 nonce: nonce, 624 amount: *amount, 625 gasLimit: gasLimit, 626 data: data, 627 accessList: accessList, 628 checkNonce: checkNonce, 629 isFree: isFree, 630 } 631 if gasPrice != nil { 632 m.gasPrice.Set(gasPrice) 633 } 634 if tip != nil { 635 m.tip.Set(tip) 636 } 637 if feeCap != nil { 638 m.feeCap.Set(feeCap) 639 } 640 return m 641 } 642 643 // AsMessage returns the transaction as a core.Message. 644 func (tx *Transaction) AsMessage(s Signer, baseFee *uint256.Int) (Message, error) { 645 msg := Message{ 646 nonce: tx.Nonce(), 647 gasLimit: tx.Gas(), 648 gasPrice: *new(uint256.Int).Set(tx.GasPrice()), 649 feeCap: *new(uint256.Int).Set(tx.GasFeeCap()), 650 tip: *new(uint256.Int).Set(tx.GasTipCap()), 651 //gasFeeCap: new(big.Int).Set(tx.GasFeeCap()), 652 //gasTipCap: new(big.Int).Set(tx.GasTipCap()), 653 to: tx.To(), 654 amount: *tx.Value(), 655 data: tx.Data(), 656 accessList: tx.AccessList(), 657 checkNonce: false, 658 //isFake: false, 659 } 660 661 // If baseFee provided, set gasPrice to effectiveGasPrice. 662 if baseFee != nil { 663 msg.gasPrice.Add(&msg.tip, baseFee) 664 665 if msg.gasPrice.Gt(&msg.feeCap) { 666 msg.gasPrice = msg.feeCap 667 } 668 } 669 //var err error 670 //msg.from, err = Sender(s, tx) 671 //if nil != err { 672 // return msg, err 673 //} 674 msg.from = *tx.From() 675 676 return msg, nil 677 } 678 func (m Message) From() types.Address { return m.from } 679 func (m Message) To() *types.Address { return m.to } 680 func (m Message) GasPrice() *uint256.Int { return &m.gasPrice } 681 func (m Message) FeeCap() *uint256.Int { return &m.feeCap } 682 func (m Message) Tip() *uint256.Int { return &m.tip } 683 func (m Message) Value() *uint256.Int { return &m.amount } 684 func (m Message) Gas() uint64 { return m.gasLimit } 685 func (m Message) Nonce() uint64 { return m.nonce } 686 func (m Message) Data() []byte { return m.data } 687 func (m Message) AccessList() AccessList { return m.accessList } 688 func (m Message) CheckNonce() bool { return m.checkNonce } 689 func (m *Message) SetCheckNonce(checkNonce bool) { 690 m.checkNonce = checkNonce 691 } 692 func (m Message) IsFree() bool { return m.isFree } 693 func (m *Message) SetIsFree(isFree bool) { 694 m.isFree = isFree 695 }