public function testMethods()
 {
     $loop = new \React\EventLoop\StreamSelectLoop();
     $dns = (new \BitWasp\Bitcoin\Networking\Dns\Factory())->create('8.8.8.8', $loop);
     $network = Bitcoin::getDefaultNetwork();
     $random = new Random();
     $messages = new \BitWasp\Bitcoin\Networking\Messages\Factory($network, $random);
     $factory = new Factory($dns, $messages, $loop);
     $this->assertInstanceOf($this->peerType, $factory->getPeer());
     $services = Buffer::hex('00', 8);
     $address = $factory->getAddress('127.0.0.1', 8332, $services);
     $this->assertInstanceOf($this->addrType, $address);
     $connector = $factory->getConnector();
     $this->assertInstanceOf($this->connType, $connector);
     $server = $factory->getServer();
     $this->assertInstanceOf($this->serverType, $server);
     $locator = $factory->getLocator();
     $this->assertInstanceOf($this->locatorType, $locator);
     $listener = $factory->getListener($server);
     $this->assertInstanceOf($this->listenerType, $listener);
     $handler = $factory->getPacketHandler();
     $this->assertInstanceOf($this->handlerType, $handler);
     $manager = $factory->getManager();
     $this->assertInstanceOf($this->managerType, $manager);
 }
 public function __construct()
 {
     parent::__construct(function () {
         $consensus = new ConsensusFactory(Bitcoin::getEcAdapter());
         $loop = LoopFactory::create();
         $context = new ZmqContext($loop);
         $control = $context->getSocket(\ZMQ::SOCKET_SUB);
         $control->connect('tcp://127.0.0.1:5594');
         $control->subscribe('control');
         $control->on('messages', function ($msg) use($loop) {
             if ($msg[1] == 'shutdown') {
                 $loop->stop();
             }
         });
         $results = $context->getSocket(\ZMQ::SOCKET_PUSH);
         $results->connect("tcp://127.0.0.1:5593");
         $workers = $context->getSocket(\ZMQ::SOCKET_PULL);
         $workers->connect('tcp://127.0.0.1:5592');
         $workers->on('message', function ($message) use($consensus, $results) {
             $details = json_decode($message, true);
             $txid = $details['txid'];
             $flags = $details['flags'];
             $vin = $details['vin'];
             $scriptPubKey = new Script(Buffer::hex($details['scriptPubKey']));
             $tx = TransactionFactory::fromHex($details['tx']);
             $results->send(json_encode(['txid' => $txid, 'vin' => $vin, 'result' => $consensus->getConsensus(new Flags($flags))->verify($tx, $scriptPubKey, $vin)]));
         });
         $loop->run();
         exit(0);
     });
 }
Exemple #3
0
 /**
  * Connect to $numSeeds DNS seeds
  *
  * @param int $numSeeds
  * @return \React\Promise\Promise|\React\Promise\PromiseInterface
  */
 public function queryDnsSeeds($numSeeds = 1)
 {
     $peerList = new Deferred();
     // Take $numSeeds
     $seedHosts = self::dnsSeedHosts();
     $seeds = array_slice($seedHosts, 0, min($numSeeds, count($seedHosts)));
     // Connect to $numSeeds peers
     /** @var Peer[] $vNetAddr */
     $vNetAddr = [];
     foreach ($seeds as $seed) {
         echo " [ query DNS seed: " . $seed . " ] \n";
         $this->dns->resolve($seed)->then(function ($ipList) use(&$vNetAddr, $peerList, &$numSeeds) {
             $vNetAddr[] = $ipList;
             if (count($vNetAddr) == $numSeeds) {
                 $peerList->resolve($vNetAddr);
             }
         });
     }
     // Compile the list of lists of peers into $this->knownAddresses
     return $peerList->promise()->then(function (array $vPeerVAddrs) {
         shuffle($vPeerVAddrs);
         /** @var NetworkAddressInterface[] $addresses */
         $addresses = [];
         array_map(function (array $value) use(&$addresses) {
             foreach ($value as $ip) {
                 $addresses[] = new NetworkAddress(Buffer::hex('01', 8), $ip, 8333);
             }
         }, $vPeerVAddrs);
         $this->knownAddresses = array_merge($this->knownAddresses, $addresses);
         return $this;
     });
 }
Exemple #4
0
 public function testPeer()
 {
     $localhost = '127.0.0.1';
     $localport = '8333';
     $remotehost = '127.0.0.1';
     $remoteport = '9999';
     $loop = new StreamSelectLoop();
     $dnsResolverFactory = new \React\Dns\Resolver\Factory();
     $dns = $dnsResolverFactory->createCached('8.8.8.8', $loop);
     $reactServer = new Server($loop);
     $network = Bitcoin::getDefaultNetwork();
     $client = new NetworkAddress(Buffer::hex('0000000000000001'), $localhost, $localport);
     $server = new NetworkAddress(Buffer::hex('0000000000000001'), $remotehost, $remoteport);
     $msgs = new Factory($network, new Random());
     $serverReceivedConnection = false;
     $serverListener = new Listener($server, $msgs, $reactServer, $loop);
     $serverListener->on('connection', function (Peer $peer) use(&$serverReceivedConnection, &$serverListener) {
         $peer->close();
         $serverReceivedConnection = true;
     });
     $serverListener->listen($server->getPort());
     $connector = new Connector($loop, $dns);
     $clientConnection = new Peer($client, $msgs, $loop);
     $clientConnection->connect($connector, $server)->then(function (Peer $peer) use($serverListener, &$loop) {
         $peer->close();
         $serverListener->close();
     });
     $loop->run();
     $this->assertTrue($serverReceivedConnection);
 }
 /**
  * Composes a send transaction
  * @param  string $asset                     A counterparty asset name or BTC
  * @param  mixed  $quantity                  Quantity of asset to send.  Accepts a float or a Tokenly\CounterpartyTransactionComposer\Quantity or Tokenly\CryptoQuantity\CryptoQuantity object.  Use a Quantity object for indivisible assets.
  * @param  mixed  $destination               A single destination bitcoin address.  For BTC sends an array of [[address, amount], [address, amount]] is also allowed.  Amounts should be float values.
  * @param  string $private_key_wif           The private key in ASCII WIF format.  This can be null to compose an unsigned transaction.
  * @param  array  $utxos                     An array of UTXOs.  Each UTXO should be ['txid' => txid, 'n' => n, 'amount' => amount (in satoshis), 'script' => script hexadecimal string]
  * @param  mixed  $change_address_collection a single address string to receive all change. Or an array of [[address, amount], [address, amount], [address]].  Amounts should be float values.  An address with no amount for the last entry will send the remaining change to that address.
  * @param  float  $fee                       A fee
  * @param  float  $btc_dust                  Amount of BTC dust to send with the Counterparty transaction.
  * @return Array returns a ComposedTransaction object
  */
 public function composeSend($asset, $quantity, $destination, $private_key_wif, $utxos, $change_address_collection = null, $fee = null, $btc_dust = null)
 {
     if ($asset == 'BTC') {
         return $this->composeBTCSend($quantity, $destination, $private_key_wif, $utxos, $change_address_collection, $fee);
     }
     $fee_satoshis = $fee === null ? self::DEFAULT_FEE : intval(round($fee * self::SATOSHI));
     $btc_dust_satoshis = $btc_dust === null ? self::DEFAULT_BTC_DUST : intval(round($btc_dust * self::SATOSHI));
     // get total and change amount
     $change_amounts = $this->calculateAndValidateChange($utxos, $btc_dust_satoshis, $fee_satoshis, $change_address_collection);
     $tx_builder = TransactionFactory::build();
     // add the UTXO inputs
     $transaction_outputs = $this->addInputsAndReturnPreviousOutputs($utxos, $tx_builder);
     // pay the btc_dust to the destination
     if (is_array($destination)) {
         throw new Exception("Multiple destinations are not supported for counterparty sends", 1);
     }
     $tx_builder->payToAddress($btc_dust_satoshis, AddressFactory::fromString($destination));
     // build the OP_RETURN script
     $op_return_builder = new OpReturnBuilder();
     $op_return = $op_return_builder->buildOpReturn($quantity, $asset, $utxos[0]['txid']);
     $script = ScriptFactory::create()->op('OP_RETURN')->push(Buffer::hex($op_return, 28))->getScript();
     $tx_builder->output(0, $script);
     // pay the change to self
     $this->payChange($change_amounts, $tx_builder);
     // sign
     if ($private_key_wif !== null) {
         $signed_transaction = $this->signTx($private_key_wif, $tx_builder, $transaction_outputs);
         return $this->buildReturnValuesFromTransactionAndInputs($signed_transaction, $utxos, true);
     }
     return $this->buildReturnValuesFromTransactionAndInputs($tx_builder->get(), $utxos, false);
 }
 /**
  * @param string $hex
  * @param bool $compressed
  * @param EcAdapterInterface|null $ecAdapter
  * @return PrivateKey
  */
 public static function fromHex($hex, $compressed = false, EcAdapterInterface $ecAdapter = null)
 {
     $hex = Buffer::hex($hex);
     $ecAdapter = $ecAdapter ?: Bitcoin::getEcAdapter();
     $hexSerializer = new HexPrivateKeySerializer($ecAdapter);
     return $hexSerializer->parse($hex)->setCompressed($compressed);
 }
Exemple #7
0
 /**
  * @return \BitWasp\Bitcoin\Block\BlockInterface
  */
 public function getGenesisBlock()
 {
     $timestamp = new Buffer('The Times 03/Jan/2009 Chancellor on brink of second bailout for banks', null, $this->math);
     $publicKey = Buffer::hex('04678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5f', null, $this->math);
     $inputScript = ScriptFactory::sequence([Buffer::int('486604799', 4, $this->math)->flip(), Buffer::int('4', null, $this->math), $timestamp]);
     $outputScript = ScriptFactory::sequence([$publicKey, Opcodes::OP_CHECKSIG]);
     return new Block($this->math, $this->getGenesisBlockHeader(), new TransactionCollection([(new TxBuilder())->version('1')->input(new Buffer('', 32), 4294967295.0, $inputScript)->output(5000000000.0, $outputScript)->locktime(0)->get()]));
 }
 public function testHashIsSerializedInReverseOrder()
 {
     $buffer = Buffer::hex('0001020300010203000102030001020300010203000102030001020300010203');
     $inv = Inventory::block($buffer);
     $results = unpack("Vtype/H64hash", $inv->getBinary());
     $parsedBuffer = Buffer::hex($results['hash']);
     $this->assertEquals($buffer->getHex(), Buffertools::flipBytes($parsedBuffer)->getHex());
 }
 /**
  * @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 NodeInterface $node
  * @param array $params
  * @return array
  */
 public function execute(NodeInterface $node, array $params)
 {
     if (strlen($params[self::PARAM_HASH]) !== 64) {
         throw new \RuntimeException('Invalid hash');
     }
     $index = $node->chain()->fetchIndex(Buffer::hex($params[self::PARAM_HASH]));
     return ['header' => $this->convertIndexToArray($index)];
 }
 /**
  * @param string $ip
  * @return Buffer
  */
 private function getIpBuffer($ip)
 {
     $hex = (string) dechex(ip2long($ip));
     $hex = strlen($hex) % 2 == 1 ? '0' . $hex : $hex;
     $hex = '00000000000000000000' . 'ffff' . $hex;
     $buffer = Buffer::hex($hex);
     return $buffer;
 }
 /**
  * @param $hex
  * @return PublicKey
  * @throws \Exception
  */
 public function parse($hex)
 {
     $hex = Buffer::hex($hex);
     if (!in_array($hex->getSize(), [PublicKey::LENGTH_COMPRESSED, PublicKey::LENGTH_UNCOMPRESSED])) {
         throw new \Exception('Invalid hex string, must match size of compressed or uncompressed public key');
     }
     return $this->ecAdapter->publicKeyFromBuffer($hex);
 }
 /**
  * @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 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);
 }
 /**
  * @param NetworkInterface|null $network
  * @return string
  */
 public function getAddress(NetworkInterface $network = null)
 {
     $network = $network ?: Bitcoin::getNetwork();
     $witnessByte = dechex($this->witnessVersion);
     $witnessByte = strlen($witnessByte) % 2 == 0 ? $witnessByte : '0' . $witnessByte;
     $payload = Buffer::hex($this->getPrefixByte($network) . $witnessByte . "00" . $this->getHash());
     return Base58::encodeCheck($payload);
 }
Exemple #16
0
 /**
  * @param NodeInterface $node
  * @param array $params
  * @return array
  */
 public function execute(NodeInterface $node, array $params)
 {
     if (strlen($params[self::PARAM_TXID]) !== 64) {
         throw new \RuntimeException('Invalid txid field');
     }
     $txid = Buffer::hex($params[self::PARAM_TXID], 32);
     $tx = $node->chain()->fetchTransaction($node->transactions(), $txid);
     return ['tx' => $this->convertTransactionToArray($tx)];
 }
Exemple #17
0
 public function testNetworkSerializer()
 {
     $net = Bitcoin::getDefaultNetwork();
     $factory = new Factory($net, new Random());
     $inv = $factory->inv([new Inventory(Inventory::MSG_BLOCK, Buffer::hex('4141414141414141414141414141414141414141414141414141414141414141'))]);
     $serialized = $inv->getNetworkMessage()->getBuffer();
     $parsed = $factory->parse(new Parser($serialized))->getPayload();
     $this->assertEquals($inv, $parsed);
 }
 public function testNetworkSerializer()
 {
     $array = [new Inventory(Inventory::MSG_TX, Buffer::hex('4141414141414141414141414141414141414141414141414141414141414141')), new Inventory(Inventory::MSG_TX, Buffer::hex('4141414141414141414141414141414141414141414141414141414141414142')), new Inventory(Inventory::MSG_TX, Buffer::hex('4141414141414141414141414141414141414141414141414141414141414143'))];
     $not = new NotFound($array);
     $serializer = new NetworkMessageSerializer(Bitcoin::getDefaultNetwork());
     $serialized = $not->getNetworkMessage()->getBuffer();
     $parsed = $serializer->parse($serialized)->getPayload();
     $this->assertEquals($not, $parsed);
 }
 /**
  * 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());
 }
 public function testNetworkSerializer()
 {
     $net = Bitcoin::getDefaultNetwork();
     $factory = new Factory($net, new Random());
     $locator = new BlockLocator([Buffer::hex('4141414141414141414141414141414141414141414141414141414141414141')], Buffer::hex('0000000000000000000000000000000000000000000000000000000000000000'));
     $getblocks = $factory->getblocks('1', $locator);
     $serialized = $getblocks->getNetworkMessage()->getBuffer();
     $parsed = $factory->parse(new Parser($serialized))->getPayload();
     $this->assertEquals($getblocks, $parsed);
 }
 /**
  * @dataProvider getVectors
  */
 public function testByteStringLe($math, $size, $string)
 {
     $buffer = Buffer::hex($string, $size);
     $t = new ByteString($math, $size, ByteOrder::LE);
     $out = $t->write($buffer);
     $eFlipped = Buffertools::flipBytes(pack("H*", $string));
     $this->assertEquals($eFlipped, $out);
     $parser = new Parser(new Buffer($out));
     $this->assertEquals($string, $t->read($parser)->getHex());
 }
 /**
  * @param EcAdapterInterface $ecAdapter
  * @param $int
  * @param bool $compressed
  * @throws InvalidPrivateKey
  */
 public function __construct(EcAdapterInterface $ecAdapter, $int, $compressed = false)
 {
     $buffer = Buffer::hex($ecAdapter->getMath()->decHex($int), 32);
     if (false === $ecAdapter->validatePrivateKey($buffer)) {
         throw new InvalidPrivateKey('Invalid private key - must be less than curve order.');
     }
     $this->ecAdapter = $ecAdapter;
     $this->secretMultiplier = $int;
     $this->setCompressed($compressed);
 }
Exemple #23
0
 public function testIsNext()
 {
     $first = new BlockIndex(new Buffer('aa', 32), 0, 0, new BlockHeader(0, new Buffer('', 32), new Buffer('', 32), 0, new Buffer(), 0));
     $nextGood = new BlockIndex(new Buffer('bb'), 1, 0, new BlockHeader(0, new Buffer('aa', 32), new Buffer('', 32), 0, new Buffer(), 0));
     $nextBadHeight = new BlockIndex(Buffer::hex('bc', 32), 222, 0, new BlockHeader(0, new Buffer('aa', 32), new Buffer('', 32), 0, new Buffer(), 0));
     $nextBadHash = new BlockIndex(Buffer::hex('bd', 32), 1, 0, new BlockHeader(0, new Buffer('22', 32), new Buffer('', 32), 0, new Buffer(), 0));
     $this->assertFalse($first->isNext($nextBadHash));
     $this->assertFalse($first->isNext($nextBadHeight));
     $this->assertTrue($first->isNext($nextGood));
 }
 public function testNetworkSerialize()
 {
     $math = new Math();
     $factory = new Factory(Bitcoin::getDefaultNetwork(), new Random());
     $filter = BloomFilter::create($math, 10, 1.0E-6, 0, new Flags(BloomFilter::UPDATE_ALL));
     $filter->insertData(Buffer::hex('04943fdd508053c75000106d3bc6e2754dbcff19'));
     $filterload = $factory->filterload($filter);
     $serialized = $filterload->getNetworkMessage()->getBuffer();
     $parsed = $factory->parse(new Parser($serialized))->getPayload();
     $this->assertEquals($parsed, $filterload);
 }
 public function testGetVarString()
 {
     $strings = array('', '00', '00010203040506070809', '00010203040506070809000102030405060708090001020304050607080900010203040506070809000102030405060708090001020304050607080900010203040506070809000102030405060708090001020304050607080900010203040506070809000102030405060708090001020304050607080900010203040506070809000102030405060708090001020304050607080900010203040506070809000102030405060708090001020304050607080900010203040506070809000102030405060708090001020304050607080900010203040506070809000102030405060708090001020304050607080900010203040506070809000102');
     $math = EccFactory::getAdapter();
     $varstring = new VarString(new VarInt($math));
     foreach ($strings as $string) {
         $binary = $varstring->write(Buffer::hex($string));
         $parser = new Parser(new Buffer($binary));
         $original = $varstring->read($parser);
         $this->assertSame($string, $original->getHex());
     }
 }
 public function testNetworkAddressTimestamp()
 {
     $ip = '127.0.0.1';
     $port = 8333;
     $time = time();
     $services = Buffer::hex('0000000000000001');
     $from = new NetworkAddressTimestamp($time, $services, $ip, $port);
     $this->assertEquals($time, $from->getTimestamp());
     $this->assertEquals($services, $from->getServices());
     $this->assertEquals($ip, $from->getIp());
     $this->assertEquals($port, $from->getPort());
 }
 /**
  * @param $bitSize
  * @return array
  */
 private function generateSizeBasedTests($bitSize, $byteOrder)
 {
     $math = EccFactory::getAdapter();
     $halfPos = $math->baseConvert(str_pad('7', $bitSize / 4, 'f', STR_PAD_RIGHT), 16, 10);
     $maxPos = $math->baseConvert(str_pad('', $bitSize / 4, 'f', STR_PAD_RIGHT), 16, 10);
     $test = function ($integer) use($bitSize, $math, $byteOrder) {
         $hex = str_pad($math->baseConvert($integer, 10, 16), $bitSize / 4, '0', STR_PAD_LEFT);
         if ($byteOrder == ByteOrder::LE) {
             $hex = Buffertools::flipBytes(Buffer::hex($hex))->getHex();
         }
         return [$integer, $hex, null];
     };
     return [$test(0), $test(1), $test($halfPos), $test($maxPos)];
 }
Exemple #28
0
 public function testNetworkSerializer()
 {
     $network = Bitcoin::getDefaultNetwork();
     $time = '9999999';
     $ip = '192.168.0.1';
     $port = '8333';
     $services = Buffer::hex('0000000000000000', 8);
     $add = new NetworkAddressTimestamp($time, $services, $ip, $port);
     $parser = new NetworkMessageSerializer(Bitcoin::getDefaultNetwork());
     $factory = new Factory($network, new Random());
     $addr = $factory->addr([$add]);
     $serialized = $addr->getNetworkMessage()->getBuffer();
     $parsed = $parser->parse($serialized)->getPayload();
     $this->assertEquals($addr, $parsed);
 }
 /**
  * @throws \BitWasp\Bitcoin\Exceptions\RandomBytesFailure
  * @expectedException \RuntimeException
  * @expectedExceptionMessage
  */
 public function testInvalidBytes()
 {
     $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);
     $bitcoin = new NetworkMessageSerializer(NetworkFactory::bitcoin());
     $serialized = $version->getNetworkMessage(NetworkFactory::viacoinTestnet())->getBuffer();
     $bitcoin->parse($serialized);
 }
 public function testReadVector()
 {
     $math = EccFactory::getAdapter();
     $varint = new VarInt($math);
     $vector = new Vector($varint, function (Parser &$parser) {
         return $parser->readBytes(16);
     });
     $eBuffer = Buffer::hex('010203040506070809000a0b0c0d0e0f');
     $hex = '03010203040506070809000a0b0c0d0e0f010203040506070809000a0b0c0d0e0f010203040506070809000a0b0c0d0e0f';
     $buffer = Buffer::hex($hex);
     $parser = new Parser($buffer);
     $array = $vector->read($parser);
     foreach ($array as $item) {
         $this->assertEquals($eBuffer->getBinary(), $item->getBinary());
     }
 }