/**
  * @param NetworkInterface $network
  * @param PrivateKeyInterface $privateKey
  * @return string
  */
 public function serialize(NetworkInterface $network, PrivateKeyInterface $privateKey)
 {
     $serialized = Buffertools::concat(Buffer::hex($network->getPrivByte()), $this->hexSerializer->serialize($privateKey));
     if ($privateKey->isCompressed()) {
         $serialized = Buffertools::concat($serialized, new Buffer("", 1));
     }
     return Base58::encodeCheck($serialized);
 }
Пример #2
0
 /**
  * @expectedException \RuntimeException
  * @expectedExceptionMessage Invalid packet checksum
  */
 public function testInvalidChecksum()
 {
     $v = '60002';
     $services = Buffer::hex('0000000000000001');
     $time = '123456789';
     $recipient = new NetworkAddress(Buffer::hex('0000000000000001'), '10.0.0.1', '8332');
     $sender = new NetworkAddress(Buffer::hex('0000000000000001'), '10.0.0.2', '8332');
     $userAgent = new Buffer("/Satoshi:0.7.2/");
     $lastBlock = '212672';
     $random = new Random();
     $nonce = $random->bytes(8)->getInt();
     $version = new Version($v, $services, $time, $recipient, $sender, $nonce, $userAgent, $lastBlock, true);
     $msg = $version->getNetworkMessage();
     $realBuffer = $msg->getBuffer();
     $invalid = Buffertools::concat(Buffertools::concat($realBuffer->slice(0, 20), Buffer::hex('00000000')), $realBuffer->slice(24));
     $serializer = new NetworkMessageSerializer(Bitcoin::getDefaultNetwork());
     $serializer->parse($invalid);
 }
Пример #3
0
 /**
  * Traverse the Merkle Tree hashes and extract those which have a matching bit.
  *
  * @param int $height
  * @param int $position
  * @param int $nBitsUsed
  * @param int $nHashUsed
  * @param BufferInterface[] $vMatch
  * @return BufferInterface
  */
 public function traverseAndExtract($height, $position, &$nBitsUsed, &$nHashUsed, &$vMatch)
 {
     if ($nBitsUsed >= count($this->vFlagBits)) {
         $this->fBad = true;
         return new Buffer();
     }
     $parent = $this->vFlagBits[$nBitsUsed++];
     if (0 === $height || !$parent) {
         if ($nHashUsed >= count($this->vHashes)) {
             $this->fBad = true;
             return new Buffer();
         }
         $hash = $this->vHashes[$nHashUsed++];
         if ($height === 0 && $parent) {
             $vMatch[] = $hash->flip();
         }
         return $hash;
     } else {
         $left = $this->traverseAndExtract($height - 1, $position * 2, $nBitsUsed, $nHashUsed, $vMatch);
         if ($position * 2 + 1 < $this->calcTreeWidth($height - 1)) {
             $right = $this->traverseAndExtract($height - 1, $position * 2 + 1, $nBitsUsed, $nHashUsed, $vMatch);
             if ($right === $left) {
                 $this->fBad = true;
             }
         } else {
             $right = $left;
         }
         return Hash::sha256d(Buffertools::concat($left, $right));
     }
 }
 /**
  * @param NetworkMessage $object
  * @return Buffer
  */
 public function serialize(NetworkMessage $object)
 {
     $payload = $object->getPayload()->getBuffer();
     $command = str_pad(unpack("H*", $object->getCommand())[1], 24, '0', STR_PAD_RIGHT);
     $header = $this->getHeaderTemplate()->write([Buffer::hex($this->network->getNetMagicBytes()), Buffer::hex($command), $payload->getSize(), $object->getChecksum()]);
     return Buffertools::concat($header, $payload);
 }
Пример #5
0
 /**
  * @param BlockInterface $block
  * @return \BitWasp\Buffertools\Buffer
  */
 public function serialize(BlockInterface $block)
 {
     return Buffertools::concat($this->headerSerializer->serialize($block->getHeader()), $this->getTxsTemplate()->write([$block->getTransactions()->all()]));
 }
Пример #6
0
 public function testConcat()
 {
     $a = Buffer::hex("1100");
     $b = Buffer::hex("0011");
     $c = Buffer::hex("11", 2);
     $this->assertEquals("11000011", Buffertools::concat($a, $b)->getHex());
     $this->assertEquals("00111100", Buffertools::concat($b, $a)->getHex());
     $this->assertEquals("11000011", Buffertools::concat($a, $c)->getHex());
     $this->assertEquals("00111100", Buffertools::concat($c, $a)->getHex());
 }
 /**
  * @param GetBlocks $msg
  * @return \BitWasp\Buffertools\Buffer
  */
 public function serialize(GetBlocks $msg)
 {
     return Buffertools::concat($this->getVersionTemplate()->write([$msg->getVersion()]), $this->locator->serialize($msg->getLocator()));
 }
Пример #8
0
 /**
  * Encode the given data in base58, with a checksum to check integrity.
  *
  * @param BufferInterface $data
  * @return string
  * @throws \Exception
  */
 public static function encodeCheck(BufferInterface $data)
 {
     return self::encode(Buffertools::concat($data, self::checksum($data)));
 }
Пример #9
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 int $inputToSign
  * @param int $sighashType
  * @return BufferInterface
  * @throws \Exception
  */
 public function calculate(ScriptInterface $txOutScript, $inputToSign, $sighashType = SigHash::ALL)
 {
     $math = Bitcoin::getMath();
     $tx = new TxMutator($this->transaction);
     $inputs = $tx->inputsMutator();
     $outputs = $tx->outputsMutator();
     // Default SIGHASH_ALL procedure: null all input scripts
     foreach ($inputs as $input) {
         $input->script(new Script());
     }
     $inputs[$inputToSign]->script($txOutScript);
     if ($math->cmp($math->bitwiseAnd($sighashType, 31), SigHash::NONE) === 0) {
         // Set outputs to empty vector, and set sequence number of inputs to 0.
         $outputs->null();
         // Let the others update at will. Set sequence of inputs we're not signing to 0.
         foreach ($inputs as $i => $input) {
             if ($i !== $inputToSign) {
                 $input->sequence(0);
             }
         }
     } elseif ($math->cmp($math->bitwiseAnd($sighashType, 31), SigHash::SINGLE) === 0) {
         // Resize output array to $inputToSign + 1, set remaining scripts to null,
         // and set sequence's to zero.
         $nOutput = $inputToSign;
         if ($nOutput >= $this->nOutputs) {
             return Buffer::hex('0100000000000000000000000000000000000000000000000000000000000000', 32, $math);
         }
         // Resize, set to null
         $outputs->slice(0, $nOutput + 1);
         for ($i = 0; $i < $nOutput; $i++) {
             $outputs[$i]->null();
         }
         // Let the others update at will. Set sequence of inputs we're not signing to 0
         foreach ($inputs as $i => $input) {
             if ($i !== $inputToSign) {
                 $input->sequence(0);
             }
         }
     }
     // This can happen regardless of whether it's ALL, NONE, or SINGLE
     if ($math->cmp($math->bitwiseAnd($sighashType, SigHash::ANYONECANPAY), 0) > 0) {
         $input = $inputs[$inputToSign]->done();
         $inputs->null()->add($input);
     }
     return Hash::sha256d(Buffertools::concat($tx->done()->getBuffer(), Buffertools::flipBytes(Buffer::int($sighashType, 4, $math))));
 }
Пример #10
0
 /**
  * @return Buffer
  */
 public function getMPK()
 {
     $math = $this->ecAdapter->getMath();
     $point = $this->getMasterPublicKey()->getPoint();
     return Buffertools::concat(Buffer::hex($math->decHex($point->getX()), 32), Buffer::hex($math->decHex($point->getY()), 32));
 }
Пример #11
0
 /**
  * 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)
 {
     $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");
         }
         $buffer = Buffertools::concat(new Buffer(""), $this->getPrivateKey()->getBuffer());
     } else {
         $buffer = $this->getPublicKey()->getBuffer();
     }
     return (new Parser($buffer))->writeBytes(4, Buffer::int($sequence, 4))->getBuffer();
 }
 /**
  * @param TransactionInputInterface $input
  * @return Buffer
  */
 public function serialize(TransactionInputInterface $input)
 {
     return Buffertools::concat($this->outpointSerializer->serialize($input->getOutPoint()), $this->getInputTemplate()->write([$input->getScript()->getBuffer(), $input->getSequence()]));
 }
 /**
  * @param FilteredBlock $merkleBlock
  * @return \BitWasp\Buffertools\BufferInterface
  */
 public function serialize(FilteredBlock $merkleBlock)
 {
     return Buffertools::concat($this->headerSerializer->serialize($merkleBlock->getHeader()), $this->treeSerializer->serialize($merkleBlock->getPartialTree()));
 }
Пример #14
0
 /**
  * @param Alert $alert
  * @return \BitWasp\Buffertools\Buffer
  */
 public function serialize(Alert $alert)
 {
     $sig = $alert->getSignature();
     return Buffertools::concat($alert->getDetail()->getBuffer(), $this->getSigTemplate()->write([$sig->getR(), $sig->getS()]));
 }
Пример #15
0
 /**
  * @param Alert $alert
  * @return \BitWasp\Buffertools\Buffer
  */
 public function serialize(Alert $alert)
 {
     $detail = $alert->getDetail()->getBuffer();
     $sig = $this->getSigBuf()->write([$alert->getSignature()->getBuffer()]);
     return Buffertools::concat($detail, $sig);
 }