3
I have a unsigned transaction hex. Now I want to sign this transaction input with my private key in PHP. Bitwasp library looks nice. But I can't find how to sign my transaction. Can you give me any advices?
Transaction Hex
010000000414ae2264cdbe754b9ae4be18d84bfeb4f578af553b9b9e4f9cb2303d04ee9e45000000001976a91458b6e991b45487df810f4d96d5315da739637f1788acffffffffec15d27b74516fefd921cecbe043ea63124d28a3903aef8fb1682ccc926b1c62000000001976a91458b6e991b45487df810f4d96d5315da739637f1788acffffffff9878f76e1424c1d1eeb6b15d06902dd8f0c78f9bdb61263e4ca3ae68c571a292000000001976a91458b6e991b45487df810f4d96d5315da739637f1788acfffffffffdac7f1c83b01a8924a8965d356b804c2608bc261fc18041116ddb4a143bc499000000001976a91458b6e991b45487df810f4d96d5315da739637f1788acffffffff0336150000000000001976a9141485d9d03b41aaa9dca7d70d7f63ff4a0826100e88ac00000000000000001e6a1c246698efc5d81b78ceadf3179316b5eb6cc5c2c347c0b7b42121a94e92180000000000001976a91458b6e991b45487df810f4d96d5315da739637f1788ac00000000
Decoded Transaction
{
"txid":"6c521937d8fa889d71609ebed2e23b694cbca89778c8b8d967167e5a4c9d5b78",
"size":381,
"version":1,
"locktime":0,
"vin":[
{
"txid":"459eee043d30b29c4f9e9b3b55af78f5b4fe4bd818bee49a4b75becd6422ae14",
"vout":0,
"scriptSig":{
"asm":"OP_DUP OP_HASH160 58b6e991b45487df810f4d96d5315da739637f17 OP_EQUALVERIFY OP_CHECKSIG",
"hex":"76a91458b6e991b45487df810f4d96d5315da739637f1788ac"
},
"sequence":4294967295
},
{
"txid":"621c6b92cc2c68b18fef3a90a3284d1263ea43e0cbce21d9ef6f51747bd215ec",
"vout":0,
"scriptSig":{
"asm":"OP_DUP OP_HASH160 58b6e991b45487df810f4d96d5315da739637f17 OP_EQUALVERIFY OP_CHECKSIG",
"hex":"76a91458b6e991b45487df810f4d96d5315da739637f1788ac"
},
"sequence":4294967295
},
{
"txid":"92a271c568aea34c3e2661db9b8fc7f0d82d90065db1b6eed1c124146ef77898",
"vout":0,
"scriptSig":{
"asm":"OP_DUP OP_HASH160 58b6e991b45487df810f4d96d5315da739637f17 OP_EQUALVERIFY OP_CHECKSIG",
"hex":"76a91458b6e991b45487df810f4d96d5315da739637f1788ac"
},
"sequence":4294967295
},
{
"txid":"99c43b144adb6d114180c11f26bc08264c806b355d96a824891ab0831c7facfd",
"vout":0,
"scriptSig":{
"asm":"OP_DUP OP_HASH160 58b6e991b45487df810f4d96d5315da739637f17 OP_EQUALVERIFY OP_CHECKSIG",
"hex":"76a91458b6e991b45487df810f4d96d5315da739637f1788ac"
},
"sequence":4294967295
}
],
"vout":[
{
"value":5.43e-5,
"n":0,
"scriptPubKey":{
"asm":"OP_DUP OP_HASH160 1485d9d03b41aaa9dca7d70d7f63ff4a0826100e OP_EQUALVERIFY OP_CHECKSIG",
"hex":"76a9141485d9d03b41aaa9dca7d70d7f63ff4a0826100e88ac",
"reqSigs":1,
"type":"pubkeyhash",
"addresses":[
"12sWrxRY7E7Nhmuyjbz4TtGE9jRewGqEZD"
]
}
},
{
"value":0,
"n":1,
"scriptPubKey":{
"asm":"OP_RETURN 246698efc5d81b78ceadf3179316b5eb6cc5c2c347c0b7b42121a94e",
"hex":"6a1c246698efc5d81b78ceadf3179316b5eb6cc5c2c347c0b7b42121a94e",
"type":"nulldata"
}
},
{
"value":6.29e-5,
"n":2,
"scriptPubKey":{
"asm":"OP_DUP OP_HASH160 58b6e991b45487df810f4d96d5315da739637f17 OP_EQUALVERIFY OP_CHECKSIG",
"hex":"76a91458b6e991b45487df810f4d96d5315da739637f1788ac",
"reqSigs":1,
"type":"pubkeyhash",
"addresses":[
"1965areciqapsuL2hsia2yKkRLfAsH1smG"
]
}
}
]
}
composer.json
"require": {
"bitwasp/bitcoin": "v0.0.29.1"
}
sample.php
<?php
require 'vendor/autoload.php';
use BitWasp\Bitcoin\Key\PrivateKeyFactory;
use BitWasp\Bitcoin\Transaction\TransactionFactory;
// Load private key
$private_key = PrivateKeyFactory::fromWif('KEY');
// Transaction from Hex
$transaction = TransactionFactory::fromHex('HEX');
... what should I next...?
Update 1
Solved! Thank you @karimkorun.
composer.json
"require": {
"bitwasp/bitcoin": "v0.0.29.1"
}
test.php
<?php
require 'vendor/autoload.php';
use BitWasp\Bitcoin\Bitcoin;
use BitWasp\Bitcoin\Script\ScriptFactory;
use BitWasp\Bitcoin\Key\PrivateKeyFactory;
use BitWasp\Bitcoin\Transaction\TransactionFactory;
use BitWasp\Bitcoin\Transaction\Factory\Signer;
use BitWasp\Bitcoin\Transaction\OutPoint;
use BitWasp\Bitcoin\Utxo\Utxo;
use BitWasp\Buffertools\Buffer;
use BitWasp\Bitcoin\Transaction\TransactionOutput;
$hex = '010000000414ae2264cdbe754b9ae4be18d84bfeb4f578af553b9b9e4f9cb2303d04ee9e45000000001976a91458b6e991b45487df810f4d96d5315da739637f1788acffffffffec15d27b74516fefd921cecbe043ea63124d28a3903aef8fb1682ccc926b1c62000000001976a91458b6e991b45487df810f4d96d5315da739637f1788acffffffff9878f76e1424c1d1eeb6b15d06902dd8f0c78f9bdb61263e4ca3ae68c571a292000000001976a91458b6e991b45487df810f4d96d5315da739637f1788acfffffffffdac7f1c83b01a8924a8965d356b804c2608bc261fc18041116ddb4a143bc499000000001976a91458b6e991b45487df810f4d96d5315da739637f1788acffffffff0336150000000000001976a9141485d9d03b41aaa9dca7d70d7f63ff4a0826100e88ac00000000000000001e6a1c246698efc5d81b78ceadf3179316b5eb6cc5c2c347c0b7b42121a94e92180000000000001976a91458b6e991b45487df810f4d96d5315da739637f1788ac00000000';
$privateKey = 'XXX';
$tx = TransactionFactory::fromHex($hex);
$utxos = [];
foreach ($tx->getInputs() as $idx => $input) {
$txid = $input->getOutPoint()->getTxId()->getHex();
$vout = $input->getOutPoint()->getVout();
$scriptPubKey = $input->getScript()->getBuffer()->getHex();
$utxo = new Utxo(new OutPoint(Buffer::hex($txid, 32), $vout), new TransactionOutput(0, ScriptFactory::fromHex($scriptPubKey)));
array_push($utxos, $utxo);
}
$priv = PrivateKeyFactory::fromWif($privateKey);
$signer = new Signer($tx, Bitcoin::getEcAdapter());
foreach ($utxos as $i => $utxo) {
$signer->sign($i, $priv, $utxo->getOutput());
}
$signed = $signer->get();
echo $signed->getHex() . PHP_EOL;
Update 2
This is shorter. UTXO objects are not necessary.
$tx = TransactionFactory::fromHex($hex);
$transactionOutputs = [];
foreach ($tx->getInputs() as $idx => $input) {
$transactionOutput = new TransactionOutput(0, ScriptFactory::fromHex($input->getScript()->getBuffer()->getHex()));
array_push($transactionOutputs, $transactionOutput);
}
$priv = PrivateKeyFactory::fromWif($privateKey);
$signer = new Signer($tx, Bitcoin::getEcAdapter());
foreach ($transactionOutputs as $idx => $transactionOutput) {
$signer->sign($idx, $priv, $transactionOutput);
}
$signed = $signer->get();
echo $signed->getHex() . PHP_EOL;
There's a folder with examples: https://github.com/Bit-Wasp/bitcoin-php/tree/master/examples check them out as I think your case is covered. On an unrelated note, your transaction input scriptSigs shouldn't have the scriptPubKey's from the outpoints being spent. What way did you generate it?
– karimkorun – 2016-07-30T13:26:58.107