bip32 hd wallets – I’m not having the ability to signal PSBT transactions with Zprv in uBitcoin

0
63


I’m simply toying round with this in my Arduino ESP32 Nano, and for some motive I’m not having the ability to export a sound PSBT when utilizing a non-public key within the Zprv format, the next method:

#embody "Bitcoin.h"
#embody "PSBT.h"

#embody "Secrets and techniques.h"

#outline MAX_PSBT_SIZE 3000

HDPrivateKey hd(XPRV); // Only a string like "ZprvAhrnh(...)"
PSBT psbt;

void setup() {
  Serial.start(115200);
  whereas (!Serial) ;
  Serial.println(LABEL);
  Serial.println("Please enter the bottom 64 PSBT:");
}

void loop() {
  if (Serial.accessible() > 0) {

    String enter = "";
    char c;
    int charCount = 0;

    whereas (true) {
      c = Serial.learn();
      if(c == 'n' || charCount >= MAX_PSBT_SIZE) {
        break;
      } else if ((int)c < (int)'!' || (int)c > (int)'z') {
        proceed;
      }

      enter += c;
      charCount++;
    }

    Serial.println("Acquired PSBT:");
    Serial.println(enter);
    // Parse the enter as base64 PSBT
    psbt.parseBase64(enter);

    // Verify parsing is OK
    if (!psbt) {
      Serial.println("Failed parsing transaction");
      Serial.println("Please enter the bottom 64 PSBT:");
      return;
    }

    Serial.println("Transactions particulars:");

    // going via all outputs to print data
    Serial.println("Outputs:");
    for(int i=0; i<psbt.tx.outputsNumber; i++){
      // print addresses
      Serial.print(psbt.tx.txOuts[i].tackle(&Regtest));
      Serial.print(" -> ");
      Serial.print(psbt.tx.txOuts[i].btcAmount()*1e3);
      Serial.println(" mBTC");
    }
    Serial.print("Price: ");
    Serial.print(float(psbt.price()));
    Serial.println(" sats");
    
    psbt.signal(hd);
    Serial.println("============================================");
    Serial.println(psbt.toBase64()); // now you possibly can mix and finalize PSBTs in Bitcoin Core
    Serial.println("============================================");

    Serial.println(LABEL);
    Serial.println("Please enter the bottom 64 PSBT:");
    return;
  }
}

This mainly receives a PSBT from the serial comm, and outputs the signed PSBT.

Nonetheless, I imagine the parsing of Zprv is buggy, I attempted to debug the fingerprint half and the parsed fingerprint appears completely completely different, then from that time on every thing fails, the PSBT.signal perform can not discover a match public key matching my non-public key and proceeds with out signing.

PS. Neglect “Secrets and techniques.h”, it simply defines the XPRV fixed (I ought to really name it ZPRV).

This is what I used to be capable of debug:

For instance, for this key:

Screenshot from 2023-10-21 08-05-10

Screenshot from 2023-10-21 08-11-07

(Discover the Grasp fingerprint of 5A:21:88:34).

Then I export this with Sparrow to the Electrum json format to acquire the xprv:

{
  "keystore": {
    "xpub": "zpub6rgGh4Q21dLzrac8fqhtCubP5JpfDSf6BJLyJKjfn3D2ojp56PFn7nD7pwVRMtJk9EkkFDW4UrGeDWyFnBfptgvC8uvjWY6PoutNMLwzTyu",
    "xprv": "zprvAY3WiCK4YLmi4neGTqnauNMd8cFLhobtcP3ANMi4CtbLeCeVRzRWCw9qivm3stUnXQ3hwDfCSBzY5qUWcLeatCjadMLmaebwR2fS2suNaHL",
    "kind": "bip32",
    "pw_hash_version": 1
  },
  "wallet_type": "normal",
  "use_encryption": false,
  "seed_type": "bip39"
}

Now, if I present

HDPrivateKey hd("zprvAY3WiCK4YLmi4neGTqnauNMd8cFLhobtcP3ANMi4CtbLeCeVRzRWCw9qivm3stUnXQ3hwDfCSBzY5qUWcLeatCjadML");

The fingerprint I’ll discover at this a part of the code shall be: B9:40:6D:D9

And on this a part of the code shall be: FF:73:D5:35

And as you possibly can see from the photographs above, they don’t have anything to do with the true grasp fingerprint of 5A:21:88:34.

I don’t know how the initally parsed B9:40:6D:D9 turns into FF:73:D5:35 when it reaches the PSBT signing perform, however each values don’t match the anticipated 5A:21:88:34.

Thus, I imagine there is a bug parsing these Zprv keys. Perhaps even parsing different elements as effectively, I did not validate additional as a result of the fingerprint alone is motive for it to fail.

It makes the PSBT.signal() perform fail at this situation, thus ignore signing any PSBT, as a result of it’ll by no means match any fingerprint within the PSBT metadata.

LEAVE A REPLY

Please enter your comment!
Please enter your name here