Last active
November 6, 2024 23:10
-
-
Save neoeno/00be262e827a1f0d7dab6bf841225d95 to your computer and use it in GitHub Desktop.
Blockchain (I think?? maybe there needs to be more to be real but it's something)
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
const hashMaker = require("hash.js"); | |
const hashString = string => | |
hashMaker | |
.sha256() | |
.update(string) | |
.digest("hex"); | |
const findBlockWithHashPrefix = (signedGenerator, prefix) => { | |
let nonce = 0; | |
while (true) { | |
nonce++; | |
const signed = signedGenerator(nonce); | |
const hash = hashString(signed); | |
if (hash.slice(0, prefix.length) == prefix) { | |
return { signed, hash }; | |
} | |
} | |
}; | |
const makeSigned = (chain, payload) => nonce => { | |
return JSON.stringify({ | |
lastBlockHash: chain[chain.length - 1].hash, | |
payload, | |
nonce | |
}); | |
}; | |
const addBlock = (chain, payload) => { | |
const signedGenerator = makeSigned(chain, payload); | |
return [...chain, findBlockWithHashPrefix(signedGenerator, "0")]; | |
}; | |
const verifyChain = chain => { | |
return chain.every((block, idx) => { | |
return ( | |
verifyBlockHashMatchesContent(block) && | |
verifyBlockContainsPreviousHash(block, chain[idx - 1]) | |
); | |
}); | |
}; | |
const verifyBlockHashMatchesContent = block => { | |
return hashString(block.signed) === block.hash; | |
}; | |
const verifyBlockContainsPreviousHash = (block, prevBlock) => { | |
// If prevBlock is undefined, we're the genesis block and we can do what we like | |
if (prevBlock === undefined) { | |
return true; | |
} | |
return JSON.parse(block.signed).lastBlockHash === prevBlock.hash; | |
}; | |
module.exports = { | |
addBlock, | |
verifyChain | |
}; |
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
const hashMaker = require("hash.js"); | |
const Chain = require("./chain"); | |
const GENESIS_BLOCK = { | |
hash: "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", | |
signed: "" | |
}; | |
describe("addBlock", () => { | |
test("adds a block", () => { | |
const chain = Chain.addBlock([GENESIS_BLOCK], "hi!"); | |
expect(chain).toEqual([ | |
GENESIS_BLOCK, | |
{ | |
hash: | |
"0574f789c3b7f5cbd10470f2fdec7d9c590d51e8663d69f96dcf0a775b263449", | |
signed: | |
'{"lastBlockHash":"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855","payload":"hi!","nonce":2}' | |
} | |
]); | |
}); | |
}); | |
describe("verifyChain", () => { | |
test("verifies a correct chain", () => { | |
const correctChain = Chain.addBlock([GENESIS_BLOCK], "hi!"); | |
expect(Chain.verifyChain(correctChain)).toBe(true); | |
}); | |
test("invalidates an incorrectly hashed chain", () => { | |
const correctChain = [ | |
GENESIS_BLOCK, | |
{ | |
hash: "badhash", | |
signed: | |
'{"lastBlockHash":"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855","payload":"hi!","nonce":2}' | |
} | |
]; | |
expect(Chain.verifyChain(correctChain)).toBe(false); | |
}); | |
test("invalidates an incorrectly chained chain", () => { | |
const correctChain = [ | |
GENESIS_BLOCK, | |
{ | |
hash: | |
"0574f789c3b7f5cbd10470f2fdec7d9c590d51e8663d69f96dcf0a775b263449", | |
signed: '{"lastBlockHash":"badhash","payload":"hi!","nonce":2}' | |
} | |
]; | |
expect(Chain.verifyChain(correctChain)).toBe(false); | |
}); | |
}); |
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
{ | |
"name": "bchain", | |
"version": "1.0.0", | |
"main": "index.js", | |
"license": "MIT", | |
"dependencies": { | |
"hash.js": "^1.1.3", | |
"jest": "^22.0.3" | |
}, | |
"scripts": { | |
"test": "jest" | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment