echo " : " . BIP32::key_to_address($pub[0]) . "\n"; ///////////////////////////// // We're gonna spent the first txout from this tx: // https://www.blocktrail.com/BTC/tx/4a2231e13182cdb64fa2f9aae38fca46549891e9dc15e8aaf484d82fc6e0a1d8 // Set up inputs here $inputs = array(array('txid' => '4a2231e13182cdb64fa2f9aae38fca46549891e9dc15e8aaf484d82fc6e0a1d8', 'vout' => 0)); // Set up outputs here $outputs = array('1KuE17Fbcdsn3Ns5T9Wzi1epurRnKC9qVr' => BitcoinLib::toSatoshi(0.0004)); //////////////////////////// // Parameters for signing. // Create JSON inputs parameter // - These can come from bitcoind, or just knowledge of the txid/vout/scriptPubKey, // and redeemScript if needed. $json_inputs = json_encode(array(array('txid' => '4a2231e13182cdb64fa2f9aae38fca46549891e9dc15e8aaf484d82fc6e0a1d8', 'vout' => 0, 'scriptPubKey' => '76a914' . 'bf012bde5bd12eb7f9a66de5697b241b65a9a3c9' . '88ac'))); // build wallet from private key(s) $wallet = array(); BIP32::bip32_keys_to_wallet($wallet, array($key), '00'); // Create raw transaction $raw_transaction = RawTransaction::create($inputs, $outputs); // Sign the transaction $signed = RawTransaction::sign($wallet, $raw_transaction, $json_inputs); print_r($signed); echo "\n"; // Decode and print the TX // print_r(RawTransaction::decode($sign['hex'])); // To broadcast the transaction onto the network // - grab the $signed['hex'] // - `bitcoind sendrawtransaction <singed HEX>` // or use an API that supports sendraw // This transaction was broadcasted and confirmed here: // https://www.blocktrail.com/BTC/tx/e04c14270b2a9fcff548bc0bdd16b22ec6c2903ea6aaf9f7656b81f1c4c6153b
/** * signs a raw transaction * * @param $rawTransaction * @param $inputs * @return array */ protected function signTransaction($rawTransaction, $inputs) { $wallet = []; $keys = []; $redeemScripts = []; foreach ($inputs as $input) { //create private keys for signing $path = BIP32Path::path($input['path'])->privatePath(); $keys[] = $this->primaryPrivateKey->buildKey($path); $keys[] = $this->backupPrivateKey->buildKey($path->unhardenedPath()); $redeemScripts[] = $input['redeemScript']; } //add the keys and redeem scripts to a wallet to sign the transaction with BIP32::bip32_keys_to_wallet($wallet, array_map(function (BIP32Key $key) { return $key->tuple(); }, $keys)); RawTransaction::redeem_scripts_to_wallet($wallet, $redeemScripts); return RawTransaction::sign($wallet, $rawTransaction, json_encode($inputs)); }
/** * sign a raw transaction with the private keys that we have * * @param string $raw_transaction * @param array[] $inputs * @return array response from RawTransaction::sign * @throws \Exception */ protected function signTransaction($raw_transaction, array $inputs) { $wallet = []; $keys = []; $redeemScripts = []; foreach ($inputs as $input) { $redeemScript = null; $key = null; if (isset($input['redeemScript'], $input['path'])) { $redeemScript = $input['redeemScript']; $path = BIP32Path::path($input['path'])->privatePath(); $key = $this->primaryPrivateKey->buildKey($path); $address = $this->getAddressFromKey($key, $path); if ($address != $input['address']) { throw new \Exception("Generated address does not match expected address!"); } } else { throw new \Exception("No redeemScript/path for input"); } if ($redeemScript && $key) { $keys[] = $key; $redeemScripts[] = $redeemScript; } } BIP32::bip32_keys_to_wallet($wallet, array_map(function (BIP32Key $key) { return $key->tuple(); }, $keys)); RawTransaction::redeem_scripts_to_wallet($wallet, $redeemScripts); return RawTransaction::sign($wallet, $raw_transaction, json_encode($inputs)); }