-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathTODOs
369 lines (246 loc) · 17.2 KB
/
TODOs
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
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
npm init
npm install jest@23.6.0 --save-dev
cat package.json =>to see the package.json to check if the package has actually been installed
SHA-256 => 256 for bits(0's and 1's) of hash
=> equal to 64 Hexadecimal characters (0-9 and A-F)
=>produces a unique value for unique input
=> A one-way function(data -> hash)
=>[encryption is easy but decryption(hash -> data) is next to impossible]
Proof of work in blockchain:
Bitcoin: inspired by a system called HashCash(1997)
HashCash => originally developed to prevent the problem of email spamming
=> any any point, there's going to be a level of difficulty in the system
=>depending upon this diff, one miner shall add a new block
=>they'll have to find a hash value for this block that matches the difficulty
=>for matching, miners will have to find the same number of leading zeros as the current difficulty for the generated hash of the new block to add to the chain
=>becomes exponentially harder as the diff increases
=>nonce comes in play
=>generate new hashes by changing nonce values
=>takes decent amt of computational work
=>Thus, finding the nonce that unlocks a hash that meets the difficulty requirement is that very proof of work
NONCE: Number Used Once
NOTE: We're using Hexadecimal form of SHA-256 {rep in 64 characters}
BITCOIN uses BINARY form of the hash (rep in 256 binary(0 and 1) characters)
DIFFICULTY : no of leading 0 BITS(Binary format ma) in a 256 bit binary string
O=0 Once a miner has succesfully mined a block (found the correct nonce value), s/he has the rights to submit their block with the correctfound nonce value to other miners
0-0 Then the other miners can quickly verify the valid block and then add it to their own chain w/o having to redo the same computational work
Bitcoin adds a new block to the chain in every 10 minutes
=>> 51% attack : when a evil miner has 51% of the computational power of the whole blockchain ntk
=>> impossible because it COSTS TOO MUCH!
=> as of the EOY 2018, it would cost more than $9 Billion to take over the entire ntk with 51% attack
WE've:
=> implemented Proof of work
=> set dynamic difficulty and Mine Rate
[to adjust the blockchain diff level in order to bring the average rate of blocks being added mined closer to as set mining rate]
=> by adding a diff attribute to each block
=> in addition to this we've introduced a global time-value called the MINE_RATE
=> MINE_RATE: reps the rate at which we want a block to be added to the chain
>DIFFICULTY ADUSTMENT:
=> check the timestamp of the new block which is being mined
=> compare it's timestamp with the last block
=> calculate the diff btn the two timestamps
=> if diff < MINE_RATE => the block was mined too quickly
=> So, raise the difficulty for the next block by 1
=> if diff > MINE_RATE => the block was mined too slowly
=> So, lower the diff by 1
=>THIS WAY, We'll always ADJUST the difficulty
key diff btn Bitcoin's DIFFICULTY sys and ours:
=>Bitcoin checks for leading zer0's in 256 binary bits hash
=> Our sys checks it on 64 characters Hexadecimal hash
INSTALL: npm i hex-to-binary@1.0.1 --save
==> WHICH WE CHANGED TO CHECK FOR BINARY HASHES (using hex-to-binary node module we added)
TROUBLE encountered: due to dynamic difficulty setting, our system was vulnerable to hacker attacks to reset it according to them
SOVED: => in isValidChain() mthd in `blockchain.js`, make a rule to make sure that the difficulty never adjusts by more than 1 for every adjacent blocks
Part 4: BLOCKCHAIN API
=> Read the blockchain
=> write to the blockchain
INSTALL API: EXPRESS ()
npm i express@4.16.3 --save
will serve 2 main purposes:
=> allow a frontned application to interact w/ the blockchain in order to read data abt the blockchain and also write data to the blockchain
=> allow other blockchain backends to interact w/ each other
We'll configure EXPRESS server to access various HTTP requests that'll be made over the web
HTTP REQUESTS:
GET=> associated w/ reading data [to read the blocks of the blockchain]
POST => w/ sending data to the web server [to carry data to add new block to the chain consisting of that data]
GET:
//.get takes 2 instances("endpoint_on_the_server_where_we_want_this_req_to_be_located" , a_callback_fxn_which_aill_fire_when_this_get_req_is_used(request, response)=>{})
//res object allows us to define how we want this get request to respond
POST: same as above
receives data from the user in json format
Blockchain instances in the ntk=> can read each other's data and add new blocks to the chains if necessary
ADDED: index.js file
NOTE: in package.json, add a script: "start":"node index.js"
COMMAND: npm run start
INSTALL: npm i nodemon@1.18.4 --save-dev
NOTE: in package.json, add a script: "dev":"nodemon index.js"
INSTALL : npm i body-parser@1.18.3 --save
Networking pattern used: PubSub [vd: 5.4]
PubSub=> Real-Time Messaging ntk
=> To broadcast updates of a local bc to all the peers of the ntk
=> Reduces a lot of work needed for alternative ntk implementations like "Tracking Socket Addresses" [often used in peer-peer ntks]
Tracking Socket Address:
=>In this ntk implementation, realtime socket cnnxns are open btn servers and each server has to maintain a list of peers it's made a connection with.
=>Whenever a msg broadcast needs to happen in the entire ntk btn all peers, that node needs to send a direct msg to every single peer that has kept track of in its list.
=> It's a lot of work
Blockchain Pub/Sub [ntk implementation used here]
PubNub: used for this [vd: 5.9]
$ npm i pubnub@4.21.6 —save
=>make pubsub.js
=> write code in it
=> make an instance of it in index.js
goto pubnub.com => login using dhun... gmail => create a new app => click on it=> get the keys => use it in pubsub.js
=> For: Start Peers and Broadcast Chain on API Mine
INSTALL Module: Cross-environment [vd: 5.11]
$ npm i cross-env@5.2.0 --save-dev
ADD to package.json :"dev-peer" : "cross-env GENERATE_PEER_PORT='true' nodemon index.js"
=>helps us to set environment variables programmatically no matter what OS or Cmd Line Appn one is using
=> develop precisely nodejs appns to work w/ environment variables no matter what machine one's using
=>to start and GENERATE PEER PORT command: npm run dev-peer
TASK: SYNC CHAINS on CONNECT
INSTALL MODULE: request
$ npm i request@2.88.0 --save
=> gives us a fxn has the ability to send a http get request
import it in index.js and use it
ERROR: vd: 5.12
[PART: 6]
DID => refactored the whole project directories
CREATED: wallet.js
=>made a Wallet class
=>gave each wallet a starting balance of 1000
4] TASK: CREATE the public key address to the wallet
=> PROBLEM: can't just be a unique id and has to be based on a cryptographic private-public key pair
=> SOLUTION: INSTALL "elliptic" module
INSTALL: npm install elliptic@6.4.1 --save
Elliptic:
=> a node module that has classes and fxns that enable elliptic curve-based cryptography.
=>Elliptic cryptography is an advanced mathematical subject
=> Idea: It is computationally infeasible and impossibly expensive to guess the answer to a randomly generated elliptic curve
=>Look up for it online
=> Look up =>how the key pairs are generated ; how the signatures are done; how they're verified
=>PUBLIC and PRIVATE key capablilities of Elliptic:
EC: elliptic cryptography
=> CREATE: index.js in utils for this
=> used EC('secp256k1) [this is the same algo used by Bitcoin [secp256k1]
=>sec: standards of efficient cryptography ; p: prime ; 256: 256 bits; k: mathematician's initials; 1: first implementation
NOTE: the keys we get from EC 's genKeyPair() are in the form of points in Ellipse
=> we needa convert them to Hexadecimal form to be able to use them as addresses
=> NOTE: DON't USE ATH REGARDING PRIVATE KEYS in the code [use getPublic() but never getPrivate() until u don't have to]
5] added fxnality for signing data and verifying valid/invalid signatures
6]INSTALL: npm install uuid@3.3.2 --save
=>provides us with a way to generate a truly unique value for the actual transaction on its ID field.
=>we used version 1 of this module
vid:6.12 bata continue
13]NOTE: js always treats [different references to the same object] as equal even thought it's property has changed in one of the references
=> So it was producing the same hash using cryptohash() fxn for changed instances referenced to the same object(transaction)
=> so we made sure that the hash is unique for any object that has new properties
=>by stringifying each input inside an object and hashing them
=> Now, hash was gen. using SHA-256 online generator for "ash" and lowercasing it[including the double quotes since our stringified version of input is hashed now in the real program]
[[7]] TRANSACTION POOL
[7.1] The transaction pool is a data structure which is going to collect the transactions that are created by wallets throughout the ntk.
Implementation should satisfy 3 main purposes:
=>1. It collects a unique set of transaction objects
=>2. It could update already existing store transactions when a change has been submitted by a wallet.
=>3. It can rewrite multiple transactions in the inner collection.
wheather that means replacing the collection with an entirely new set or clearing the pool iteself with a handful or all of its transactions.
HOW IS THIS TRANSACTION POOL GOING TO BE USED?
=>Every node in the ntk is gonna have their own instance of transaction pool.
=> like the Blockchain, everyone is going to have their own running version of the pool.
=> THE KEY is MAKING SURE that all of these transaction pools stay synchronized.
=>When one node creates a new transaction or updates an existing one, the transaction is going to have to be BROADCASTED to the ENTIRE NTK.
=> Based on the TRANSACTION ID,
IF it's NEW=> it'll be added to each transaction pool
If a transaction w/ that ID already exists=> it'll be updated
SIGNIFICANCE:
=>It'll enable MINERS to get an accurate list of recent transactions in order to include them within the new block.
=>When looking to add a new block to the BC, a miner is going to use the trnxns in the pool as the data for a new block to mine.
[7.2] Create the TRANSACTION POOL object (in wallet folder)
=> It'll collect transactions from various contributors over time in the overall blockchain ntk.
=> Similar to the outputMap for a trnxn itself, we maintain the transaction pools's data through a
=> MAP -like structure
=>Make an INNER MAP in the transaction pool called "transactionMap"
=> MAP : a key-value structure
=>Benfit : storing unique items in the collection as long as you use the same key for that items every time
[Array doesn't immediately support these kinds of duplicates]
=> If we set a trnxn by its ID within a transactionMap, everytime , when that trnxn is actually updated, it's going to overwrite its prev stored value within the trnxn map as long as we used that same trnxn ID
=>The primary way we're gonna add a trnxn is through a mthd called "setTransaction"
=> It'll have 2 primary behaviours:
=>1. add a transaction by passing the transaction object, which it'll add to the transaction pool
transactionMap[transactionId] = transaction (object)
[7.3] Created a Main Transaction Pool and allowed Transactions to be added through the API
=> whenever one wants to send some currency, they'll only have to make a POST request
=> whenever the transaction is created, it'll be added to the growing transaction pool for the application
=> in the main index.js:
=> import the transaction-pool file
=> make a local instance of the TransactionPool() in there
=>import the wallet
=>make a local instance of the Wallet() in there
=>that way, anytime we want to create a new transaction, we can use the
wallet.createTransaction() mthd
make a new POST endpoint to create or generate transaction
/api/transact
[7.4] solved the bugs from the prev sxn:
BUGS: 1. the updates to the existing trnxn weren't working yet through the API
2. Invalid amount was causing a pretty ugly error to appear
[fixed 2]
[7.5] fix transaction updates
=> introduced try{}catch(err){} block in the above endpoint
=> created existingTransaction() mthd in transaction-pool.js
[7.6] create a transaction-pool-map get enpoint in main/index.js
[7.9] status 200: success
[7.12] synced up the transaction-pool-map enpoint on connect
(any new peer added will automatically get synced up with the transaction-pool already existing in the BC)
[[8]] MINE Transactions
[8.1] Mine Transactions:
=>the transaction miner will get the transactions from the transaction pool
=> called MINERS because => they pay the costs of computational power and do the work to find a valid hash for a new block
=>MINING REWARD:
=>comes in the form of a special transaction
=> that transaction only has a single output which will be for the miner's wallet w/ an official mining reward value
=>input value will be a unique transaction input as well
=> all the nodes have the ability to validate it
=> WITHOUT the reward or the incentive, the blockchain growth will stagnate
=>FUNCTIONALITIES a miner needs to achieve to validate a block of Transactions
=>5 ACTIONS:
=>1. Grab all the valid transactions that are currently in the pool
=>2. Generate a miner's reward
=>3. Do the CPU work to find a valid hash
=>4. Broadcast the updated blockchain w/ the new block created
=>5. Clear the transaction pool now that the miner has already included the transaction data in the BC
[NOTE: Miner only needs to clear the pools of its own node and not the pools on the behalf of all the other BC instances]
=>MAKE: transaction-miner.js file in app
[8.4] Reward Transaction
=> The REWARD_INPUT is set as a hardcoded value (takes only one argument, here, address)
=>It must fo through validation to make sure that a peer in the system cannot abuse or alter it
=> added a new rewardTransaction() mthd in the Transaction class
[8.6] Made /mine-transactions endpoint
=> Added clearBlockchainTransactions() to clear the blockchain transactions that have successfully been mined using this endpoint in all the nodes in the blockchain
[8.7] Clear Recorded Transactions on Successful Replace
=> added some fxnality to replaceChain(__, onSuccess)
=> onSuceess() in pubsub.s insided replaceChain() is a callback fxn that clears clears the blockchain trnxns in transaction pool that have been mined succesfully
[8.8] BC balance overview
=>Calculate balance
=>Balance = ntk of a wallet rather than 'net worth' of a wallet in cryptocurrency.
=>Initially, everyone is going to start out with the same starting balance: 1000
=>we'll add an algo that will calculate the wallet's balance and figure out it balance at any point in the BC history
=>Overall mthd flow:
=>Scan the entire BC and the transaction history starting from the most recent block and going all the way to genesis block.
=>A wallet w/ no transactions still has the starting balance in it
=>A wallet that has actually made a transaction should have its balance whatever is the output of the transaction
=>Output reps the remaining balance after the trnxn
=>When a wallet is the recipient of one or more transactions:
=>it has even more value to its balance
=>it gets to add any output amt sent to its adderess after its most recent transaction to its overall balance
=>The balance of a wallet will always be the output of the most recent transaction done from it unwithstanding it's older transactions in the overall BC history
[8.13] Validate Transaction Blocks Overview
=> 1. Each transaction must be correctly formatted
=> 2. Only one mining reward per block
=> 3. The block's input amt should be valid according to the blockchain history.
=> 4. There cannot be multiple identical transactions in the same block
[8.12] Valid Transaction Data in the Blockchain
=>TWO types of trnxns:
=> Reward trnxns
=> Regular trnxns
=>Both need to be handled individually
[8.16] Validate Input Balances
=> Even when an evil trnxn is attempted to be submitted, we're gonna make sure that it doesn't pass the validTransactionData() mthd unless its input balance is actually matching what we have in out blockchain.