/** * @param TransactionSignature $txSig * @return \BitWasp\Buffertools\Buffer */ public function serialize(TransactionSignature $txSig) { $sig = $this->sigSerializer->serialize($txSig->getSignature()); $parser = new Parser($sig->getHex()); $parser->writeBytes(1, Buffer::int($txSig->getHashType(), 1)); $buffer = $parser->getBuffer(); return $buffer; }
/** * @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(); }
/** * @param \BitWasp\Bitcoin\Signature\TransactionSignature $txSig * @return \BitWasp\Buffertools\Buffer */ public function serialize(\BitWasp\Bitcoin\Signature\TransactionSignature $txSig) { $sig = $this->sigSerializer->serialize($txSig->getSignature()); $parser = new Parser($sig->getHex()); $parser->writeInt(1, $txSig->getHashType()); $buffer = $parser->getBuffer(); return $buffer; }
/** * @param string|BufferInterface $data * @return \BitWasp\Bitcoin\Transaction\TransactionInterface */ public function parse($data) { $parser = new Parser($data); $buffer = $parser->getBuffer(); $parsed = $this->txSerializer->parse($buffer); $this->storage->attach($parsed, $buffer); return $parsed; }
/** * @param PublicKeyInterface $publicKey * @return Buffer */ public function serialize(PublicKeyInterface $publicKey) { $point = $publicKey->getPoint(); $parser = new Parser(); $parser->writeBytes(1, $this->getPrefix($publicKey->isCompressed(), $point)); $math = $this->ecAdapter->getMath(); $publicKey->isCompressed() ? $parser->writeBytes(32, $math->decHex($point->getX())) : $parser->writeBytes(32, $math->decHex($point->getX()))->writeBytes(32, $math->decHex($point->getY())); return $parser->getBuffer(); }
/** * @param PublicKey $publicKey * @return Buffer */ private function doSerialize(PublicKey $publicKey) { $math = $this->ecAdapter->getMath(); $point = $publicKey->getPoint(); $compressed = $publicKey->isCompressed(); $parser = new Parser('', $math); $parser->writeBytes(1, $this->getPrefix($compressed, $point)); $compressed ? $parser->writeBytes(32, Buffer::int($point->getX(), null, $math)) : $parser->writeBytes(32, Buffer::int($point->getX(), null, $math))->writeBytes(32, Buffer::int($point->getY(), null, $math)); return $parser->getBuffer(); }
/** * @param Headers $msg * @return \BitWasp\Buffertools\Buffer */ public function serialize(Headers $msg) { $headers = []; $null = new Buffer(""); foreach ($msg->getHeaders() as $header) { $temp = new Parser($header->getBuffer()); $temp->writeBytes(1, $null); $headers[] = $temp->getBuffer(); } return $this->getTemplate()->write([$headers]); }
/** * @param Parser $parser * @return array|OutPointInterface */ public function fromParser(Parser $parser) { $buffer = $parser->getBuffer(); if ($buffer->getSize() > 36) { $buffer = $buffer->slice(0, 36); if (isset($this->cachedStr[$buffer->getBinary()])) { $this->cached++; return $this->cachedStr[$buffer->getBinary()]; } } $parsed = $this->serializer->fromParser($parser); $this->parse++; return $parsed; }
/** * Push data into the stack. * * @param $data * @return $this * @throws \Exception */ public function push(Buffer $data) { $length = $data->getSize(); $parsed = new Parser('', $this->math); /** Note that larger integers are serialized without flipping bits - Big endian */ if ($length < $this->opcodes->getOpByName('OP_PUSHDATA1')) { $varInt = Buffertools::numToVarInt($length); $data = new Buffer($varInt->getBinary() . $data->getBinary(), null, $this->math); $parsed->writeBytes($data->getSize(), $data); } else { if ($length <= 0xff) { $lengthSize = 1; } elseif ($length <= 0xffff) { $lengthSize = 2; } else { $lengthSize = 4; } $op = $this->opcodes->getOpByName('OP_PUSHDATA' . $lengthSize); $parsed->writeBytes(1, Buffer::int($op))->writeBytes($lengthSize, Buffer::int($length), true)->writeBytes($length, $data); } $this->script .= $parsed->getBuffer()->getBinary(); return $this; }
/** * Take an array containing serializable objects. * @param SerializableInterface []|Buffer[] * @return $this */ public function writeArray($serializable) { $parser = new Parser(Buffertools::numToVarInt(count($serializable)), $this->math); foreach ($serializable as $object) { if ($object instanceof SerializableInterface) { $object = $object->getBuffer(); } if ($object instanceof Buffer) { $parser->writeBytes($object->getSize(), $object); } else { throw new \RuntimeException('Input to writeArray must be Buffer[], or SerializableInterface[]'); } } $this->string .= $parser->getBuffer()->getBinary(); return $this; }
public function testWriteBytesFlipPadded() { $parser = new Parser(); $parser->writeBytes(4, Buffer::hex('34'), true); $this->assertEquals("34000000", $parser->getBuffer()->getHex()); }
/** * Calculate the hash of the current transaction, when you are looking to * spend $txOut, and are signing $inputToSign. The SigHashType defaults to * SIGHASH_ALL, though SIGHASH_SINGLE, SIGHASH_NONE, SIGHASH_ANYONECANPAY * can be used. * * @param ScriptInterface $txOutScript * @param $inputToSign * @param int $sighashType * @return Buffer * @throws \Exception */ public function calculate(ScriptInterface $txOutScript, $inputToSign, $sighashType = SignatureHashInterface::SIGHASH_ALL) { $copy = $this->transaction->makeCopy(); $inputs = $copy->getInputs(); $outputs = $copy->getOutputs(); if ($inputToSign > count($inputs)) { throw new \Exception('Input does not exist'); } // Default SIGHASH_ALL procedure: null all input scripts $inputCount = count($inputs); for ($i = 0; $i < $inputCount; $i++) { $inputs->getInput($i)->setScript(new Script()); } $inputs->getInput($inputToSign)->setScript($txOutScript); $math = Bitcoin::getMath(); if ($math->bitwiseAnd($sighashType, 31) == SignatureHashInterface::SIGHASH_NONE) { // Set outputs to empty vector, and set sequence number of inputs to 0. $copy->setOutputs(new TransactionOutputCollection()); // Let the others update at will. Set sequence of inputs we're not signing to 0. $inputCount = count($inputs); for ($i = 0; $i < $inputCount; $i++) { if ($math->cmp($i, $inputToSign) !== 0) { $inputs->getInput($i)->setSequence(0); } } } elseif ($math->bitwiseAnd($sighashType, 31) == SignatureHashInterface::SIGHASH_SINGLE) { // Resize output array to $inputToSign + 1, set remaining scripts to null, // and set sequence's to zero. $nOutput = $inputToSign; if ($math->cmp($nOutput, count($outputs)) >= 0) { return Buffer::hex('0100000000000000000000000000000000000000000000000000000000000000'); } // Resize.. $outputs = $outputs->slice(0, $nOutput + 1)->getOutputs(); // Set to null for ($i = 0; $i < $nOutput; $i++) { $outputs[$i] = new TransactionOutput($math->getBinaryMath()->getTwosComplement(-1, 64), new Script()); } $copy->setOutputs(new TransactionOutputCollection($outputs)); // Let the others update at will. Set sequence of inputs we're not signing to 0. $inputCount = count($inputs); for ($i = 0; $i < $inputCount; $i++) { if ($math->cmp($i, $inputToSign) != 0) { $inputs->getInput($i)->setSequence(0); } } } // This can happen regardless of whether it's ALL, NONE, or SINGLE if ($math->bitwiseAnd($sighashType, SignatureHashInterface::SIGHASH_ANYONECANPAY)) { $input = $inputs->getInput($inputToSign); $copy->setInputs(new TransactionInputCollection([$input])); } // Serialize the TxCopy and append the 4 byte hashtype (little endian); $txParser = new Parser($copy->getBuffer()); $txParser->writeInt(4, $sighashType, true); return Hash::sha256d($txParser->getBuffer()); }