def test_block_creation(self): # Create genesis transaction transaction = Transaction("Genesis Addr", "Genesis Block") key = RSA.generate(1024) miner_id = "1234" # Create genesis block with genesis transaction, signing it genesis = Block("Genesis Block", 0, [transaction.get_signed_json(key)], miner_id) self.assertDictEqual( genesis.get_json(), { "miner": miner_id, "hash": "", "prevHash": "Genesis Block", "height": 0, "nonce": 0, "data": [transaction.get_signed_json(key)] })
def create_and_add_transaction(self, addr_to): """ Used to make a transaction from current node to another """ logger.info("Add transaction to pool") if self.has_to_vote(): if self.check_valid_address(addr_to): transaction = Transaction(self.miner_id, addr_to) self.blockchain.add_transaction_to_pool( transaction.get_signed_json(self.private_key)) self.propagate_transaction( transaction.get_signed_json(self.private_key)) if len(self.sched.get_jobs()) == 0: logger.info("Start block schedule") self.sched.add_job(self.create_and_add_block, 'date', run_date=datetime.now() + timedelta(seconds=5)) else: logger.error("Cannot vote for this ledger, check the address")
def test_block_validation(self): chain = Blockchain() private_key = RSA.generate(1024) miner_id = "1234" chain.create_genesis_block(private_key, miner_id) prevBlock = chain.storage[0] t = Transaction("1234", "4567") # Create Block with dummy transaction block = Block(prevBlock["hash"], prevBlock["height"] + 1, [t.get_signed_json(private_key)], miner_id) block.mine() # Check block validation is ok self.assertTrue(chain.validate_block(block.get_json(), prevBlock)) # Mess with blockchain structure block.block["prevHash"] = "00012345" self.assertFalse(chain.validate_block(block.get_json(), prevBlock)) # Mess with height block.block["prevHash"] = prevBlock["hash"] block.block["height"] = 5 self.assertFalse(chain.validate_block(block.get_json(), prevBlock)) # Mess with PoW block.block["height"] = 2 block.block["hash"] = "0111111111" self.assertFalse(chain.validate_block(block.get_json(), prevBlock)) # Mess with hash but keep PoW block.block["hash"] = "0001111111" self.assertFalse(chain.validate_block(block.get_json(), prevBlock)) # Mess with transaction integrity t.signature = "L7TBH0ahox4GOAdF8om2ijbNVPcO3Ys6+KdvfFhvfX/SysetaJw+0rlU6VMuzwB0rQ/X2+ioAdtXcstutSeRAfZTYP+utaNFL1nP48as/C6mca4sp+ya39AWWLIUuZeGMit9kSUavx6uX5cSAuqXB4tcK/bUSVghtMC9vG4JyC8=" block = Block(prevBlock["prevHash"], prevBlock["height"] + 1, [t.get_signed_json(private_key)], miner_id) block.mine() self.assertFalse(chain.validate_block(block.get_json(), prevBlock))
def test_transaction_signature(self): # Create transaction t = Transaction("1234", "4567") # Create Private Key key = RSA.generate(1024) # Sign transaction and recover complete transaction JSON signed_json = t.get_signed_json(key) # Verify signature and public key match t_sig = b64decode(signed_json["signature"].encode()) pubkey = b64decode(signed_json["pubkey"].encode()) verifier = PKCS1_v1_5.new(RSA.importKey(pubkey)) digest = SHA256.new() t = Transaction(signed_json["addr_from"], signed_json["addr_to"]) digest.update(str(t.get_json()).encode()) self.assertTrue(verifier.verify(digest, t_sig))