{"id":220,"date":"2015-05-30T18:29:00","date_gmt":"2015-05-30T18:29:00","guid":{"rendered":"https:\/\/santiagomarquezsolis.com\/index.php\/2026\/04\/20\/building-a-basic-blockchain-in-python-part-2\/"},"modified":"2026-04-20T16:12:44","modified_gmt":"2026-04-20T16:12:44","slug":"building-a-basic-blockchain-in-python-part-2","status":"publish","type":"post","link":"https:\/\/santiagomarquezsolis.com\/index.php\/en\/2015\/05\/30\/building-a-basic-blockchain-in-python-part-2\/","title":{"rendered":"Building a Basic Blockchain in Python. Part 2."},"content":{"rendered":"<p>In Part 1, we built a basic blockchain with blocks, hashing, and chain validation. In this second part, we add Proof of Work mining and a transaction system.<\/p>\n<h2>Proof of Work<\/h2>\n<p>Proof of Work requires miners to find a hash that meets certain criteria (starts with N zeros). This computational work makes it expensive to rewrite history.<\/p>\n<h2>Adding Mining to the Block<\/h2>\n<pre><code>import hashlib, json\r\nfrom datetime import datetime\r\n\r\nclass Block:\r\n    def __init__(self, index, transactions, previous_hash):\r\n        self.index = index\r\n        self.timestamp = datetime.now().isoformat()\r\n        self.transactions = transactions\r\n        self.previous_hash = previous_hash\r\n        self.nonce = 0\r\n        self.hash = self.calculate_hash()\r\n    \r\n    def calculate_hash(self):\r\n        block_string = json.dumps({\r\n            'index': self.index, 'timestamp': self.timestamp,\r\n            'transactions': self.transactions,\r\n            'previous_hash': self.previous_hash, 'nonce': self.nonce\r\n        }, sort_keys=True)\r\n        return hashlib.sha256(block_string.encode()).hexdigest()\r\n    \r\n    def mine_block(self, difficulty):\r\n        target = \"0\" * difficulty\r\n        while not self.hash.startswith(target):\r\n            self.nonce += 1\r\n            self.hash = self.calculate_hash()\r\n        print(f\"Mined! Nonce: {self.nonce}, Hash: {self.hash}\")<\/code><\/pre>\n<h2>Updated Blockchain with Transactions<\/h2>\n<pre><code>class Blockchain:\r\n    def __init__(self, difficulty=4):\r\n        self.chain = [Block(0, [], \"0\")]\r\n        self.difficulty = difficulty\r\n        self.pending_transactions = []\r\n        self.mining_reward = 10\r\n    \r\n    def add_transaction(self, sender, recipient, amount):\r\n        self.pending_transactions.append({\r\n            'sender': sender, 'recipient': recipient, 'amount': amount\r\n        })\r\n    \r\n    def mine_pending_transactions(self, miner_address):\r\n        block = Block(len(self.chain), self.pending_transactions, self.chain[-1].hash)\r\n        block.mine_block(self.difficulty)\r\n        self.chain.append(block)\r\n        self.pending_transactions = [{'sender': 'REWARD', 'recipient': miner_address, 'amount': self.mining_reward}]\r\n    \r\n    def get_balance(self, address):\r\n        balance = 0\r\n        for block in self.chain:\r\n            for tx in block.transactions:\r\n                if tx['recipient'] == address: balance += tx['amount']\r\n                if tx['sender'] == address: balance -= tx['amount']\r\n        return balance<\/code><\/pre>\n<h2>Usage Example<\/h2>\n<pre><code>bc = Blockchain(difficulty=4)\r\nbc.add_transaction(\"Alice\", \"Bob\", 50)\r\nbc.add_transaction(\"Bob\", \"Charlie\", 25)\r\nprint(\"Mining...\")\r\nbc.mine_pending_transactions(\"Miner1\")\r\nprint(f\"Alice: {bc.get_balance('Alice')}\")\r\nprint(f\"Miner1: {bc.get_balance('Miner1')}\")<\/code><\/pre>\n<h2>Key Concepts Learned<\/h2>\n<ul>\n<li>Mining finds a valid nonce that produces a hash meeting the difficulty target<\/li>\n<li>The mining reward creates an incentive for miners to secure the network<\/li>\n<li>Balances are calculated by scanning all transactions (UTXO-style)<\/li>\n<\/ul>\n<p>Real blockchains add peer-to-peer networking, Merkle trees, digital signatures, and dynamic difficulty adjustment on top of these fundamentals.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>In Part 1, we built a basic blockchain with blocks, hashing, and chain validation. In this second part, we add Proof of Work mining and a transaction system. Proof of Work Proof of Work requires miners to find a hash that meets certain criteria (starts with N zeros). This computational work makes it expensive to [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[180,162,182],"tags":[184,268,186],"class_list":["post-220","post","type-post","status-publish","format-standard","hentry","category-blockchain-en","category-blog-en","category-cripto-en","tag-blockchain-en","tag-cadena-de-bloques-en","tag-cripto-en"],"jetpack_featured_media_url":"","_links":{"self":[{"href":"https:\/\/santiagomarquezsolis.com\/index.php\/wp-json\/wp\/v2\/posts\/220","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/santiagomarquezsolis.com\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/santiagomarquezsolis.com\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/santiagomarquezsolis.com\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/santiagomarquezsolis.com\/index.php\/wp-json\/wp\/v2\/comments?post=220"}],"version-history":[{"count":1,"href":"https:\/\/santiagomarquezsolis.com\/index.php\/wp-json\/wp\/v2\/posts\/220\/revisions"}],"predecessor-version":[{"id":246,"href":"https:\/\/santiagomarquezsolis.com\/index.php\/wp-json\/wp\/v2\/posts\/220\/revisions\/246"}],"wp:attachment":[{"href":"https:\/\/santiagomarquezsolis.com\/index.php\/wp-json\/wp\/v2\/media?parent=220"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/santiagomarquezsolis.com\/index.php\/wp-json\/wp\/v2\/categories?post=220"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/santiagomarquezsolis.com\/index.php\/wp-json\/wp\/v2\/tags?post=220"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}