Ethereum  PoC-8
The C++ Implementation of Ethereum
TransactionBase.cpp
Go to the documentation of this file.
1 /*
2  This file is part of cpp-ethereum.
3 
4  cpp-ethereum is free software: you can redistribute it and/or modify
5  it under the terms of the GNU 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  cpp-ethereum 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 General Public License for more details.
13 
14  You should have received a copy of the GNU General Public License
15  along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
16 */
22 #include <libdevcore/vector_ref.h>
23 #include <libdevcore/Log.h>
24 #include <libdevcrypto/Common.h>
25 #include <libethcore/Exceptions.h>
26 #include "TransactionBase.h"
27 #include "EVMSchedule.h"
28 
29 using namespace std;
30 using namespace dev;
31 using namespace dev::eth;
32 
33 TransactionBase::TransactionBase(TransactionSkeleton const& _ts, Secret const& _s):
34  m_type(_ts.creation ? ContractCreation : MessageCall),
35  m_nonce(_ts.nonce),
36  m_value(_ts.value),
37  m_receiveAddress(_ts.to),
38  m_gasPrice(_ts.gasPrice),
39  m_gas(_ts.gas),
40  m_data(_ts.data),
41  m_sender(_ts.from)
42 {
43  if (_s)
44  sign(_s);
45 }
46 
48 {
49  RLP const rlp(_rlpData);
50  try
51  {
52  if (!rlp.isList())
53  BOOST_THROW_EXCEPTION(InvalidTransactionFormat() << errinfo_comment("transaction RLP must be a list"));
54 
55  m_nonce = rlp[0].toInt<u256>();
56  m_gasPrice = rlp[1].toInt<u256>();
57  m_gas = rlp[2].toInt<u256>();
58  m_type = rlp[3].isEmpty() ? ContractCreation : MessageCall;
59  m_receiveAddress = rlp[3].isEmpty() ? Address() : rlp[3].toHash<Address>(RLP::VeryStrict);
60  m_value = rlp[4].toInt<u256>();
61 
62  if (!rlp[5].isData())
63  BOOST_THROW_EXCEPTION(InvalidTransactionFormat() << errinfo_comment("transaction data RLP must be an array"));
64 
65  m_data = rlp[5].toBytes();
66 
67  int const v = rlp[6].toInt<int>();
68  h256 const r = rlp[7].toInt<u256>();
69  h256 const s = rlp[8].toInt<u256>();
70 
71  if (isZeroSignature(r, s))
72  {
73  m_chainId = v;
74  m_vrs = SignatureStruct{r, s, 0};
75  }
76  else
77  {
78  if (v > 36)
79  m_chainId = (v - 35) / 2;
80  else if (v == 27 || v == 28)
81  m_chainId = -4;
82  else
83  BOOST_THROW_EXCEPTION(InvalidSignature());
84 
85  m_vrs = SignatureStruct{r, s, static_cast<byte>(v - (m_chainId * 2 + 35))};
86 
87  if (_checkSig >= CheckTransaction::Cheap && !m_vrs->isValid())
88  BOOST_THROW_EXCEPTION(InvalidSignature());
89  }
90 
91  if (_checkSig == CheckTransaction::Everything)
92  m_sender = sender();
93 
94  if (rlp.itemCount() > 9)
95  BOOST_THROW_EXCEPTION(InvalidTransactionFormat() << errinfo_comment("too many fields in the transaction RLP"));
96  }
97  catch (Exception& _e)
98  {
99  _e << errinfo_name("invalid transaction format: " + toString(rlp) + " RLP: " + toHex(rlp.data()));
100  throw;
101  }
102 }
103 
104 Address const& TransactionBase::safeSender() const noexcept
105 {
106  try
107  {
108  return sender();
109  }
110  catch (...)
111  {
112  return ZeroAddress;
113  }
114 }
115 
117 {
118  if (!m_sender.is_initialized())
119  {
120  if (hasZeroSignature())
122  else
123  {
124  if (!m_vrs)
125  BOOST_THROW_EXCEPTION(TransactionIsUnsigned());
126 
127  auto p = recover(*m_vrs, sha3(WithoutSignature));
128  if (!p)
129  BOOST_THROW_EXCEPTION(InvalidSignature());
130  m_sender = right160(dev::sha3(bytesConstRef(p.data(), sizeof(p))));
131  }
132  }
133  return *m_sender;
134 }
135 
137 {
138  if (!m_vrs)
139  BOOST_THROW_EXCEPTION(TransactionIsUnsigned());
140 
141  return *m_vrs;
142 }
143 
144 void TransactionBase::sign(Secret const& _priv)
145 {
146  auto sig = dev::sign(_priv, sha3(WithoutSignature));
147  SignatureStruct sigStruct = *(SignatureStruct const*)&sig;
148  if (sigStruct.isValid())
149  m_vrs = sigStruct;
150 }
151 
152 void TransactionBase::streamRLP(RLPStream& _s, IncludeSignature _sig, bool _forEip155hash) const
153 {
154  if (m_type == NullTransaction)
155  return;
156 
157  _s.appendList((_sig || _forEip155hash ? 3 : 0) + 6);
158  _s << m_nonce << m_gasPrice << m_gas;
159  if (m_type == MessageCall)
160  _s << m_receiveAddress;
161  else
162  _s << "";
163  _s << m_value << m_data;
164 
165  if (_sig)
166  {
167  if (!m_vrs)
168  BOOST_THROW_EXCEPTION(TransactionIsUnsigned());
169 
170  if (hasZeroSignature())
171  _s << m_chainId;
172  else
173  {
174  int const vOffset = m_chainId * 2 + 35;
175  _s << (m_vrs->v + vOffset);
176  }
177  _s << (u256)m_vrs->r << (u256)m_vrs->s;
178  }
179  else if (_forEip155hash)
180  _s << m_chainId << 0 << 0;
181 }
182 
183 static const u256 c_secp256k1n("115792089237316195423570985008687907852837564279074904382605163141518161494337");
184 
186 {
187  if (!m_vrs)
188  BOOST_THROW_EXCEPTION(TransactionIsUnsigned());
189 
190  if (m_vrs->s > c_secp256k1n / 2)
191  BOOST_THROW_EXCEPTION(InvalidSignature());
192 }
193 
194 void TransactionBase::checkChainId(int chainId) const
195 {
196  if (m_chainId != chainId && m_chainId != -4)
197  BOOST_THROW_EXCEPTION(InvalidSignature());
198 }
199 
200 int64_t TransactionBase::baseGasRequired(bool _contractCreation, bytesConstRef _data, EVMSchedule const& _es)
201 {
202  int64_t g = _contractCreation ? _es.txCreateGas : _es.txGas;
203 
204  // Calculate the cost of input data.
205  // No risk of overflow by using int64 until txDataNonZeroGas is quite small
206  // (the value not in billions).
207  for (auto i: _data)
208  g += i ? _es.txDataNonZeroGas : _es.txDataZeroGas;
209  return g;
210 }
211 
213 {
214  if (_sig == WithSignature && m_hashWith)
215  return m_hashWith;
216 
217  RLPStream s;
218  streamRLP(s, _sig, m_chainId > 0 && _sig == WithoutSignature);
219 
220  auto ret = dev::sha3(s.out());
221  if (_sig == WithSignature)
222  m_hashWith = ret;
223  return ret;
224 }
dev::eth::TransactionException::InvalidSignature
@ InvalidSignature
dev::eth::TransactionSkeleton
Definition: Common.h:184
dev::RLP::VeryStrict
@ VeryStrict
Definition: RLP.h:58
dev::MaxAddress
Address const MaxAddress
The last address.
Definition: Address.cpp:23
dev::vector_ref< byte const >
dev::eth::WithoutSignature
@ WithoutSignature
Do not include a signature.
Definition: TransactionBase.h:37
dev::eth::TransactionBase::m_gasPrice
u256 m_gasPrice
The base fee and thus the implied exchange rate of ETH to GAS.
Definition: TransactionBase.h:180
dev::SecureFixedHash< 32 >
dev::eth::TransactionBase::rlp
bytes rlp(IncludeSignature _sig=WithSignature) const
Definition: TransactionBase.h:109
dev::sha3
bool sha3(bytesConstRef _input, bytesRef o_output) noexcept
Definition: SHA3.cpp:28
dev::eth::CheckTransaction::Cheap
@ Cheap
dev::eth::TransactionBase::m_chainId
int m_chainId
EIP155 value for calculating transaction hash https://github.com/ethereum/EIPs/issues/155.
Definition: TransactionBase.h:184
dev::eth::TransactionBase::m_gas
u256 m_gas
The total gas to convert, paid for from sender's account. Any unused gas gets refunded once the contr...
Definition: TransactionBase.h:181
dev::eth::EVMSchedule::txDataNonZeroGas
unsigned txDataNonZeroGas
Definition: EVMSchedule.h:70
dev::eth::TransactionBase::TransactionBase
TransactionBase()
Constructs a null transaction.
Definition: TransactionBase.h:53
dev::eth::CheckTransaction::Everything
@ Everything
dev::RLPStream::out
bytes const & out() const
Read the byte stream.
Definition: RLP.h:419
dev::eth::TransactionBase::isZeroSignature
static bool isZeroSignature(u256 const &_r, u256 const &_s)
Definition: TransactionBase.h:171
Exceptions.h
Common.h
dev::eth
Definition: BasicAuthority.h:32
dev::eth::TransactionBase::m_sender
boost::optional< Address > m_sender
Cached sender, determined from signature.
Definition: TransactionBase.h:187
dev::eth::TransactionBase::m_data
bytes m_data
The data associated with the transaction, or the initialiser if it's a creation transaction.
Definition: TransactionBase.h:182
dev::eth::EVMSchedule::txDataZeroGas
unsigned txDataZeroGas
Definition: EVMSchedule.h:69
dev::toString
std::string toString(std::chrono::time_point< T > const &_e, std::string const &_format="%F %T")
Definition: CommonIO.h:86
dev::FixedHash< 20 >
dev::SignatureStruct::isValid
bool isValid() const noexcept
Definition: Common.cpp:72
dev::eth::EVMSchedule::txGas
unsigned txGas
Definition: EVMSchedule.h:67
dev::right160
h160 right160(h256 const &_t)
Convert the given value into h160 (160-bit unsigned integer) using the right 20 bytes.
Definition: FixedHash.h:369
dev::ZeroAddress
Address const ZeroAddress
The zero address.
Definition: Address.cpp:22
dev::eth::errinfo_name
boost::error_info< struct tag_field, std::string > errinfo_name
Definition: Exceptions.h:33
dev::Exception
Base class for all exceptions.
Definition: Exceptions.h:39
dev::eth::IncludeSignature
IncludeSignature
Named-boolean type to encode whether a signature be included in the serialisation process.
Definition: TransactionBase.h:36
dev::eth::TransactionBase::m_nonce
u256 m_nonce
The transaction-count of the sender.
Definition: TransactionBase.h:177
dev::eth::TransactionBase::m_hashWith
h256 m_hashWith
Cached hash of transaction with signature.
Definition: TransactionBase.h:186
EVMSchedule.h
dev::eth::WithSignature
@ WithSignature
Do include a signature.
Definition: TransactionBase.h:38
dev::eth::TransactionBase::m_vrs
boost::optional< SignatureStruct > m_vrs
The signature of the transaction. Encodes the sender.
Definition: TransactionBase.h:183
dev::SignatureStruct
Definition: Common.h:51
dev::recover
Public recover(Signature const &_sig, h256 const &_hash)
Recovers Public key from signed message hash.
Definition: Common.cpp:221
TransactionBase.h
dev::eth::TransactionBase::hasZeroSignature
bool hasZeroSignature() const
Definition: TransactionBase.h:145
dev::eth::TransactionBase::safeSender
Address const & safeSender() const noexcept
Like sender() but will never throw.
Definition: TransactionBase.cpp:104
dev::bytesConstRef
vector_ref< byte const > bytesConstRef
Definition: Common.h:74
dev::eth::TransactionBase::NullTransaction
@ NullTransaction
Null transaction.
Definition: TransactionBase.h:166
dev::eth::TransactionBase::sha3
h256 sha3(IncludeSignature _sig=WithSignature) const
Definition: TransactionBase.cpp:212
dev::eth::TransactionBase::MessageCall
@ MessageCall
Transaction to invoke a message call - receiveAddress() is used.
Definition: TransactionBase.h:168
dev::eth::TransactionBase::m_value
u256 m_value
The amount of ETH to be transferred by this transaction. Called 'endowment' for contract-creation tra...
Definition: TransactionBase.h:178
dev::eth::TransactionBase::baseGasRequired
int64_t baseGasRequired(EVMSchedule const &_es) const
Definition: TransactionBase.h:157
dev::eth::TransactionBase::sign
void sign(Secret const &_priv)
Sign the transaction.
Definition: TransactionBase.cpp:144
dev::RLPStream
Class for writing to an RLP bytestream.
Definition: RLP.h:370
vector_ref.h
dev::eth::CheckTransaction
CheckTransaction
Definition: TransactionBase.h:42
dev::eth::TransactionBase::checkChainId
void checkChainId(int chainId=-4) const
Definition: TransactionBase.cpp:194
dev::sign
Signature sign(Secret const &_k, h256 const &_hash)
Returns siganture of message hash.
Definition: Common.cpp:251
dev::eth::EVMSchedule::txCreateGas
unsigned txCreateGas
Definition: EVMSchedule.h:68
dev::eth::TransactionBase::sender
Address const & sender() const
Definition: TransactionBase.cpp:116
std
Definition: FixedHash.h:393
dev::u256
boost::multiprecision::number< boost::multiprecision::cpp_int_backend< 256, 256, boost::multiprecision::unsigned_magnitude, boost::multiprecision::unchecked, void > > u256
Definition: Common.h:121
dev
Definition: Address.cpp:21
dev::eth::TransactionBase::m_receiveAddress
Address m_receiveAddress
The receiving address of the transaction.
Definition: TransactionBase.h:179
dev::toHex
std::string toHex(Iterator _it, Iterator _end, std::string const &_prefix)
Definition: CommonData.h:46
dev::eth::EVMSchedule
Definition: EVMSchedule.h:29
dev::eth::TransactionBase::checkLowS
void checkLowS() const
Definition: TransactionBase.cpp:185
dev::RLP
Definition: RLP.h:48
dev::eth::TransactionBase::streamRLP
void streamRLP(RLPStream &_s, IncludeSignature _sig=WithSignature, bool _forEip155hash=false) const
Definition: TransactionBase.cpp:152
dev::Address
h160 Address
Definition: Address.h:30
Log.h
dev::eth::TransactionBase::m_type
Type m_type
Is this a contract-creation transaction or a message-call transaction?
Definition: TransactionBase.h:176
dev::RLPStream::appendList
RLPStream & appendList(size_t _items)
Appends a list.
Definition: RLP.cpp:268
dev::errinfo_comment
boost::error_info< struct tag_comment, std::string > errinfo_comment
Definition: Assertions.h:69
dev::eth::TransactionBase::ContractCreation
@ ContractCreation
Transaction to create contracts - receiveAddress() is ignored.
Definition: TransactionBase.h:167
dev::eth::TransactionBase::signature
SignatureStruct const & signature() const
Definition: TransactionBase.cpp:136