/**
  * @param Parser $parser
  * @return PrivateKey
  */
 public function fromParser(Parser &$parser)
 {
     $bytes = $parser->readBytes(32);
     $multiplier = $bytes->getInt();
     $privateKey = PrivateKeyFactory::fromInt($multiplier, false, $this->ecAdapter);
     return $privateKey;
 }
 /**
  * @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 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;
 }
Example #6
0
 /**
  * @param Parser $parser
  * @return Buffer
  * @throws \BitWasp\Buffertools\Exceptions\ParserOutOfRange
  */
 public function read(Parser &$parser)
 {
     $bits = $this->readBits($parser->readBytes($this->length));
     if (!$this->isBigEndian()) {
         $bits = $this->flipBits($bits);
     }
     return Buffer::hex(str_pad($this->getMath()->baseConvert($bits, 2, 16), $this->length * 2, '0', STR_PAD_LEFT), $this->length, $this->getMath());
 }
 /**
  * @param Parser $parser
  * @return int|string
  * @throws \BitWasp\Buffertools\Exceptions\ParserOutOfRange
  * @throws \Exception
  */
 public function readBits(Parser &$parser)
 {
     $math = $this->getMath();
     $bitSize = $this->getBitSize();
     $bits = str_pad($math->baseConvert($parser->readBytes($bitSize / 8)->getHex(), 16, 2), $bitSize, '0', STR_PAD_LEFT);
     $integer = $math->baseConvert($this->isBigEndian() ? $bits : $this->flipBits($bits), 2, 10);
     return $integer;
 }
 /**
  * @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;
 }
 /**
  * @param AlertDetail $detail
  * @return \BitWasp\Buffertools\Buffer
  */
 public function serialize(AlertDetail $detail)
 {
     $setCancels = [];
     foreach ($detail->getSetCancel() as $toCancel) {
         $t = new Parser();
         $setCancels[] = $t->writeBytes(4, Buffer::int($toCancel), true)->getBuffer();
     }
     $setSubVers = [];
     foreach ($detail->getSetSubVer() as $subVer) {
         $t = new Parser();
         $setSubVers[] = $t->writeBytes(4, Buffer::int($subVer), true)->getBuffer();
     }
     return $this->getTemplate()->write([$detail->getVersion(), $detail->getRelayUntil(), $detail->getExpiration(), $detail->getId(), $detail->getCancel(), $setCancels, $detail->getMinVer(), $detail->getMaxVer(), $setSubVers, $detail->getPriority(), $detail->getComment(), $detail->getStatusBar()]);
 }
Example #13
0
 /**
  * @param Parser $parser
  * @return Ipv4|Ipv6|Onion
  * @throws \BitWasp\Buffertools\Exceptions\ParserOutOfRange
  * @throws \Exception
  */
 public function fromParser(Parser $parser)
 {
     $buffer = $parser->readBytes(16);
     $binary = $buffer->getBinary();
     if (Onion::MAGIC === substr($binary, 0, strlen(Onion::MAGIC))) {
         $addr = strtolower(Base32::encode($buffer->slice(strlen(Onion::MAGIC))->getBinary())) . '.onion';
         $ip = new Onion($addr);
     } elseif (Ipv4::MAGIC === substr($binary, 0, strlen(Ipv4::MAGIC))) {
         $end = $buffer->slice(strlen(Ipv4::MAGIC), 4);
         $ip = new Ipv4(long2ip($end->getInt()));
     } else {
         $addr = [];
         foreach (str_split($binary, 2) as $segment) {
             $addr[] = bin2hex($segment);
         }
         $addr = implode(":", $addr);
         $ip = new Ipv6($addr);
     }
     return $ip;
 }
Example #14
0
 /**
  * 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;
 }
Example #15
0
 /**
  * @expectedException \Exception
  */
 public function testReadBytesBeyondLength()
 {
     $bytes = '41424344';
     $parser = new Parser($bytes);
     $parser->readBytes(5);
 }
 /**
  * @param Parser $parser
  * @return PrivateKey
  * @throws \BitWasp\Buffertools\Exceptions\ParserOutOfRange
  */
 public function fromParser(Parser $parser)
 {
     $compressed = $this->haveNextCompressed;
     $this->haveNextCompressed = false;
     return $this->ecAdapter->getPrivateKey($parser->readBytes(32)->getInt(), $compressed);
 }
Example #17
0
 /**
  * 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;
 }
Example #18
0
<?php

require "../vendor/autoload.php";
use BitWasp\Buffertools\Buffer;
use BitWasp\Buffertools\Parser;
// Parsers read Buffers
$buffer = new Buffer('abc');
$parser = new Parser($buffer);
// Call readBytes to unpack the data
/** @var Buffer[] $set */
$set = [$parser->readBytes(1), $parser->readBytes(1), $parser->readBytes(1)];
foreach ($set as $item) {
    echo $item->getBinary() . PHP_EOL;
}
 /**
  * Create a buffer containing data to be hashed hashed to yield the child offset
  *
  * @param integer|string $sequence
  * @return Buffer
  * @throws \Exception
  */
 public function getHmacSeed($sequence)
 {
     $parser = new Parser();
     $hardened = $this->ecAdapter->getMath()->getBinaryMath()->isNegative($sequence, 32);
     if ($hardened) {
         if ($this->isPrivate() === false) {
             throw new \Exception("Can't derive a hardened key without the private key");
         }
         $parser->writeBytes(1, '00')->writeBytes(32, $this->getPrivateKey()->getBuffer());
     } else {
         $parser->writeBytes(33, $this->getPublicKey()->getBuffer());
     }
     return $parser->writeInt(4, $sequence)->getBuffer();
 }
Example #20
0
 /**
  * {@inheritdoc}
  * @see \BitWasp\Bitcoin\Block\BlockHeaderInterface::getBlockHash()
  */
 public function getBlockHash()
 {
     $parser = new Parser();
     return $parser->writeBytes(32, Hash::sha256d($this->getBuffer()), true)->getBuffer()->getHex();
 }
Example #21
0
 /**
  * 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());
 }