A block including all transactions in it
| 553 | """The block does not have witness data""" |
| 554 | |
| 555 | class CBlock(CBlockHeader): |
| 556 | """A block including all transactions in it""" |
| 557 | __slots__ = ['vtx', 'vMerkleTree', 'vWitnessMerkleTree'] |
| 558 | |
| 559 | @staticmethod |
| 560 | def build_merkle_tree_from_txids(txids): |
| 561 | """Build a full CBlock merkle tree from txids |
| 562 | |
| 563 | txids - iterable of txids |
| 564 | |
| 565 | Returns a new merkle tree in deepest first order. The last element is |
| 566 | the merkle root. |
| 567 | |
| 568 | WARNING! If you're reading this because you're learning about crypto |
| 569 | and/or designing a new system that will use merkle trees, keep in mind |
| 570 | that the following merkle tree algorithm has a serious flaw related to |
| 571 | duplicate txids, resulting in a vulnerability. (CVE-2012-2459) Bitcoin |
| 572 | has since worked around the flaw, but for new applications you should |
| 573 | use something different; don't just copy-and-paste this code without |
| 574 | understanding the problem first. |
| 575 | """ |
| 576 | merkle_tree = list(txids) |
| 577 | |
| 578 | size = len(txids) |
| 579 | j = 0 |
| 580 | while size > 1: |
| 581 | for i in range(0, size, 2): |
| 582 | i2 = min(i+1, size-1) |
| 583 | merkle_tree.append(Hash(merkle_tree[j+i] + merkle_tree[j+i2])) |
| 584 | |
| 585 | j += size |
| 586 | size = (size + 1) // 2 |
| 587 | |
| 588 | return merkle_tree |
| 589 | |
| 590 | @staticmethod |
| 591 | def build_merkle_tree_from_txs(txs): |
| 592 | """Build a full merkle tree from transactions""" |
| 593 | txids = [tx.GetTxid() for tx in txs] |
| 594 | return CBlock.build_merkle_tree_from_txids(txids) |
| 595 | |
| 596 | def calc_merkle_root(self): |
| 597 | """Calculate the merkle root |
| 598 | |
| 599 | The calculated merkle root is not cached; every invocation |
| 600 | re-calculates it from scratch. |
| 601 | """ |
| 602 | if not len(self.vtx): |
| 603 | raise ValueError('Block contains no transactions') |
| 604 | return self.build_merkle_tree_from_txs(self.vtx)[-1] |
| 605 | |
| 606 | @staticmethod |
| 607 | def build_witness_merkle_tree_from_txs(txs): |
| 608 | """Calculate the witness merkle tree from transactions""" |
| 609 | has_witness = False |
| 610 | hashes = [] |
| 611 | for tx in txs: |
| 612 | hashes.append(tx.GetHash()) |
no outgoing calls