Example #1
0
 public function gather_inputs($wallet_id, $amount, $privkeys = array())
 {
     // Initialize
     global $config;
     $bip32 = new bip32();
     $enc = new encrypt();
     // Get wallet
     if (!($wallet = DB::queryFirstRow("SELECT * FROM coin_wallets WHERE id = %d", $wallet_id))) {
         trigger_error("Wallet does not exist, ID# {$wallet_id}", E_USER_ERROR);
     }
     // Go through inputs
     $inputs = array();
     $input_amount = 0;
     $rows = DB::query("SELECT * FROM coin_inputs WHERE is_spent = 0 AND is_confirmed = 1 ORDER BY id");
     foreach ($rows as $row) {
         if ($input_amount >= $amount) {
             break;
         }
         // Get address row
         if (!($addr_row = DB::queryFirstRow("SELECT * FROM coin_addresses WHERE address = %s", $row['address']))) {
             continue;
         }
         // Multisig address
         if ($wallet['address_type'] == 'multisig') {
             // Go through addresses
             $keys = array();
             $public_keys = array();
             $arows = DB::query("SELECT * FROM coin_addresses_multisig WHERE address = %s ORDER BY id", $row['address']);
             foreach ($arows as $arow) {
                 // Get public key
                 $keyindex = $addr_row['is_change_address'] . '/' . $arow['address_num'];
                 $ext_pubkey = trim($enc->decrypt(DB::queryFirstField("SELECT public_key FROM coin_wallets_keys WHERE id = %d", $arow['key_id'])));
                 $child_pubkey = $bip32->build_key($ext_pubkey, $keyindex)[0];
                 $import = $bip32->import($child_pubkey);
                 $public_keys[] = $import['key'];
                 // Go through private keys
                 foreach ($privkeys as $privkey) {
                     // Get child key
                     $child_privkey = $bip32->build_key($privkey, $keyindex)[0];
                     $chk_pubkey = $bip32->extended_private_to_public($child_privkey);
                     if ($chk_pubkey != $child_pubkey) {
                         continue;
                     }
                     // Validate privkey
                     if (!in_array($child_privkey, $keys)) {
                         $keys[] = $child_privkey;
                     }
                 }
             }
             if (count($keys) < $wallet['sigs_required']) {
                 continue;
             }
             // Add to inputs
             $vars = array('input_id' => $row['id'], 'txid' => $row['txid'], 'vout' => $row['vout'], 'amount' => $row['amount'], 'scriptsig' => $bip32->create_redeem_script($wallet['sigs_required'], $public_keys), 'public_keys' => $public_keys, 'privkeys' => $keys);
             array_push($inputs, $vars);
             // Standard address
         } else {
             // Get private key
             $keyindex = $addr_row['is_change_address'] . '/' . $addr_row['address_num'];
             $privkey = $bip32->build_key($privkeys[0], $keyindex)[0];
             // Get script sig
             $decode_address = $bip32->base58_decode($row['address']);
             $scriptsig = '76a914' . substr($decode_address, 2, 40) . '88ac';
             // Get public key
             $public_key = DB::queryFirstField("SELECT public_key FROM coin_wallets_keys WHERE wallet_id = %d ORDER BY id LIMIT 0,1", $wallet_id);
             $public_key = trim($enc->decrypt($public_key));
             $child_pubkey = $bip32->build_key($public_key, $keyindex)[0];
             // Validate key
             $chk_pubkey = $bip32->extended_private_to_public($privkey);
             if ($chk_pubkey != $child_pubkey) {
                 continue;
             }
             // Add to inputs
             $vars = array('input_id' => $row['id'], 'txid' => $row['txid'], 'vout' => $row['vout'], 'amount' => $row['amount'], 'scriptsig' => $scriptsig, 'public_keys' => array($public_key), 'privkeys' => array($privkey));
             array_push($inputs, $vars);
         }
         // Add to amounts
         $input_amount += $row['amount'];
         $amount += $config['btc_txfee'];
     }
     // Check amount
     if ($input_amount < $amount) {
         return false;
     }
     // Return
     return $inputs;
 }
Example #2
0
         continue;
     }
     // Get keyindexes
     if ($wrow['address_type'] == 'multisig') {
         $keyindexes = array();
         $public_keys = array();
         $addr_rows = DB::query("SELECT * FROM coin_addresses_multisig WHERE address = %s ORDER BY id", $row['address']);
         foreach ($addr_rows as $arow) {
             $keyindexes[] = $addr_row['is_change_address'] . '/' . $arow['address_num'];
             // Get public key
             $ext_public_key = trim($encrypt->decrypt(DB::queryFirstField("SELECT public_key FROM coin_wallets_keys WHERE id = %d", $arow['key_id'])));
             $child_key = $bip32->build_key($ext_public_key, $addr_row['is_change_address'] . '/' . $arow['address_num'])[0];
             $import = $bip32->import($child_key);
             $public_keys[] = $import['key'];
         }
         $sigscript = $bip32->create_redeem_script($wrow['sigs_required'], $public_keys);
     } else {
         $keyindexes = $addr_row['is_change_address'] . '/' . $addr_row['address_num'];
         $decode_address = $bip32->base58_decode($row['address']);
         $sigscript = '76a914' . substr($decode_address, 2, 40) . '88ac';
     }
     // Set vars
     $vars = array('input_id' => $row['id'], 'amount' => $row['amount'], 'txid' => $row['txid'], 'vout' => $row['vout'], 'sigscript' => $sigscript, 'keyindex' => $keyindexes);
     array_push($json['inputs'], $vars);
 }
 // Gather outputs
 $rows = DB::query("SELECT * FROM coin_sends WHERE status = 'pending' ORDER BY id");
 foreach ($rows as $row) {
     // Gather recipients
     $recipients = array();
     $arows = DB::query("SELECT * FROM coin_sends_addresses WHERE send_id = %d", $row['id']);
Example #3
0
        // Set variables
        $is_change = DB::queryFirstField("SELECT is_change_address FROM coin_addresses WHERE address = %s", $row['address']);
        // Get addresses
        $public_keys = array();
        $keyindexes = array();
        $addr_rows = DB::query("SELECT * FROM coin_addresses_multisig WHERE address = %s ORDER BY id", $row['address']);
        foreach ($addr_rows as $addr_row) {
            // Get public key & index
            $public_key = trim($enc->decrypt(DB::queryFirstField("SELECT public_key FROM coin_wallets_keys WHERE id = %d", $addr_row['key_id'])));
            $keyindex = $is_change . '/' . $addr_row['address_num'];
            $keyindexes[] = $keyindex;
            // Generate child key
            $child_ext_key = $bip32->build_key($public_key, $keyindex)[0];
            $public_keys[] = $bip32->import($child_ext_key)['key'];
        }
        $scriptsig = $bip32->create_redeem_script($wallet['sigs_required'], $public_keys);
        $keyindex = implode(", ", $keyindexes);
    } else {
        $addr_row = DB::queryFirstRow("SELECT * FROM coin_addresses WHERE address = %s", $row['address']);
        $keyindex = $addr_row['is_change_address'] . '/' . $addr_row['address_num'];
        $decode_address = $bip32->base58_decode($row['address']);
        $scriptsig = '76a914' . substr($decode_address, 2, 40) . '88ac';
    }
    // Add input
    $vars = array('input_id' => $row['id'], 'txid' => $row['txid'], 'vout' => $row['vout'], 'amount' => $row['amount'], 'keyindex' => $keyindex, 'scriptsig' => $scriptsig);
    array_push($inputs, $vars);
    $input_ids[] = $row['id'];
}
// Create transaction
$client = new rawtx();
$trans = $client->create_transaction($send['wallet_id'], $inputs, $outputs);