From 56e7bcbfb6ac8c7fa04326b4fb79254eca6e5246 Mon Sep 17 00:00:00 2001 From: Michael Vandeberg Date: Mon, 27 Jan 2025 16:10:29 -0700 Subject: [PATCH] Implement signing of a transaction id --- internal/cli/commands.go | 61 ++++++++++++++++++++++++--------- internal/cliutil/transaction.go | 13 +++++++ 2 files changed, 58 insertions(+), 16 deletions(-) diff --git a/internal/cli/commands.go b/internal/cli/commands.go index 1f905d4..e494a41 100644 --- a/internal/cli/commands.go +++ b/internal/cli/commands.go @@ -4,6 +4,7 @@ import ( "bytes" "context" "encoding/base64" + "encoding/hex" "encoding/json" "errors" "fmt" @@ -1418,13 +1419,8 @@ func NewSignTransactionCommand(inv *CommandParseResult) Command { } } -// Execute signs a transaction -func (c *SignTransactionCommand) Execute(ctx context.Context, ee *ExecutionEnvironment) (*ExecutionResult, error) { - if !ee.IsWalletOpen() { - return nil, fmt.Errorf("%w: cannot sign transaction", cliutil.ErrWalletClosed) - } - - trxBytes, err := base64.URLEncoding.DecodeString(c.Transaction) +func parseTransaction(transaction string) (*protocol.Transaction, error) { + trxBytes, err := base64.URLEncoding.DecodeString(transaction) if err != nil { return nil, err } @@ -1435,25 +1431,58 @@ func (c *SignTransactionCommand) Execute(ctx context.Context, ee *ExecutionEnvir return nil, err } - err = util.SignTransaction(ee.Key.PrivateBytes(), trx) - if err != nil { - return nil, err + return trx, nil +} + +func parseTransactionId(tid string) ([]byte, error) { + return hex.DecodeString(tid[2:]) +} + +// Execute signs a transaction +func (c *SignTransactionCommand) Execute(ctx context.Context, ee *ExecutionEnvironment) (*ExecutionResult, error) { + if !ee.IsWalletOpen() { + return nil, fmt.Errorf("%w: cannot sign transaction", cliutil.ErrWalletClosed) } - trxBytes, err = proto.Marshal(trx) + trx, err := parseTransaction(c.Transaction) + if err == nil { + err = util.SignTransaction(ee.Key.PrivateBytes(), trx) + if err != nil { + return nil, err + } + + trxBytes, err := proto.Marshal(trx) + if err != nil { + return nil, err + } + + jsonTrx, err := json.MarshalIndent(trx, "", " ") + if err != nil { + return nil, err + } + + encodedTrx := base64.URLEncoding.EncodeToString(trxBytes) + + result := NewExecutionResult() + result.AddMessage(fmt.Sprintf("Signed Transaction:\nJSON:\n%v\nBase64:\n%v", string(jsonTrx), encodedTrx)) + + return result, nil + } + + trxErr := err + + tid, err := parseTransactionId(c.Transaction) if err != nil { - return nil, err + return nil, trxErr } - jsonTrx, err := json.MarshalIndent(trx, "", " ") + signature, err := cliutil.SignTransactionId(ee.Key.PrivateBytes(), tid) if err != nil { return nil, err } - encodedTrx := base64.URLEncoding.EncodeToString(trxBytes) - result := NewExecutionResult() - result.AddMessage(fmt.Sprintf("Signed Transaction:\nJSON:\n%v\nBase64:\n%v", string(jsonTrx), encodedTrx)) + result.AddMessage(fmt.Sprintf("Transaction Signature: %v", base64.URLEncoding.EncodeToString(signature))) return result, nil } diff --git a/internal/cliutil/transaction.go b/internal/cliutil/transaction.go index f309b6d..09387e2 100644 --- a/internal/cliutil/transaction.go +++ b/internal/cliutil/transaction.go @@ -106,3 +106,16 @@ func SignTransaction(key []byte, tx *protocol.Transaction) error { return nil } + +// SignTransactionId signs the transaction ID with the given key +func SignTransactionId(key []byte, tid []byte) ([]byte, error) { + privateKey, _ := btcec.PrivKeyFromBytes(btcec.S256(), key) + + // Decode to multihash ID + idBytes, err := multihash.Decode(tid) + if err != nil { + return nil, err + } + + return btcec.SignCompact(btcec.S256(), privateKey, idBytes.Digest, true) +}