vulpemventures / go-elements

Go support for Liquid/Elements transactions
MIT License
30 stars 13 forks source link

Get the WitnessPubKeyHash from a Payment #186

Closed SonnyAD closed 2 years ago

SonnyAD commented 2 years ago

Hi,

I was wondering something.

I am making P2WPKH payments with an application, and from another one I try to read the blocks and retrieve any payment made by the other application.

data := []byte(msg)
x := bytes.NewBuffer(data)
b, err := block.NewFromBuffer(x)
if err != nil {
    fmt.Println(err)
    return
}
fmt.Println("-- BLOCK")
for tx := range b.TransactionsData.Transactions {
    fmt.Println("---- TXN")
    for output := range tx.Outputs {
        fmt.Println("------ OUTPUT")

        if output.Script == nil || len(output.Script) == 0 {
            return
        }

        switch address.GetScriptType(output.Script) {
        case address.P2WpkhScript:
            fmt.Println("------ P2WPKH")

            p, err := payment.FromScript(output.Script, &network.Regtest, nil)
            if err != nil {
                fmt.Println(err)
                continue
            }

                        // same outputs
            fmt.Println(p.WitnessPubKeyHash())
            fmt.Println(p.WitnessScriptHash())

        default:
            fmt.Println("------ OTHER")
            continue
        }
    }
}

So my first question is why the output of the two lines:

            fmt.Println(p.WitnessPubKeyHash())
            fmt.Println(p.WitnessScriptHash())

is the same?

And my second question is that somehow the output is the same, but actually it's not what I am expecting. I get a long address of 75 bytes, while the payments are made on addresses of 43 bytes. So I am expecting an address of 43 bytes.

Looking more carefully at the output, I noticed that the addresses are matching minus the "checksum":

Original address:      ert1q989xa8zz0a4fs7zrsmfsacwkvnup8vyd 27xnhv
p.WitnessPubKeyHash(): ert1q989xa8zz0a4fs7zrsmfsacwkvnup8vyd 989xa8zz0a4fs7zrsmfsacwkvnup8vydul8w9d

But a checksum of 38 chars for WitnessPubKeyHash not sure, that makes sense.

So isn't there too much data in the p.WitnessHash? It looks like it.

I have been able to recompute the address I was expecting with the right checksum, by using bech32.ConvertBits on p.WitnessHash then cutting the results to keep the 32 first bytes.

So that kind of comforts me into that idea that there are too much data in WitnessHash, or (most likely) just something out of my knowledge.

Sorry the lengthy message, thanks for your help

altafan commented 2 years ago

Hi @SonnyAD

Thanks for the detailed report.

I was able to replicate what you're experiencing and after inspecting the payment pkg I found the bug. I'll open a PR soon to fix it.