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); }