From bd4662fc7f62283736207296ea487b9d55674d4a Mon Sep 17 00:00:00 2001 From: LDE Date: Sun, 3 Nov 2019 20:33:47 +0100 Subject: [PATCH 1/4] Class MerkleTree --- merkle_tree.py | 60 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 60 insertions(+) create mode 100644 merkle_tree.py diff --git a/merkle_tree.py b/merkle_tree.py new file mode 100644 index 0000000..1565433 --- /dev/null +++ b/merkle_tree.py @@ -0,0 +1,60 @@ +import hashlib + +class MerkleTree: + # Hash pairs of items recursively until a single value is obtained + @staticmethod + def merkle(hashList): + if len(hashList) == 1: + return hashList[0] + newHashList = [] + # Process pairs. For odd length, the last is skipped + for i in range(0, len(hashList)-1, 2): + newHashList.append(MerkleTree.hashRoot(hashList[i], hashList[i+1])) + if len(hashList) % 2 == 1: # odd, hash last item twice + newHashList.append(MerkleTree.hashRoot(hashList[-1], hashList[-1])) + return MerkleTree.merkle(newHashList) + + @staticmethod + def hashRoot(a, b): + strTmp=(a+b) + h = hashlib.sha256(strTmp.encode()).hexdigest() + return h + + @staticmethod + def merkleProof(txs, tx, proof = None): + if proof is None: + proof = [] + + if len(txs) == 1: + return proof + tree = [] + + for i in range(0, len(txs)-1, 2): + tmpHash = MerkleTree.hashRoot(txs[i], txs[i+1]) + if txs[i] == tx: + proof.append([1, txs[i+1]]) + tx = tmpHash + elif txs[i+1] == tx: + tx = tmpHash + proof.append([0, txs[i]]) + tree.append(tmpHash) + + if len(txs) % 2 == 1: # odd, hash last item twice + tmpHash = MerkleTree.hashRoot(txs[-1], txs[-1]) + if txs[i] == tx: + proof.append([1, txs[-1]]) + tx = tmpHash + tree.append(tmpHash) + + return MerkleTree.merkleProof(tree, tx, proof) + + @staticmethod + def merkleProofRoot(root, proof, tx): + tmpHash = tx + for i in range(0, len(proof), 1): + if proof[i][0] == 0: + tmpHash = MerkleTree.hashRoot(proof[i][1], tmpHash) + else: + tmpHash = MerkleTree.hashRoot(tmpHash, proof[i][1]) + return root == tmpHash + From 11758b45f3f8d4213298f9167855787b21ac88bb Mon Sep 17 00:00:00 2001 From: LDE Date: Tue, 5 Nov 2019 00:40:40 +0100 Subject: [PATCH 2/4] Ajout du merkleRoot dans chaque block --- block.py | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/block.py b/block.py index 95bb2a9..a0a4031 100644 --- a/block.py +++ b/block.py @@ -2,8 +2,10 @@ from time import time import hashlib +from merkle_tree import MerkleTree + MINING_DIFFICULTY = 2 -HASH_GENESIS_BLOCK = "a37c5dfb2a28763c7e4468f4d817f109d9ae4ccbbb7fdefe9ee2f27b0ab3974f" +HASH_GENESIS_BLOCK = "b4358083b2c93824360c5779e1cbe00998d7f09553fd7d18ef8f012b59e82a0f" class Block(object): @@ -14,6 +16,15 @@ def __init__(self, nonce, transactions, index, previous_hash): self.timestamp = time() self.previous_hash = previous_hash + self.merkle_root + + @property + def merkle_root(self): + txs_hashes = [] + for tx in self.transactions: + txs_hashes.append(hashlib.sha256(tx.toJSON().encode()).hexdigest()) + return MerkleTree.merkle(txs_hashes) + @staticmethod def hash(block): """ From f5765eb62bc60b3b235172ba87e1a3d95b17ddc1 Mon Sep 17 00:00:00 2001 From: LDE Date: Tue, 5 Nov 2019 01:02:59 +0100 Subject: [PATCH 3/4] Test : fonction get MerkleRoot --- merkle_tree.py | 2 ++ test_merkle_tree.py | 15 +++++++++++++++ 2 files changed, 17 insertions(+) create mode 100644 test_merkle_tree.py diff --git a/merkle_tree.py b/merkle_tree.py index 1565433..1161805 100644 --- a/merkle_tree.py +++ b/merkle_tree.py @@ -4,6 +4,8 @@ class MerkleTree: # Hash pairs of items recursively until a single value is obtained @staticmethod def merkle(hashList): + if len(hashList) == 0: + return False if len(hashList) == 1: return hashList[0] newHashList = [] diff --git a/test_merkle_tree.py b/test_merkle_tree.py new file mode 100644 index 0000000..f8a8b42 --- /dev/null +++ b/test_merkle_tree.py @@ -0,0 +1,15 @@ +from merkle_tree import MerkleTree + +txHashes = [ + 'ca978112ca1bbdcafac231b39a23dc4da786eff8147c4e72b9807785afee48bb', # a + '3e23e8160039594a33894f6564e1b1348bbd7a0088d42c4acb73eeaed59c009d', # b + '2e7d2c03a9507ae265ecf5b5356885a53393a2029d241394997265a1a25aefc6', # c + '18ac3e7343f016890c510e93f935261169d9e3f565436429830faf0934f4f8e4', # d + '3f79bb7b435b05321651daefd374cdc681dc06faa65e374e38337b88ca046dea' # e +] + +def test_merkle(): + assert MerkleTree.merkle([]) == False + assert MerkleTree.merkle(['aa']) == 'aa' + assert MerkleTree.merkle(txHashes[:2]) == '62af5c3cb8da3e4f25061e829ebeea5c7513c54949115b1acc225930a90154da' + assert MerkleTree.merkle(txHashes[:3]) == '0bdf27bf7ec894ca7cadfe491ec1a3ece840f117989e8c5e9bd7086467bf6c38' From afce7c45141b6631badf5c5ad93d374280ac2ada Mon Sep 17 00:00:00 2001 From: LDE Date: Wed, 6 Nov 2019 00:27:12 +0100 Subject: [PATCH 4/4] Correction merkle root --- block.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/block.py b/block.py index 1ea0b35..75d1918 100644 --- a/block.py +++ b/block.py @@ -22,7 +22,7 @@ def __init__(self, nonce, transactions, index, previous_hash): def merkle_root(self): txs_hashes = [] for tx in self.transactions: - txs_hashes.append(hashlib.sha256(tx.toJSON().encode()).hexdigest()) + txs_hashes.append(hashlib.sha256(tx.signature).hexdigest()) return MerkleTree.merkle(txs_hashes) @staticmethod