Skip to content

Instantly share code, notes, and snippets.

@zoxee
Created October 31, 2022 08:35
Show Gist options
  • Save zoxee/fc7465e8197538aa14493d40da2716ea to your computer and use it in GitHub Desktop.
Save zoxee/fc7465e8197538aa14493d40da2716ea to your computer and use it in GitHub Desktop.
Simple Proof Of Work Blockchain
<div class="container">
<h1>Simple Proof Of Work Blockchain</h1>
<div class="text">
<p><span class="number">01</span> <span class="green">class </span><span class="orange">Blockchain </span>{</p>
<p><span class="number">02</span>
<span class="indent"></span>
<span class="red">constructor</span>(difficulty) {</p>
<p><span class="number">03</span><span class="indent"></span><span class="indent"></span> this.<span class="blue">difficulty =</span> difficulty;</p>
<p><span class="number">04</span><span class="indent"></span><span class="indent"></span> this.<span class="blue">blocks =</span> [];</p>
<p><span class="number">05</span><span class="indent"></span><span class="indent"></span><span class="indent"></span><span class="number">// Add Genesis Block</span></p>
<p><span class="number">06</span><span class="indent"></span><span class="indent"></span><span class="indent"></span><span class="red">var </span>genesisBlock <span class="blue">= </span><span class="red">new </span><span class="orange">Block</span>(<span class="blue">0</span>, <span class="blue">null</span>, <span class="orange">Date</span>.<span class="red">now</span>(), "Genesis block");</p>
<p><span class="number">07</span><span class="indent"></span><span class="indent"></span> genesisBlock.<span class="red">mineBlock</span>(this.<span class="blue">difficulty</span>);</p>
<p><span class="number">08</span><span class="indent"></span><span class="indent"></span> this.<span class="blue">blocks</span>.<span class="red">push</span>(genesisBlock);</p>
<p><span class="number">09</span><span class="indent"></span> }</p>
<p><span class="number">10</span> }</p>
<p><span class="number">11</span></p>
<p><span class="number">12</span><span class="orange"> Blockchain</span>.<span class="blue">prototype</span>.<span class="red">newBlock</span><span class="blue"> =</span><span class="darkGreen"> function</span>(data) {</p>
<p><span class="number">13</span><span class="indent"></span><span class="red"> var</span> latestBlock<span class="blue"> =</span> this.<span class="blue">blocks</span>[this.<span class="blue">blocks</span>.<span class="blue">length - 1</span>];</p>
<p><span class="number">14</span><span class="indent"></span><span class="red"> return new </span><span class="orange">Block</span>(latestBlock.<span class="blue">index + 1</span>, latestBlock.<span class="blue">hash</span>,<span class="orange"> Date</span>.<span class="red">now</span>(), data);</p>
<p><span class="number">15</span> }</p>
<p><span class="number">16</span><span class="orange"> Blockchain</span>.<span class="blue">prototype</span>.<span class="red">addBlock</span><span class="blue"> =</span><span class="darkGreen"> function</span>(block) {</p>
<p><span class="number">17</span><span class="indent"></span> block.<span class="red">mineBlock</span>(this.<span class="blue">difficulty</span>);</p>
<p><span class="number">18</span><span class="indent"></span> this.<span class="blue">blocks</span>.<span class="red">push</span>(block);</p>
<p><span class="number">19</span> }</p>
<p><span class="number">20</span></p>
<p><span class="number">21</span><span class="orange"> Blockchain</span>.<span class="blue">prototype</span>.<span class="red">isFirstBlockValid</span><span class="blue"> =</span><span class="darkGreen"> function</span>() {</p>
<p><span class="number">22</span><span class="indent"></span><span class="red"> var</span> firstBlock<span class="blue"> =</span> this.<span class="blue">blocks</span>[<span class="blue">0</span>];</p>
<p><span class="number">23</span><span class="indent"></span><span class="red"> if</span> (firstBlock.<span class="blue">index</span> != <span class="blue">0</span>) {</p>
<p><span class="number">24</span><span class="indent"></span><span class="indent"></span><span class="red"> return</span><span class="blue"> false</span>;</p>
<p><span class="number">25</span><span class="indent"></span> }</p>
<p><span class="number">26</span><span class="indent"></span><span class="red"> if</span> (firstBlock.<span class="blue">previousHash</span> == <span class="blue">null</span>) {</p>
<p><span class="number">27</span><span class="indent"></span><span class="indent"></span><span class="red"> return</span><span class="blue"> false</span>;</p>
<p><span class="number">28</span><span class="indent"></span> }</p>
<p><span class="number">29</span><span class="indent"></span><span class="red"> if</span> (firstBlock.<span class="blue">hash == null ||</span><span class="red"> calculateHash</span>(firstBlock) != firstBlock.<span class="blue">hash</span>) {</p>
<p><span class="number">30</span><span class="indent"></span><span class="indent"></span><span class="red"> return</span><span class="blue"> false</span>;</p>
<p><span class="number">31</span><span class="indent"></span> }</p>
<p><span class="number">32</span></span><span class="indent"></span><span class="red"> return</span><span class="blue"> true</span>;</p>
</p>
<p><span class="number">33</span> }</p>
<p><span class="number">34</span></p>
<p><span class="number">35</span><span class="orange"> Blockchain</span>.<span class="blue">prototype</span>.<span class="red">isValidBlock</span><span class="blue"> =</span><span class="darkGreen"> function</span>(block, previousBlock) {</p>
<p><span class="number">36</span><span class="indent"></span><span class="red"> if</span> (previousBlock.<span class="blue">index + 1</span> != block.<span class="blue">index</span>) {</p>
<p><span class="number">37</span><span class="indent"></span><span class="indent"></span><span class="red"> return</span><span class="blue"> false</span>;</p>
<p><span class="number">38</span><span class="indent"></span> }</p>
<p><span class="number">39</span><span class="indent"></span><span class="red"> if</span> (block.<span class="blue">previousHash == null || </span>block.<span class="blue">previousHash</span> != previousBlock.<span class="blue">hash</span>) {</p>
<p><span class="number">40</span><span class="indent"></span><span class="indent"></span><span class="red"> return</span><span class="blue"> false</span>;
</p>
<p><span class="number">41</span><span class="indent"></span> }</p>
<p><span class="number">42</span><span class="indent"></span><span class="red"> if</span> (block.<span class="blue">hash == null || </span><span class="red">calculateHash</span>(block) != block.<span class="blue">hash</span>) {</p>
<p><span class="number">43</span><span class="indent"></span><span class="indent"></span><span class="red"> return</span><span class="blue"> false</span>;</p>
<p><span class="number">44</span><span class="indent"></span> }</p>
<p><span class="number">45</span><span class="indent"></span><span class="indent"></span><span class="red"> return</span><span class="blue"> true</span>;</p>
<p><span class="number">46</span> }</p>
<p><span class="number">47</span></p>
<p><span class="number">48</span><span class="orange"> Blockchain</span>.<span class="blue">prototype</span>.<span class="red">isBlockchainValid</span><span class="blue"> =</span><span class="darkGreen"> function</span>() {</p>
<p><span class="number">49</span><span class="indent"></span><span class="red"> if</span> (!this.<span class="red">isFirstBlockValid</span>()) {</p>
<p><span class="number">50</span><span class="indent"></span><span class="indent"></span><span class="red"> return</span><span class="blue"> false</span>;</p>
<p><span class="number">51</span><span class="indent"></span> }</p>
<p><span class="number">52</span><span class="indent"></span><span class="red"> for</span>(<span class="red">var</span> i<span class="blue"> = 1</span>; i<span class="blue">
< </span>this.<span class="blue">blocks</span>.<span class="blue">length</span>; i<span class="blue">++</span>) {</p>
<p><span class="number">53</span><span class="indent"></span><span class="indent"></span><span class="red"> var</span> block<span class="blue"> =</span> this.<span class="blue">blocks</span>[i];</p>
<p><span class="number">54</span><span class="indent"></span><span class="indent"></span><span class="red"> var</span> previousBlock<span class="blue"> =</span> this.<span class="blue">blocks</span>[i<span class="blue"> - 1</span>];</p>
<p><span class="number">55</span><span class="indent"></span><span class="indent"></span><span class="red"> if</span> (!this.<span class="red">isValidBlock</span>(block, previousBlock)) {</p>
<p><span class="number">56</span><span class="indent"></span><span class="indent"></span><span class="indent"></span><span class="red"> return</span><span class="blue"> false</span>;</p>
<p><span class="number">57</span><span class="indent"></span> }}</p>
<p><span class="number">58</span><span class="indent"></span><span class="red"> return</span><span class="blue"> true</span>;</p>
<p><span class="number">59</span> }</p>
<p><span class="number">60</span></p>
<p><span class="number">61</span><span class="orange"> Blockchain</span>.<span class="blue">prototype</span>.<span class="red">display</span><span class="blue"> =</span><span class="darkGreen"> function</span>() {</p>
<p><span class="number">62</span><span class="indent"></span><span class="red"> for </span>(<span class="red">var </span>i<span class="blue"> = 0</span>; i<span class="blue">
< </span>this.<span class="blue">blocks</span>.<span class="blue">length</span>; i<span class="blue">++</span>) {</p>
<p><span class="number">63</span><span class="indent"></span><span class="indent"></span><span class="red"> var </span>block<span class="blue"> =</span> this.<span class="blue">blocks</span>[i];</p>
<p><span class="number">64</span><span class="indent"></span><span class="indent"></span><span class="red"> var </span>str<span class="blue"> = </span>"Block #"<span class="blue"> + </span>block.<span class="blue">index + </span>" ["<span class="blue"> +</span></p>
<p><span class="number">65</span><span class="indent"></span><span class="indent"></span><span class="indent"></span><span class="indent"></span><span class="indent"></span><span class="indent"></span><span class="indent"></span><span class="indent"></span><span class="indent"></span><span class="indent"></span><span class="indent"></span><span class="indent"></span> "previousHash: "<span class="blue"> + </span>block.<span class="blue">timestamp + </span>block.<span class="blue">timestamp + </span>", "<span class="blue"> +</span></p>
<p><span class="number">66</span><span class="indent"></span><span class="indent"></span><span class="indent"></span><span class="indent"></span><span class="indent"></span><span class="indent"></span><span class="indent"></span><span class="indent"></span><span class="indent"></span><span class="indent"></span><span class="indent"></span><span class="indent"></span> "timestamp: "<span class="blue"> + </span>block.<span class="blue">timestamp + </span>", "<span class="blue"> + </span></p>
<p><span class="number">67</span><span class="indent"></span><span class="indent"></span><span class="indent"></span><span class="indent"></span><span class="indent"></span><span class="indent"></span><span class="indent"></span><span class="indent"></span><span class="indent"></span><span class="indent"></span><span class="indent"></span><span class="indent"></span> "data: "<span class="blue"> + </span>block.<span class="blue">data + </span>", "<span class="blue"> + </span></p>
<p><span class="number">68</span><span class="indent"></span><span class="indent"></span><span class="indent"></span><span class="indent"></span><span class="indent"></span><span class="indent"></span><span class="indent"></span><span class="indent"></span><span class="indent"></span><span class="indent"></span><span class="indent"></span><span class="indent"></span> "hash: "<span class="blue"> + </span>block.<span class="blue">hash + </span>"]";</p>
<p><span class="number">69</span><span class="indent"></span><span class="indent"></span> console.<span class="red">log</span>(str);</p>
<p><span class="number">70</span><span class="indent"></span> }</p>
<p><span class="number">71</span> }</p>
</div>
</div>
//We started by importing SHA-256 from cloudfare https://cdnjs.cloudflare.com/ajax/libs/js-sha256/0.9.0/sha256.min.js
// First we create our Block. The Block is what stores information on the blockchain. This includes the information we define in the Block structure.
class Block {
constructor(index, previousHash, timestamp, data) {
this.index = index;
this.previousHash = previousHash;
this.timestamp = timestamp;
this.data = data;
this.nonce = 0;
this.hash = calculateHash(this);
}
}
// Here we will create the Block and Blockchain hash. The has is what ensures the validity of the network.
function calculateHash(block) {
return sha256(
block.index +
block.previousHash +
block.timestamp +
block.data +
block.nonce
);
}
// Here we determine how Blocks are mined on the Blockchain.
Block.prototype.mineBlock = function (difficulty) {
this.nonce = 0;
var zeros = "0".repeat(difficulty);
while (this.hash.substring(0, difficulty) != zeros) {
this.nonce++;
this.hash = calculateHash(this);
}
};
// This is where our Blockchain comes to life. This is the network architecture of our blockchain network. This allows us to determine how blocks are added to the network, how the mining difficulty is adjusted, check the validity of old blocks, new blocks, and verify the integrity of the network.
class Blockchain {
constructor(difficulty) {
this.difficulty = difficulty;
this.blocks = [];
// Add Genesis Block
var genesisBlock = new Block(0, null, Date.now(), "Genesis block");
genesisBlock.mineBlock(this.difficulty);
this.blocks.push(genesisBlock);
}
}
Blockchain.prototype.newBlock = function (data) {
var latestBlock = this.blocks[this.blocks.length - 1];
return new Block(latestBlock.index + 1, latestBlock.hash, Date.now(), data);
};
Blockchain.prototype.addBlock = function (block) {
block.mineBlock(this.difficulty);
this.blocks.push(block);
};
Blockchain.prototype.isFirstBlockValid = function () {
var firstBlock = this.blocks[0];
if (firstBlock.index != 0) return false;
if (firstBlock.previousHash != null) return false;
if (firstBlock.hash == null || calculateHash(firstBlock) != firstBlock.hash)
return false;
return true;
};
Blockchain.prototype.isValidBlock = function (block, previousBlock) {
if (previousBlock.index + 1 != block.index) return false;
if (block.previousHash == null || block.previousHash != previousBlock.hash)
return false;
if (block.hash == null || calculateHash(block) != block.hash) return false;
return true;
};
Blockchain.prototype.isBlockchainValid = function () {
if (!this.isFirstBlockValid()) return false;
for (var i = 1; i < this.blocks.length; i++) {
var block = this.blocks[i];
var previousBlock = this.blocks[i - 1];
if (!this.isValidBlock(block, previousBlock)) return false;
}
return true;
};
Blockchain.prototype.display = function () {
for (var i = 0; i < this.blocks.length; i++) {
var block = this.blocks[i];
var str =
"Block #" +
block.index +
" [" +
"previousHash: " +
block.previousHash +
", " +
"timestamp: " +
block.timestamp +
", " +
"data: " +
block.data +
", " +
"hash: " +
block.hash +
"]";
console.log(str);
}
};
//Testing Blockchian Validity
// Open Console to see result
var blockchain = new Blockchain(4);
var block1 = blockchain.newBlock("Second Block");
blockchain.addBlock(block1);
var block2 = blockchain.newBlock("Third Block");
blockchain.addBlock(block2);
var block3 = blockchain.newBlock("Fourth Block");
blockchain.addBlock(block3);
console.log("Blockchain Validity: " + blockchain.isBlockchainValid());
blockchain.display();
var block4 = new Block(12, "fakeHash", Date.now(), "Block Invalid");
blockchain.addBlock(block4);
console.log("Blockchain Validity: " + blockchain.isBlockchainValid());
blockchain.display();
<script src="https://cdnjs.cloudflare.com/ajax/libs/js-sha256/0.9.0/sha256.min.js"></script>

Simple Proof Of Work Blockchain

This is a simplified POW Blockchain network. POW (or proof of work) is a method of validating blockchain transactions that relies on physical miners to solve hash based algorithms. POW is a network architecture that is used in many different Blockchain projects, however this specific arcitecture is most similar to the Bitcoin network

A Pen by Alex on CodePen.

License.

* {
background: rgb(20, 18, 28);
font-family: "Source Code Pro", monospace;
}
.container {
display: flex;
flex-direction: column;
justify-content: flex-start;
align-items: center;
}
h1 {
color: white;
padding: 3%;
}
.text {
width: 80%;
}
p {
color: white;
}
.green {
color: #24c452;
}
.orange {
color: #ff9900;
}
.number {
color: #908796;
}
.red {
color: #e3244c;
}
.blue {
color: #0080d6;
}
.indent {
padding: 5px;
}
.darkGreen {
color: #1d7e5a;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment