PHP Bitwasp, подписание транзакции биткойн-наличные

Я пытаюсь подписать тестовую транзакцию биткойн-наличные, а затем транслировать. Для версии bitwasp 0.0.35.0 код:

   $utxoOwnerPrivateKey = 'MyPrIvAtEKey';//public key is "16Dbmp13CqdLVwjXrd6amF48t7L8gYSGBj", note - the real private key is another
   $utxo = '5e44cdab9cb4a4f1871f2137ab568bf9ef2760e52816971fbaf0198f19e28378';
   $utxoAmount = 598558;
   $reciverPublicKey = '1EjCxux1FcohsBNGzY9KdF59Dz7MYHQyPN';
   $fee = 1000;

   $addressCreator = new \Btccom\BitcoinCash\Address\AddressCreator();

   $networkObject = \Btccom\BitcoinCash\Network\NetworkFactory::bitcoinCash();
   $keyPairInput = \BitWasp\Bitcoin\Key\PrivateKeyFactory::fromWif($utxoOwnerPrivateKey, null, $networkObject);


   $outpoint = new \BitWasp\Bitcoin\Transaction\OutPoint(\BitWasp\Buffertools\Buffer::hex($utxo, 32), 0);


   $transaction = \BitWasp\Bitcoin\Transaction\TransactionFactory::build()
       ->spendOutPoint($outpoint)
       ->payToAddress($utxoAmount - $fee, $addressCreator->fromString($reciverPublicKey, $networkObject) )
       ->get();

   echo "Unsigned transaction: " . $transaction->getHex() . '<BR><BR>';

   $signScript = \BitWasp\Bitcoin\Script\ScriptFactory::scriptPubKey()->payToPubKeyHash($keyPairInput->getPublicKey()->getPubKeyHash());
   $txOut = new \BitWasp\Bitcoin\Transaction\TransactionOutput($utxoAmount  - $fee, $signScript);

   $signer = new \BitWasp\Bitcoin\Transaction\Factory\Signer($transaction);

   $signatureChecker = \Btccom\BitcoinCash\Transaction\Factory\Checker\CheckerCreator::fromEcAdapter( \BitWasp\Bitcoin\Bitcoin::getEcAdapter() ); // for version 0.0.35
   $signer->setCheckerCreator( $signatureChecker ); // for version 0.0.35
   $input = $signer->input(0, $txOut);
   $signatureType = \Btccom\BitcoinCash\Transaction\SignatureHash\SigHash::ALL | \Btccom\BitcoinCash\Transaction\SignatureHash\SigHash::BITCOINCASH;
   $input->sign($keyPairInput, $signatureType);
   $signed = $signer->get();


   echo "Witness serialized transaction: " . $signed->getHex() . '<BR><BR>';
   echo "Base serialized transaction: " . $signed->getBaseSerialization()->getHex() . '<BR><BR>';
   echo "Script validation result: " . ($input->verify() ? "yes\n" : "no\n"). '<BR><BR>';

   die();

В этом случае я получаю результат:

Script validation result: no

При попытке транслировать транзакцию BCH возникает ошибка:

An error occured:
16: mandatory-script-verify-flag-failed (Signature must be zero for failed CHECK(MULTI)SIG operation). Code:-26

Думаю, значит, подпись неправильная. Если мы уберем флаг $signatureType (оставим это значение по умолчанию), тогда Script validation result будет yes, но трансляция выдаст ошибку:

16: mandatory-script-verify-flag-failed (Signature must use SIGHASH_FORKID). Code:-26

Я думаю, это означает - транзакция, подписанная как в сети биткойнов, должна быть подписана правилами биткойн-наличных. Может я ошибаюсь. Но подписание транзакции биткойнов - это нормально. У Bitwasp нет руководств, как подписывать транзакции bitcoin-cash, у меня такой же код для bitwasp v.0.0.34.2 (без надстройки «btccom / bitwasp-bitcoin-bch-addon», с использованием функции $signer->redeemBitcoinCash(true);), но он дает то же самое результат.

Интересно, что в коде подписывающего bitcoin-cash он берет внутреннюю переменную amount и включает ее в хеш:

$hasher = new V1Hasher($this->transaction, $this->amount);

Но для биткойнов bitwasp не берет сумму, предположительно, она берет сумму из транзакции.

Помогите, пожалуйста, подписать транзакцию, у bitwasp есть только примеры биткойнов, а не биткойн-кеш. Очень сложно найти какую-либо информацию о подписании php альткойнов без стороннего программного обеспечения. С Уважением.


person Alexander Goncharov    schedule 07.09.2018    source источник
comment
Вы ведь не опубликовали настоящий закрытый ключ?   -  person AymDev    schedule 07.09.2018
comment
@AymDev да, это не настоящий закрытый ключ, но я могу выложить настоящий, если нужно, он содержит всего полдоллара :) Главное, узнать, как отправлять транзакции ..   -  person Alexander Goncharov    schedule 07.09.2018


Ответы (1)


Этот код для подписи транзакции bitcoin-cash с библиотекой PHP bitwasp v.0.0.35 работает!

    $unspendedTx = '49343e0a4ef29b819f87df1371c6f8eafa1f235074a27fb6aa5f4ab4c48e5c16';
    $utxOutputIndex = 0;
    $utxoPrivateKey = 'MyPrIvAtEKey';
    $utxoAmount = 300000;
    $reciverPublicKey = '1E8XaWNsCWyVaZaWTLh8uBdAZjLQqwWmzM';
    $fee = 1000;

    $networkObject = \Btccom\BitcoinCash\Network\NetworkFactory::bitcoinCash();

    $outpoint = new \BitWasp\Bitcoin\Transaction\OutPoint(\BitWasp\Buffertools\Buffer::hex($unspendedTx, 32), $utxOutputIndex /* index of utxo in transaction, generated it */);
    $destination = \BitWasp\Bitcoin\Script\ScriptFactory::scriptPubKey()->payToPubKeyHash( (new \Btccom\BitcoinCash\Address\AddressCreator())->fromString($reciverPublicKey)->getHash() );

    $transaction = \BitWasp\Bitcoin\Transaction\TransactionFactory::build()
        ->spendOutPoint($outpoint)
        ->output($utxoAmount - $fee, $destination)
        ->get();
    echo "Unsigned transaction: " . $transaction->getHex() . '<BR><BR>';


    $keyPairInput = \BitWasp\Bitcoin\Key\PrivateKeyFactory::fromWif($utxoPrivateKey, null, $networkObject);
    $txOut = new \BitWasp\Bitcoin\Transaction\TransactionOutput($utxoAmount, \BitWasp\Bitcoin\Script\ScriptFactory::scriptPubKey()->payToPubKeyHash(  $keyPairInput->getPubKeyHash() ) );
    $signer = new \BitWasp\Bitcoin\Transaction\Factory\Signer($transaction);

    $signatureChecker = \Btccom\BitcoinCash\Transaction\Factory\Checker\CheckerCreator::fromEcAdapter( \BitWasp\Bitcoin\Bitcoin::getEcAdapter() ); // for version 0.0.35
    $signer->setCheckerCreator( $signatureChecker ); // for version 0.0.35

    $input = $signer->input(0, $txOut);
    $signatureType = \Btccom\BitcoinCash\Transaction\SignatureHash\SigHash::ALL | \Btccom\BitcoinCash\Transaction\SignatureHash\SigHash::BITCOINCASH;
    $input->sign($keyPairInput, $signatureType);
    $signed = $signer->get();


    echo "Transaction: " . $signed->getHex() . '<BR><BR>';
    die();

Я транслировал эту сгенерированную PHP тестовую транзакцию, см.

$txOut = new \BitWasp\Bitcoin\Transaction\TransactionOutput($utxoAmount  - $fee, $signScript);

Мы должны создать ввод tx (предыдущий вывод) без комиссии.

Используемые библиотеки (composer.json):

{
    "require" : {
        "php" : ">=7.0",
        "bitwasp/bitcoin": "0.0.35.0",
        "btccom/bitwasp-bitcoin-bch-addon" : "0.0.2"
    }
}

Надеюсь, это поможет всем создателям api альткойнов на PHP.

person Alexander Goncharov    schedule 09.09.2018
comment
Спасибо вам большое за это. Я застрял на много часов, и эта строка является основным виновником: $txOut = new \BitWasp\Bitcoin\Transaction\TransactionOutput($utxoAmount, \BitWasp\Bitcoin\Script\ScriptFactory::scriptPubKey()->payToPubKeyHash( $keyPairInput->getPubKeyHash() ) ); Я забыл включить комиссию в сумму вывода, и транзакция всегда не транслировалась. - person Alvin Rusli; 23.01.2019