-
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathblock.hpp
124 lines (105 loc) · 4.47 KB
/
block.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
111
112
113
114
115
116
117
118
119
120
121
122
123
124
#include <iostream>
#include <chrono>
#include <set>
#define MIN_DIFFICULTY 1
#define MED_DIFFICULTY 2
#define MAX_DIFFICULTY 3
namespace ra
{
template <class Transaction, class HashFunctionClass>
class block
{
private:
int id;
std::size_t previous_hash;
std::size_t hash;
// block and transaction both require timestamp
std::chrono::steady_clock::time_point timestamp;
// template input as here std::hash is used but u can make sha256 and the inetegrate them
HashFunctionClass hash_function;
// random data
int nonce;
// pending transactin will become tranctionlist here
std::set<Transaction> transaction_set;
// for proof of work
long long int find_hash_length(int difficulty)
{
int factor = 1;
for (int i = 0; i < difficulty; i++)
{
factor *= 10;
}
// hash functor produces a number of 10 or 9 digits
return (100000000000000 / factor);
}
// converion to string and concatenation of data
std::string generate_hash_input()
{
std::string hash_input = std::to_string((std::chrono::duration_cast<std::chrono::microseconds>(timestamp.time_since_epoch()).count()));
for (typename std::set<Transaction>::iterator trans_elem = transaction_set.begin(); trans_elem != transaction_set.end(); trans_elem++)
{
hash_input += trans_elem->generate_hash_input();
}
hash_input += std::to_string(previous_hash);
return hash_input;
}
public:
block(std::size_t previous_hash, int difficulty, std::set<Transaction> transaction_set, int id)
{
this->id = id;
this->previous_hash = previous_hash;
this->transaction_set = transaction_set;
difficulty = std::max(std::min(difficulty, MAX_DIFFICULTY), MIN_DIFFICULTY);
nonce = 0;
timestamp = std::chrono::steady_clock::now();
hash = mine_block(generate_hash_input(), find_hash_length(difficulty));
}
std::size_t mine_block(std::string hash_input, long long int hash_length)
{
std::size_t hash_output = hash_function(hash_input + std::to_string(nonce));
while (hash_output / hash_length != 0) // own time of proof of work
{
nonce += 1;
hash_output = hash_function(hash_input + std::to_string(nonce));
}
return hash_output;
}
std::size_t get_hash() { return hash; }
std::size_t get_previous_hash() { return previous_hash; }
// recalculates hash and matches to current hash
bool is_hash_valid()
{
std::string hash_input = generate_hash_input();
hash_input += std::to_string(nonce);
return (hash == hash_function(hash_input));
}
bool is_block_valid(bool (*verfication_function)(std::string, std::size_t, unsigned long long int))
{
for (typename std::set<Transaction>::iterator trans_elem = transaction_set.begin(); trans_elem != transaction_set.end(); trans_elem++)
if (!((*trans_elem).is_transaction_valid(verfication_function)))
return false;
return true;
}
// traverse thorugh all transaction
float get_balance(const unsigned long long int address)
{
float balance = 0;
for (typename std::set<Transaction>::iterator trans_elem = transaction_set.begin(); trans_elem != transaction_set.end(); trans_elem++)
balance += (*trans_elem).get_balance(address);
return balance;
}
// modifiable.
friend std::ostream &operator<<(std::ostream &out, block<Transaction, HashFunctionClass> const &temp)
{
int i = 1;
if (temp.id == 0)
out << "...\nGenesis block\n";
else
out << "\n\n...\nBlock No. " << temp.id;
out << "\n\nNo of Entries: " << temp.transaction_set.size() << "\nHash: " << temp.hash << "\nPrevious Hash: " << temp.previous_hash;
for (typename std::set<Transaction>::const_iterator trans_elem = (temp.transaction_set).begin(); trans_elem != temp.transaction_set.end(); trans_elem++, i++)
out << "\n\nEntry no: " << i << (*trans_elem);
return out;
}
};
}