Bit-Wasp / bitcoin-php

Bitcoin implementation in PHP
The Unlicense
1.05k stars 418 forks source link

Can the addresses generated by "addresstypes.php" not be the same? #842

Closed wartw closed 4 years ago

wartw commented 4 years ago

Can the addresses generated by "addresstypes.php" not be the same?

afk11 commented 4 years ago

The example has a fixed private key. You want a random one instead? https://github.com/Bit-Wasp/bitcoin-php/blob/1.0/examples/privatekey.php and review methods in PrivateKeyFactory.

wartw commented 4 years ago

I want to generate multiple isolated addresses using a fixed set of private keys. Is there a way to do this?

afk11 commented 4 years ago

Look into bip32 "HierarchicalKey" in this lib. Check over the BIP so you understand what it does https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki

wartw commented 4 years ago

I do understand there is an error it?(GOOGLE translation may be a bit off-topic) https://github.com/Bit-Wasp/bitcoin-php/blob/1.0/examples/bip32.php

//Generate private key
$hdFactory = new HierarchicalKeyFactory();
$master = $hdFactory->generateMasterKey($random);
//Main address
echo "Master key (m)\n";
echo "   " . $master->toExtendedPrivateKey($network) . "\n";
//Generate public key
$masterAddr = new PayToPubKeyHashAddress($master->getPublicKey()->getPubKeyHash());
//Block address
$key1 = $master->deriveChild(0);
//Block 999999 address
$key2 = $key1->deriveChild(999999);
afk11 commented 4 years ago

Is there an error? share it?

You should check out BIP44 as well by the way (or bip49, or bip84) They all do the same thing, but the difference is the address types.

Electrum supports these wallet formats too!

wartw commented 4 years ago

I get up and continue to study, now it is 3 am in Taiwan time (I should take a break

wartw commented 4 years ago
<?php
ignore_user_abort(true);
set_time_limit(0);
require "vendor/autoload.php";
use BitWasp\Bitcoin\Bitcoin;
use BitWasp\Bitcoin\Address\PayToPubKeyHashAddress;
use BitWasp\Bitcoin\Key\Factory\PrivateKeyFactory;
use BitWasp\Bitcoin\Script\Interpreter\InterpreterInterface as I;
use BitWasp\Bitcoin\Transaction\Factory\Signer;
use BitWasp\Bitcoin\Transaction\Factory\TxBuilder;
use BitWasp\Bitcoin\Transaction\OutPoint;
use BitWasp\Bitcoin\Transaction\TransactionOutput;
use BitWasp\Buffertools\Buffer;
use BitWasp\Bitcoin\Script\ScriptFactory;
use BitWasp\Bitcoin\Address\AddressCreator;
use BitWasp\Bitcoin\Transaction\TransactionFactory;
use BitWasp\Bitcoin\Script\WitnessProgram;
use BitWasp\Bitcoin\Address\SegwitAddress;
use BitWasp\Bitcoin\Address\Base58AddressInterface;
use BitWasp\Bitcoin\Key\Factory\HierarchicalKeyFactory;

$adses='bc1qjenhvd63sjz7q0gnx90wtu5xx85w8kxnmaduua';
$url = "https://api.blockchair.com/bitcoin/dashboards/address/".$adses."?limit=1";
$adstes=file_get_contents($url);
$adstes_ok=json_decode($adstes, true);
$final_balance=$adstes_ok['data'][$adses]['address']['balance'];
$hash_balance=$adstes_ok['data'][$adses]['utxo'][0]['transaction_hash'];
$indextx=$adstes_ok['data'][$adses]['utxo'][0]['index'];
// Setup network and private key to segnet
$privKeyFactory = new PrivateKeyFactory();
//$key = $privKeyFactory->fromWif($row['skey']);//WIF
$math = Bitcoin::getMath();
$network = Bitcoin::getNetwork();
$hdFactory = new HierarchicalKeyFactory();

$key0 = $hdFactory->fromExtended("xprv9vk7fGTQx3oxxxxxx");//existing xprv
$key=$key0->toExtendedPrivateKey($network);
$key1 = $key0->deriveChild(0);
$key2 = $key1->deriveChild(999999);
// scriptPubKey is P2WKH
$program = ScriptFactory::scriptPubKey()->p2wkh($key2->getPublicKey()->getPubKeyHash());
// UTXO
$outpoint = new OutPoint(Buffer::hex($hash_balance, 32), $indextx);
$txOut = new TransactionOutput($final_balance, $program);

// move to p2pkh
//to address
$addressCreator = new AddressCreator();
$dest = $addressCreator->fromString('bc1q0wk5uqdynyczmj574v8qm2cehkk6p3f4mrq7sk');
$moneysss=$final_balance-1000;
// Create unsigned transaction
$tx = (new TxBuilder())
    ->spendOutPoint($outpoint)
    ->payToAddress($moneysss, $dest)//-1000frees
    ->get();

// Sign transaction
$signer = new Signer($tx);
$input = $signer->input(0, $txOut);
$input->sign($key);
$signed = $signer->get();

// Check our signature is correct
//echo "Script validation result: " . ($input->verify(I::VERIFY_P2SH | I::VERIFY_WITNESS) ? "yay\n" : "nay\n");

//echo PHP_EOL;
//echo "Witness serialized transaction: " . $signed->getHex() . PHP_EOL. PHP_EOL;
//echo "Base serialized transaction: " . $signed->getBaseSerialization()->getHex() . PHP_EOL;
echo "txid: {$signed->getTxId()->getHex()}\n";//TXID
$ch = curl_init();

curl_setopt($ch, CURLOPT_URL, 'https://api.blockchair.com/bitcoin/push/transaction');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, "data=".$signed->getHex());

$headers = array();
$headers[] = 'Content-Type: application/x-www-form-urlencoded';
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);

$result = curl_exec($ch);
if (curl_errno($ch)) {
    echo 'Error:' . curl_error($ch);
}
curl_close($ch);
$totx=json_decode($result, true);
$sytx=$signed->getTxId()->getHex();
if($totx['data']['transaction_hash']==$sytx){
   $DB->exec("UPDATE `btc` SET `tx`='{$sytx}',`status`='0' WHERE `id`='{$row['id']}'");
echo 'great';
}else{
echo 'error:'.$result;
}
wartw commented 4 years ago

Fatal error: Uncaught TypeError: Argument 1 passed to BitWasp\Bitcoin\Transaction\Factory\InputSigner::sign() must implement interface BitWasp\Bitcoin\Crypto\EcAdapter\Key\PrivateKeyInterface, string given, called in /var/www/admin/corn/test.php on line 61 and defined in /var/www/admin/corn/vendor/bitwasp/bitcoin/src/Transaction/Factory/InputSigner.php:1021 Stack trace:

0 /var/www/admin/corn/test.php(61): BitWasp\Bitcoin\Transaction\Factory\InputSigner->sign('xprv9vk7fGTQx3o...')

1 {main}

thrown in /var/www/admin/corn/vendor/bitwasp/bitcoin/src/Transaction/Factory/InputSigner.php on line 1021

wartw commented 4 years ago

Am I misunderstanding something?

wartw commented 4 years ago

I don't understand which sign of bip2 should I use to sign the transaction

afk11 commented 4 years ago

This is a very obvious PHP error, what is confusing about it? I'm not here to do your job.

I don't understand which sign of bip2 should I use to sign the transaction

What is "Sign of bip32"?

wartw commented 4 years ago

Google translation, may misunderstand what I mean! My address is generated by bip32. I have successfully received the money. I need to transfer it now, but I do n’t know what to get the signed key.

afk11 commented 4 years ago

$key1->getPrivateKey() gets the privkey from a HD key. Then you use the privkey to sign, like the last time.

wartw commented 4 years ago
OK, if I use
 $ key0 = $ hdFactory-> fromExtended ("xprv9vk7fGTQx3oxxxxxx"); // existing xprv $ key = $ key0-> toExtendedPrivateKey ($ network); 
$ key1 = $ key0-> deriveChild (0); 
$ key2  = $ key1-> deriveChild (999999);
 Use "$ key2-> getPrivateKey ();" to sign?
afk11 commented 4 years ago

It depends where you sent the funds. If you made the address from key2, then you should sign with key2.

wartw commented 4 years ago

I'll get up tomorrow and try it out, thank you for helping me speed up a lot of development time. I have also studied for more than half a month before I understand that OUTX is the last transaction TXID (I know this is funny

wartw commented 4 years ago

I succeeded! !!