diff --git a/core/types/transaction.go b/core/types/transaction.go index 7f1447ef8..24035a3ae 100644 --- a/core/types/transaction.go +++ b/core/types/transaction.go @@ -2,6 +2,7 @@ package types import ( "bytes" + "errors" "fmt" "io" "math/big" @@ -21,19 +22,19 @@ type Transaction struct { AccountNonce uint64 Price *big.Int GasLimit *big.Int - Recipient common.Address + Recipient *common.Address // nil means contract creation Amount *big.Int Payload []byte V byte R, S []byte } -func NewContractCreationTx(amount, gasAmount, price *big.Int, data []byte) *Transaction { - return NewTransactionMessage(common.Address{}, amount, gasAmount, price, data) +func NewContractCreationTx(amount, gasLimit, gasPrice *big.Int, data []byte) *Transaction { + return &Transaction{Recipient: nil, Amount: amount, GasLimit: gasLimit, Price: gasPrice, Payload: data} } -func NewTransactionMessage(to common.Address, amount, gasAmount, price *big.Int, data []byte) *Transaction { - return &Transaction{Recipient: to, Amount: amount, Price: price, GasLimit: gasAmount, Payload: data} +func NewTransactionMessage(to common.Address, amount, gasAmount, gasPrice *big.Int, data []byte) *Transaction { + return &Transaction{Recipient: &to, Amount: amount, GasLimit: gasAmount, Price: gasPrice, Payload: data} } func NewTransactionFromBytes(data []byte) *Transaction { @@ -73,12 +74,21 @@ func (self *Transaction) SetNonce(AccountNonce uint64) { self.AccountNonce = AccountNonce } -func (self *Transaction) From() common.Address { - return self.sender() +func (self *Transaction) From() (common.Address, error) { + pubkey := self.PublicKey() + if len(pubkey) == 0 || pubkey[0] != 4 { + return common.Address{}, errors.New("invalid public key") + } + var addr common.Address + copy(addr[:], crypto.Sha3(pubkey[1:])) + return addr, nil } -func (self *Transaction) To() common.Address { - return self.Recipient +// To returns the recipient of the transaction. +// If transaction is a contract creation (with no recipient address) +// To returns nil. +func (tx *Transaction) To() *common.Address { + return tx.Recipient } func (tx *Transaction) Curve() (v byte, r []byte, s []byte) { @@ -105,18 +115,6 @@ func (tx *Transaction) PublicKey() []byte { return pubkey } -func (tx *Transaction) sender() (a common.Address) { - pubkey := tx.PublicKey() - - // Validate the returned key. - // Return nil if public key isn't in full format - if len(pubkey) == 0 || pubkey[0] != 4 { - return a - } - copy(a[:], crypto.Sha3(pubkey[1:])) - return a -} - func (tx *Transaction) SetSignatureValues(sig []byte) error { tx.R = sig[:32] tx.S = sig[32:64] @@ -149,11 +147,22 @@ func (tx *Transaction) RlpEncode() []byte { } func (tx *Transaction) String() string { + var from, to string + if f, err := tx.From(); err != nil { + from = "[invalid sender]" + } else { + from = fmt.Sprintf("%x", f[:]) + } + if t := tx.To(); t == nil { + to = "[contract creation]" + } else { + to = fmt.Sprintf("%x", t[:]) + } return fmt.Sprintf(` TX(%x) Contract: %v - From: %x - To: %x + From: %s + To: %s Nonce: %v GasPrice: %v GasLimit %v @@ -166,8 +175,8 @@ func (tx *Transaction) String() string { `, tx.Hash(), len(tx.Recipient) == 0, - tx.From(), - tx.To(), + from, + to, tx.AccountNonce, tx.Price, tx.GasLimit, diff --git a/core/types/transaction_test.go b/core/types/transaction_test.go index 1af59436e..0b0dfe3ff 100644 --- a/core/types/transaction_test.go +++ b/core/types/transaction_test.go @@ -19,8 +19,9 @@ var ( nil, ) - rightvrsTx = &Transaction{ - Recipient: common.HexToAddress("b94f5374fce5edbc8e2a8697c15331677e6ebf0b"), + rightvrsRecipient = common.HexToAddress("b94f5374fce5edbc8e2a8697c15331677e6ebf0b") + rightvrsTx = &Transaction{ + Recipient: &rightvrsRecipient, AccountNonce: 3, Price: big.NewInt(1), GasLimit: big.NewInt(2000),