Пример #1
0
 /**
  * @param callable|null $hashFunction
  * @return Buffer
  * @throws MerkleTreeEmpty
  */
 public function calculateHash(callable $hashFunction = null)
 {
     $hashFxn = $hashFunction ?: function ($value) {
         return hash('sha256', hash('sha256', $value, true), true);
     };
     $txCount = count($this->transactions);
     if ($txCount === 0) {
         // TODO: Probably necessary. Should always have a coinbase at least.
         throw new MerkleTreeEmpty('Cannot compute Merkle root of an empty tree');
     }
     if ($txCount === 1) {
         $binary = $hashFxn($this->transactions[0]->getBinary());
     } else {
         // Create a fixed size Merkle Tree
         $tree = new FixedSizeTree($txCount + $txCount % 2, $hashFxn);
         // Compute hash of each transaction
         $last = '';
         foreach ($this->transactions as $i => $transaction) {
             $last = $transaction->getBinary();
             $tree->set($i, $last);
         }
         // Check if we need to repeat the last hash (odd number of transactions)
         if (!$this->math->isEven($txCount)) {
             $tree->set($txCount, $last);
         }
         $binary = $tree->hash();
     }
     $this->setLastHash((new Buffer($binary))->flip());
     return $this->getLastHash();
 }
Пример #2
0
 public function testWidthOfSixConstructsCorrectly()
 {
     $expected = '1c532ad0b8d7a2af86c321f14f722416';
     $builder = new FixedSizeTree(6, $this->hasher);
     $builder->set(0, 'at');
     $builder->set(1, 'the');
     $builder->set(2, 'end');
     $builder->set(3, 'of');
     $builder->set(4, 'the');
     $builder->set(5, 'day');
     $actual = $builder->hash();
     $this->assertEquals($expected, $actual);
 }
Пример #3
0
 /**
  * @param BlockInterface $block
  * @param TransactionSerializerInterface $txSerializer
  * @return Buffer
  * @throws MerkleTreeEmpty
  */
 public function calcMerkleRoot(BlockInterface $block, TransactionSerializerInterface $txSerializer)
 {
     $hashFxn = function ($value) {
         return hash('sha256', hash('sha256', $value, true), true);
     };
     $txCount = count($block->getTransactions());
     if ($txCount === 0) {
         // TODO: Probably necessary. Should always have a coinbase at least.
         throw new MerkleTreeEmpty('Cannot compute Merkle root of an empty tree');
     }
     if ($txCount === 1) {
         $transaction = $block->getTransaction(0);
         $serialized = $txSerializer->serialize($transaction);
         $binary = $hashFxn($serialized->getBinary());
     } else {
         // Create a fixed size Merkle Tree
         $tree = new FixedSizeTree($txCount + $txCount % 2, $hashFxn);
         // Compute hash of each transaction
         $last = '';
         foreach ($block->getTransactions() as $i => $transaction) {
             $last = $txSerializer->serialize($transaction)->getBinary();
             $tree->set($i, $last);
         }
         // Check if we need to repeat the last hash (odd number of transactions)
         if (!($txCount % 2 === 0)) {
             $tree->set($txCount, $last);
         }
         $binary = $tree->hash();
     }
     return (new Buffer($binary))->flip();
 }