22
loading...
This website collects cookies to deliver better user experience
JavaScript
code to compare.python
code in the promised 60 lines.class Block:
def __init__(self, timestamp=None, data=None):
self.timestamp = timestamp or time()
# this.data should contain information like transactions.
self.data = [] if data is None else data
self
instead of this
and init is a constructor
method.#
to comment vs. //
in javascript.from hashlib import sha256
class Block:
def __init__(self, timestamp=None, data=None):
self.timestamp = timestamp or time()
self.data = [] if data is None else data
self.hash = self.getHash()
self.prevHash = None # previous block's hash
def getHash(self):
hash = sha256()
hash.update(str(self.prevHash).encode('utf-8'))
hash.update(str(self.timestamp).encode('utf-8'))
hash.update(str(self.data).encode('utf-8'))
return hash.hexdigest()
.encode('utf-8')
to convert the string to bytes.class Blockchain:
def __init__(self):
# This property will contain all the blocks.
self.chain = []
str
instead of toString
.from time import time
class Blockchain:
def __init__(self):
# Create our genesis block
self.chain = [Block(str(int(time())))]
len
to get the length of the chain instead of length
in javascript.def getLastBlock(self):
return self.chain[len(self.chain) - 1]
addBlock
method. The code is almost the same except the append
(push
in javascript).def addBlock(self, block):
# Since we are adding a new block, prevHash will be the hash of the old latest block
block.prevHash = self.getLastBlock().hash
# Since now prevHash has a value, we must reset the block's hash
block.hash = block.getHash()
self.chain.append(block)
range
as a big difference. Also, because we don't use constants in Python, we just use normal variables.or
instead of ||
in javascript.def isValid(self):
# Iterate over the chain, we need to set i to 1 because there are nothing before the genesis block, so we start at the second block.
for i in range(1, len(self.chain)):
currentBlock = self.chain[i]
prevBlock = self.chain[i - 1]
# Check validation
if (currentBlock.hash != currentBlock.getHash() or prevBlock hash != currentBlock.prevHash):
return False
return True
mine
method and a nonce
property to our block. Be careful because nonce
must be declared before calling the self.getHash()
method. If not, you will get the error AttributeError: 'Block' object has no attribute 'nonce'
.class Block:
def __init__(self, timestamp=None, data=None):
self.timestamp = timestamp or time()
self.data = [] if data is None else data
self.prevHash = None # previous block's hash
self.nonce = 0
self.hash = self.getHash()
# Our hash function.
def getHash(self):
hash = sha256()
hash.update(str(self.prevHash).encode('utf-8'))
hash.update(str(self.timestamp).encode('utf-8'))
hash.update(str(self.data).encode('utf-8'))
hash.update(str(self.nonce).encode('utf-8'))
return hash.hexdigest()
def mine(self, difficulty):
# Basically, it loops until our hash starts with
# the string 0...000 with length of <difficulty>.
while self.hash[:difficulty] != '0' * difficulty:
# We increases our nonce so that we can get a whole different hash.
self.nonce += 1
# Update our new hash with the new nonce value.
self.hash = self.getHash()
self.difficulty = 1
addBlock
method:def addBlock(self, block):
block.prevHash = self.getLastBlock().hash
block.hash = block.getHash()
block.mine(self.difficulty)
self.chain.append(block)
Blockchain
class the same way using JeChain object:from blockchain import Block
from blockchain import Blockchain
from time import time
JeChain = Blockchain()
# Add a new block
JeChain.addBlock(Block(str(int(time())), ({"from": "John", "to": "Bob", "amount": 100})))
# (This is just a fun example, real cryptocurrencies often have some more steps to implement).
# Prints out the updated chain
print(JeChain)
[
{
"data": [],
"timestamp": "1636153236",
"nonce": 0,
"hash": "4caa5f684eb3871cb0eea217a6d043896b3775f047e699d92bd29d0285541678",
"prevHash": null
},
{
"data": {
"from": "John",
"to": "Bob",
"amount": 100
},
"timestamp": "1636153236",
"nonce": 14,
"hash": "038f82c6e6605acfcad4ade04e454eaa1cfa3d17f8c2980f1ee474eefb9613e9",
"prevHash": "4caa5f684eb3871cb0eea217a6d043896b3775f047e699d92bd29d0285541678"
}
]
__repr__
method to the Blockchain class:import json
def __repr__(self):
return json.dumps([{'data': item.data, 'timestamp': item.timestamp, 'nonce': item.nonce, 'hash': item.hash, 'prevHash': item.prevHash} for item in self.chain], indent=4)
self.blockTime = 30000
(if_test_is_false, if_test_is_true)[test]
, resulting in:def addBlock(self, block):
block.prevHash = self.getLastBlock().hash
block.hash = block.getHash()
block.mine(self.difficulty)
self.chain.append(block)
self.difficulty += (-1, 1)[int(time()) - int(self.getLastBlock().timestamp) < self.blockTime]
# -*- coding: utf-8 -*-
from hashlib import sha256
import json
from time import time
class Block:
def __init__(self, timestamp=None, data=None):
self.timestamp = timestamp or time()
self.data = [] if data is None else data
self.prevHash = None
self.nonce = 0
self.hash = self.getHash()
def getHash(self):
hash = sha256()
hash.update(str(self.prevHash).encode('utf-8'))
hash.update(str(self.timestamp).encode('utf-8'))
hash.update(str(self.data).encode('utf-8'))
hash.update(str(self.nonce).encode('utf-8'))
return hash.hexdigest()
def mine(self, difficulty):
while self.hash[:difficulty] != '0' * difficulty:
self.nonce += 1
self.hash = self.getHash()
class Blockchain:
def __init__(self):
self.chain = [Block(str(int(time())))]
self.difficulty = 1
self.blockTime = 30000
def getLastBlock(self):
return self.chain[len(self.chain) - 1]
def addBlock(self, block):
block.prevHash = self.getLastBlock().hash
block.hash = block.getHash()
block.mine(self.difficulty)
self.chain.append(block)
self.difficulty += (-1, 1)[int(time()) - int(self.getLastBlock().timestamp) < self.blockTime]
def isValid(self):
for i in range(1, len(self.chain)):
currentBlock = self.chain[i]
prevBlock = self.chain[i - 1]
if (currentBlock.hash != currentBlock.getHash() or prevBlock.hash != currentBlock.prevHash):
return False
return True
def __repr__(self):
return json.dumps([{'data': item.data, 'timestamp': item.timestamp, 'nonce': item.nonce, 'hash': item.hash, 'prevHash': item.prevHash} for item in self.chain], indent=4)