-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathblockchain(1).cpp
More file actions
322 lines (273 loc) · 7.76 KB
/
Copy pathblockchain(1).cpp
File metadata and controls
322 lines (273 loc) · 7.76 KB
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
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
#include <iostream>
#include <ctime>
#include <vector>
#include <stdio.h>
#include <string>
struct TransactionData
{
double amount;
std::string senderKey;
std::string receiverKey;
time_t timestamp;
TransactionData(){};
TransactionData(double amt, std::string sender, std::string receiver)
{
amount = amt;
senderKey = sender;
receiverKey = receiver;
// timestamp = time;
};
};
class Block
{
private:
int index;
size_t blockHash;
size_t previousHash;
size_t generateHash();
public:
// Constuctor
Block(int idx, TransactionData d, size_t prevHash);
// Get Index
int getIndex();
// Get Original Hash
size_t getHash();
// Get Previous Hash
size_t getPreviousHash();
// Transaction Data
// Would ordinarily be a private member with a "getter": getData()
TransactionData data;
// Validate Hash
bool isHashValid();
};
class Blockchain
{
private:
int data1=0,data2=0,data3=0;
std::vector<Block> chain;
public:
// Constuctor
// Public Functions
std::vector<Block> getChain();
Block *getLatestBlock();
bool isChainValid();
void addBlock(TransactionData data);
void printChain();
void edit_data1(int x){
data1=x;
}
void edit_data2(int x){
data2=x;
}
void edit_data3(int x){
data3=x;
}
int get_data1(){
return data1;
}
int get_data2(){
return data2;
}
int get_data3(){
return data3;
}
};
// Constructor with params
Block::Block(int idx, TransactionData d, size_t prevHash)
{
index = idx;
data = d;
previousHash = prevHash;
blockHash = generateHash();
}
// private functions
int Block::getIndex()
{
return index;
}
/*
Generates hash for current block
- Includes previousHash in generation
- ^ Very important
*/
size_t Block::generateHash()
{
// creating string of transaction data
std::string toHashS = std::to_string(data.amount) + data.receiverKey + data.senderKey + std::to_string(data.timestamp);
// 2 hashes to combine
std::hash<std::string> tDataHash; // hashes transaction data string
std::hash<std::string> prevHash; // re-hashes previous hash (for combination)
// combine hashes and get size_t for block hash
return tDataHash(toHashS) ^ (prevHash(std::to_string(previousHash)) << 1);
}
// Public Functions
size_t Block::getHash()
{
return blockHash;
}
size_t Block::getPreviousHash()
{
return previousHash;
}
bool Block::isHashValid()
{
return generateHash() == getHash();
}
// Blockchain Constructor
// Public Chain Getter
std::vector<Block> Blockchain::getChain() {
return chain;
}
// We only need pointer here
// to demonstrate manipulation of transaction data
Block *Blockchain::getLatestBlock()
{
return &chain.back();
}
void Blockchain::addBlock(TransactionData d)
{
int index = (int)chain.size();
std::size_t previousHash = (int)chain.size() > 0 ? getLatestBlock()->getHash() : 0;
Block newBlock(index, d, previousHash);
chain.push_back(newBlock);
}
bool Blockchain::isChainValid()
{
std::vector<Block>::iterator it;
for (it = chain.begin(); it != chain.end(); ++it)
{
Block currentBlock = *it;
if (!currentBlock.isHashValid())
{
return false;
}
// Don't forget to check if this is the first item
if (it != chain.begin())
{
Block previousBlock = *(it - 1);
if (currentBlock.getPreviousHash() != previousBlock.getHash())
{
return false;
}
}
}
return true;
}
void Blockchain::printChain() {
std::vector<Block>::iterator it;
for (it = chain.begin(); it != chain.end(); ++it)
{
Block currentBlock = *it;
printf("\n\nBlock ===================================");
printf("\nIndex: %d", currentBlock.getIndex());
printf("\nAmount: %f", currentBlock.data.amount);
// printf("\nSenderKey: %s", currentBlock.data.senderKey.c_str());
// printf("\nReceiverKey: %s", currentBlock.data.receiverKey.c_str());
printf("\nTimestamp: %ld", currentBlock.data.timestamp);
printf("\nHash: %zu", currentBlock.getHash());
//printf("\nPrevious Hash: %zu", currentBlock.getPreviousHash());
printf("\nIs Block Valid?: %d", currentBlock.isHashValid());
}
}
using namespace std;
int main()
{
// Start Blockchain
Blockchain awesomeCoin;
int t=0;
while(t>=0){
cout<<"Type 0 to proceed and -1 to stop"<<endl;
cin>>t;
if(t==-1){ break; };
// Data for first block
/*time_t data1Time;
TransactionData data1(1.5, "Joe", "Sally", time(&data1Time));
awesomeCoin.addBlock(data1);
time_t data2Time;
TransactionData data2(0.2233, "Martha", "Fred", time(&data2Time));
awesomeCoin.addBlock(data2);
// Let's see what's in the awesomeCoin blockchain!
awesomeCoin.printChain();
// Is it valid?
printf("\nIs chain still valid? %d\n", awesomeCoin.isChainValid());
// Someone's getting sneaky
Block *hackBlock = awesomeCoin.getLatestBlock();
hackBlock->data.amount = 10000; // Oh yeah!
hackBlock->data.receiverKey = "Jon"; // mwahahahaha!
// Let's look at data
awesomeCoin.printChain();
// Awww! Why is it not valid?
printf("\nIs chain still valid? %d\n", awesomeCoin.isChainValid());*/
cout<<"Please choose who you are"<<endl;
cout<<"1 for customer"<<endl;
cout<<"2 for dealer"<<endl;
cout<<"3 for OEM"<<endl;
//cout<<"4 for OEM"<<endl;
int choice;
cin>>choice;
if(choice==1){
cout<<"enter the amount"<<endl;
double amount;
cin>>amount;
TransactionData data1(amount,"customer","dealer");
awesomeCoin.addBlock(data1);
awesomeCoin.printChain();
cout<<endl;
cout<<"To see stored data type 1 and to edit data type zero"<<endl;
int d;
cin>> d;
if(d==1){
cout<<awesomeCoin.get_data1()<<endl;
}
else if(d==0){
int y;
cout<<"enter data(only integers) : "<<endl;
cin>>y;
awesomeCoin.edit_data1(y);
}
}
else if(choice==2){
cout<<"enter the amount"<<endl;
double amount;
cin>>amount;
TransactionData data1(amount,"dealer","OEM");
awesomeCoin.addBlock(data1);
awesomeCoin.printChain();
cout<<endl;
cout<<"To see stored data type 1 and to edit data type zero"<<endl;
int d;
cin>> d;
if(d==1){
cout<<awesomeCoin.get_data2()<<endl;
}
else if(d==0){
int y;
cout<<"enter data(only integers) : "<<endl;
cin>>y;
awesomeCoin.edit_data2(y);
}
}
else if(choice==3){
cout<<"enter the amount"<<endl;
double amount;
cin>>amount;
TransactionData data1(amount,"OEM","Supplier");
awesomeCoin.addBlock(data1);
awesomeCoin.printChain();
cout<<endl;
cout<<"To see stored data type 1 and to edit data type zero"<<endl;
int d;
cin>> d;
if(d==1){
cout<<awesomeCoin.get_data3()<<endl;
}
else if(d==0){
int y;
cout<<"enter data(only integers) : "<<endl;
cin>>y;
awesomeCoin.edit_data3(y);
}
}
};
return 0;
}