/**
  * @param int $m
  * @param PublicKeyInterface[] $keys
  * @param bool|true $sort
  * @return ScriptCreator|Script
  */
 public function multisig($m, array $keys = [], $sort = true)
 {
     $n = count($keys);
     if ($m > $n) {
         throw new \LogicException('Required number of sigs exceeds number of public keys');
     }
     if ($n > 16) {
         throw new \LogicException('Number of public keys is greater than 16');
     }
     if ($sort) {
         $keys = Buffertools::sort($keys);
     }
     $opM = \BitWasp\Bitcoin\Script\encodeOpN($m);
     $opN = \BitWasp\Bitcoin\Script\encodeOpN($n);
     $script = ScriptFactory::create();
     foreach ($keys as $key) {
         if (!$key instanceof PublicKeyInterface) {
             throw new \LogicException('Values in $keys[] must be a PublicKey');
         }
         $script->push($key->getBuffer());
     }
     $keyBuf = $script->getScript()->getBuffer();
     $script = new Script(new Buffer(chr($opM) . $keyBuf->getBinary() . chr($opN) . chr(Opcodes::OP_CHECKMULTISIG)));
     return $script;
 }
 protected function addressFromScriptHex($script_hex)
 {
     $address = null;
     try {
         $script = ScriptFactory::fromHex($script_hex);
         $classifier = new InputClassifier($script);
         if ($classifier->isPayToPublicKeyHash()) {
             $decoded = $script->getScriptParser()->decode();
             $public_key = PublicKeyFactory::fromHex($decoded[1]->getData());
             $address = $public_key->getAddress()->getAddress();
         } else {
             if ($classifier->isPayToScriptHash()) {
                 $decoded = $script->getScriptParser()->decode();
                 $hex_buffer = $decoded[count($decoded) - 1]->getData();
                 $sh_address = new ScriptHashAddress(ScriptFactory::fromHex($hex_buffer)->getScriptHash());
                 $address = $sh_address->getAddress();
             } else {
                 // unknown script type
                 Log::debug("Unable to classify script " . substr($hex, 0, 20) . "...");
             }
         }
     } catch (Exception $e) {
         Log::error("failed to get address from script. " . $e->getMessage());
     }
     return $address;
 }
 /**
  * @param EcAdapterInterface $ecAdapter
  * @param ScriptInterface $outputScript
  * @param ScriptInterface $redeemScript
  */
 public function __construct(EcAdapterInterface $ecAdapter, ScriptInterface $outputScript, ScriptInterface $redeemScript = null)
 {
     /*
             $classifier = new OutputClassifier($outputScript);
             $this->scriptType = $this->prevOutType = $classifier->classify();
     
             // Get the handler for this script type, and reclassify p2sh
             if ($this->scriptType === OutputClassifier::PAYTOSCRIPTHASH) {
                 if (null === $redeemScript) {
                     throw new \InvalidArgumentException('Redeem script is required when output is P2SH');
                 }
     
                 $handler = new ScriptHash($redeemScript);
                 $this->scriptType = $handler->classification();
             } else {
                 $handler = ScriptFactory::info($outputScript);
             }
     */
     $handler = ScriptFactory::info($outputScript, $redeemScript);
     $this->scriptType = $this->prevOutType = $handler->classification();
     if ($handler instanceof ScriptHash) {
         $this->scriptType = $handler->getInfo()->classification();
     }
     // Gather public keys from redeemScript / outputScript
     $this->ecAdapter = $ecAdapter;
     $this->redeemScript = $redeemScript;
     $this->prevOutScript = $outputScript;
     $this->scriptInfo = $handler;
     // According to scriptType, extract public keys
     $this->publicKeys = $this->scriptInfo->getKeys();
 }
Exemple #4
0
 /**
  * @param TransactionSignatureInterface[] $signatures
  * @param PublicKeyInterface[] $publicKeys
  * @return Script|ScriptInterface
  */
 public function makeScriptSig(array $signatures = [], array $publicKeys = [])
 {
     $newScript = new Script();
     if (count($signatures) === $this->getRequiredSigCount()) {
         $newScript = ScriptFactory::sequence([$signatures[0]->getBuffer()]);
     }
     return $newScript;
 }
 /**
  * ScriptValidation constructor.
  * @param bool $active
  * @param int $flags
  */
 public function __construct($active = true, $flags = InterpreterInterface::VERIFY_NONE)
 {
     if (!is_bool($active)) {
         throw new \InvalidArgumentException('ScriptValidationState: $active should be bool');
     }
     $this->active = $active;
     $this->consensus = ScriptFactory::consensus($flags);
 }
 /**
  * @param array $signatures
  * @param array $publicKeys
  * @return Script|ScriptInterface
  */
 public function makeScriptSig(array $signatures = [], array $publicKeys = [])
 {
     $newScript = new Script();
     if (count($publicKeys) > 0 && count($signatures) === $this->getRequiredSigCount()) {
         $newScript = ScriptFactory::scriptSig()->payToPubKeyHash($signatures[0], $publicKeys[0]);
     }
     return $newScript;
 }
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()]));
 }
Exemple #8
0
 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;
 }
Exemple #9
0
 /**
  * @param UtxoView $view
  * @param TransactionInterface $tx
  * @return int
  */
 public function getP2shSigOps(UtxoView $view, TransactionInterface $tx)
 {
     if ($tx->isCoinbase()) {
         return 0;
     }
     $nSigOps = 0;
     $scriptPubKey = ScriptFactory::scriptPubKey();
     for ($i = 0, $c = count($tx->getInputs()); $i < $c; $i++) {
         $input = $tx->getInput($i);
         $outputScript = $view->fetchByInput($input)->getOutput()->getScript();
         if ($scriptPubKey->classify($outputScript)->isPayToScriptHash()) {
             $nSigOps += $outputScript->countP2shSigOps($input->getScript());
         }
     }
     return $nSigOps;
 }
 /**
  * TxSignerContext constructor.
  * @param EcAdapterInterface $ecAdapter
  * @param ScriptInterface $outputScript
  * @param ScriptInterface|null $redeemScript
  */
 public function __construct(EcAdapterInterface $ecAdapter, ScriptInterface $outputScript, ScriptInterface $redeemScript = null)
 {
     $handler = ScriptFactory::info($outputScript, $redeemScript);
     $handler->getKeys();
     $this->scriptType = $this->prevOutType = $handler->classification();
     if ($handler instanceof ScriptHash) {
         $this->scriptType = $handler->getInfo()->classification();
     }
     // Gather public keys from redeemScript / outputScript
     $this->ecAdapter = $ecAdapter;
     $this->redeemScript = $redeemScript;
     $this->prevOutScript = $outputScript;
     $this->scriptInfo = $handler;
     // According to scriptType, extract public keys
     $this->publicKeys = $this->scriptInfo->getKeys();
 }
 /**
  * @param ScriptInterface $script
  * @param ScriptInterface|null $redeemScript
  * @return \BitWasp\Bitcoin\Script\ScriptInfo\ScriptInfoInterface
  */
 public function load(ScriptInterface $script, ScriptInterface $redeemScript = null)
 {
     $classifier = ScriptFactory::scriptPubKey()->classify($script);
     if ($classifier->isPayToScriptHash()) {
         if (null === $redeemScript) {
             throw new \InvalidArgumentException('Redeem script is required when output is P2SH');
         }
         $handler = new ScriptHash($redeemScript);
     } elseif ($classifier->isMultisig()) {
         $handler = new Multisig($script);
     } elseif ($classifier->isPayToPublicKey()) {
         $handler = new PayToPubkey($script);
     } elseif ($classifier->isPayToPublicKeyHash()) {
         $handler = new PayToPubkeyHash($script);
     } else {
         throw new \InvalidArgumentException('Unparsable script type');
     }
     return $handler;
 }
Exemple #12
0
 /**
  * @param int|string $m
  * @param string $path
  * @param array $keys
  * @param HierarchicalKeySequence $sequences
  * @param bool $sort
  */
 public function __construct($m, $path, array $keys, HierarchicalKeySequence $sequences, $sort = false)
 {
     if (count($keys) < 1) {
         throw new \RuntimeException('Must have at least one HierarchicalKey for Multisig HD Script');
     }
     // Sort here to guarantee calls to getKeys() returns keys in the same order as the redeemScript.
     if ($sort) {
         $keys = $this->sortHierarchicalKeys($keys);
     }
     foreach ($keys as $key) {
         $this->keys[] = $key;
     }
     $this->m = $m;
     $this->path = $path;
     $this->sort = $sort;
     $this->sequences = $sequences;
     $this->redeemScript = ScriptFactory::p2sh()->multisig($m, array_map(function (HierarchicalKey $key) {
         return $key->getPublicKey();
     }, $this->keys));
 }
<?php

require "../vendor/autoload.php";
use BitWasp\Buffertools\Buffer;
use BitWasp\Bitcoin\Key\PrivateKeyFactory;
use BitWasp\Bitcoin\Script\ScriptFactory;
use BitWasp\Bitcoin\Transaction\OutPoint;
use BitWasp\Bitcoin\Transaction\TransactionFactory;
use BitWasp\Bitcoin\Script\WitnessProgram;
use BitWasp\Bitcoin\Bitcoin;
$wif = 'QP3p9tRpTGTefG4a8jKoktSWC7Um8qzvt8wGKMxwWyW3KTNxMxN7';
$s = \BitWasp\Bitcoin\Network\NetworkFactory::bitcoinSegnet();
Bitcoin::setNetwork($s);
$ec = \BitWasp\Bitcoin\Bitcoin::getEcAdapter();
$key = PrivateKeyFactory::fromWif($wif);
echo $key->getPublicKey()->getAddress()->getAddress() . PHP_EOL;
$outpoint = new OutPoint(Buffer::hex('703f50920bff10e1622117af81b622d8bbd625460e61909cc3f8b8ee78a59c0d', 32), 0);
$scriptPubKey = ScriptFactory::scriptPubKey()->payToPubKeyHash($key->getPublicKey());
$value = 100000000;
$txOut = new \BitWasp\Bitcoin\Transaction\TransactionOutput($value, $scriptPubKey);
$destination = new WitnessProgram(0, $key->getPubKeyHash());
$p2sh = new \BitWasp\Bitcoin\Script\P2shScript($destination->getScript());
$tx = TransactionFactory::build()->spendOutPoint($outpoint)->output(95590000, $p2sh->getOutputScript())->get();
$signed = new \BitWasp\Bitcoin\Transaction\Factory\Signer($tx, $ec);
$signed->sign(0, $key, $txOut);
$ss = $signed->get();
echo $ss->getHex() . PHP_EOL;
 /**
  * @param ScriptInterface $inputScript
  * @param ScriptInterface $redeemScript
  * @return ScriptInterface
  */
 public function payToScriptHash(ScriptInterface $inputScript, ScriptInterface $redeemScript)
 {
     return ScriptFactory::create($inputScript->getBuffer())->push($redeemScript->getBuffer())->getScript();
 }
 /**
  * @param AddressInterface $address
  * @param NetworkInterface $network
  * @return \React\Promise\Promise
  */
 public function addressListUnspent(AddressInterface $address, NetworkInterface $network = null)
 {
     return $this->client->request('blockchain.address.listunspent', [$address->getAddress($network)])->then(function (Response $response) use($address) {
         return array_map(function (array $value) use($address) {
             return new Utxo($value['tx_hash'], $value['tx_pos'], new TransactionOutput($value['value'], ScriptFactory::scriptPubKey()->payToAddress($address)));
         }, $response->getResult());
     });
 }
 /**
  * Create an output paying $value to an Address.
  *
  * @param AddressInterface $address
  * @param $value
  * @return $this
  */
 public function payToAddress(AddressInterface $address, $value)
 {
     // Create Script from address, then create an output.
     $this->addOutput(new TransactionOutput($value, ScriptFactory::scriptPubKey()->payToAddress($address)));
     return $this;
 }
 /**
  * @param TransactionInterface $tx
  * @return Transaction
  */
 public function fixTransaction(Peer $sender, TransactionInterface $tx, &$wasMalleated = false)
 {
     $c = count($tx->getInputs());
     $new = new TransactionInputCollection();
     for ($i = 0; $i < $c; $i++) {
         $input = $tx->getInput($i);
         $script = $input->getScript();
         $classify = ScriptFactory::scriptSig()->classify($input->getScript());
         $this->inputs++;
         if ($classify->isPayToPublicKeyHash()) {
             $parsed = $input->getScript()->getScriptParser()->parse();
             $txSig = TransactionSignatureFactory::fromHex($parsed[0]);
             $txSig = $this->fixSig($sender, $txSig, $wasMalleated);
             $script = ScriptFactory::create()->push($txSig->getBuffer())->push($parsed[1])->getScript();
         }
         $new->addInput(new TransactionInput($input->getTransactionId(), $input->getVout(), $script, $input->getSequence()));
     }
     return new Transaction($tx->getVersion(), $new, $tx->getOutputs(), $tx->getLockTime());
 }
 /**
  * @return ScriptInterface
  */
 public function getScript()
 {
     return ScriptFactory::create()->int($this->version)->push($this->program)->getScript();
 }
Exemple #19
0
 /**
  * @param array $signatures
  * @param array $publicKeys
  * @return Script|ScriptInterface
  */
 public function makeScriptSig(array $signatures = [], array $publicKeys = [])
 {
     $newScript = new Script();
     if (count($signatures) > 0) {
         $newScript = ScriptFactory::scriptSig()->multisig($signatures);
     }
     return $newScript;
 }
Exemple #20
0
    $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)));
        }
Exemple #21
0
 /**
  * @param TransactionSignatureInterface[] $signatures
  * @param PublicKeyInterface[] $publicKeys
  * @return Script|ScriptInterface
  */
 public function makeScriptSig(array $signatures = [], array $publicKeys = [])
 {
     $newScript = new Script();
     if (count($signatures) > 0) {
         $sequence = [Opcodes::OP_0];
         foreach ($signatures as $sig) {
             $sequence[] = $sig->getBuffer();
         }
         $newScript = ScriptFactory::sequence($sequence);
     }
     return $newScript;
 }
 /**
  * @param Buffer $secret
  * @param PublicKeyInterface $a1
  * @param PublicKeyInterface $a2
  * @param PublicKeyInterface $b1
  * @param PublicKeyInterface $b2
  * @return ScriptInterface
  */
 public function payToLightningChannel(Buffer $secret, PublicKeyInterface $a1, PublicKeyInterface $a2, PublicKeyInterface $b1, PublicKeyInterface $b2)
 {
     return ScriptFactory::create()->op('OP_DEPTH')->op('OP_3')->op('OP_EQUAL')->op('OP_IF')->op('OP_HASH160')->push(Hash::sha256ripe160($secret))->op('OP_EQUALVERIFY')->concat(ScriptFactory::scriptPubKey()->multisig(2, [$a1, $b1]))->op('OP_ELSE')->concat(ScriptFactory::scriptPubKey()->multisig(2, [$a2, $b2]))->op('OP_ENDIF')->getScript();
 }
<?php

require "../vendor/autoload.php";
use BitWasp\Bitcoin\Bitcoin;
use BitWasp\Bitcoin\Key\PrivateKeyFactory;
use BitWasp\Bitcoin\Script\ScriptFactory;
use BitWasp\Bitcoin\Transaction\Factory\TxSigner;
use BitWasp\Bitcoin\Transaction\Factory\TxBuilder;
$ecAdapter = Bitcoin::getEcAdapter();
// Two users independently create private keys.
$pk1 = PrivateKeyFactory::fromHex('421c76d77563afa1914846b010bd164f395bd34c2102e5e99e0cb9cf173c1d87');
$pk2 = PrivateKeyFactory::fromHex('f7225388c1d69d57e6251c9fda50cbbf9e05131e5adb81e5aa0422402f048162');
// They exchange public keys, and a multisignature address is made.
$redeemScript = ScriptFactory::scriptPubKey()->multisig(2, [$pk1->getPublicKey(), $pk2->getPublicKey()]);
$os = ScriptFactory::scriptPubKey()->payToScriptHash($redeemScript);
// The address is funded with a transaction (fake, for the purposes of this script).
// You would do getrawtransaction normall
$fundTx = (new TxBuilder())->input('4141414141414141414141414141414141414141414141414141414141414141', 0)->output(50, $os)->get();
// One party wants to spend funds. He creates a transaction spending the funding tx to his address.
$spendTx = (new TxBuilder())->spendOutputFrom($fundTx, 0)->payToAddress(50, $pk1->getAddress())->get();
// Two parties sign the transaction (can be done in steps)
$signer = new TxSigner($ecAdapter, $spendTx);
$signer->sign(0, $pk1, $os, $redeemScript)->sign(0, $pk2, $os, $redeemScript);
$rawTx = $signer->get()->getHex();
echo "Fully signed transaction: " . $signer->get()->getHex() . "\n";
 /**
  * @param AddressInterface $address
  * @param $value
  * @return PaymentRequestBuilder
  */
 public function addAddressPayment(AddressInterface $address, $value)
 {
     $script = ScriptFactory::scriptPubKey()->payToAddress($address);
     $output = new TransactionOutput($value, $script);
     return $this->addOutput($output);
 }
<?php

require_once "../vendor/autoload.php";
use BitWasp\Bitcoin\Script\ScriptFactory;
use BitWasp\Bitcoin\Transaction\Transaction;
use BitWasp\Bitcoin\Script\Script;
$ec = \BitWasp\Bitcoin\Bitcoin::getEcAdapter();
$scriptSig = ScriptFactory::create()->int(1)->int(1)->getScript();
$scriptPubKey = ScriptFactory::create()->op('OP_ADD')->int(2)->op('OP_EQUAL')->getScript();
echo "Formed script: " . $scriptSig->getHex() . " " . $scriptPubKey->getHex() . "\n";
$flags = new \BitWasp\Bitcoin\Flags(0);
$i = new \BitWasp\Bitcoin\Script\Interpreter\Interpreter($ec, new Transaction(), $flags);
$result = $i->verify($scriptSig, $scriptPubKey, 0);
echo "Script result: " . ($result ? 'true' : 'false') . "\n";
Exemple #26
0
<?php

require_once "../vendor/autoload.php";
use BitWasp\Bitcoin\Script\ScriptFactory;
$script = ScriptFactory::fromHex($argv[1]);
print_r($script->getScriptParser()->getHumanReadable());
Exemple #27
0
 /**
  * P2shScript constructor.
  * @param ScriptInterface $script
  * @param Opcodes|null $opcodes
  */
 public function __construct(ScriptInterface $script, Opcodes $opcodes = null)
 {
     parent::__construct($script->getBuffer(), $opcodes);
     $this->outputScript = ScriptFactory::scriptPubKey()->payToScriptHash($script);
 }
use BitWasp\Bitcoin\Key\PrivateKeyFactory;
use BitWasp\Bitcoin\Key\PublicKeyFactory;
use BitWasp\Bitcoin\Address\AddressFactory;
use BitWasp\Bitcoin\Rpc\RpcFactory;
$network = Bitcoin::getNetwork();
$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());
$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);
 /**
  * @param TransactionSignatureInterface $signature
  * @return Script
  */
 public function payToPubKey(TransactionSignatureInterface $signature)
 {
     return ScriptFactory::create()->push($signature->getBuffer());
 }
 protected function generateComposedTransactionModel($request_id, PaymentAddress $payment_address, $destination, $float_quantity, $asset, $float_fee, $float_btc_dust_size, $is_sweep)
 {
     // check to see if this signed transaction already exists in the database
     $composed_transaction_model = $this->composed_transaction_repository->getComposedTransactionByRequestID($request_id);
     if ($composed_transaction_model === null) {
         // build the signed transactions
         $change_address_collection = null;
         $built_transaction_to_send = $this->buildSignedTransactionToSend($payment_address, $destination, $float_quantity, $asset, $change_address_collection, $float_fee, $float_btc_dust_size, $is_sweep);
         // get the utxo identifiers
         $utxo_identifiers = $this->buildUTXOIdentifiersFromUTXOs($built_transaction_to_send->getInputUtxos());
         // store the signed transactions to the database cache
         $signed_transaction_hex = $built_transaction_to_send->getTransactionHex();
         $txid = $built_transaction_to_send->getTxId();
         $composed_transaction_model = $this->composed_transaction_repository->storeOrFetchComposedTransaction($request_id, $txid, $signed_transaction_hex, $utxo_identifiers);
         // mark each UTXO as spent
         $this->txo_repository->updateByTXOIdentifiers($utxo_identifiers, ['spent' => 1]);
         // create the new UTXOs that belong to any of our addresses
         $account = AccountHandler::getAccount($payment_address);
         $this->clearPaymentAddressInfoCache();
         foreach ($built_transaction_to_send->getOutputUtxos() as $output_utxo) {
             if ($output_utxo['amount'] <= 0) {
                 // don't store OP_RETURN UTXOs with no value
                 continue;
             }
             // create new UTXO
             $utxo_destination_address = AddressFactory::fromOutputScript(ScriptFactory::fromHex($output_utxo['script']))->getAddress();
             list($found_payment_address, $found_account) = $this->loadPaymentAddressInfo($utxo_destination_address);
             if ($found_payment_address) {
                 $this->txo_repository->create($found_payment_address, $found_account, ['txid' => $output_utxo['txid'], 'n' => $output_utxo['n'], 'amount' => $output_utxo['amount'], 'script' => $output_utxo['script'], 'type' => TXO::UNCONFIRMED, 'spent' => 0, 'green' => 1]);
             }
         }
     }
     return $composed_transaction_model;
 }