public function testMnemonicDecode() { $mnemonic = trim('teach start paradise collect blade chill gay childhood creek picture creator branch'); $known_seed = 'dcb85458ec2fcaaac54b71fba90bd4a5'; $known_secexp = '74b1f6c0caae485b4aeb2f26bab3cabdec4f0b432751bd454fe11b2d2907cbda'; $known_mpk = '819519e966729f31e1855eb75133d9e7f0c31abaadd8f184870d62771c62c2e759406ace1dee933095d15e4c719617e252f32dc0465393055f867aee9357cd52'; $known_addresses = ["", "", "", "", ""]; $seed = Electrum::decode_mnemonic($mnemonic); $this->assertEquals($seed, $known_seed); $mpk = Electrum::generate_mpk($seed); $this->assertEquals($mpk, $known_mpk); $secexp = Electrum::stretch_seed($seed); $secexp = $secexp['seed']; $this->assertEquals($secexp, $known_secexp); $count_known_addresses = count($known_addresses); for ($i = 0; $i < $count_known_addresses; $i++) { $privkey = Electrum::generate_private_key($secexp, $i, 0); $address_private_deriv = BitcoinLib::private_key_to_address($privkey, $this->magic_byte); $public_deriv = Electrum::public_key_from_mpk($mpk, $i); $address_private_deriv = BitcoinLib::public_key_to_address($public_deriv, $this->magic_byte); } }
<?php use BitWasp\BitcoinLib\BitcoinLib; use BitWasp\BitcoinLib\RawTransaction; require_once __DIR__ . '/../vendor/autoload.php'; while (!isset($redeem_script)) { echo "Enter redeem script: "; $line = trim(fgets(STDIN)); $decode_redeem_script = RawTransaction::decode_redeem_script($line); if ($decode_redeem_script == FALSE) { echo "[ERROR]- Not a valid script!\n"; unset($decode_redeem_script); } else { $redeem_script = $line; echo "Learned about {$decode_redeem_script['m']} of {$decode_redeem_script['n']} address: " . BitcoinLib::public_key_to_address($redeem_script, '05') . "\n"; } } echo "Enter WIF encoded private keys: \n (1): "; $private_keys = array(); while ("\n" != ($line = fgets(STDIN))) { $line = trim($line); $t = BitcoinLib::validate_WIF($line, '80'); var_dump($t); if (BitcoinLib::validate_WIF($line, '80') == TRUE) { $private_keys[] = $line; } else { echo "Not a valid private key.\n"; } echo " (" . (count($private_keys) + 1) . "): "; } // Initialize wallet
<?php use BitWasp\BitcoinLib\BitcoinLib; require_once __DIR__ . '/../vendor/autoload.php'; $magic_byte = '00'; $keypair = BitcoinLib::get_new_key_set($magic_byte); echo "Key pair: \n"; print_r($keypair); echo "\n"; $compress = BitcoinLib::compress_public_key($keypair['pubKey']); echo "Compressed public key: {$compress} \n"; $decompress = BitcoinLib::decompress_public_key($compress); echo "Decompressed key info: \n"; print_r($decompress); echo "\n"; $address = BitcoinLib::public_key_to_address($compress, $magic_byte); echo "decoding {$address}\n"; echo BitcoinLib::base58_decode($address); echo "\n\n"; $sc = '5357'; $ad = BitcoinLib::public_key_to_address($sc, '05'); echo $ad . "\n";
/** * Address from MPK * * Generate an address from the $mpk, and $iteration. This function * uses the public_key_from_mpk() function, and converts the result * to the bitcoin address. * * @param string $mpk - master public key * @param int $sequence - pubkey sequence # to derive * @param string $magic_byte for address * @param int $change - 0 for regular sequence, 1 for change sequence * @param bool $compressed - return the compressed address * @return string */ public static function address_from_mpk($mpk, $sequence, $magic_byte, $change = 0, $compressed = false) { $change = $change == 0 ? 0 : 1; $public_key = self::public_key_from_mpk($mpk, $sequence, $change, $compressed); $address = BitcoinLib::public_key_to_address($public_key, $magic_byte); return $address; }
public function get_user_key_usage($user_id) { $query = $this->db->get_where('bip32_user_keys', array('user_id' => $user_id))->result_array(); if (count($query) > 0) { foreach ($query as &$row) { $row['address'] = \BitWasp\BitcoinLib\BitcoinLib::public_key_to_address($row['public_key'], $this->bw_config->currencies[0]['crypto_magic_byte']); } } return $query; }
/** * Details * Buyer URI: purchases/details/<order_id> * Vendor URI: orders/details/<order_id> * Admin URI: admin/orders/<order_id> * * Order details page. Shows buyer/vendor/admin the details of the * the order. * * @param int $order_id */ public function details($order_id) { if (!(is_numeric($order_id) && $order_id >= 0)) { redirect(''); } $data['order'] = $this->order_model->get($order_id); // no restriction on buyer/vendor if ($data['order'] == FALSE) { redirect(''); } // Work out if the user is allowed to view this order. if (!$this->current_user->user_role == 'Admin' && !($this->current_user->user_id == $data['order']['buyer']['id']) && !($this->current_user->user_id == $data['order']['vendor']['id'])) { redirect(''); } // Only allow access when the order is confirmed by the buyer. if ($data['order']['progress'] == '0') { redirect(''); } if ($this->current_user->user_role == 'Buyer') { $data['action_page'] = 'purchases/details/' . $order_id; $data['cancel_page'] = 'purchases'; } else { if ($this->current_user->user_role == 'Vendor') { $data['action_page'] = 'orders/details/' . $order_id; $data['cancel_page'] = 'orders'; } else { if ($this->current_user->user_role == 'Admin') { $data['action_page'] = 'admin/order/' . $order_id; $data['cancel_page'] = 'admin/orders'; } } } $this->load->model('transaction_cache_model'); $this->load->model('bip32_model'); $this->load->model('review_model'); $child_key_id = $data['order'][strtolower($this->current_user->user_role) . '_public_key']; $data['my_multisig_key'] = $this->bip32_model->get_child_key($child_key_id); $data['wallet_salt'] = $this->users_model->wallet_salt($this->current_user->user_id); $this->load->library('bw_bitcoin'); $html = $this->bw_bitcoin->js_html($data['order']['redeemScript'], $data['order']['unsigned_transaction']); if (is_array($data['my_multisig_key'])) { $data['signing_info'] = array('parent_extended_public_key' => $data['my_multisig_key']['parent_extended_public_key'], 'extended_public_key' => $data['my_multisig_key']['extended_public_key'], 'bip32_provider' => $data['my_multisig_key']['provider'], 'full_key_index' => "m/0'/0/" . $data['my_multisig_key']['key_index'], 'key_index' => "m/0'/0/" . $data['my_multisig_key']['key_index'], 'public_key' => $data['my_multisig_key']['public_key'], 'partially_signed_transaction' => $data['order']['partially_signed_transaction'], 'unsigned_transaction' => $data['order']['unsigned_transaction'], 'wallet_salt' => $data['wallet_salt'], 'crafted_html' => $html); $ident = strtolower($data['my_multisig_key']['provider']); $this->_partial("sign_form_output", "orders/details_form_" . $ident); if ($ident == 'js') { $data['header_meta'] = $this->load->view('orders/add_signature_js', $data['signing_info'], TRUE); $this->load->model('users_model'); } elseif ($ident == 'onchain') { $this->load->library('onchainlib'); $tx_crc = substr(hash('sha256', $data['order']['partially_signed_transaction'] == '' ? $data['order']['unsigned_transaction'] : $data['order']['partially_signed_transaction']), 0, 8); $data['onchain_sign'] = $this->onchainlib->sign_request($data['order']['id'], $tx_crc); } } // Only allow a vendor to refund, if the progress is either 3 or 4 (not yet dispatched) $data['can_refund'] = ($this->current_user->user_role == 'Vendor' and in_array($data['order']['progress'], array('3', '4'))); $data['display_sign_form'] = (bool) (($data['order']['vendor_selected_upfront'] == '1' or $data['order']['vendor_selected_escrow'] == '0') and $data['order']['progress'] == '3' && $this->current_user->user_role == 'Buyer' or $data['order']['progress'] == '4' && $this->current_user->user_role == 'Vendor' or ($data['order']['vendor_selected_escrow'] == '1' and $data['order']['vendor_selected_upfront'] == '0' and $data['order']['progress'] == '4' && $this->current_user->user_role == 'Vendor' or $data['order']['progress'] == '5' && $this->current_user->user_role == 'Buyer') or ($data['order']['progress'] == '6' and $data['order']['partially_signed_transaction'] == '' or $data['order']['partially_signed_transaction'] !== '' and $data['order']['partially_signing_user_id'] !== $this->current_user->user_id) or ($data['order']['progress'] == '8' and $data['order']['partially_signed_transaction'] == '' or $data['order']['partially_signed_transaction'] !== '' and $data['order']['partially_signing_user_id'] !== $this->current_user->user_id)); $data['display_sign_msg'] = $data['order']['partially_signed_transaction'] == '' ? 'Please add first signature.' : 'Please sign to complete transaction.'; // Only allow access to the form handling script if the form is allowed to be displayed. if ($data['display_sign_form'] == TRUE) { // JS if ($this->input->post('submit_js_signed_transaction') == 'Submit Transaction') { if ($this->form_validation->run('submit_js_signed_transaction') == TRUE) { $check = $this->bw_bitcoin->handle_order_tx_submission($data['order'], $this->input->post('js_transaction'), $data['my_multisig_key']); if (is_string($check)) { $data['invalid_transaction_error'] = $check; } else { if ($check == TRUE) { if (strlen($data['order']['partially_signed_transaction']) > 0) { $this->current_user->set_return_message('Transaction has been submitted, and will be processed shortly.', 'success'); redirect($data['action_page']); } else { if ($data['order']['progress'] == '3') { // Buyer must sign early before vendor dispatches. $update = array('partially_signed_transaction' => $this->input->post('js_transaction'), 'partially_signing_user_id' => $this->current_user->user_id, 'partially_signed_time' => time()); $this->order_model->progress_order($order_id, '3', '4', $update); } else { if ($data['order']['progress'] == '4') { // Vendor indicates they have dispatched. $update = array('partially_signed_transaction' => $this->input->post('js_transaction'), 'partially_signing_user_id' => $this->current_user->user_id, 'partially_signed_time' => time(), 'dispatched_time' => time(), 'dispatched' => '1'); $this->order_model->progress_order($order_id, '4', '5', $update); } else { if ($data['order']['progress'] == '6') { $update = array('partially_signed_transaction' => $this->input->post('js_transaction'), 'partially_signing_user_id' => $this->current_user->user_id, 'partially_signed_time' => time()); $this->order_model->update_order($order_id, $update); } else { if ($data['order']['progress'] == '8') { $update = array('partially_signed_transaction' => $this->input->post('js_transaction'), 'partially_signing_user_id' => $this->current_user->user_id, 'partially_signed_time' => time()); $this->order_model->update_order($order_id, $update); } } } } $this->current_user->set_return_message('Your partially signed transaction has been saved!', 'success'); redirect($data['action_page']); } } } } } // Manual if ($this->input->post('submit_signed_transaction') == 'Submit Transaction') { if ($this->form_validation->run('input_transaction') == TRUE) { $validate = $this->bw_bitcoin->handle_order_tx_submission($data['order'], $this->input->post('partially_signed_transaction'), $data['my_multisig_key']); if (is_string($validate)) { $data['invalid_transaction_error'] = $validate; } else { if ($validate == TRUE) { if (strlen($data['order']['partially_signed_transaction']) > 0) { $this->current_user->set_return_message('Transaction has been submitted, and will be processed shortly.', 'success'); redirect($data['action_page']); } else { if ($data['order']['progress'] == '3') { // Buyer must sign early before vendor dispatches. $update = array('partially_signed_transaction' => $this->input->post('partially_signed_transaction'), 'partially_signing_user_id' => $this->current_user->user_id, 'partially_signed_time' => time()); $this->order_model->progress_order($order_id, '3', '4', $update); } else { if ($data['order']['progress'] == '4') { // Vendor indicates they have dispatched. $update = array('partially_signed_transaction' => $this->input->post('partially_signed_transaction'), 'partially_signing_user_id' => $this->current_user->user_id, 'partially_signed_time' => time(), 'dispatched_time' => time(), 'dispatched' => '1'); $this->order_model->progress_order($order_id, '4', '5', $update); } else { if ($data['order']['progress'] == '6') { $update = array('partially_signed_transaction' => $this->input->post('partially_signed_transaction'), 'partially_signing_user_id' => $this->current_user->user_id, 'partially_signed_time' => time()); $this->order_model->update_order($order_id, $update); } else { if ($data['order']['progress'] == '8') { $update = array('partially_signed_transaction' => $this->input->post('partially_signed_transaction'), 'partially_signing_user_id' => $this->current_user->user_id, 'partially_signed_time' => time()); $this->order_model->update_order($order_id, $update); } } } } $this->current_user->set_return_message('Your partially signed transaction has been saved!', 'success'); redirect($data['action_page']); } } } } } } $data['redeem_script'] = RawTransaction::decode_redeem_script($data['order']['redeemScript']); $data['addrs'] = array($data['order']['buyer_payout'] => 'buyer', $data['order']['vendor_payout'] => 'vendor'); if (isset($data['order']['public_keys']['admin'])) { $data['addrs'][BitcoinLib::public_key_to_address($data['order']['public_keys']['admin']['public_key'], $this->bw_config->currencies[0]['crypto_magic_byte'])] = 'admin'; } if (strlen($data['order']['partially_signed_transaction']) > 0) { $data['raw_tx'] = RawTransaction::decode($data['order']['partially_signed_transaction']); $data['signer'] = $this->accounts_model->get(array('id' => $data['order']['partially_signing_user_id'])); } else { if (strlen($data['order']['unsigned_transaction']) > 0) { $data['raw_tx'] = RawTransaction::decode($data['order']['unsigned_transaction']); } } $checkStrangeAddress = function () use($data) { $tx_addrs = array(); foreach ($data['raw_tx']['vout'] as $vout) { $tx_addrs[] = $vout['scriptPubKey']['addresses'][0]; } return count($tx_addrs) != count(array_intersect($tx_addrs, array_keys($data['addrs']))); }; $data['strange_address'] = isset($data['raw_tx']) ? $checkStrangeAddress() : FALSE; $data['fees']['shipping_cost'] = $data['order']['shipping_costs']; $data['fees']['fee'] = $data['order']['fees']; $data['fees']['escrow_fees'] = $data['order']['extra_fees']; $data['fees']['total'] = $data['order']['shipping_costs'] + $data['order']['fees']; if ($this->current_user->user_role == 'Buyer' && $data['order']['paid_time'] == '') { $this->load->library('ciqrcode'); $data['payment_url'] = "bitcoin:{$data['order']['address']}?amount={$data['order']['order_price']}&message=Order+{$data['order']['id']}&label=Order+{$data['order']['id']}"; $data['qr'] = $this->ciqrcode->generate_base64(array('data' => $data['payment_url'])); } $data['page'] = 'orders/details'; $data['title'] = 'Order Details: #' . $data['order']['id']; $this->_render($data['page'], $data); }
/** * Dispute * * This controller shows either the disputes list (if $order_id is unset) * or a specified disputed order (set by $order_id). * * @param int $order_id */ public function dispute($order_id = NULL) { $this->load->library('form_validation'); $this->load->model('order_model'); $this->load->model('disputes_model'); // If no order is specified, load the list of disputes. if ($order_id == NULL) { $data['page'] = 'admin/disputes_list'; $data['title'] = 'Active Disputes'; $data['disputes'] = $this->disputes_model->disputes_list(); } else { $data['dispute'] = $this->disputes_model->get_by_order_id($order_id); // If the dispute cannot be found, redirect to the dispute list. if ($data['dispute'] == FALSE) { redirect('admin/disputes'); } $data['page'] = 'admin/dispute'; $data['title'] = "Disputed Order #{$order_id}"; // Load the order information. $data['current_order'] = $this->order_model->get($order_id); // Work out whether the vendor or buyer is disputing. $data['disputing_user'] = $data['dispute']['disputing_user_id'] == $data['current_order']['buyer']['id'] ? $data['current_order']['buyer'] : $data['current_order']['vendor']; $data['other_user'] = $data['dispute']['other_user_id'] == $data['current_order']['buyer']['id'] ? $data['current_order']['buyer'] : $data['current_order']['vendor']; // If the message is updated: if ($this->input->post('post_dispute_message') == 'Post Message') { if ($this->form_validation->run('add_dispute_update') == TRUE) { // Update the dispute record. $update = array('posting_user_id' => $this->current_user->user_id, 'order_id' => $order_id, 'dispute_id' => $data['dispute']['id'], 'message' => $this->input->post('update_message')); if ($this->disputes_model->post_dispute_update($update) == TRUE) { redirect('admin/dispute/' . $order_id); } } } // Resolution: $data['transaction_fee'] = 0.0001; $data['admin_fee'] = $data['current_order']['fees'] + $data['current_order']['extra_fees'] - $data['transaction_fee']; $data['user_funds'] = (double) ($data['current_order']['order_price'] - $data['admin_fee'] - $data['transaction_fee']); if ($this->input->post('resolve_dispute') !== null) { if ($this->form_validation->run('admin_resolve_dispute') == TRUE) { if ($this->input->post('resolve_dispute_id') == $data['current_order']['id']) { if ($this->input->post('relinquish_fee') == '1') { $data['admin_fee'] = 0; $data['user_funds'] = (double) ($data['current_order']['order_price'] - $data['admin_fee'] - $data['transaction_fee']); } if ($data['current_order']['vendor_selected_escrow'] == '1') { $pay_buyer_amount = $this->input->post('pay_buyer'); $pay_vendor_amount = $this->input->post('pay_vendor'); $sum = $pay_buyer_amount + $pay_vendor_amount; $epsilon = 1.0E-8; // Must total user funds available if (abs($sum - $data['user_funds']) < $epsilon) { $tx_outs = array(); // Add outputs for the sites fee, buyer, and vendor. if ($data['admin_fee'] > 0) { $admin_address = BitcoinLib::public_key_to_address($data['current_order']['public_keys']['admin']['public_key'], $this->bw_config->currencies[0]['crypto_magic_byte']); $tx_outs[$admin_address] = (double) $data['admin_fee']; } if ($pay_buyer_amount > 0) { $tx_outs[$data['current_order']['buyer_payout']] = (double) $pay_buyer_amount; } if ($pay_vendor_amount > 0) { $tx_outs[$data['current_order']['vendor_payout']] = (double) $pay_vendor_amount; } // Create spend transaction and redirect, otherwise display an error $create_spend_transaction = $this->order_model->create_spend_transaction($data['current_order']['address'], $tx_outs, $data['current_order']['redeemScript']); if ($create_spend_transaction == TRUE) { // Notify users by way of a dispute update $this->disputes_model->post_dispute_update(array('posting_user_id' => '', 'order_id' => $order_id, 'dispute_id' => $data['dispute']['id'], 'message' => 'New transaction on order page.')); redirect('admin/dispute/' . $order_id); } else { $data['returnMessage'] = $create_spend_transaction; } } else { $data['amount_error'] = 'The User Funds amount must be completely spread between both users.'; } } else { if ($this->order_model->progress_order($data['current_order']['id'], '6') == TRUE) { $update = array('posting_user_id' => '', 'order_id' => $order_id, 'dispute_id' => $data['dispute']['id'], 'message' => 'Dispute closed by admin.'); $this->disputes_model->post_dispute_update($update); $this->disputes_model->set_final_response($data['current_order']['id']); redirect('admin/dispute/' . $order_id); } } } } } } $this->_render($data['page'], $data); }
/** * Log Key Usage * * @param string $usage * @param string $mpk * @param int $iteration * @param string $public_key * @param int $order_id * @param string $user_hash * @return boolean */ public function log_key_usage($usage, $mpk, $iteration, $public_key, $order_id = FALSE, $user_hash = FALSE) { if (!in_array($usage, array('fees', 'order'))) { return FALSE; } if ($usage == 'order' && $order_id == FALSE) { return FALSE; } if ($usage == 'fees' && $user_hash == FALSE) { return FALSE; } $coin = $this->bw_config->currencies[0]; $address = BitcoinLib::public_key_to_address($public_key, $coin['crypto_magic_byte']); $order_id = $usage == 'order' ? $order_id : ''; $user_hash = $usage == 'fees' ? $user_hash : ''; $log = array('usage' => $usage, 'mpk' => $mpk, 'iteration' => $iteration, 'public_key' => $public_key, 'address' => $address, 'order_id' => $order_id, 'fees_user_hash' => $user_hash); return $this->db->insert('key_usage', $log) == TRUE ? TRUE : FALSE; }
/** * create checksum to verify ownership of the master primary key * * @return string[] [address, signature] */ protected function createChecksumVerificationSignature() { $import = BIP32::import($this->primaryPrivateKey->key()); $public = $this->primaryPrivateKey->publicKey(); $address = BitcoinLib::public_key_to_address($public, $import['version']); return [$address, BitcoinLib::signMessage($address, $import)]; }
/** * Create Multisig * * This function mirrors that of Bitcoind's. It creates a redeemScript * out of keys given in the given order, creates a redeemScript, and * creates the address from this. $m must be greater than zero, and * public keys are required. * * @param int $m * @param array $public_keys * @param string $magic_p2sh_byte * @return array|FALSE */ public static function create_multisig($m, $public_keys = array(), $magic_p2sh_byte = null) { $magic_p2sh_byte = BitcoinLib::magicP2SHByte($magic_p2sh_byte); if ($m == 0) { throw new \InvalidArgumentException("M should be larger than 0"); } if (count($public_keys) == 0) { throw new \InvalidArgumentException("No public keys provided"); } $redeem_script = self::create_redeem_script($m, $public_keys); return array('redeemScript' => $redeem_script, 'address' => BitcoinLib::public_key_to_address($redeem_script, $magic_p2sh_byte)); }
public function testKeyConversion() { $tests = $this->keyConversionData; foreach ($tests as $priv_key => $true_address) { $priv_key = trim($priv_key); $priv_key_info = BitcoinLib::WIF_to_private_key($priv_key); $pubkey = BitcoinLib::private_key_to_public_key($priv_key_info['key'], $priv_key_info['is_compressed']); // validate public key to address $this->assertEquals(BitcoinLib::public_key_to_address($pubkey, $this->addressVersion), $true_address); // validate public key to address, without specifying address version $this->assertEquals(BitcoinLib::public_key_to_address($pubkey), $true_address); } }
<?php use BitWasp\BitcoinLib\BitcoinLib; use BitWasp\BitcoinLib\Electrum; require_once __DIR__ . '/../vendor/autoload.php'; $magic_byte = '00'; $string = trim('teach start paradise collect blade chill gay childhood creek picture creator branch'); $seed = Electrum::decode_mnemonic($string); echo "Words: {$string}\n"; echo "Seed: {$seed}\n"; $secexp = Electrum::stretch_seed($seed); $secexp = $secexp['seed']; echo "Secret Exponent: {$secexp}\n"; $mpk = Electrum::generate_mpk($seed); echo "MPK: {$mpk}\n"; for ($i = 0; $i < 5; $i++) { $privkey = Electrum::generate_private_key($secexp, $i, 0); echo "Private key: {$privkey}\n"; echo "Private WIF: " . BitcoinLib::private_key_to_WIF($privkey, FALSE, $magic_byte) . "\n"; $public_key = Electrum::public_key_from_mpk($mpk, $i); echo "Public Key: {$public_key}\n"; $address = BitcoinLib::public_key_to_address($public_key, $magic_byte); echo "Public derivation: {$address}.\n"; $address = BitcoinLib::private_key_to_address($privkey, $magic_byte); echo "Private derivation: {$address}.\n"; echo "-----------\n"; }
/** * Key To Address * * This function accepts a bip32 extended key, and converts it to a * bitcoin address. * * @param string $extended_key * @return string */ public static function key_to_address($extended_key) { $import = self::import($extended_key); if ($import['type'] == 'public') { $public = $import['key']; } else { $public = BitcoinLib::private_key_to_public_key($import['key'], true); } // Convert the public key to the address. return BitcoinLib::public_key_to_address($public, $import['version']); }
/** * Order Paid Callback * * Loads orders marked as paid, and generates the transaction * for each. This is done at the end of the callback function, since * it will have prepared all the information in the payments table. * */ public function order_paid_callback() { $query = $this->db->get('paid_orders_cache'); if ($query->num_rows() == 0) { return FALSE; } $paid = $query->result_array(); $coin = $this->bw_config->currencies[0]; $this->load->model('transaction_cache_model'); $this->load->model('accounts_model'); foreach ($paid as $record) { $order = $this->get($record['order_id']); $vendor_address = $order['vendor_payout']; $admin_address = BitcoinLib::public_key_to_address($order['public_keys']['admin']['public_key'], $coin['crypto_magic_byte']); // Create the transaction outputs $tx_outs = array($admin_address => (string) number_format($order['fees'] + $order['extra_fees'] - 0.0001, 8), $vendor_address => (string) number_format($order['price'] + $order['shipping_costs'] - $order['extra_fees'], 8)); $create_spend_transaction = $this->create_spend_transaction($order['address'], $tx_outs, $order['redeemScript']); if ($create_spend_transaction == TRUE) { $next_progress = $order['vendor_selected_escrow'] == '1' ? '4' : '3'; $this->progress_order($order['id'], '2', $next_progress, array('paid_time' => time())); } else { //$this->log_model-> } $this->transaction_cache_model->delete_finalized_record($order['id']); } }