forked from cooganb/bitcoin-whitepaper-exercises
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
initial exercise files (minus README content)
- Loading branch information
0 parents
commit bd830e6
Showing
17 changed files
with
735 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
# Bitcoin Whitepaper Exercises | ||
|
||
In these exercises, you will learn about blockchains from the perspective of the [original Bitcoin Whitepaper](https://bitcoin.org/en/bitcoin-paper). | ||
|
||
* [Hashing](hashing/README.md) | ||
* [Transactions](transactions/README.md) | ||
* [Wallet](wallet/README.md) | ||
* [Proof of Work](pow/README.md) | ||
* [Incentives](incentives/README.md) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
# Bitcoin Whitepaper Exercises - Hashing | ||
|
||
TODO |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
"use strict"; | ||
|
||
var crypto = require("crypto"); | ||
|
||
// The Power of a Smile | ||
// by Tupac Shakur | ||
var poem = [ | ||
"The power of a gun can kill", | ||
"and the power of fire can burn", | ||
"the power of wind can chill", | ||
"and the power of a mind can learn", | ||
"the power of anger can rage", | ||
"inside until it tears u apart", | ||
"but the power of a smile", | ||
"especially yours can heal a frozen heart", | ||
]; | ||
|
||
var Blockchain = { | ||
blocks: [], | ||
}; | ||
|
||
// Genesis block | ||
Blockchain.blocks.push({ | ||
index: 0, | ||
hash: "000000", | ||
data: "", | ||
timestamp: Date.now(), | ||
}); | ||
|
||
// TODO: insert each line into blockchain | ||
// for (let line of poem) { | ||
// } | ||
|
||
// console.log(`Blockchain is valid: ${verifyChain(Blockchain)}`); | ||
|
||
|
||
// ********************************** | ||
|
||
function blockHash(bl) { | ||
return crypto.createHash("sha256").update( | ||
// TODO: use block data to calculate hash | ||
).digest("hex"); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
# Bitcoin Whitepaper Exercises - Incentives | ||
|
||
TODO |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
"use strict"; | ||
|
||
var path = require("path"); | ||
var fs = require("fs"); | ||
var openpgp = require("openpgp"); | ||
|
||
const KEYS_DIR = path.join(__dirname,"keys"); | ||
|
||
var options = { | ||
userIds: [{ name: "Bitcoin Whitepaper", email: "[email protected]" }], | ||
numBits: 2048, | ||
passphrase: "", | ||
}; | ||
|
||
openpgp.generateKey(options).then(function onGenerated(key) { | ||
try { fs.mkdirSync(KEYS_DIR); } catch (err) {} | ||
|
||
fs.writeFileSync(path.join(KEYS_DIR,"priv.pgp.key"),key.privateKeyArmored,"utf8"); | ||
fs.writeFileSync(path.join(KEYS_DIR,"pub.pgp.key"),key.publicKeyArmored,"utf8"); | ||
|
||
console.log("Keypair generated."); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,107 @@ | ||
"use strict"; | ||
|
||
var path = require("path"); | ||
var fs = require("fs"); | ||
var crypto = require("crypto"); | ||
|
||
const KEYS_DIR = path.join(__dirname,"keys"); | ||
const PUB_KEY_TEXT = fs.readFileSync(path.join(KEYS_DIR,"pub.pgp.key"),"utf8"); | ||
|
||
// The Power of a Smile | ||
// by Tupac Shakur | ||
var poem = [ | ||
"The power of a gun can kill", | ||
"and the power of fire can burn", | ||
"the power of wind can chill", | ||
"and the power of a mind can learn", | ||
"the power of anger can rage", | ||
"inside until it tears u apart", | ||
"but the power of a smile", | ||
"especially yours can heal a frozen heart", | ||
]; | ||
|
||
const maxBlockSize = 4; | ||
const blockFee = 5; | ||
var difficulty = 16; | ||
|
||
var Blockchain = { | ||
blocks: [], | ||
}; | ||
|
||
// Genesis block | ||
Blockchain.blocks.push({ | ||
index: 0, | ||
hash: "000000", | ||
data: "", | ||
timestamp: Date.now(), | ||
}); | ||
|
||
var transactionPool = []; | ||
|
||
addPoem(); | ||
processPool(); | ||
countMyEarnings(); | ||
|
||
|
||
// ********************************** | ||
|
||
function addPoem() { | ||
// TODO: add lines of poem as transactions to the transaction-pool | ||
} | ||
|
||
function processPool() { | ||
// TODO: process the transaction-pool in order of highest fees | ||
} | ||
|
||
function countMyEarnings() { | ||
// TODO: count up block-fees and transaction-fees | ||
} | ||
|
||
function createBlock(data) { | ||
var bl = { | ||
index: Blockchain.blocks.length, | ||
prevHash: Blockchain.blocks[Blockchain.blocks.length-1].hash, | ||
data, | ||
timestamp: Date.now(), | ||
}; | ||
|
||
bl.hash = blockHash(bl); | ||
|
||
return bl; | ||
} | ||
|
||
function blockHash(bl) { | ||
while (true) { | ||
bl.nonce = Math.trunc(Math.random() * 1E7); | ||
let hash = crypto.createHash("sha256").update( | ||
`${bl.index};${bl.prevHash};${JSON.stringify(bl.data)};${bl.timestamp};${bl.nonce}` | ||
).digest("hex"); | ||
|
||
if (hashIsLowEnough(hash)) { | ||
return hash; | ||
} | ||
} | ||
} | ||
|
||
function hashIsLowEnough(hash) { | ||
var neededChars = Math.ceil(difficulty / 4); | ||
var threshold = Number(`0b${"".padStart(neededChars * 4,"1111".padStart(4 + difficulty,"0"))}`); | ||
var prefix = Number(`0x${hash.substr(0,neededChars)}`); | ||
return prefix <= threshold; | ||
} | ||
|
||
function createTransaction(data) { | ||
var tr = { | ||
data, | ||
}; | ||
|
||
tr.hash = transactionHash(tr); | ||
|
||
return tr; | ||
} | ||
|
||
function transactionHash(tr) { | ||
return crypto.createHash("sha256").update( | ||
`${JSON.stringify(tr.data)}` | ||
).digest("hex"); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
# Bitcoin Whitepaper Exercises - Proof of Work | ||
|
||
TODO |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,93 @@ | ||
"use strict"; | ||
|
||
var crypto = require("crypto"); | ||
|
||
// The Power of a Smile | ||
// by Tupac Shakur | ||
var poem = [ | ||
"The power of a gun can kill", | ||
"and the power of fire can burn", | ||
"the power of wind can chill", | ||
"and the power of a mind can learn", | ||
"the power of anger can rage", | ||
"inside until it tears u apart", | ||
"but the power of a smile", | ||
"especially yours can heal a frozen heart", | ||
]; | ||
|
||
var difficulty = 10; | ||
|
||
var Blockchain = { | ||
blocks: [], | ||
}; | ||
|
||
// Genesis block | ||
Blockchain.blocks.push({ | ||
index: 0, | ||
hash: "000000", | ||
data: "", | ||
timestamp: Date.now(), | ||
}); | ||
|
||
for (let line of poem) { | ||
let bl = createBlock(line); | ||
Blockchain.blocks.push(bl); | ||
console.log(`Hash (Difficulty: ${difficulty}): ${bl.hash}`); | ||
|
||
difficulty++; | ||
} | ||
|
||
|
||
// ********************************** | ||
|
||
function createBlock(data) { | ||
var bl = { | ||
index: Blockchain.blocks.length, | ||
prevHash: Blockchain.blocks[Blockchain.blocks.length-1].hash, | ||
data, | ||
timestamp: Date.now(), | ||
}; | ||
|
||
bl.hash = blockHash(bl); | ||
|
||
return bl; | ||
} | ||
|
||
function blockHash(bl) { | ||
// TODO | ||
} | ||
|
||
function hashIsLowEnough(hash) { | ||
// TODO | ||
} | ||
|
||
function verifyBlock(bl) { | ||
if (bl.data == null) return false; | ||
if (bl.index === 0) { | ||
if (bl.hash !== "000000") return false; | ||
} | ||
else { | ||
if (!bl.prevHash) return false; | ||
if (!( | ||
typeof bl.index === "number" && | ||
Number.isInteger(bl.index) && | ||
bl.index > 0 | ||
)) { | ||
return false; | ||
} | ||
if (bl.hash !== blockHash(bl)) return false; | ||
} | ||
|
||
return true; | ||
} | ||
|
||
function verifyChain(chain) { | ||
var prevHash; | ||
for (let bl of chain.blocks) { | ||
if (prevHash && bl.prevHash !== prevHash) return false; | ||
if (!verifyBlock(bl)) return false; | ||
prevHash = bl.hash; | ||
} | ||
|
||
return true; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
# Bitcoin Whitepaper Exercises - Transactions | ||
|
||
TODO |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
"use strict"; | ||
|
||
var path = require("path"); | ||
var fs = require("fs"); | ||
var openpgp = require("openpgp"); | ||
|
||
const KEYS_DIR = path.join(__dirname,"keys"); | ||
|
||
var options = { | ||
userIds: [{ name: "Bitcoin Whitepaper", email: "[email protected]" }], | ||
numBits: 2048, | ||
passphrase: "", | ||
}; | ||
|
||
openpgp.generateKey(options).then(function onGenerated(key) { | ||
try { fs.mkdirSync(KEYS_DIR); } catch (err) {} | ||
|
||
fs.writeFileSync(path.join(KEYS_DIR,"priv.pgp.key"),key.privateKeyArmored,"utf8"); | ||
fs.writeFileSync(path.join(KEYS_DIR,"pub.pgp.key"),key.publicKeyArmored,"utf8"); | ||
|
||
console.log("Keypair generated."); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
{ | ||
"name": "solutions-transactions", | ||
"main": "transactions.js", | ||
"dependencies": { | ||
"openpgp": "~3.0.7" | ||
} | ||
} |
Oops, something went wrong.