Example #1
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);
 }