/** * @param BlockInterface $block * @return \BitWasp\Buffertools\BufferInterface */ public function serialize(BlockInterface $block) { $buffer = $block->getBuffer(); $size = $buffer->getSize(); $data = new Parser($this->getHeaderTemplate()->write([Buffer::hex($this->network->getNetMagicBytes()), $size])); $data->writeBytes($size, $buffer); return $data->getBuffer(); }
/** * {@inheritdoc} * @see \BitWasp\Bitcoin\SerializableInterface::getBuffer() */ public function getBuffer() { return $this->block->getBuffer(); }
/** * @param BlockInterface $block * @return $this */ public function check(BlockInterface $block) { $header = $block->getHeader(); if ($block->getMerkleRoot() !== $header->getMerkleRoot()) { throw new \RuntimeException('Blocks::check(): failed to verify merkle root'); } $transactions = $block->getTransactions(); $txCount = count($transactions); if ($txCount == 0 || $block->getBuffer()->getSize() > $this->params->maxBlockSizeBytes()) { throw new \RuntimeException('Blocks::check(): Zero transactions, or block exceeds max size'); } // The first transaction is coinbase, and only the first transaction is coinbase. if (!$transactions[0]->isCoinbase()) { throw new \RuntimeException('Blocks::check(): First transaction was not coinbase'); } for ($i = 1; $i < $txCount; $i++) { if ($transactions->offsetGet($i)->isCoinbase()) { throw new \RuntimeException('Blocks::check(): more than one coinbase'); } } $nSigOps = 0; foreach ($transactions as $transaction) { if (!$this->checkTransaction($transaction)) { throw new \RuntimeException('Blocks::check(): failed checkTransaction'); } $nSigOps += $this->getLegacySigOps($transaction); } if ($this->math->cmp($nSigOps, $this->params->getMaxBlockSigOps()) > 0) { throw new \RuntimeException('Blocks::check(): out-of-bounds sigop count'); } return $this; }