Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

I was able to get the hash of a bitcoin transaction on the testnet, but it is never displayed on the blockchain. Why is this happening? #856

Open
joma512900 opened this issue Nov 4, 2020 · 9 comments

Comments

@joma512900
Copy link

My code:

`function Transaction($to,$amount,$privateKey,$from){
// Load private key
$ecAdapter = Bitcoin::getEcAdapter();
$privKeyFactory = new PrivateKeyFactory();
$private_key = $privKeyFactory->fromWif($privateKey);
// Generate raw transaction
$addressCreator = new AddressCreator();
$transaction = TransactionFactory::build();
// inputs
$inputs = file_get_contents("https://testnet-api.smartbit.com.au/v1/blockchain/address/".$from);
$inputs = json_decode($inputs, true);
$inputs = $inputs['address']['transactions'];

$inValue = '0';
$inputs_all = array();
$ouputs_all = array();
$i = 0; while ($i < count($inputs)) {
	unset($item_input);
	$item_input = array(
		'txid' => $inputs[$i]['txid'],
		'vout' => $inputs[$i]['inputs'][0]['vout'],
		'sequence' => strval($inputs[$i]['inputs'][0]['sequence']),
		'scriptPubKey' => $inputs[$i]['outputs'][0]['script_pub_key']['hex']
	);
	$inValue += $inputs[$i]['inputs'][0]['value'];
	array_push($inputs_all, $item_input);
	unset($item_ouput);
	$item_ouput = array(
		'satochis' => $inputs[$i]['outputs'][0]['value_int'],
		'address' => $inputs[$i]['outputs'][0]['addresses'][0]
	);
	array_push($ouputs_all, $item_input);
	unset($item_ouput);
	$item_ouput = array(
		'satochis' => $inputs[$i]['outputs'][1]['value_int'],
		'address' => $inputs[$i]['outputs'][1]['addresses'][0]
	);
	array_push($ouputs_all, $item_input);
$i++; }

foreach ($inputs_all as $input) {
   	$transaction->input(
       	$input['txid'],
       	$input['vout'],
       	ScriptFactory::fromHex(''),
   		$input['sequence']
   	);
}
// fee
$fee = 0.00005; // It depends on # inputs, # outputs, type of scriptPubKey.. 
$toSpend = $inValue - $fee;
$outputValue = '0.0000900';
$changeValue = $toSpend - $outputValue;

$outputValue = ToSatochis($outputValue);
$transaction->payToAddress($outputValue,  $addressCreator->fromString($to));

$txOut = new TransactionOutput(
    $outputValue,
    ScriptFactory::scriptPubKey()->payToPubKeyHash($private_key->getPubKeyHash())
);

// Make transaction
$transaction = $transaction->get();
// Sign transaction
$signer = new Signer($transaction, $ecAdapter);
foreach ($transaction->getInputs() as $index=>$input) {
        $signer->sign($index, $private_key, $txOut);
}

echo "txid: {$transaction->getTxId()->getHex()}\n";
// Signing and get output
$hex = $signer -> get() -> getHex();
echo "raw: {$hex}\n";

}`

  • Hash: 9fc6c63ec94e711f99e0c3e438a0054969bbddaed116f2619368a632a2bf87a5
  • I decoded my transaction but everything seems fine at https://live.blockcypher.com/btc-testnet/decodetx/
  • Transaction Hex:
    01000000020242d906a535e30fdb252efbdb64d244bd4d0b967b3891758f0f525b869cd5c6000000006b483045022100a8850a12ae48134c191beafe3b20f2296e53df446882618f83975a720a6ad66202207a1f33f31416b06646f579b9b82eb1895698838f358e69a4eb1adf286284ec0001210227b77566b2dd02f173a83d3eec49bb5efd87866bbfc3d97ac83286c13099507afeffffffac69380a9b96542e7ef800fc6e65cdefbe2fc73504416cf290b029cc5775debe000000006a47304402202884b2c82e0a3fea5bc2fa76eff494577710e682783afba8dec7dc0e9661fa8b022070e4aea86cc9a9b89bde5a7854d5d48334696e617e63e325556a8f2c09dd6f7501210227b77566b2dd02f173a83d3eec49bb5efd87866bbfc3d97ac83286c13099507afeffffff012823000000000000160014def0ed2a458563620f30a8c09d46143ec757fc1e00000000
@afk11
Copy link
Member

afk11 commented Nov 4, 2020

Have you broadcast the transaction anywhere or have you just run the script here? bitcoin-php doesn't broadcast transactions for you, it's up to you.

I notice you're using smartbit as an api, those guys probably have a tx broadcast endpoint (maybe blockcypher too). Or you could use a local bitcoin node. With both of these, you'll get some feedback if your transaction is invalid or something.

Also there's bit-wasp/bitcoin-p2p-php which supports connecting to the p2p network, so you could broadcast that way, but you get ZERO feedback from the p2p if the transaction is invalid.. what you do here is connect to multiple peers, broadcast through one, and watch if you receive it back from the others. Make sure to do signature verification on every input before sending, peers will ban you for sending silly stuff :)

@afk11
Copy link
Member

afk11 commented Nov 9, 2020

Did this help you?

@joma512900
Copy link
Author

joma512900 commented Nov 9, 2020

hello friend, currently I don't have a local node, I want to send transactions without using a local node, so I am checking Bit-Wasp / bitcoin-p2p-php in specific in this example:
https://github.com/Bit-Wasp/bitcoin-p2p-php/blob/master/examples/pushtx.php

Is that reference example okay? or which one do you recommend

@afk11
Copy link
Member

afk11 commented Nov 10, 2020

The example you linked to actually doesn't do all the work necessary to make sure it broadcast. If you have an error it'd silently do nothing, but it should really connect to some other nodes and listen for the tx.

The most common way for quick scripts is to broadcast through a block explorer. Blockstreams API, blockcypher, blockchain.info. They're usually unauthenticated, but they'll tell you if a signature was invalid.

Or if you have an electrum server you like, you could probably broadcast with that: https://github.com/Bit-Wasp/stratum-php/blob/master/src/Api/ElectrumClient.php Super old code, but it worked once ;)

@joma512900
Copy link
Author

joma512900 commented Nov 10, 2020

Hello friend, what am I doing wrong?
It gives me the following error, however I have tried to correct it without success.
https://live.blockcypher.com/btc/pushtx/

Captura de pantalla 2020-11-10 a las 11 53 29

My code:
`
$from = 'mg14RzWyo3dAR95FZZDdf9hd394twa5t85';
$inputs = file_get_contents("https://api.blockcypher.com/v1/btc/test3/addrs/".$from."/full?limit=50");
$inputs = json_decode($inputs, true);
$inputs = $inputs['txs'];

$inValue = '0';
$inputs_all = array();
$ouputs_all = array();
$i = 0; while ($i < count($inputs)) {
	unset($item_input);
	$item_input = array(
		'txid' => $inputs[$i]['hash'],
		'vout' => $inputs[$i]['vout_sz'],
		'sequence' => strval($inputs[$i]['inputs'][0]['sequence']),
		'scriptPubKey' => $inputs[$i]['intputs'][0]['witness'][0]
	);
	$inValue += $inputs[$i]['inputs'][0]['output_value'];
	array_push($inputs_all, $item_input);
	unset($item_ouput);
	$item_ouput = array(
		'satochis' => $inputs[$i]['outputs'][0]['value'],
		'address' => $inputs[$i]['outputs'][0]['addresses'][0]
	);
	array_push($ouputs_all, $item_input);
	unset($item_ouput);
	$item_ouput = array(
		'satochis' => $inputs[$i]['outputs'][1]['value'],
		'address' => $inputs[$i]['outputs'][1]['addresses'][0]
	);
	array_push($ouputs_all, $item_input);
$i++; }

foreach ($inputs_all as $input) {
   	$transaction->input(
       	$input['txid'],
       	$input['vout'],
       	ScriptFactory::fromHex($input['scriptPubKey']),
   		$input['sequence']
   	);
}

`

@afk11
Copy link
Member

afk11 commented Nov 10, 2020

It looks like you still haven't corrected the issue I mentioned in that other issue/PR where you shared it with me
(ScriptFactory::fromHex($input['scriptPubKey']), at the bottom)

Also, this is wrong (typo, and a witness element isn't a scriptPubKey)
'scriptPubKey' => $inputs[$i]['intputs'][0]['witness'][0]

I don't think this is based on an example from this repo, maybe take the closest one to your case, then shape that into what you need. Bitcoin stuff is extremely fragile, you need to get it all right or transactions won't work

@joma512900
Copy link
Author

@joma512900
Copy link
Author

when i try to download blockcypher a package is abandoned.

Failed to download
rgooding/protobuf-php from dist: The "https://api.github.com/repos/rgooding/Protobuf-PHP/zipball/d688d7894d65d80a38846e0b622b9a2cd7fd4d68" file could not be downloaded (HTTP/1.1 404 Not Found)

blockcypher/php-client#115

@afk11
Copy link
Member

afk11 commented Nov 10, 2020

Yea block cypher isn't kept up to date, but you might not need that to broadcast, maybe you could make the request with curl? Or else just pick a different explorer API.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants