Uniswap Sniper Bot  1.0
transaction.hpp
Go to the documentation of this file.
1 #pragma once
2 
3 #include <secp256k1_recovery.h>
4 
5 extern "C" {
6  #include <KeccakSponge.h>
7 }
8 
9 #include "config.hpp"
10 #include "utils.hpp"
11 #include "rlp.hpp"
12 
13 class Transaction {
14  public:
15 
19  static inline constexpr std::size_t FieldsCount = 9;
20 
24  enum Field {
26  };
27 
28  private:
29 
33  enum FieldType {
35  };
36 
41 
53  secp256k1_context *secp256k1Context;
54 
64 
69  { .buffer = nonce, .length = 0 },
70  { .buffer = gasPrice, .length = 0 },
71  { .buffer = gasLimit, .length = 0 },
72  { .buffer = to, .length = 0 },
73  { .buffer = value, .length = 0 },
74  { .buffer = data, .length = 0 },
75  { .buffer = v, .length = 0 },
76  { .buffer = r, .length = 0 },
77  { .buffer = s, .length = 0 },
78  };
79 
88  inline std::size_t _keccak256(Utils::Buffer input, std::size_t inputLength, Utils::Buffer hash) {
89  KeccakWidth1600_Sponge(1088, 512, input, inputLength, 0x01, hash, 32);
90  return 32;
91  }
92 
102  inline std::size_t _ecdsa(Utils::Buffer hash, Utils::Buffer privateKey, Utils::Buffer signature, int *recid) {
103  secp256k1_ecdsa_recoverable_signature ecdsaSig;
104  secp256k1_ecdsa_sign_recoverable(secp256k1Context, &ecdsaSig, hash, privateKey, secp256k1_nonce_function_rfc6979, NULL);
105  secp256k1_ecdsa_recoverable_signature_serialize_compact(secp256k1Context, signature, recid, &ecdsaSig);
106  return 64;
107  }
108 
109  public:
110 
116  secp256k1Context = secp256k1_context_create(SECP256K1_CONTEXT_SIGN);
117  }
118 
124  secp256k1_context_destroy(secp256k1Context);
125  }
126 
133  void setField(Field field, const char *value) {
135  value,
136  rlpInput[field].buffer,
137  fieldTypeMapping[field] == FieldType::QUANTITY
138  );
139  }
140 
148  void setField(Field field, Buffer value, std::size_t size) {
149  // Trim leading zero bytes if of type Quantity
150  if(fieldTypeMapping[field] == FieldType::QUANTITY) {
151  while(*value == 0 && size > 0) {
152  ++value;
153  --size;
154  }
155  }
156 
157  rlpInput[field].length = size;
158  memcpy(rlpInput[field].buffer, value, size);
159  }
160 
169  std::size_t sign(const char *privateKey, Utils::Buffer transaction) {
170  Utils::Byte privateKeyBuffer[32];
171  Utils::hexStringToBuffer(privateKey, 64, privateKeyBuffer);
172  return sign(privateKeyBuffer, transaction);
173  }
174 
183  std::size_t sign(Utils::Buffer privateKey, Utils::Buffer transaction) {
184  // Inject Chain ID as v
185  rlpInput[Field::V].buffer[0] = 0x01;
186  rlpInput[Field::V].length = 1;
187 
188  // Reset signature
189  rlpInput[Field::R].length = 0;
190  rlpInput[Field::S].length = 0;
191 
192  // Encode transaction
193  std::size_t transactionLength = RLP::encodeList(rlpInput, FieldsCount, transaction);
194 
195  // Get transaction hash
196  Utils::Byte hash[32];
197  _keccak256(transaction, transactionLength, hash);
198 
199  // Get transaction signature
200  Utils::Byte signature[64];
201  int recid;
202  _ecdsa(hash, privateKey, signature, &recid);
203 
204  // Inject signature
205  rlpInput[Field::V].buffer[0] = recid + 37;
206  setField(Field::R, signature, 32);
207  setField(Field::S, signature + 32, 32);
208 
209  // Encode signed transaction and return buffer length
210  return RLP::encodeList(rlpInput, FieldsCount, transaction);
211  }
212 };
Definition: transaction.hpp:13
Utils::Byte nonce[Config::Size::TransactionQuantityBuffer]
Definition: transaction.hpp:55
secp256k1_context * secp256k1Context
SECP256K1 context, allows preinitialization as it's very slow to create.
Definition: transaction.hpp:53
Utils::Byte r[Config::Size::TransactionQuantityBuffer]
Definition: transaction.hpp:62
~Transaction()
Destroys the Transaction object. Destroys SECP256K1 context.
Definition: transaction.hpp:123
Utils::Byte data[Config::Size::TransactionDataBuffer]
Definition: transaction.hpp:60
static constexpr FieldType fieldTypeMapping[FieldsCount]
Transaction field to its type mapping.
Definition: transaction.hpp:40
Utils::Byte s[Config::Size::TransactionQuantityBuffer]
Definition: transaction.hpp:63
std::size_t _keccak256(Utils::Buffer input, std::size_t inputLength, Utils::Buffer hash)
KECCAK256 hashing function.
Definition: transaction.hpp:88
Field
Enum containing available transaction fields.
Definition: transaction.hpp:24
@ GasPrice
Definition: transaction.hpp:25
@ GasLimit
Definition: transaction.hpp:25
@ R
Definition: transaction.hpp:25
@ V
Definition: transaction.hpp:25
@ S
Definition: transaction.hpp:25
@ Nonce
Definition: transaction.hpp:25
@ Data
Definition: transaction.hpp:25
@ Value
Definition: transaction.hpp:25
@ To
Definition: transaction.hpp:25
void setField(Field field, const char *value)
Sets the transaction field value.
Definition: transaction.hpp:133
Utils::Byte v[Config::Size::TransactionQuantityBuffer]
Definition: transaction.hpp:61
Utils::Byte gasLimit[Config::Size::TransactionQuantityBuffer]
Definition: transaction.hpp:57
Utils::Byte gasPrice[Config::Size::TransactionQuantityBuffer]
Definition: transaction.hpp:56
Utils::Byte to[Config::Size::TransactionAddressBuffer]
Definition: transaction.hpp:58
RLP::Item rlpInput[FieldsCount]
RLP input data to encode.
Definition: transaction.hpp:68
Utils::Byte value[Config::Size::TransactionQuantityBuffer]
Definition: transaction.hpp:59
static constexpr std::size_t FieldsCount
Transaction's fields count.
Definition: transaction.hpp:19
Transaction()
Constructs a new Transaction object. Creates SECP256K1 context.
Definition: transaction.hpp:115
std::size_t _ecdsa(Utils::Buffer hash, Utils::Buffer privateKey, Utils::Buffer signature, int *recid)
ECDSA hashing function.
Definition: transaction.hpp:102
void setField(Field field, Buffer value, std::size_t size)
Sets the transaction field value.
Definition: transaction.hpp:148
std::size_t sign(Utils::Buffer privateKey, Utils::Buffer transaction)
Signs transaction.
Definition: transaction.hpp:183
FieldType
Enum containing available transaction fields types.
Definition: transaction.hpp:33
@ DATA
Definition: transaction.hpp:34
@ QUANTITY
Definition: transaction.hpp:34
std::size_t sign(const char *privateKey, Utils::Buffer transaction)
Signs transaction.
Definition: transaction.hpp:169
constexpr std::size_t TransactionQuantityBuffer
Definition: config.hpp:91
constexpr std::size_t TransactionDataBuffer
Definition: config.hpp:93
constexpr std::size_t TransactionAddressBuffer
Definition: config.hpp:92
std::size_t encodeList(Item input[], std::size_t inputLength, Buffer output)
Encodes list of items.
Definition: rlp.hpp:86
std::uint8_t Byte
Definition: utils.hpp:11
Byte * Buffer
Definition: utils.hpp:12
std::size_t hexStringToBuffer(const char *input, std::size_t inputLength, Buffer output, bool stripZeroes=false)
Converts hexadecimal string to buffer.
Definition: utils.hpp:52
Struct holding single item data - its byte representation and length.
Definition: rlp.hpp:21
Buffer buffer
Definition: rlp.hpp:22
std::size_t length
Definition: rlp.hpp:23