Example #1
0
<?php

// Initialize
global $template;
// Update general settings
if (isset($_POST['submit']) && $_POST['submit'] == tr('Add New Wallet')) {
    // Initialize
    $b32 = new bip32();
    $enc_client = new encrypt();
    $required_sigs = $_POST['address_type'] == 'standard' ? 1 : $_POST['multisig_sig_required'];
    $total_sigs = $_POST['address_type'] == 'standard' ? 1 : $_POST['multisig_sig_total'];
    // Validate public keys
    if ($_POST['autogen_keys'] == 0) {
        for ($x = 1; $x <= $total_sigs; $x++) {
            if (!($import = $b32->import($_POST['bip32_key' . $x]))) {
                $template->add_message("The #{$x} BIP32 key you specified is an invalid BIP32 key.", 'error');
            } elseif ($import['type'] != 'public') {
                $template->add_message("The #{$x} BIP32 key you specified is an invalid BIP32 key.", 'error');
            }
        }
    }
    // Create wallet, if no errors
    if ($template->has_errors != 1) {
        // Add to DB
        DB::insert('coin_wallets', array('address_type' => $_POST['address_type'], 'sigs_required' => $required_sigs, 'sigs_total' => $total_sigs, 'display_name' => $_POST['wallet_name']));
        $wallet_id = DB::insertId();
        // Gather BIP32 keys
        $keys = array();
        for ($x = 1; $x <= $total_sigs; $x++) {
            // Auto-generate, if needed
            if ($_POST['autogen_keys'] == 1) {
Example #2
0
 public function sign_transaction($transaction, $inputs)
 {
     // Initialize
     $bip32 = new bip32();
     // Start transaction
     $transaction[] = '01000000';
     $orig_transaction = $transaction;
     // Add inputs temporarily
     $temp_input = 3;
     foreach ($inputs as $input) {
         // Set transaction variables
         $temp_transaction = $orig_transaction;
         if (count($input['privkeys']) > 1) {
             $temp_transaction[$temp_input] = $this->encode_vint(strlen(hex2bin($input['scriptsig'])));
             $temp_transaction[$temp_input + 1] = $input['scriptsig'];
         } else {
             $temp_transaction[$temp_input] = dechex(strlen(hex2bin($input['scriptsig'])));
             $temp_transaction[$temp_input + 1] = $input['scriptsig'];
         }
         // Initialize
         $generator = SECcurve::generator_secp256k1();
         // Hash structure
         $temp_hex_trans = pack("H*", implode("", $temp_transaction));
         $hash = hash('sha256', hash('sha256', $temp_hex_trans, true));
         // Go through the keys
         $signatures = array();
         $total_sign = 0;
         foreach ($input['privkeys'] as $privkey) {
             // Get public key
             $import = $bip32->import($privkey);
             $pubkey = $bip32->private_to_public($import['key']);
             $cpubkey = $bip32->private_to_public($import['key'], true);
             // Get ready to sign
             $point = new Point($generator->getCurve(), gmp_init(substr($pubkey, 2, 64), 16), gmp_init(substr($pubkey, 66, 64), 16), $generator->getOrder());
             $_public_key = new PublicKey($generator, $point);
             $_private_key = new PrivateKey($_public_key, gmp_init($import['key'], 16));
             // Sign
             $sign = $_private_key->sign(gmp_init($hash, 16), gmp_init((string) bin2hex(openssl_random_pseudo_bytes(32)), 16));
             $signatures[$cpubkey] = $this->_encode_signature($sign);
             $total_sign++;
         }
         // Encode signature
         if (count($input['privkeys']) > 1) {
             $sig = '00';
             foreach ($signatures as $pubkey => $sign) {
                 $sig .= $this->encode_vint(strlen($sign) / 2) . $sign;
             }
             $sig .= '4c' . $this->encode_vint(strlen($input['scriptsig']) / 2) . $input['scriptsig'];
         } else {
             $key = array_keys($signatures)[0];
             $sig = $this->encode_vint(strlen($signatures[$key]) / 2) . $signatures[$key];
             $sig .= $this->encode_vint(strlen($key) / 2) . $key;
         }
         // Add to transaction
         $transaction[$temp_input] = $this->encode_vint(strlen(hex2bin($sig)));
         $transaction[$temp_input + 1] = $sig;
         $temp_input += 4;
     }
     array_pop($transaction);
     // Return
     return implode("", $transaction);
 }
Example #3
0
     }
     // Get address row
     if (!($addr_row = DB::queryFirstRow("SELECT * FROM coin_addresses WHERE address = %s", $row['address']))) {
         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) {
Example #4
0
    // Create sigscript
    if ($wallet['address_type'] == 'multisig') {
        // 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