-
Notifications
You must be signed in to change notification settings - Fork 2
/
main.hpp
110 lines (96 loc) · 2.9 KB
/
main.hpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
#include "core_imports.hpp"
#include "core_functions.cpp"
typedef unsigned char byte;
typedef h256 EthereumTxId;
class EthereumAddress {
public:
EthereumAddress() {}
EthereumAddress(bytesConstRef a) {
assert(a.size() == 20 || a.size() == 21);
if (a.size() == 20)
copy(a.begin(), a.end(), m_data);
else if (a.size() == 21)
copy(a.begin() + 1, a.end(), m_data);
}
EthereumAddress(Public pubkey) {
h256 hash = sha3(pubkey.ref());
std::copy(hash.data() + 12, hash.data() + 32, m_data);
}
byte m_data[20];
std::string hex()
{
std::stringstream ss;
ss << std::hex;
for(int i=0;i<20;++i)
ss << std::setw(2) << std::setfill('0') << (int)m_data[i];
return ss.str();
}
};
std::string hexStrB(byte * data, int len)
{
std::stringstream ss;
ss << std::hex;
for(int i=0;i<len;++i)
ss << std::setw(2) << std::setfill('0') << (int)data[i];
return ss.str();
}
class EthereumTx {
public:
EthereumTx(RLP tx_rlp) {
id = sha3(tx_rlp.data());
nonce = uint64_t(tx_rlp[0]);
gasPrice = uint64_t(tx_rlp[1]);
gasLimit = uint64_t(tx_rlp[2]);
to = EthereumAddress(tx_rlp[3].data());
value = u256(tx_rlp[4]);
data = tx_rlp[5].data();
v = tx_rlp[6].data()[0];
r = tx_rlp[7].data();
s = tx_rlp[8].data();
RLPStream rstream;
rstream.appendList(9);
for (int i=0; i<6; i++)
rstream.appendRaw(tx_rlp[i].data());
rstream.append(1);
rstream.append("");
rstream.append("");
RLP sig_rlp = RLP(rstream.out());
bytes b = sig_rlp.data().toBytes();
Signature sig = signature();
h256 signing_hash = sha3(sig_rlp.data());
sig.data()[64] = 0; // v must be set to 0 just for the recovery
// NOTE: This line takes 40ms on its own. Can it be optimized?
Public pubkey = recover(sig, signing_hash);
from = EthereumAddress(pubkey);
}
Signature signature () {
h520 sig;
std::copy(r.begin() + 1, r.end(), sig.data());
std::copy(s.begin() + 1, s.end(), sig.data() + 32);
*(sig.data() + 64) = v;
return sig;
}
EthereumTxId id;
EthereumAddress from;
EthereumAddress to;
u256 value;
uint64_t gasLimit;
uint64_t gasPrice;
uint64_t nonce;
byte v;
bytesConstRef r; // size=32
bytesConstRef s; // size=32
bytesConstRef init;
bytesConstRef data;
};
ostream& operator<<(ostream& os, const EthereumTx& tx)
{
os << "Ethereum Tx " << tx.id << endl;
os << " from " << tx.from.hex() << endl;
os << " to " << tx.to.hex() << endl;
os << " nonce " << tx.nonce << endl;
os << " gas price " << tx.gasPrice << endl;
os << " gas limit " << tx.gasLimit << endl;
os << " value " << tx.value << endl;
os << " signature " << tx.signature() << endl;
};