I used open source bitcoin-php library to create a rawtransaction hex code and sign it. When send it to bitcoin network, get an error
An error occured: Transaction rejected by network (code -26). Reason: 16: mandatory-script-verify-flag-failed (Script evaluated without error but finished with a false/empty top stack element)
Library:
https://github.com/Bit-Wasp/bitcoin-phpCode:
$private_key = PrivateKeyFactory::fromWif('address1 wif private key');
try {
$transaction = TransactionFactory::build()
->input('unspent hash of address1','2')// unspent hash value : 147900, vout : 2
->payToAddress('39479',AddressFactory::fromString('address2'))
->payToAddress('97200',AddressFactory::fromString('address1'))// Give change
->payToAddress('1221',AddressFactory::fromString('address3'))
->get();
$hex = $transaction->getHex();
$myTx = TransactionFactory::fromHex($hex);
$hex = TransactionFactory::sign($transaction)
-> sign (0, $private_key, $myTx->getOutputs()->get(2)->getScript())
-> get() -> getHex();
echo ($hex);
} catch (Exception $e) {
echo $e->getMessage().PHP_EOL;
}
Issue:
https://github.com/Bit-Wasp/bitcoin-php/issues/166The author have another library bitcoin-lib-php , Still have the same error
You need to get the output from the previous transaction. What you have is that you are getting the output script for signing from one of your outputs in the transaction. It actually has to come from the transaction which the input references, and it needs to be exactly the same output.
Use another library
https://github.com/Bit-Wasp/bitcoin-lib-phpSample code:
function createTransaction(Array $inputs,Array $privs,Array $outputs) {
try {
foreach ($outputs as $address=>$amount) {
if (!is_int($amount)) {
$amount = is_numeric($amount) ? (int)$amount: (int)BitcoinLib::toSatoshi($amount);
$outputs[$address] = $amount;
}
}
$wallet = array();
RawTransaction::private_keys_to_wallet($wallet, $privs, '00');
$raw_transaction = RawTransaction::create($inputs, $outputs);
$sign = RawTransaction::sign($wallet, $raw_transaction, json_encode($inputs));
return $sign['hex'];
} catch(Exception $e) {
self::$error = $e->getMessage();
return false;
}
}
$hex = createTransaction([
[
'txid'=>'address1 unspent hash', // use public http api https://chain.so/ to get unspet transaction hashs of an address
'vout'=>2,
'scriptPubKey'=>'address1 pubkey',
]
],['address1_wif_private_key],[
'address2'=>'amount',
'address3' =>'amount',
'address1' => 'amount', //give change
]);
// error
$hex = createTransaction([
[
'txid'=>'address1 unspent hash',
'vout'=>2,
'scriptPubKey'=>'address1 pubkey',
]
],['address1_wif_private_key],[
'address2'=>'amount',
'address1' => 'amount', //give change
]);
// Success!!! why !?