Fabcoin Core  0.16.2
P2P Digital Currency
Transaction.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 <libdevcore/CommonIO.h>
25 #include <libdevcrypto/Common.h>
26 #include <libevmcore/EVMSchedule.h>
27 #include <libethcore/Exceptions.h>
28 #include "Transaction.h"
29 
30 using namespace std;
31 using namespace dev;
32 using namespace dev::eth;
33 
34 TransactionBase::TransactionBase(TransactionSkeleton const& _ts, Secret const& _s):
35  m_type(_ts.creation ? ContractCreation : MessageCall),
36  m_nonce(_ts.nonce),
37  m_value(_ts.value),
38  m_receiveAddress(_ts.to),
39  m_gasPrice(_ts.gasPrice),
40  m_gas(_ts.gas),
41  m_data(_ts.data),
42  m_sender(_ts.from)
43 {
44  if (_s)
45  sign(_s);
46 }
47 
49 {
50  int field = 0;
51  RLP rlp(_rlpData);
52  try
53  {
54  if (!rlp.isList())
55  BOOST_THROW_EXCEPTION(InvalidTransactionFormat() << errinfo_comment("transaction RLP must be a list"));
56 
57  m_nonce = rlp[field = 0].toInt<u256>();
58  m_gasPrice = rlp[field = 1].toInt<u256>();
59  m_gas = rlp[field = 2].toInt<u256>();
60  m_type = rlp[field = 3].isEmpty() ? ContractCreation : MessageCall;
61  m_receiveAddress = rlp[field = 3].isEmpty() ? Address() : rlp[field = 3].toHash<Address>(RLP::VeryStrict);
62  m_value = rlp[field = 4].toInt<u256>();
63 
64  if (!rlp[field = 5].isData())
65  BOOST_THROW_EXCEPTION(InvalidTransactionFormat() << errinfo_comment("transaction data RLP must be an array"));
66 
67  m_data = rlp[field = 5].toBytes();
68 
69  byte v = rlp[field = 6].toInt<byte>();
70  h256 r = rlp[field = 7].toInt<u256>();
71  h256 s = rlp[field = 8].toInt<u256>();
72 
73  if (v > 36)
74  m_chainId = (v - 35) / 2;
75  else if (v == 27 || v == 28)
76  m_chainId = -4;
77  else
78  BOOST_THROW_EXCEPTION(InvalidSignature());
79 
80  v = v - (m_chainId * 2 + 35);
81 
82  if (rlp.itemCount() > 9)
83  BOOST_THROW_EXCEPTION(InvalidTransactionFormat() << errinfo_comment("to many fields in the transaction RLP"));
84 
85  m_vrs = SignatureStruct{ r, s, v };
86  if (_checkSig >= CheckTransaction::Cheap && !m_vrs.isValid())
87  BOOST_THROW_EXCEPTION(InvalidSignature());
88  if (_checkSig == CheckTransaction::Everything)
89  m_sender = sender();
90  }
91  catch (Exception& _e)
92  {
93  _e << errinfo_name("invalid transaction format: " + toString(rlp) + " RLP: " + toHex(rlp.data()));
94  throw;
95  }
96 }
97 
98 Address const& TransactionBase::safeSender() const noexcept
99 {
100  try
101  {
102  return sender();
103  }
104  catch (...)
105  {
106  return ZeroAddress;
107  }
108 }
109 
111 {
112  if (!m_sender)
113  {
114  auto p = recover(m_vrs, sha3(WithoutSignature));
115  if (!p)
116  BOOST_THROW_EXCEPTION(InvalidSignature());
117  m_sender = right160(dev::sha3(bytesConstRef(p.data(), sizeof(p))));
118  }
119  return m_sender;
120 }
121 
122 void TransactionBase::sign(Secret const& _priv)
123 {
124  auto sig = dev::sign(_priv, sha3(WithoutSignature));
125  SignatureStruct sigStruct = *(SignatureStruct const*)&sig;
126  if (sigStruct.isValid())
127  m_vrs = sigStruct;
128 }
129 
130 void TransactionBase::streamRLP(RLPStream& _s, IncludeSignature _sig, bool _forEip155hash) const
131 {
132  if (m_type == NullTransaction)
133  return;
134 
135  _s.appendList((_sig || _forEip155hash ? 3 : 0) + 6);
136  _s << m_nonce << m_gasPrice << m_gas;
137  if (m_type == MessageCall)
138  _s << m_receiveAddress;
139  else
140  _s << "";
141  _s << m_value << m_data;
142 
143  if (_sig)
144  {
145  int vOffset = m_chainId*2 + 35;
146  _s << (m_vrs.v + vOffset) << (u256)m_vrs.r << (u256)m_vrs.s;
147  }
148  else if (_forEip155hash)
149  _s << m_chainId << 0 << 0;
150 }
151 
152 static const u256 c_secp256k1n("115792089237316195423570985008687907852837564279074904382605163141518161494337");
153 
155 {
156  if (m_vrs.s > c_secp256k1n / 2)
157  BOOST_THROW_EXCEPTION(InvalidSignature());
158 }
159 
160 void TransactionBase::checkChainId(int chainId) const
161 {
162  if (m_chainId != chainId && m_chainId != -4)
163  BOOST_THROW_EXCEPTION(InvalidSignature());
164 }
165 
166 int64_t TransactionBase::baseGasRequired(bool _contractCreation, bytesConstRef _data, EVMSchedule const& _es)
167 {
168  int64_t g = _contractCreation ? _es.txCreateGas : _es.txGas;
169 
170  // Calculate the cost of input data.
171  // No risk of overflow by using int64 until txDataNonZeroGas is quite small
172  // (the value not in billions).
173  for (auto i: _data)
174  g += i ? _es.txDataNonZeroGas : _es.txDataZeroGas;
175  return g;
176 }
177 
179 {
180  if (_sig == WithSignature && m_hashWith)
181  return m_hashWith;
182 
183  RLPStream s;
184  streamRLP(s, _sig, m_chainId > 0 && _sig == WithoutSignature);
185 
186  auto ret = dev::sha3(s.out());
187  if (_sig == WithSignature)
188  m_hashWith = ret;
189  return ret;
190 }
Adapted from code found on http://stackoverflow.com/questions/180947/base64-decode-snippet-in-c Origi...
Definition: Arith256.cpp:15
std::string toHex(T const &_data, int _w=2, HexPrefix _prefix=HexPrefix::DontAdd)
Definition: CommonData.h:54
u256 m_gas
The total gas to convert, paid for from sender&#39;s account. Any unused gas gets refunded once the contr...
Definition: Transaction.h:167
TransactionBase()
Constructs a null transaction.
Definition: Transaction.h:54
uint8_t byte
Definition: Common.h:57
u256 m_gasPrice
The base fee and thus the implied exchange rate of ETH to GAS.
Definition: Transaction.h:166
boost::error_info< struct tag_field, std::string > errinfo_name
Definition: Exceptions.h:33
bool isList() const
List value.
Definition: RLP.h:112
Do include a signature.
Definition: Transaction.h:39
h160 right160(h256 const &_t)
Convert the given value into h160 (160-bit unsigned integer) using the right 20 bytes.
Definition: FixedHash.h:353
bytesConstRef data() const
The bare data of the RLP.
Definition: RLP.h:97
size_t itemCount() const
Definition: RLP.h:118
bytes const & out() const
Read the byte stream.
Definition: RLP.h:433
h160 Address
An Ethereum address: 20 bytes.
Definition: Common.h:62
#define g(i)
Definition: sha.cpp:735
Address const & sender() const
std::hash for asio::adress
Definition: Common.h:323
Transaction to create contracts - receiveAddress() is ignored.
Definition: Transaction.h:158
unsigned txDataNonZeroGas
Definition: EVMSchedule.h:66
std::string toString(string32 const &_s)
Make normal string from fixed-length string.
Definition: CommonData.cpp:141
int64_t baseGasRequired(EVMSchedule const &_es) const
Definition: Transaction.h:148
IncludeSignature
Named-boolean type to encode whether a signature be included in the serialisation process...
Definition: Transaction.h:36
h256 m_hashWith
Cached hash of transaction with signature.
Definition: Transaction.h:172
bytes rlp(IncludeSignature _sig=WithSignature) const
Definition: Transaction.h:107
Do not include a signature.
Definition: Transaction.h:38
_N toHash(int _flags=Strict) const
Definition: RLP.h:298
Base class for all exceptions.
Definition: Exceptions.h:39
bytes m_data
The data associated with the transaction, or the initialiser if it&#39;s a creation transaction.
Definition: Transaction.h:168
u256 m_value
The amount of ETH to be transferred by this transaction. Called &#39;endowment&#39; for contract-creation tra...
Definition: Transaction.h:164
int m_chainId
EIP155 value for calculating transaction hash https://github.com/ethereum/EIPs/issues/155.
Definition: Transaction.h:170
Address ZeroAddress
The zero address.
Definition: Common.cpp:65
u256 m_nonce
The transaction-count of the sender.
Definition: Transaction.h:163
Public recover(Signature const &_sig, h256 const &_hash)
Recovers Public key from signed message hash.
Definition: Common.cpp:203
vector_ref< byte const > bytesConstRef
Definition: Common.h:77
Fixed-size raw-byte array container type, with an API optimised for storing hashes.
Definition: FixedHash.h:47
RLPStream & appendList(size_t _items)
Appends a list.
Definition: RLP.cpp:276
CheckTransaction
Definition: Transaction.h:42
Address m_receiveAddress
The receiving address of the transaction.
Definition: Transaction.h:165
ANONYMOUS_NAMESPACE_BEGIN const CryptoPP::GF2_32 field
Definition: ida.cpp:14
h256 sha3(IncludeSignature _sig=WithSignature) const
void checkChainId(int chainId=-4) const
boost::multiprecision::number< boost::multiprecision::cpp_int_backend< 256, 256, boost::multiprecision::unsigned_magnitude, boost::multiprecision::unchecked, void >> u256
Definition: Common.h:125
Address const & safeSender() const noexcept
Like sender() but will never throw.
Definition: Transaction.cpp:98
Signature sign(Secret const &_k, h256 const &_hash)
Returns siganture of message hash.
Definition: Common.cpp:233
boost::error_info< struct tag_comment, std::string > errinfo_comment
Definition: Assertions.h:78
bool sha3(bytesConstRef _input, bytesRef o_output)
Calculate SHA3-256 hash of the given input and load it into the given output.
Definition: SHA3.cpp:214
SignatureStruct m_vrs
The signature of the transaction. Encodes the sender.
Definition: Transaction.h:169
void streamRLP(RLPStream &_s, IncludeSignature _sig=WithSignature, bool _forEip155hash=false) const
Serialises this transaction to an RLPStream.
bool isEmpty() const
Contains a zero-length string or zero-length list.
Definition: RLP.h:106
_T toInt(int _flags=Strict) const
Converts to int of type given; if isString(), decodes as big-endian bytestream.
Definition: RLP.h:275
Class for writing to an RLP bytestream.
Definition: RLP.h:383
uint8_t const * data
Definition: sha3.h:19
Class for interpreting Recursive Linear-Prefix Data.
Definition: RLP.h:64
Transaction to invoke a message call - receiveAddress() is used.
Definition: Transaction.h:159
void sign(Secret const &_priv)
Sign the transaction.
bool isValid() const noexcept
Definition: Common.cpp:57
bytes toBytes(int _flags=LaissezFaire) const
Converts to bytearray.
Definition: RLP.h:195
Address m_sender
Cached sender, determined from signature.
Definition: Transaction.h:173
Type m_type
Is this a contract-creation transaction or a message-call transaction?
Definition: Transaction.h:162