Transaction Tracing

All transactions on the Lombard Protocol are fully traceable between different blockchain networks (both Bitcoin and destination chains where LBTC is supported).

This technical document is aimed at users and developers familiar with different blockchain networks and how data is represented on-chain.

Tracing the Bitcoin Transaction Hash from an LBTC Mint

Scenario: When a user mints LBTC from staking native BTC, the Bitcoin transaction hash to their deposit address is included in the on-chain event logs.

View Mint Events

To view event logs, use a blockchain explorer like Etherscan. Select any one of the transfers of Method type Mint made on the LBTC ERC-20 token smart contract. In the Transaction Details, view the Logs tab and find the OutputProcessedevent log. This log contains:

  • Bitcoin transaction hash in Big-Endian Order: The transactionId value.

  • UTXO index: The index value of the corresponding Lombard deterministic deposit address.

Convert Byte Ordering from Big-Endian to Little-Endian

Bitcoin transactions are stored in big-endian order, but displayed in little-endian order. To search for the transaction on Mempool Space, you will need to convert the transactionId.

The easiest method to convert the Bitcoin transaction hash from big-endian to little-endian is to use an online tool such as this handy converter, selecting Hexal.

Alternatively, via script:

# Reverse the byte order of a transaction ID and convert it to lowercase
echo "D4A6996A178682D3D7123F19E48A502C6076D6916A188C1DAB1C83CCADE7D7D9" \
  | tr 'A-F' 'a-f' \
  | sed 's/../& /g' \
  | awk '{for (i=NF; i>0; i--) printf $i" "; print ""}' \
  | tr -d ' \n'

# Resulting transaction ID to search for on Mempool Space
d9d7e7adcc831cab1d8c186a91d676602c508ae4193f12d7d38286176a99a6d4

Finding the Bitcoin address from an LBTC Redemption

Scenario: Users can initiate the redemption of their native BTC at any time to a chosen recipient address by unstaking LBTC. When a user unstakes LBTC, the recipient Bitcoin address is embedded within the script public key in the on-chain event logs.

View Unstake Events

To view the mint event logs, use a blockchain explorer like Etherscan. Select any one of the transfer of Method type Redeem made on the LBTC ERC-20 token smart contract. In the Transaction Details, view the Logs tab and find the UnstakeRequest event log. This log contains:

  • The address is embedded in the scriptPubKey value of in the event log's data object.

Decode Recipient Bitcoin Address

Use the following Go code snippet with the relevant hexadecimal-encoded scriptPubKey. The resulting output is the recipient Bitcoin address. Alternatively, this snippet can also be run here.

Note: Lombard only supports unstaking to Native Segwit and Taproot addresses. For more information, see LBTC FAQs.

package main

import (
	"encoding/hex"
	"log"

	"github.com/btcsuite/btcd/chaincfg"
	"github.com/btcsuite/btcd/txscript"
)

func main() {
	// Example script public key
	scriptPubKey := "0014ECF86E0724CDD2F803B40FD72D9E40E621494674"

	// Decode the hex-encoded scriptPubKey
	pkScript, err := hex.DecodeString(scriptPubKey)
	if err != nil {
		log.Fatalf("Error decoding hex string: %v", err)
	}

	// Extract the script class and address from the pkScript
	scriptClass, addresses, _, err := txscript.ExtractPkScriptAddrs(pkScript, &chaincfg.MainNetParams)
	if err != nil {
		log.Fatalf("Error extracting address: %v", err)
	}

	// Ensure exactly one address is returned for supported cases
	if len(addresses) != 1 {
		log.Fatalf("Error: Unexpected number of addresses: %d", len(addresses))
	}
	
	// Handle supported script classes
	switch scriptClass {
	case txscript.WitnessV0PubKeyHashTy: // P2WPKH
		log.Println("Extracted Recipient Address:", addresses[0].EncodeAddress())
	case txscript.WitnessV0ScriptHashTy: // P2WSH
		log.Println("Extracted Recipient Address:", addresses[0].EncodeAddress())
	case txscript.WitnessV1TaprootTy: // P2TR
		log.Println("Extracted Recipient Address:", addresses[0].EncodeAddress())
	default:
		log.Fatalf("Unsupported script type: %v", scriptClass)
	}
}

Last updated