/** * @param int|null $flags * @param EcAdapterInterface|null $ecAdapter * @return NativeConsensus */ public static function getNativeConsensus($flags = null, EcAdapterInterface $ecAdapter = null) { if ($flags === null) { $flags = self::defaultFlags(); } return new NativeConsensus($ecAdapter ?: Bitcoin::getEcAdapter(), $flags); }
/** * @param \BitWasp\Buffertools\Buffer|string $string * @param EcAdapterInterface $ecAdapter * @return SignatureInterface */ public static function fromHex($string, EcAdapterInterface $ecAdapter = null) { $ecAdapter = $ecAdapter ?: Bitcoin::getEcAdapter(); $serializer = EcSerializer::getSerializer($ecAdapter, 'BitWasp\\Bitcoin\\Crypto\\EcAdapter\\Serializer\\Signature\\DerSignatureSerializerInterface'); /** @var DerSignatureSerializerInterface $serializer */ return $serializer->parse($string); }
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 testNetworkSerializer() { $mem = new MemPool(); $serializer = new NetworkMessageSerializer(Bitcoin::getDefaultNetwork()); $parsed = $serializer->parse($mem->getNetworkMessage()->getBuffer())->getPayload(); $this->assertEquals($mem, $parsed); }
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); }); }
/** * @param $string * @param Math $math * @return TransactionSignatureInterface */ public static function fromHex($string, Math $math = null) { $math = $math ?: Bitcoin::getMath(); $serializer = new TransactionSignatureSerializer(new DerSignatureSerializer($math)); $signature = $serializer->parse($string); return $signature; }
/** * @param InputInterface $input * @param OutputInterface $output * @return int */ protected function execute(InputInterface $input, OutputInterface $output) { $config = (new ConfigLoader())->load(); // Create the child process // All the code after pcntl_fork () will be performed by two processes: parent and child if ($config->getItem('config', 'daemon', false)) { $child_pid = pcntl_fork(); if ($child_pid) { // Exit from the parent process that is bound to the console exit; } // Make the child as the main process. posix_setsid(); } $math = Bitcoin::getMath(); $params = new Params($math); $loop = \React\EventLoop\Factory::create(); $db = new DebugDb(Db::create($config)); $node = new BitcoinNode($config, $params, $db); $container = new Container(); $container['debug'] = function (Container $c) use($node) { $context = $c['zmq']; return new ZmqDebug($node, $context); }; $this->setupServices($container, $node, $loop, $config, $db); $loop->run(); return 0; }
/** * @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); }
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); }
public function testNetworkSerializer() { $network = Bitcoin::getDefaultNetwork(); $parser = new NetworkMessageSerializer(Bitcoin::getDefaultNetwork()); $factory = new Factory($network, new Random()); $version = '1'; $relayUntil = '9999999'; $expiration = '9898989'; $id = '123'; $cancel = '0'; $minVer = '0'; $maxVer = '0'; $priority = '50'; $comment = new Buffer('comment'); $statusBar = new Buffer('statusBar'); $setCancel = [1, 2]; $setSubVer = [50, 99]; $detail = new AlertDetail($version, $relayUntil, $expiration, $id, $cancel, $minVer, $maxVer, $priority, $comment, $statusBar, $setCancel, $setSubVer); $adapter = EcAdapterFactory::getPhpEcc(new Math(), EccFactory::getSecgCurves()->generator256k1()); $sig = new Signature($adapter, '1', '1'); $alert = $factory->alert($detail, $sig); $serialized = $alert->getNetworkMessage()->getBuffer(); $parsed = $parser->parse($serialized)->getPayload(); /** @var \BitWasp\Bitcoin\Networking\Messages\Alert $parsed */ $this->assertEquals($alert->getDetail(), $parsed->getDetail()); $this->assertEquals($alert->getSignature()->getR(), $parsed->getSignature()->getR()); $this->assertEquals($alert->getSignature()->getS(), $parsed->getSignature()->getS()); }
public function __construct(NodeInterface $node, Container $container) { $this->db = $container['db']; $this->retargetDb = new RetargetDb($this->db->getPdo()); $this->math = Bitcoin::getMath(); $this->consensus = new Consensus(Bitcoin::getMath(), new Params(Bitcoin::getMath())); $node->chains()->on('retarget', [$this, 'onRetarget']); }
public function testNetworkSerializable() { $factory = new Factory(Bitcoin::getDefaultNetwork(), new Random()); $filterclear = $factory->filterclear(); $serialized = $filterclear->getNetworkMessage()->getBuffer(); $parsed = $factory->parse(new Parser($serialized))->getPayload(); $this->assertEquals($parsed, $filterclear); }
public function testNetworkSerializer() { $parser = new NetworkMessageSerializer(Bitcoin::getDefaultNetwork()); $getaddr = new GetAddr(); $serialized = $getaddr->getNetworkMessage()->getBuffer(); $parsed = $parser->parse($serialized)->getPayload(); $this->assertEquals($getaddr, $parsed); }
/** * @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); }
/** * @param Parser $parser * @return Alert */ public function fromParser(Parser $parser) { $detail = $this->detail->fromParser($parser); list($sigBuffer) = $this->getSigBuf()->parse($parser); $adapter = Bitcoin::getEcAdapter(); $serializer = EcSerializer::getSerializer('BitWasp\\Bitcoin\\Crypto\\EcAdapter\\Serializer\\Signature\\DerSignatureSerializerInterface', true, $adapter); $sig = $serializer->parse($sigBuffer); return new Alert($detail, $sig); }
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); }
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); }
/** * 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 testGetValueIn() { $utxo1 = new Utxo(new OutPoint(new Buffer('a', 32), 0), new TransactionOutput(2, new Script())); $utxo2 = new Utxo(new OutPoint(new Buffer('a', 32), 1), new TransactionOutput(4, new Script())); $utxo3 = new Utxo(new OutPoint(new Buffer('b', 32), 0), new TransactionOutput(1, new Script())); $view = new UtxoView([$utxo1, $utxo2, $utxo3]); $transaction = TransactionFactory::build()->spendOutPoint($utxo1->getOutPoint())->spendOutPoint($utxo2->getOutPoint())->spendOutPoint($utxo3->getOutPoint())->output(5, new Script())->get(); $this->assertEquals(7, $view->getValueIn(Bitcoin::getMath(), $transaction)); $this->assertEquals(2, $view->getFeePaid(Bitcoin::getMath(), $transaction)); }
public function testNetworkSerializer() { $net = Bitcoin::getDefaultNetwork(); $serializer = new NetworkMessageSerializer($net); $factory = new Factory($net, new Random()); $ping = $factory->ping(); $serialized = $ping->getNetworkMessage()->getBuffer(); $parsed = $serializer->parse($serialized)->getPayload(); $this->assertEquals($ping, $parsed); }
/** * @param InputInterface $input * @param OutputInterface $output * @return int */ protected function execute(InputInterface $input, OutputInterface $output) { $math = Bitcoin::getMath(); $params = new Params($math); $loop = \React\EventLoop\Factory::create(); $app = new BitcoinNode($params, $loop); $app->start(); $loop->run(); return 0; }
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); }
public function testNetworkMessage() { $net = Bitcoin::getDefaultNetwork(); $parser = new NetworkMessageSerializer($net); $factory = new Factory($net, new Random()); $headers = $factory->headers([BlockHeaderFactory::fromHex('0100000000000000000000000000000000000000000000000000000000000000000000003ba3edfd7a7b12b27ac72c3e67768f617fc81bc3888a51323a9fb8aa4b1e5e4a29ab5f49ffff001d1dac2b7c')]); $serialized = $headers->getNetworkMessage()->getBuffer(); $parsed = $parser->parse($serialized)->getPayload(); $this->assertEquals($headers, $parsed); }
/** * @param \BitWasp\Buffertools\BufferInterface|string $hex * @param bool $compressed * @param EcAdapterInterface|null $ecAdapter * @return PrivateKey */ public static function fromHex($hex, $compressed = false, EcAdapterInterface $ecAdapter = null) { $ecAdapter = $ecAdapter ?: Bitcoin::getEcAdapter(); /** @var PrivateKeySerializerInterface $serializer */ $serializer = EcSerializer::getSerializer($ecAdapter, 'BitWasp\\Bitcoin\\Crypto\\EcAdapter\\Serializer\\Key\\PrivateKeySerializerInterface'); $parsed = $serializer->parse($hex); if ($compressed) { $parsed = $ecAdapter->getPrivateKey($parsed->getSecretMultiplier(), $compressed); } return $parsed; }
public function testBlockSerializer() { $parser = new NetworkMessageSerializer(Bitcoin::getDefaultNetwork()); $txHex = '01000000' . '01' . '0000000000000000000000000000000000000000000000000000000000000000FFFFFFFF' . '4D' . '04FFFF001D0104455468652054696D65732030332F4A616E2F32303039204368616E63656C6C6F72206F6E206272696E6B206F66207365636F6E64206261696C6F757420666F722062616E6B73' . 'FFFFFFFF' . '01' . '00F2052A01000000' . '43' . '4104678AFDB0FE5548271967F1A67130B7105CD6A828E03909A67962E0EA1F61DEB649F6BC3F4CEF38C4F35504E51EC112DE5C384DF7BA0B8D578A4C702B6BF11D5FAC' . '00000000'; $blockHex = '01000000' . '0000000000000000000000000000000000000000000000000000000000000000' . '3BA3EDFD7A7B12B27AC72C3E67768F617FC81BC3888A51323A9FB8AA4B1E5E4A' . '29AB5F49' . 'FFFF001D' . '1DAC2B7C' . '01' . $txHex; $newBlock = BlockFactory::fromHex($blockHex); $block = new Block($newBlock); $serialized = $block->getNetworkMessage()->getBuffer(); $parsed = $parser->parse($serialized)->getPayload(); $this->assertEquals($block, $parsed); }
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); }
/** * @param ScriptInterface $script * @param NetworkInterface $network * @return String * @throws \RuntimeException */ public static function getAssociatedAddress(ScriptInterface $script, NetworkInterface $network = null) { $classifier = new OutputClassifier($script); $network = $network ?: Bitcoin::getNetwork(); try { $address = $classifier->isPayToPublicKey() ? PublicKeyFactory::fromHex($script->getScriptParser()->parse()[0]->getHex())->getAddress() : self::fromOutputScript($script); return Base58::encodeCheck(Buffer::hex($network->getAddressByte() . $address->getHash())); } catch (\Exception $e) { throw new \RuntimeException('No address associated with this script type'); } }
public function testNetworkSerializer() { list($hex, $tx) = $this->getTestTx(); $net = Bitcoin::getDefaultNetwork(); $serializer = new NetworkMessageSerializer($net); $factory = new Factory($net, new Random()); $txMsg = $factory->tx($tx); $serialized = $txMsg->getNetworkMessage()->getBuffer(); $parsed = $serializer->parse($serialized)->getPayload(); $this->assertEquals($txMsg, $parsed); }
/** * Forks constructor. * @param ParamsInterface $params * @param BlockIndexInterface $index * @param array[] $versions */ public function __construct(ParamsInterface $params, BlockIndexInterface $index, array $versions) { $this->versionCount = ['v1' => 0, 'v2' => 0, 'v3' => 0, 'v4' => 0, 'v5' => 0]; foreach ($versions as $value) { $this->updateCount($value); } $this->math = Bitcoin::getMath(); $this->params = $params; $this->index = $index; $this->versions = $versions; $this->update(); }
/** * @param array $bits * @return array */ private function bitsToBuffers(array $bits) { $math = Bitcoin::getMath(); $vBuffers = str_split(str_pad('', (count($bits) + 7) / 8, '0', STR_PAD_LEFT)); $nBits = count($bits); for ($p = 0; $p < $nBits; $p++) { $index = (int) floor($p / 8); $vBuffers[$index] |= $bits[$p] << $p % 8; } foreach ($vBuffers as &$value) { $value = Buffer::int($value, null, $math); } unset($value); return $vBuffers; }