1 // Aleth: Ethereum C++ client, tools and libraries. 2 // Copyright 2014-2019 Aleth Authors. 3 // Licensed under the GNU General Public License, Version 3. 4 5 #pragma once 6 7 #include <libethcore/Common.h> 8 #include <libdevcrypto/Common.h> 9 #include <libdevcore/RLP.h> 10 #include <libdevcore/SHA3.h> 11 12 #include <boost/optional.hpp> 13 14 namespace dev 15 { 16 namespace eth 17 { 18 19 struct EVMSchedule; 20 21 /// Named-boolean type to encode whether a signature be included in the serialisation process. 22 enum IncludeSignature 23 { 24 WithoutSignature = 0, ///< Do not include a signature. 25 WithSignature = 1, ///< Do include a signature. 26 }; 27 28 enum class CheckTransaction 29 { 30 None, 31 Cheap, 32 Everything 33 }; 34 35 #define o_has_value(o) (o.get_ptr() != 0) 36 37 /// Encodes a transaction, ready to be exported to or freshly imported from RLP. 38 class TransactionBase 39 { 40 public: 41 /// Constructs a null transaction. TransactionBase()42 TransactionBase() {} 43 44 /// Constructs a transaction from a transaction skeleton & optional secret. 45 TransactionBase(TransactionSkeleton const& _ts, Secret const& _s = Secret()); 46 47 /// Constructs a signed message-call transaction. TransactionBase(u256 const & _value,u256 const & _gasPrice,u256 const & _gas,Address const & _dest,bytes const & _data,u256 const & _nonce,Secret const & _secret)48 TransactionBase(u256 const& _value, u256 const& _gasPrice, u256 const& _gas, Address const& _dest, bytes const& _data, u256 const& _nonce, Secret const& _secret): m_type(MessageCall), m_nonce(_nonce), m_value(_value), m_receiveAddress(_dest), m_gasPrice(_gasPrice), m_gas(_gas), m_data(_data) { sign(_secret); } 49 50 /// Constructs a signed contract-creation transaction. TransactionBase(u256 const & _value,u256 const & _gasPrice,u256 const & _gas,bytes const & _data,u256 const & _nonce,Secret const & _secret)51 TransactionBase(u256 const& _value, u256 const& _gasPrice, u256 const& _gas, bytes const& _data, u256 const& _nonce, Secret const& _secret): m_type(ContractCreation), m_nonce(_nonce), m_value(_value), m_gasPrice(_gasPrice), m_gas(_gas), m_data(_data) { sign(_secret); } 52 53 /// Constructs an unsigned message-call transaction. m_type(MessageCall)54 TransactionBase(u256 const& _value, u256 const& _gasPrice, u256 const& _gas, Address const& _dest, bytes const& _data, u256 const& _nonce = 0): m_type(MessageCall), m_nonce(_nonce), m_value(_value), m_receiveAddress(_dest), m_gasPrice(_gasPrice), m_gas(_gas), m_data(_data) {} 55 56 /// Constructs an unsigned contract-creation transaction. m_type(ContractCreation)57 TransactionBase(u256 const& _value, u256 const& _gasPrice, u256 const& _gas, bytes const& _data, u256 const& _nonce = 0): m_type(ContractCreation), m_nonce(_nonce), m_value(_value), m_gasPrice(_gasPrice), m_gas(_gas), m_data(_data) {} 58 59 /// Constructs a transaction from the given RLP. 60 explicit TransactionBase(bytesConstRef _rlp, CheckTransaction _checkSig); 61 62 /// Constructs a transaction from the given RLP. TransactionBase(bytes const & _rlp,CheckTransaction _checkSig)63 explicit TransactionBase(bytes const& _rlp, CheckTransaction _checkSig): TransactionBase(&_rlp, _checkSig) {} 64 65 /// Checks equality of transactions. 66 bool operator==(TransactionBase const& _c) const { return m_type == _c.m_type && (m_type == ContractCreation || m_receiveAddress == _c.m_receiveAddress) && m_value == _c.m_value && m_data == _c.m_data; } 67 /// Checks inequality of transactions. 68 bool operator!=(TransactionBase const& _c) const { return !operator==(_c); } 69 70 /// @returns sender of the transaction from the signature (and hash). 71 /// @throws TransactionIsUnsigned if signature was not initialized 72 Address const& sender() const; 73 /// Like sender() but will never throw. @returns a null Address if the signature is invalid. 74 Address const& safeSender() const noexcept; 75 /// Force the sender to a particular value. This will result in an invalid transaction RLP. forceSender(Address const & _a)76 void forceSender(Address const& _a) { m_sender = _a; } 77 78 /// @throws TransactionIsUnsigned if signature was not initialized 79 /// @throws InvalidSValue if the signature has an invalid S value. 80 void checkLowS() const; 81 82 /// @throws InvalidSignature if the transaction is replay protected 83 /// and chain id is not equal to @a _chainId 84 void checkChainId(uint64_t _chainId) const; 85 86 /// @returns true if transaction is non-null. 87 explicit operator bool() const { return m_type != NullTransaction; } 88 89 /// @returns true if transaction is contract-creation. isCreation()90 bool isCreation() const { return m_type == ContractCreation; } 91 92 /// Serialises this transaction to an RLPStream. 93 /// @throws TransactionIsUnsigned if including signature was requested but it was not initialized 94 void streamRLP(RLPStream& _s, IncludeSignature _sig = WithSignature, bool _forEip155hash = false) const; 95 96 /// @returns the RLP serialisation of this transaction. 97 bytes rlp(IncludeSignature _sig = WithSignature) const { RLPStream s; streamRLP(s, _sig); return s.out(); } 98 99 /// @returns the SHA3 hash of the RLP serialisation of this transaction. 100 h256 sha3(IncludeSignature _sig = WithSignature) const; 101 102 /// @returns the amount of ETH to be transferred by this (message-call) transaction, in Wei. Synonym for endowment(). value()103 u256 value() const { return m_value; } 104 105 /// @returns the base fee and thus the implied exchange rate of ETH to GAS. gasPrice()106 u256 gasPrice() const { return m_gasPrice; } 107 108 /// @returns the total gas to convert, paid for from sender's account. Any unused gas gets refunded once the contract is ended. gas()109 u256 gas() const { return m_gas; } 110 111 /// @returns the receiving address of the message-call transaction (undefined for contract-creation transactions). receiveAddress()112 Address receiveAddress() const { return m_receiveAddress; } 113 114 /// Synonym for receiveAddress(). to()115 Address to() const { return m_receiveAddress; } 116 117 /// Synonym for safeSender(). from()118 Address from() const { return safeSender(); } 119 120 /// @returns the data associated with this (message-call) transaction. Synonym for initCode(). data()121 bytes const& data() const { return m_data; } 122 123 /// @returns the transaction-count of the sender. nonce()124 u256 nonce() const { return m_nonce; } 125 126 /// Sets the nonce to the given value. Clears any signature. setNonce(u256 const & _n)127 void setNonce(u256 const& _n) { clearSignature(); m_nonce = _n; } 128 129 /// @returns true if the transaction was signed hasSignature()130 bool hasSignature() const { return o_has_value(m_vrs); } 131 132 /// @returns true if the transaction was signed with zero signature hasZeroSignature()133 bool hasZeroSignature() const { return m_vrs && isZeroSignature(m_vrs->r, m_vrs->s); } 134 135 /// @returns true if the transaction uses EIP155 replay protection isReplayProtected()136 bool isReplayProtected() const { return o_has_value(m_chainId); } 137 138 /// @returns the signature of the transaction (the signature has the sender encoded in it) 139 /// @throws TransactionIsUnsigned if signature was not initialized 140 SignatureStruct const& signature() const; 141 142 /// @returns v value of the transaction (has chainID and recoveryID encoded in it) 143 /// @throws TransactionIsUnsigned if signature was not initialized 144 u256 rawV() const; 145 146 void sign(Secret const& _priv); ///< Sign the transaction. 147 148 /// @returns amount of gas required for the basic payment. baseGasRequired(EVMSchedule const & _es)149 int64_t baseGasRequired(EVMSchedule const& _es) const { return baseGasRequired(isCreation(), &m_data, _es); } 150 151 /// Get the fee associated for a transaction with the given data. 152 static int64_t baseGasRequired(bool _contractCreation, bytesConstRef _data, EVMSchedule const& _es); 153 154 protected: 155 /// Type of transaction. 156 enum Type 157 { 158 NullTransaction, ///< Null transaction. 159 ContractCreation, ///< Transaction to create contracts - receiveAddress() is ignored. 160 MessageCall ///< Transaction to invoke a message call - receiveAddress() is used. 161 }; 162 isZeroSignature(u256 const & _r,u256 const & _s)163 static bool isZeroSignature(u256 const& _r, u256 const& _s) { return !_r && !_s; } 164 165 /// Clears the signature. clearSignature()166 void clearSignature() { m_vrs = SignatureStruct(); } 167 168 Type m_type = NullTransaction; ///< Is this a contract-creation transaction or a message-call transaction? 169 u256 m_nonce; ///< The transaction-count of the sender. 170 u256 m_value; ///< The amount of ETH to be transferred by this transaction. Called 'endowment' for contract-creation transactions. 171 Address m_receiveAddress; ///< The receiving address of the transaction. 172 u256 m_gasPrice; ///< The base fee and thus the implied exchange rate of ETH to GAS. 173 u256 m_gas; ///< The total gas to convert, paid for from sender's account. Any unused gas gets refunded once the contract is ended. 174 bytes m_data; ///< The data associated with the transaction, or the initialiser if it's a creation transaction. 175 boost::optional<SignatureStruct> m_vrs; ///< The signature of the transaction. Encodes the sender. 176 /// EIP155 value for calculating transaction hash 177 /// https://github.com/ethereum/EIPs/blob/master/EIPS/eip-155.md 178 boost::optional<uint64_t> m_chainId; 179 180 mutable h256 m_hashWith; ///< Cached hash of transaction with signature. 181 mutable boost::optional<Address> m_sender; ///< Cached sender, determined from signature. 182 }; 183 184 /// Nice name for vector of Transaction. 185 using TransactionBases = std::vector<TransactionBase>; 186 187 /// Simple human-readable stream-shift operator. 188 inline std::ostream& operator<<(std::ostream& _out, TransactionBase const& _t) 189 { 190 _out << _t.sha3().abridged() << "{"; 191 if (_t.receiveAddress()) 192 _out << _t.receiveAddress().abridged(); 193 else 194 _out << "[CREATE]"; 195 196 _out << "/" << _t.data().size() << "$" << _t.value() << "+" << _t.gas() << "@" << _t.gasPrice(); 197 _out << "<-" << _t.safeSender().abridged() << " #" << _t.nonce() << "}"; 198 return _out; 199 } 200 201 } 202 } 203