def __init__(self, block_num, conn=None): """Validating and inserting data hashes into the database.""" self.block_num = int(block_num) self.merkle_tree = MerkleTree() self.closed = False self.tx_id = None self.conn = conn
class DataBlock: def __init__(self, block_num, conn=None): """Validating and inserting data hashes into the database.""" self.block_num = int(block_num) self.merkle_tree = MerkleTree() self.closed = False self.tx_id = None self.conn = conn def close(self): """Close block, and generate Merkle root.""" self.closed = True def find_leaves(self): """Find leaves from database and generate tree.""" """Get the items for this block.""" query = 'SELECT * FROM hash_table where block=? ORDER BY id DESC' cur = self.conn.execute(query, (self.block_num,)) hashes = cur.fetchall() if len(hashes) > 0: for row in hashes: self.add_hash(row[1]) else: raise LookupError("Empty Block.") def add_hash(self, ahash): """As long as its not closed add hash.""" self.merkle_tree.add_hash(ahash) def merkle_root(self): """Find the data Merkle root.""" if self.closed: return self.merkle_tree.merkle_root() def merkle_proof(self, target): """Find the Merkle proof of a target.""" if self.closed: return self.merkle_tree.merkle_proof(target) def to_json(self): """For the API.""" block_data = { 'block_num': self.block_num, 'closed': self.closed, 'merkle_root': self.merkle_root(), 'tx_id': self.tx_id, 'leaves': self.merkle_tree.leaves } return block_data def generate(self): pass
class DataBlock: def __init__(self, block_num, conn=None): """Validating and inserting data hashes into the database.""" self.block_num = int(block_num) self.merkle_tree = MerkleTree() self.closed = False self.tx_id = None self.conn = conn def close(self): """Close block, and generate Merkle root.""" self.closed = True def find_leaves(self): """Find leaves from database and generate tree.""" """Get the items for this block.""" query = 'SELECT * FROM hash_table where block=? ORDER BY id DESC' cur = self.conn.execute(query, (self.block_num, )) hashes = cur.fetchall() if len(hashes) > 0: for row in hashes: self.add_hash(row[1]) else: raise LookupError("Empty Block.") def add_hash(self, ahash): """As long as its not closed add hash.""" self.merkle_tree.add_hash(ahash) def merkle_root(self): """Find the data Merkle root.""" if self.closed: return self.merkle_tree.merkle_root() def merkle_proof(self, target): """Find the Merkle proof of a target.""" if self.closed: return self.merkle_tree.merkle_proof(target) def to_json(self): """For the API.""" block_data = { 'block_num': self.block_num, 'closed': self.closed, 'merkle_root': self.merkle_root(), 'tx_id': self.tx_id, 'leaves': self.merkle_tree.leaves } return block_data def generate(self): pass
def test_two_even_items(self): tree = MerkleTree() tree.add_content("test") tree.add_hash(tree.hash_f("test2")) result = tree.merkle_root() ans = '694299f8eb01a328732fb21f4163fbfaa8f60d5662f04f52ad33bec63953ec7f' self.assertEqual(result, ans) target = tree.hash_f("test") proof = tree.merkle_proof(target) self.assertEqual(proof[0].get_parent(), ans)
def test_tree_odd_items(self): tree = MerkleTree() tree.add_content("test") tree.add_content("test2") tree.add_content("test3") result = tree.merkle_root() ans = 'd49e815a91a26d399f8c2fba429e6ef7e472e54b6eb1e04341d207eee219f6c0' self.assertEqual(result, ans) target = tree.hash_f("test3") proof = tree.merkle_proof(target) self.assertEqual(proof[1].get_parent(), ans)
def test_tree_odd_items(self): tree = MerkleTree() tree.add_content("test") tree.add_content("test2") tree.add_content("test3") result = tree.merkle_root() ans = 'd49e815a91a26d399f8c2fba429e6ef7e472e54b6eb1e04341d207eee219f6c0' self.assertEqual(result, ans)
def test_proof_false2(self): tree = MerkleTree() tree.add_content("test") tree.add_content("test2") tree.add_content("test3") proof = tree.merkle_proof(sha256("test4")) self.assertFalse(proof.is_valid())
def test_merkle_proof_simple_true(self): tree = MerkleTree() tree.add_content("test") tree.add_content("test2") left = sha256("test") right = sha256("test2") branch = MerkleBranch(left, right) target = left proof = MerkleProof(target, tree) proof.add(branch) self.assertTrue(proof.is_valid())
class DataBlock: def __init__(self, block_num, conn=None): """Validating and inserting data hashes into the database.""" self.conn = conn self.block_num = int(block_num) self.merkle_tree = MerkleTree() self.closed = False self.tx_id = None def close(self): """Close block, so a Merkle root can be generated.""" self.closed = True def generate_block(self): """Close the current block, and generate a new one.""" try: last_block = latest_block(self.conn) last_hash = latest_hash(self.conn) # Get Merkle Root self.find_leaves() self.close() merkle_root = self.merkle_root() # Get TXID blockchain = BtcTxStore() hexdata = merkle_root privatekeys = app.config["PRIVATE_KEYS"] changeaddress = app.config["CHANGE_ADDRESS"] tx_id = blockchain.store(hexdata, privatekeys, changeaddress) # Close current block c = self.conn.cursor() query1 = "UPDATE block_table SET end_hash=?, closed=?, merkle_root=?, tx_id=? WHERE id=?" c.execute(query1, (last_hash, True, merkle_root, tx_id, last_block)) # Start new block query2 = "INSERT INTO block_table (start_hash) VALUES (?)" c.execute(query2, (last_hash,)) self.conn.commit() self.conn.close() return 'Block {0} Built.'.format(last_block) except LookupError: return 'Block Empty.' def is_closed(self): query = 'SELECT closed FROM block_table where id=?' cur = self.conn.execute(query, (self.block_num,)) block = cur.fetchone() self.closed = block[0] return self.closed def find_leaves(self): """Load the leaves for this block.""" query = 'SELECT * FROM hash_table where block=? ORDER BY id DESC' cur = self.conn.execute(query, (self.block_num,)) hashes = cur.fetchall() if len(hashes) > 0: for row in hashes: self.add_hash(row[1]) else: raise LookupError("Empty Block.") self.is_closed() def add_hash(self, ahash): """Add hashes to the Merkle Tree.""" if not self.closed: self.merkle_tree.add_hash(ahash) def merkle_root(self): """Find the data Merkle root.""" if self.closed: return self.merkle_tree.merkle_root() def merkle_proof(self, target): """Find the Merkle proof of a target.""" self.find_leaves() if self.is_closed(): return self.merkle_tree.merkle_proof(target) def get_tx_id(self): query = 'SELECT tx_id FROM block_table where id=?' cur = self.conn.execute(query, (self.block_num,)) block = cur.fetchone() self.tx_id = block[0] return self.tx_id def to_json(self): """For the API.""" block_data = { 'block_num': self.block_num, 'closed': bool(self.closed), 'merkle_root': self.merkle_root(), 'tx_id': self.tx_id, 'leaves': self.merkle_tree.leaves } return block_data
class DataBlock: def __init__(self, block_num, conn=None): """Validating and inserting data hashes into the database.""" self.conn = conn self.block_num = int(block_num) self.merkle_tree = MerkleTree() self.closed = False self.tx_id = None def close(self): """Close block, so a Merkle root can be generated.""" self.closed = True def generate_block(self): """Close the current block, and generate a new one.""" try: last_block = latest_block(self.conn) last_hash = latest_hash(self.conn) # Get Merkle Root self.find_leaves() self.close() merkle_root = self.merkle_root() # Get TXID hexdata = merkle_root privatekeys = app.config["PRIVATE_KEYS"] changeaddress = app.config["CHANGE_ADDRESS"] fee = app.config["FEE"] testnet = app.config["TESTNET"] blockchain = BtcTxStore(testnet=testnet) tx_id = blockchain.storenulldata(hexdata, privatekeys, changeaddress=changeaddress, fee=fee) # Close current block c = self.conn.cursor() query1 = "UPDATE block_table SET end_hash=?, closed=?, merkle_root=?, tx_id=? WHERE id=?" c.execute(query1, (last_hash, True, merkle_root, tx_id, last_block)) # Start new block query2 = "INSERT INTO block_table (start_hash) VALUES (?)" c.execute(query2, (last_hash, )) self.conn.commit() self.conn.close() return 'Block {0} Built.'.format(last_block) except LookupError: return 'Block Empty.' def is_closed(self): query = 'SELECT closed FROM block_table where id=?' cur = self.conn.execute(query, (self.block_num, )) block = cur.fetchone() self.closed = block[0] return self.closed def find_leaves(self): """Load the leaves for this block.""" query = 'SELECT * FROM hash_table where block=? ORDER BY id DESC' cur = self.conn.execute(query, (self.block_num, )) hashes = cur.fetchall() if len(hashes) > 0: for row in hashes: self.add_hash(row[1]) else: raise LookupError("Empty Block.") self.is_closed() def add_hash(self, ahash): """Add hashes to the Merkle Tree.""" if not self.closed: self.merkle_tree.add_hash(ahash) def merkle_root(self): """Find the data Merkle root.""" if self.closed: return self.merkle_tree.merkle_root() def merkle_proof(self, target): """Find the Merkle proof of a target.""" self.find_leaves() if self.is_closed(): return self.merkle_tree.merkle_proof(target) def get_tx_id(self): query = 'SELECT tx_id FROM block_table where id=?' cur = self.conn.execute(query, (self.block_num, )) block = cur.fetchone() self.tx_id = block[0] return self.tx_id def to_json(self): """For the API.""" block_data = { 'block_num': self.block_num, 'closed': bool(self.closed), 'merkle_root': self.merkle_root(), 'tx_id': self.tx_id, 'leaves': self.merkle_tree.leaves } return block_data
def test_simple_sha256(self): tree = MerkleTree() result = tree.hash_f("test") ans = '9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08' self.assertEqual(result, ans)
def test_large_tree(self): tree = MerkleTree() for i in range(10000): tree.add_content(str(i)) ans = 'a048d580177b80a60cbd31355400a0c9eabb5d2d3a4704fc9c86bae277f985c7' self.assertEqual(tree.merkle_root(), ans)
def test_proof_single_true(self): tree = MerkleTree() tree.add_content("test") proof = tree.merkle_proof(sha256("test")) self.assertTrue(proof.is_valid())