Exemplo n.º 1
0
 public function testPayToPubKeyHashSignedTransaction()
 {
     $data = [1 => ['tx' => '010000000869c2997e9dd8ce50f9481a33971f0308e8d525ef8bf079f455fc7936d13f375a1f0000008a47304402202de0d834112506ed10549f751ce142094243390f3e035444f105b4764056314302205dfddc421b377c8b089182ddb3928ce02e73c86e5dfb9e66ca6a98810d7a2ac5014104b3d8c8c5896b0ed9537ccbdcfdf3f05cd4299988c72d078b841e0491bab198702c4befaa3da367c117c7c6217cd478c54b572e13de6ddd22c948f4b66c1562b5ffffffffab9aae4a00230f30795cd928225e9f69f7c0e6146c535b641541cb81aa09b5297b0000008a47304402205604456b1ed6dcae5e5f370568dd71c8bfb44823d583e3fa781ae8117ed831a30220154ee1c49bfca8bd1970953255498cb6bc347de1df267ed1b0f70385bca29184014104b3d8c8c5896b0ed9537ccbdcfdf3f05cd4299988c72d078b841e0491bab198702c4befaa3da367c117c7c6217cd478c54b572e13de6ddd22c948f4b66c1562b5ffffffffc036184c5aa93f74530359251e6ff63ab9e17ce7eb6f5d467c42675e318696e5010000008a47304402206c756a38757443794196d16e887c95b9b769b11c608b425e7580e4fcd8456642022040613fbff5e5412c8aa0c3a91b651a6fe6fcf793596a5e29bbc7bc5d73fc683a014104b3d8c8c5896b0ed9537ccbdcfdf3f05cd4299988c72d078b841e0491bab198702c4befaa3da367c117c7c6217cd478c54b572e13de6ddd22c948f4b66c1562b5ffffffff727107bfb37c254f12b4dfdda9ded7544ea6e44298a657ecb1863e00f88e0700110000008c493046022100c24b9c50820d19457fc5842a124500bf2371397144fc6166bdaa4a94275e9dda022100fc6c59286cfdc2fca4cca62d0a1b4e7dd8125a18aee59e630877f85101aa441a014104b3d8c8c5896b0ed9537ccbdcfdf3f05cd4299988c72d078b841e0491bab198702c4befaa3da367c117c7c6217cd478c54b572e13de6ddd22c948f4b66c1562b5fffffffffb862000126a61dba547524f7302bc68ea177cf00f7a49c5b834c0fd397c4dfe390000008b483045022100c837ec9105ddaa75250a38e9942a624754ecacb025feb024adfa8a77914e6eff0220538a1407d7ed8b7417421113ee29c3d9699f87780907b4121068740f1eb31d68014104b3d8c8c5896b0ed9537ccbdcfdf3f05cd4299988c72d078b841e0491bab198702c4befaa3da367c117c7c6217cd478c54b572e13de6ddd22c948f4b66c1562b5ffffffffdb35b57c65cf0fcdea54bfdebda43942d728001a06a9df0404a07801c87ccd8a090000008b483045022100b00faaa1b6a7c1cbe4c47791e302bbcbf1d4fee54cb3d1195d82ef05df0f8f0702207382b68bb44e8fadb0ae7b44f22a18df93e8e8e000d28c88f4fdff78d92a8316014104b3d8c8c5896b0ed9537ccbdcfdf3f05cd4299988c72d078b841e0491bab198702c4befaa3da367c117c7c6217cd478c54b572e13de6ddd22c948f4b66c1562b5ffffffff539ff8e14dab98db92dbbaff03dda50136470bb30bf9fb5b844eb356bc31362d1f0000008b48304502205e41d2112c190396173562d7957b16e0bba64a40adbe466cfe98778d30d91fa20221009f62ac2e345dbd16639b4269c86f156c050e5747013d2a452cdd8c25b8c9aeb9014104b3d8c8c5896b0ed9537ccbdcfdf3f05cd4299988c72d078b841e0491bab198702c4befaa3da367c117c7c6217cd478c54b572e13de6ddd22c948f4b66c1562b5ffffffffbc0dabbf27d0a58f0e2f5a36c11e7f270737ddc92ef0d8d1baacdeff24f39ed7110000008a473044021f3cfe420bd8a5baca342a3df2501f03165e8b8b76fea6fbc82dd05047c99fcd022100bfa829bce78d4f463abefbba943ea54dbbd931b5d7712e263eaf76d2779cf053014104b3d8c8c5896b0ed9537ccbdcfdf3f05cd4299988c72d078b841e0491bab198702c4befaa3da367c117c7c6217cd478c54b572e13de6ddd22c948f4b66c1562b5ffffffff023011e100000000001976a91431b07b8df3c19573388bb688b4fd89f6233f5d7988acf4f31400000000001976a914d17e062579b71bfe199a80991a253d929f8bd35b88ac00000000', 'inputs' => [["txid" => "5a373fd13679fc55f479f08bef25d5e808031f97331a48f950ced89d7e99c269", "vout" => 31, "scriptPubKey" => "76a914d17e062579b71bfe199a80991a253d929f8bd35b88ac"], ["txid" => "29b509aa81cb4115645b536c14e6c0f7699f5e2228d95c79300f23004aae9aab", "vout" => 123, "scriptPubKey" => "76a914d17e062579b71bfe199a80991a253d929f8bd35b88ac"], ["txid" => "e59686315e67427c465d6febe77ce1b93af66f1e25590353743fa95a4c1836c0", "vout" => 1, "scriptPubKey" => "76a914d17e062579b71bfe199a80991a253d929f8bd35b88ac"], ["txid" => "00078ef8003e86b1ec57a69842e4a64e54d7dea9dddfb4124f257cb3bf077172", "vout" => 17, "scriptPubKey" => "76a914d17e062579b71bfe199a80991a253d929f8bd35b88ac"], ["txid" => "fe4d7c39fdc034b8c5497a0ff07c17ea68bc02734f5247a5db616a12002086fb", "vout" => 57, "scriptPubKey" => "76a914d17e062579b71bfe199a80991a253d929f8bd35b88ac"], ["txid" => "8acd7cc80178a00404dfa9061a0028d74239a4bddebf54eacd0fcf657cb535db", "vout" => 9, "scriptPubKey" => "76a914d17e062579b71bfe199a80991a253d929f8bd35b88ac"], ["txid" => "2d3631bc56b34e845bfbf90bb30b473601a5dd03ffbadb92db98ab4de1f89f53", "vout" => 31, "scriptPubKey" => "76a914d17e062579b71bfe199a80991a253d929f8bd35b88ac"], ["txid" => "d79ef324ffdeacbad1d8f02ec9dd3707277f1ec1365a2f0e8fa5d027bfab0dbc", "vout" => 17, "scriptPubKey" => "76a914d17e062579b71bfe199a80991a253d929f8bd35b88ac"]], 'outputs' => ["1L6hCPsCq7C5rNzq7wSyu4eaQCq8LeipmG" => 0.01373172]]];
     foreach ($data as $test) {
         $this->assertTrue(RawTransaction::validate_signed_transaction($test['tx'], json_encode($test['inputs']), '00'));
     }
 }
<?php

use BitWasp\BitcoinLib\RawTransaction;
require_once __DIR__ . '/../vendor/autoload.php';
// Supply a raw transaction to verify
$raw_tx = '01000000010a74a5750934ce563a9f18812b73dea945e3796d08be5e2c7e817197b4b0665b000000006a47304402203e2b56c1728f6cdcd531d006f7a17e6608513432113290229762de1d1bc0e76902205a9a41c196845d40dc98b67641fa2a1ae52f714094c9ad1e6b99514fd567d187012103161f0ec2a99876733c7b7f63bdb3cede0980e39f18abd50adad2774bd8fe0917ffffffff02426f0f00000000001976a91402a82b3afaff3c4113d86005f7029301c770c61188acbd0e3f0e010000001976a9146284bcf16e0507a35d28c1608ee1708ed26c839488ac00000000';
// Look up the TxIn transactions to learn about the scriptPubKey..
$json_string = '[{"txid":"5b66b0b49771817e2c5ebe086d79e345a9de732b81189f3a56ce340975a5740a","vout":0,"scriptPubKey":"76a91416489ece44cc457e14f4e882fd9a0ae082fdf6c688ac"}]';
// Perform signature validation!
$verify = RawTransaction::validate_signed_transaction($raw_tx, $json_string);
var_dump($verify);
Exemplo n.º 3
0
 public function handle_order_tx_submission($order, $incoming_tx, $user_bip32_key)
 {
     $this->CI->load->model('transaction_cache_model');
     $currently_unsigned = strlen($order['partially_signed_transaction']) == 0;
     if ($currently_unsigned) {
         $start_tx = trim($order['unsigned_transaction']);
     } else {
         $start_tx = trim($order['partially_signed_transaction']);
     }
     $json = str_replace("'", '', $order['json_inputs']);
     $decode_current_tx = \BitWasp\BitcoinLib\RawTransaction::decode($start_tx);
     $decode_incoming_tx = \BitWasp\BitcoinLib\RawTransaction::decode($incoming_tx);
     // Does incoming tx match expected spend?
     $check = $this->CI->transaction_cache_model->check_if_expected_spend($decode_incoming_tx['vout'], $order['id']);
     if ($check !== $order['address']) {
         return 'Invalid transaction.';
     }
     // General check that signatures match tx
     $validate = \BitWasp\BitcoinLib\RawTransaction::validate_signed_transaction($incoming_tx, $json);
     if ($validate == FALSE) {
         return 'Invalid signature.';
     }
     $decode_redeem_script = \BitWasp\BitcoinLib\RawTransaction::decode_redeem_script($order['redeemScript']);
     if (!$currently_unsigned and $user_bip32_key['provider'] == 'JS') {
         // Need to build the sig from this tx into the last.
         $copy = $decode_incoming_tx;
         foreach ($copy['vin'] as $i => &$input) {
             $script = explode(" ", $input['scriptSig']['asm']);
             $sig1 = \BitWasp\BitcoinLib\RawTransaction::_encode_vint(strlen($script[1]) / 2) . $script[1];
             $old_script = explode(" ", $decode_current_tx['vin'][$i]['scriptSig']['asm']);
             $sig2 = \BitWasp\BitcoinLib\RawTransaction::_encode_vint(strlen($old_script[1]) / 2) . $old_script[1];
             $redeem_script = '4c' . \BitWasp\BitcoinLib\RawTransaction::_encode_vint(strlen($order['redeemScript']) / 2) . $order['redeemScript'];
             $input['scriptSig']['hex'] = '00' . $sig1 . $sig2 . $redeem_script;
         }
         $incoming_tx = \BitWasp\BitcoinLib\RawTransaction::encode($copy);
         // Now need to reorder sigs!
         $assoc = $this->associate_sigs_with_keys($incoming_tx, $json, $this->CI->bw_config->currencies[0]['crypto_magic_byte']);
         foreach ($copy['vin'] as $i => &$input) {
             $input['scriptSig']['hex'] = \BitWasp\BitcoinLib\RawTransaction::_apply_sig_scripthash_multisig($assoc[$i], array('public_keys' => $decode_redeem_script['keys'], 'script' => $order['redeemScript']));
         }
         $incoming_tx = \BitWasp\BitcoinLib\RawTransaction::encode($copy);
         $decode_incoming_tx = \BitWasp\BitcoinLib\RawTransaction::decode($incoming_tx);
     }
     // Compare signatures!
     $old_sig_map = $this->associate_sigs_with_keys($start_tx, $json, $this->CI->bw_config->currencies[0]['crypto_magic_byte']);
     // Now check current signatures against users key. submittee must have signed.
     $key_sig_map = $this->associate_sigs_with_keys($incoming_tx, $json, $this->CI->bw_config->currencies[0]['crypto_magic_byte']);
     foreach ($key_sig_map as $i => $input_sig_map) {
         // If the number of sigs hasn't increased, or no sig from the current user exists..
         if (count($old_sig_map) > 0 && count($input_sig_map) <= count($old_sig_map[$i]) or !isset($input_sig_map[$user_bip32_key['public_key']])) {
             return 'Incorrect signature!';
         }
     }
     // Broadcast tx if fully signed!
     if (!$currently_unsigned) {
         $this->CI->transaction_cache_model->to_broadcast($incoming_tx);
         $this->sendrawtransaction($incoming_tx);
     }
     return TRUE;
 }
 public function testSigLowS()
 {
     $rawWithHighS = "01000000011c615595ac93432de87bcc519f2ddffce1a5f88bd4ec3e586c56e05b35e13767000000006c493046022100e1dcb3bd5ed0cdaede2ebcab940b3c93a9cd76dbb715a31e14b1a7ca25be74a7022100ff271e52db90a34e432d9993328eb580070a895795a067ede23201a97de13c1e012102b8caae0de72e5d1904366d3393b4f81d2504da3ab2906c440deab0c442461846ffffffff01983a0000000000001976a914f444a269154eb560bebd424c2b406f1789ed49d688ac00000000";
     $json_inputs = json_encode(array(array('txid' => '6737e1355be0566c583eecd48bf8a5e1fcdf2d9f51cc7be82d4393ac9555611c', 'vout' => 0, 'scriptPubKey' => '76a914' . '7e3f939e8ded8c0d93695310d6d481ae5da39616' . '88ac')));
     // allowHighS = false
     $this->assertFalse(RawTransaction::validate_signed_transaction($rawWithHighS, $json_inputs, null, null, false));
     // allowHighS = true
     $this->assertTrue(RawTransaction::validate_signed_transaction($rawWithHighS, $json_inputs, null, null, true));
 }