public function validate($value, Constraint $constraint) { try { AddressFactory::fromString($value); } catch (\Exception $e) { $this->context->buildViolation($constraint->message)->addViolation(); } }
public function createSampleTXO($payment_address = null, $overrides = []) { if ($payment_address === null) { $payment_address = app('PaymentAddressHelper')->createSamplePaymentAddress(); } $account = AccountHandler::getAccount($payment_address, 'default'); // build a real script $script = ScriptFactory::scriptPubKey()->payToAddress(AddressFactory::fromString($payment_address['address'])); $attributes = array_merge(['txid' => $this->nextTXID(), 'n' => 0, 'script' => $script->getBuffer()->getHex(), 'amount' => 54321, 'type' => TXO::CONFIRMED, 'spent' => false, 'green' => false], $overrides); $txo_model = $this->txo_repository->create($payment_address, $account, $attributes); return $txo_model; }
<?php require "../vendor/autoload.php"; use BitWasp\Bitcoin\Bitcoin; use BitWasp\Bitcoin\MessageSigner\MessageSigner; use BitWasp\Bitcoin\Serializer\MessageSigner\SignedMessageSerializer; use BitWasp\Bitcoin\Serializer\Signature\CompactSignatureSerializer; Bitcoin::setNetwork(\BitWasp\Bitcoin\Network\NetworkFactory::bitcoinTestnet()); $address = 'n2Z2DFCxG6vktyX1MFkKAQPQFsrmniGKj5'; $sig = '-----BEGIN BITCOIN SIGNED MESSAGE----- hi -----BEGIN SIGNATURE----- IBpGR29vEbbl4kmpK0fcDsT75GPeH2dg5O199D3iIkS3VcDoQahJMGJEDozXot8JGULWjN9Llq79aF+FogOoz/M= -----END BITCOIN SIGNED MESSAGE-----'; $ec = Bitcoin::getEcAdapter(); $addr = \BitWasp\Bitcoin\Address\AddressFactory::fromString($address); $serializer = new SignedMessageSerializer(new CompactSignatureSerializer(Bitcoin::getMath())); $signedMessage = $serializer->parse($sig); $signer = new MessageSigner($ec); if ($signer->verify($signedMessage, $addr)) { echo "Signature verified!\n"; } else { echo "Failed to verify signature!\n"; }
<?php require "../vendor/autoload.php"; use BitWasp\Bitcoin\Address\AddressFactory; use BitWasp\Bitcoin\Transaction\TransactionFactory; $transaction = TransactionFactory::build()->input('99fe5212e4e52e2d7b35ec0098ae37881a7adaf889a7d46683d3fbb473234c28', 0)->payToAddress(29890000, AddressFactory::fromString('19SokJG7fgk8iTjemJ2obfMj14FM16nqzj'))->payToAddress(100000, AddressFactory::fromString('1CzcTWMAgBNdU7K8Bjj6s6ezm2dAQfUU9a'))->get(); echo $transaction->getHex() . PHP_EOL;
$url = urlencode($app->url('request.request', ['slug' => $request->slug])); $bitcoinUrl = "bitcoin:" . $requirements[0]->address . "?amount=" . $request->valuebtc . "&r=" . $url; //$bitcoinUrl = "bitcoin:?r=" . $url; //echo $bitcoinUrl . "\n"; return $app['twig']->render('info.html.twig', ['request' => $request->to_array(), 'requirements' => $reqs, 'address' => $reqs[0]['address'], 'url' => $url, 'bitcoinUrl' => $bitcoinUrl]); })->bind('info'); $app->match('/new', function (\Symfony\Component\HttpFoundation\Request $request) use($app) { // some default data for when the form is displayed the first time /** @var \Symfony\Component\Form\FormFactory $factory */ $factory = $app['form.factory']; $form = $factory->createBuilder()->add('address', 'text', array('attr' => array('class' => 'form-control', 'placeholder' => 'Bitcoin address'), 'constraints' => [new \Symfony\Component\Validator\Constraints\NotBlank(), new \BitWasp\Payments\Application\Validator\BitcoinAddress()]))->add('value', 'text', array('attr' => array('class' => 'form-control', 'placeholder' => 'Amount in satoshis'), 'constraints' => new \Symfony\Component\Validator\Constraints\NotBlank()))->add('send', 'submit', array('attr' => array('class' => 'btn btn-lg btn-primary btn-block')))->getForm(); if ('POST' == $request->getMethod()) { $form->bind($request); if ($form->isValid()) { $data = $form->getData(); $address = \BitWasp\Bitcoin\Address\AddressFactory::fromString($data['address']); $script = \BitWasp\Bitcoin\Script\ScriptFactory::scriptPubKey()->payToAddress($address); $txOut = new \BitWasp\Bitcoin\Transaction\TransactionOutput($data['value'], $script); $slug = bin2hex(openssl_random_pseudo_bytes(32)); $signer = new \BitWasp\Bitcoin\PaymentProtocol\PaymentRequestSigner('none'); $builder = new \BitWasp\Bitcoin\PaymentProtocol\PaymentRequestBuilder($signer, 'main', time()); $builder->addOutput($txOut); $details = $builder->getPaymentDetails(); $details->setPaymentUrl($app->url('request.payment', ['slug' => $slug])); $request = $builder->getPaymentRequest(); $totalValue = $data['value']; $amount = new \BitWasp\Bitcoin\Amount(); $dbRequest = \BitWasp\Payments\Db\Request::create(['slug' => $slug, 'value' => $totalValue, 'valueBtc' => $amount->toBtc($data['value']), 'payment_request' => $request->serialize()]); $output = \BitWasp\Payments\Db\OutputRequirement::create(['request_id' => $dbRequest->id, 'value' => $data['value'], 'valueBtc' => $amount->toBtc($data['value']), 'address' => $data['address'], 'script' => $txOut->getScript()->getBinary()]); $app['request_api']->pushRequest($slug, [$output]); return $app->redirect($app['url_generator']->generate('info', array('slug' => $dbRequest->slug)));
$network = Bitcoin::getNetwork(); $ecAdapter = Bitcoin::getEcAdapter(); $bitcoind = RpcFactory::bitcoind($host, $port, $user, $pass); $privateKey1 = PrivateKeyFactory::fromHex('17a2209250b59f07a25b560aa09cb395a183eb260797c0396b82904f918518d5', true); $privateKey2 = PrivateKeyFactory::fromHex('17a2209250b59f07a25b560aa09cb395a183eb260797c0396b82904f918518d6', true); $redeemScript = ScriptFactory::multisig(2, array($privateKey1->getPublicKey(), $privateKey2->getPublicKey())); $multisig = $redeemScript->getAddress(); echo "[P2SH address: " . $multisig->getAddress($network) . " ]\n"; echo "[private key order: " . implode(", ", array_map(function (PublicKeyInterface $publicKey) use($privateKey1, $privateKey2) { if ($publicKey->getBinary() == $privateKey1->getPublicKey()->getBinary()) { return "1"; } else { return "2"; } }, $redeemScript->getKeys())) . "]\n"; $myTx = $bitcoind->getrawtransaction('6d4f5d2cce43660c29e03a794497da3f204312358ca6a6e47035ef916ce19db9', true); $spendOutput = 0; $recipient = AddressFactory::fromString('n1b2a9rFvuU9wBgBaoWngNvvMxRV94ke3x'); echo "[Send to: " . $recipient->getAddress($network) . " \n"; // Prep work - importing from a tx will only bring container to contents of $new - no metadata $new = new \BitWasp\Bitcoin\Transaction\TransactionBuilder($ecAdapter); $new->spendOutput($myTx, $spendOutput)->payToAddress($recipient, 100000); // Start doing things which require state tracking $new->signInputWithKey($privateKey1, $redeemScript->getOutputScript(), $spendOutput, $redeemScript)->signInputWithKey($privateKey2, $redeemScript->getOutputScript(), $spendOutput, $redeemScript); $tx = $new->getTransaction(); // Send transaction to multisig address try { $txid = $bitcoind->sendrawtransaction($tx, true); } catch (\Exception $e) { echo "\n\nException: (" . $e->getCode() . ") " . $e->getMessage() . "\n"; }
<?php require "../vendor/autoload.php"; use BitWasp\Bitcoin\Address\AddressFactory; use BitWasp\Bitcoin\PaymentProtocol\PaymentRequestBuilder; use BitWasp\Bitcoin\PaymentProtocol\PaymentRequestSigner; $time = time(); $amount = 10000; $destination = '18Ffckz8jsjU7YbhP9P44JMd33Hdkkojtc'; $paymentUrl = 'http://192.168.0.223:81/bitcoin-php/examples/bip70.fetch.php?time=' . $time; // Create a signer for x509+sha256 - this requires a readable private key and certificate chain. // $signer = new PaymentRequestSigner('none'); $signer = new PaymentRequestSigner('x509+sha256', '/var/www/git/paymentrequestold/.keys/ssl.key', '/var/www/git/paymentrequestold/.keys/ssl.pem'); $builder = new PaymentRequestBuilder($signer, 'main', time()); // PaymentRequests contain outputs that the wallet will fulfill $address = AddressFactory::fromString($destination); $builder->addAddressPayment($address, $amount); // Create the request, write it to a temporary file $request = $builder->getPaymentRequest(); // Create a url + display a QR $encodedUrl = urlencode($paymentUrl); $uri = "bitcoin:{$address}?r={$encodedUrl}&amount=0.00010000"; $qr = urlencode($uri); echo "<a href='{$uri}'>Pay<img src='https://chart.googleapis.com/chart?chs=300x300&cht=qr&chl={$qr}'></a>";
<?php require "../vendor/autoload.php"; require "../db/bootstrap.php"; $address = \BitWasp\Bitcoin\Address\AddressFactory::fromString('1J7jgWATD4Vfe9eUs7EL4YdadbPaM7cGgj'); $script = \BitWasp\Bitcoin\Script\ScriptFactory::scriptPubKey()->payToAddress($address); /** @var \BitWasp\Bitcoin\Transaction\TransactionOutputInterface[] $outputs */ $outputs = [new \BitWasp\Bitcoin\Transaction\TransactionOutput(1000000, $script)]; $signer = new \BitWasp\Bitcoin\PaymentProtocol\PaymentRequestSigner('none'); $builder = new \BitWasp\Bitcoin\PaymentProtocol\PaymentRequestBuilder($signer, 'main', time()); foreach ($outputs as $output) { $builder->addOutput($output); } $request = $builder->getPaymentRequest(); $value = 1000000; $amount = new \BitWasp\Bitcoin\Amount(); $list = \BitWasp\Payments\Db\Request::create(['slug' => bin2hex(mcrypt_create_iv(32, MCRYPT_DEV_URANDOM)), 'value' => $value, 'valueBtc' => $amount->toBtc($value), 'payment_request' => $request->serialize()]); $req = []; foreach ($outputs as $output) { $req[] = \BitWasp\Payments\Db\OutputRequirement::create(['request_id' => $list->id, 'value' => $output->getValue(), 'valueBtc' => $amount->toBtc($value), 'script' => $output->getScript()->getBinary(), 'address' => $address->getAddress()]); }
$network = Bitcoin::getNetwork(); $ecAdapter = Bitcoin::getEcAdapter(); $host = '127.0.0.1'; $port = '18332'; $user = getenv('BITCOINLIB_RPC_USER') ?: 'bitcoinrpc'; $pass = getenv('BITCOINLIB_RPC_PASSWORD') ?: 'BBpsLqmCCx7Vp8sRd5ygDxFkHZBgWLTTi55QwWgN6Ng6'; Bitcoin::setNetwork(\BitWasp\Bitcoin\Network\NetworkFactory::bitcoinTestnet()); $bitcoind = RpcFactory::bitcoind($host, $port, $user, $pass); // Address to fund this test $fundsKey = PrivateKeyFactory::fromWif('cQTqzY1hhC8u4aeFmqodENTnJvxgSk316PakYVgcFaHqAa4aCpwW'); $address = $fundsKey->getAddress()->getAddress(); // Txid / spendable output of funding transaction, funds will be moved from here -> multisig $myTx = $bitcoind->getrawtransaction('e76ef5659124d5cacb0fa2536f8af8e279aea016be1408caa492295a6f85a214', true); $spendOutput = 0; // Funds will be send from Multisig -> this $recipient = \BitWasp\Bitcoin\Address\AddressFactory::fromString('n1b2a9rFvuU9wBgBaoWngNvvMxRV94ke3x'); // Begin $privateKey1 = PrivateKeyFactory::fromHex('17a2209250b59f07a25b560aa09cb395a183eb260797c0396b82904f918518d5', true); $privateKey2 = PrivateKeyFactory::fromHex('17a2209250b59f07a25b560aa09cb395a183eb260797c0396b82904f918518d6', true); $redeemScript = ScriptFactory::multisig(2, array($privateKey1->getPublicKey(), $privateKey2->getPublicKey())); // First, move money from fundsKey to the multisig address $new = new \BitWasp\Bitcoin\Transaction\TransactionBuilder($ecAdapter); $new->spendOutput($myTx, $spendOutput)->payToAddress($redeemScript->getAddress(), 200000); echo "[Fund this address: {$address}]\n"; echo "[P2SH address: " . $redeemScript->getAddress() . " ]\n"; $new->signInputWithKey($fundsKey, $myTx->getOutputs()->getOutput($spendOutput)->getScript(), 0); $tx = $new->getTransaction(); try { echo "try sending to multisig address\n"; echo $tx->getHex() . "\n"; $txid = $bitcoind->sendrawtransaction($tx, true);
if ($debug) { echo "[Key: " . $privateKey->toWif($network) . "]\n"; echo "[Address " . $privateKey->getAddress()->getAddress($network) . "]\n"; } // In order to run the sample you will need: // 1.- Use the faucet to fund source address // Faucet https://accounts.blockcypher.com/testnet-faucet?a=n3D2YXwvpoPg8FhcWpzJiS3SvKKGD8AXZ4 // 2.- Get unspent transaction outputs (UTXOs) and select one: // https://api.blockcypher.com/v1/btc/test3/addrs/n3D2YXwvpoPg8FhcWpzJiS3SvKKGD8AXZ4?unspentOnly=true // 3.- Get the hex tx for the selected UTXO: // https://live.blockcypher.com/btc-testnet/tx/e7f034f4a56999d04d8a3a8f07dca10e87cd4a7fd2a779e9ecd41c57afec84f8/ // 4.- Copy Tx Hex and paste here: $txHex = '0100000001b674eafd9c1a79402661e7e7b37746145869260c29263f213f6f120ea8a95574010000006b483045022100ac406c14ef2da774d64d5504340fd278a827a99941cf0bef26fdff17c191ffa4022016a69a281ec1fcdf22c34543ff97a5c332ed12856fb44e525cf8ba3aea7c2d4101210274cb62e999bdf96c9b4ef8a2b44c1ac54d9de879e2ee666fdbbf0e1a03090cdfffffffff02e8030000000000001976a914a93806b8ae200fffca565f7cf9ef3ab17d4ffe8888ac204e0000000000001976a914edeed3ce7f485e44bc33969af08ec9250510f83f88ac00000000'; $myTx = TransactionFactory::fromHex($txHex); $spendOutput = 0; $recipient = AddressFactory::fromString('mvwhcFDFjmbDWCwVJ73b8DcG6bso3CZXDj'); if ($debug) { echo "[Send to: " . $recipient->getAddress($network) . "]\n"; } $builder = new TransactionBuilder($ecAdapter); $builder->spendOutput($myTx, $spendOutput)->payToAddress($recipient, 1000); if ($debug) { echo "Setup stage\n"; //print_r($builder); echo "Signing\n"; } // This line throws a warning but it works: // https://github.com/mdanter/phpecc/issues/90 error_reporting(E_ERROR | E_PARSE); $builder->signInputWithKey($privateKey, $myTx->getOutputs()->getOutput($spendOutput)->getScript(), 0); if ($debug) {
protected function payChange($change_amounts, $tx_builder) { if ($change_amounts) { foreach ($change_amounts as $change_amount_pair) { $address = $change_amount_pair[0]; $btc_satoshis = $change_amount_pair[1]; $tx_builder->payToAddress($btc_satoshis, AddressFactory::fromString($address)); } } }
protected function buildFakeUTXO($destination, $amount, $txid_number, $n) { $tx = TransactionFactory::build()->input('deadbeef00000000000000000000000000000000000000000000000000' . sprintf('%06d', $txid_number), $n)->payToAddress(intval(round($amount * self::SATOSHI)), AddressFactory::fromString($destination))->get(); $script = $tx->getOutput(0)->getScript(); return ['txid' => $tx->getTxId()->getHex(), 'n' => $n, 'amount' => intval(round($amount * self::SATOSHI)), 'script' => $script->getHex()]; }