dart-bitcoin/bitcoin_flutter

Signin a transaction from a HDWallet fails.

Closed this issue · 1 comments

I may be doing something wrong here, but I have a test wherein I generate a wallet and use it's private key to sign a transaction (inspired by https://github.com/dart-bitcoin/bitcoin_flutter/blob/master/test/integration/transactions_test.dart#L11)

So here's how it looks: (this is just testnet so I'm going to post the keys here too)

import 'dart:convert';
import 'dart:typed_data';
import 'package:test/test.dart';
import 'package:bitcoin_flutter/bitcoin_flutter.dart';
import 'package:raven/account.dart';
import 'package:bip39/bip39.dart' as bip39;

main() {
  test('bitcoinjs-lib (transactions) can create a 1-to-1 Transaction', () {
    ...
    final alice =
ECPair.fromWIF('L1uyy5qTuGrVXrmrsvHWHgVzW9kKdrp27wBC7Vs6nZDTF2BRUVwy');
    print(alice.privateKey);
    print(Uint8List.fromList(node.wallet.privKey.codeUnits));
    print(node.wallet.privKey);
    final pair = ECPair(Uint8List.fromList(node.wallet.privKey.codeUnits),
        Uint8List.fromList(node.wallet.pubKey.codeUnits),
        network: node.params.network, compressed: true);
    final txb = TransactionBuilder(network: node.params.network);
    txb.setVersion(1);
    txb.addInput(
        '56fcc747b8067133a3dc8907565fa1b31e452c98b3f200687cb836f98c3c46ae',
        1);
    txb.addOutput('mp4dJLeLDNi4B9vZs46nEtM478cUvmx4m7', 4000000);
    txb.sign(vin: 0, keyPair: pair);
  });
}

Now when I run this test I get an error on the last line:

Invalid argument(s): Expected Private
  package:bip32/src/utils/ecurve.dart 134:22                   sign
  package:bitcoin_flutter/src/ecpair.dart 33:12                ECPair.sign
  package:bitcoin_flutter/src/transaction_builder.dart 201:33  TransactionBuilder.sign
  test\raven_tx_send_test.dart 37:9                            main.<fn>

and the print outs for the keys are:

alice.privateKey:
[140, 17, 44, 246, 40, 54, 46, 207, 77, 72, 47, 104, 175, 45, 187, 80, 200, 162, 203, 144, 210, 38, 33, 93, 233, 37, 65, 122, 169, 51, 106, 72]

Uint8List.fromList(node.wallet.privKey.codeUnits):
[102, 49, 56, 100, 98, 101, 57, 57, 101, 98, 57, 101, 102, 99, 50, 56, 100, 57, 99, 52, 97, 50, 57, 97, 53, 48, 100, 56, 57, 54, 48, 99, 97, 55, 57, 54, 48, 99, 99, 102, 101, 97, 48, 50, 101, 102, 57, 49, 98, 101, 52, 98, 102, 50, 49, 98, 49, 49, 98, 97, 101, 50, 49, 97]

node.wallet.privKey:
f18dbe99eb9efc28d9c4a29a50d8960ca7960ccfea02ef91be4bf21b11bae21a

Notice the privKey on he HDwallet is much longer than the alice privateKey from the WIF in the example.

That difference in length causes the error because when it checks to see if it's a private key in the ecurve.dart it fails:

bool isPrivate(Uint8List x) {
  if (!isScalar(x)) return false;
  return _compare(x, ZERO32) > 0 && // > 0
      _compare(x, EC_GROUP_ORDER) < 0; // < G
}

The length is actually 64 in this case. I'm wondering what to do here. Is the IsPrivate function mistaken? am I converting it to a Uint8List in the wrong way? Is there a way to convert the HDwallet privatekey to the same format as the WIF? would that cause problems? Like I said I don't know if it's a problem in the code or if I just don't understand something, thank you.

PS. I'm using a different network as well:

final ravencoinTestnet = NetworkParams(
    name: 'Ravencoin Testnet',
    testnet: true,
    network: NetworkType(
        messagePrefix: '\x16Raven Signed Message:\n',
        bech32: 'tr',
        bip32: Bip32Type(public: 0x043587cf, private: 0x04358394),
        pubKeyHash: 0x6f,
        scriptHash: 0xc4,
        wif: 0xef),
    derivationBase: "m/44'/175'/1'");

I don't know how to convert the two different kinds of signatures, however, I avoided the situation altogether by using the hdwallet.wif to generate the ecpair instead. Therefore I'm closing this issue.