2

I am looking to unmarshal a pre-built transaction envelope for signing using the new txnbuild package in the Go SDK but I'm missing a step and can't find the correct way to unmarshal. This is what I have so far:

// Unmarshall the envelope
var decoded xdr.TransactionEnvelope
err = xdr.SafeUnmarshalBase64(env, &decoded) // env is the xdr string
check(err, "Unmarshal transaction envelope")
tx := // convert to txnbuild transaction... but how?

// Rebuild, sign, encode and prepare response
txe, err := tx.BuildSignEncode(signer.(*keypair.Full))
check(err, "Rebuild, sign and encode transaction")

I think I just need to convert the xdr.TransactionEnvelope to a txnbuild.Transaction for signing.

1

2 Answers 2

2

Support for this has now been added to the SDK in txnbuild 1.4. Here's an example that produces the same output as the previous lower-level workaround: https://play.golang.org/p/5uXzCEK_bgc

package main

import (
    "fmt"
    "github.com/stellar/go/txnbuild"
    "github.com/stellar/go/network"
)

func main() {
    // An existing Base 64 serialised transaction envelope
    txeB64 := "AAAAAPkNnnxDCzRheIvmmH7rVFxjEpX/LTXrynktSZf6AlRpAAAAZAAWgB0AAAABAAAAAAAAAAAAAAABAAAAAAAAAAoAAAAEdGVzdAAAAAEAAAAEdGVzdAAAAAAAAAAA"

    // Deserialise the provided transaction
    tx, err := txnbuild.TransactionFromXDR(txeB64)
    if err != nil {
        panic(err)
    }

    // Explicitly set the network where this transaction is to be valid
    tx.Network = network.TestNetworkPassphrase

    // Add a signature
    err = tx.SignWithKeyString("SC7HGDR2N3Z5D4OJ54PZLF6LSYSDNEKM7QGR6SBEPHLN63NZ2XSLUHVQ")
    if err != nil {
        panic(err)
    }

    // Serialise the transaction
    b64, err := tx.Base64()
    if err != nil {
        panic(err)
    }

    fmt.Println("Signed XDR is: ", b64)
}
3

There is no support yet for building a txnbuild.Transaction object from a xdr.TransactionEnvelope in the Go SDK. However, you can still sign the transaction by using this work around: https://play.golang.org/p/tr6y1Gim_4d

See code below as well

package main

import (
    "bytes"
    "encoding/base64"
    "fmt"

    "github.com/stellar/go/keypair"
    "github.com/stellar/go/network"
    "github.com/stellar/go/xdr"
)

func main() {

    var txEnv xdr.TransactionEnvelope
    err := xdr.SafeUnmarshalBase64("AAAAAPkNnnxDCzRheIvmmH7rVFxjEpX/LTXrynktSZf6AlRpAAAAZAAWgB0AAAABAAAAAAAAAAAAAAABAAAAAAAAAAoAAAAEdGVzdAAAAAEAAAAEdGVzdAAAAAAAAAAA",
        &txEnv)
    if err != nil {
        panic(err)
    }
    txHash, err := network.HashTransaction(&txEnv.Tx, network.TestNetworkPassphrase)
    if err != nil {
        panic(err)
    }
    kp := keypair.MustParse("SC7HGDR2N3Z5D4OJ54PZLF6LSYSDNEKM7QGR6SBEPHLN63NZ2XSLUHVQ")

    sig, err := kp.SignDecorated(txHash[:])
    if err != nil {
        panic(err)
    }
    // Append the signature to the envelope
    txEnv.Signatures = append(txEnv.Signatures, sig)

    // convert to base64 xdr
    var txBytes bytes.Buffer
    _, err = xdr.Marshal(&txBytes, txEnv)
    if err != nil {
        panic(err)
    }

    b64 := base64.StdEncoding.EncodeToString(txBytes.Bytes())
    fmt.Println("Signed XDR is: ", b64)
}
1

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.