MetacoSA / NBitcoin

Comprehensive Bitcoin library for the .NET framework.
MIT License
1.87k stars 846 forks source link

calling GetAddress() with ScriptPubKeyType.TaprootBIP86 generates incorrect address? #1159

Closed moccajoghurt closed 1 year ago

moccajoghurt commented 1 year ago

I am trying to convert a private key (provided as hex string) to the bitcoin address using the following code:

public Task<string> GetAddress()
    {
        var bytes = Convert.FromHexString("0000000000000000000000000000000000000000000000000000000000001337");
        var secret = new Key(bytes);
        var addr = secret.GetAddress(ScriptPubKeyType.TaprootBIP86, Network.Main);
        return Task.FromResult(addr.ToString());
    }

This results in the following address: bc1pqwj9szpzxeyfrdgqt8pqlgkn4vx6frjccrw3fxeduw597t0vpjjqhwg24e

The problem I am facing is that other tools generate different addresses. I tested the same using this generator: https://privatekeys.pw/calc and the python library "bitcoinaddress".

They both generate the following addresses when I input the same hex string: Public Address 1: 1BouazM6y9R62FBUTN7q1W12qJHoRzsvGK Public Address 1 compressed: 165GPNv11qdnaFVBuZqSTrWiMoBxP41bu9 Public Address 3: 3JuU4XzrtkEhH7vPwjfe3wgpMea8xov5RD Public Address bc1 P2WPKH: bc1qx7nj9hj7nl95s3354gahkk2k4mfyah7kd2k2cq Public Address bc1 P2WSH: bc1q5sxf9jlppxxjecwt0x80vfkvavlkzetl2ph30nlzp5l4ud6jlyds243etp

They don't just look different, they point to a different wallet. Is there something I am missing? How is this possible?

Edit: I just found out that using "ScriptPubKeyType.Segwit" creates the correct address. But this confuses me. I thought the same private key will always point to the same wallet, even if the addresses can be different.

dangershony commented 1 year ago

I thought the same private key will always point to the same wallet, even if the addresses can be different

I am not sure I understand you expected to see a segwit address when using a taproot address?

NicolasDorier commented 1 year ago

But this confuses me. I thought the same private key will always point to the same wallet, even if the addresses can be different.

No, a wallet in bitcoin in general is a BIP32 seed (see https://www.youtube.com/watch?v=-7kHWZCYJkk), with a derivation path for deposit, a derivation path for change, and a function to generate an scriptPubKey from derived keys.

P2PKH, P2WPKH, wrapped P2WPKH and Taproot86 are well known functions for it.

Nowadays, if you don't know what to choose, the best is P2WPKH. (ScriptPubKeyType.Segwit)

moccajoghurt commented 1 year ago

Thanks for explaining!