Litecoin (LTC) - MimbleWimble transactions using Regtest network

Introduction

Litecoin has implemented MimbleWimble using an Extension Blocks sidechain, commonly referred to as “MWEB”. I couldn’t find any references to using MWEB other than articles which delve more into the technology but not the day to day wallet interaction. This post utilizes the standalone private Regtest network to demonstrate the usage. There are Additional links and references at the bottom of this post if you need an overview of the technology.

Definitions:

  • Peg In = Sending funds from Main chain > MWEB chain
  • Peg Out = Sending funds from MWEB > Main chain

This will run through the Regtest network set up and demonstration of Peg In and Peg Out transactions.

Assumes Ubuntu LTS is the operating system.

Build

Install dependencies

$ sudo apt-get install build-essential libtool autotools-dev automake pkg-config bsdmainutils python3
$ sudo apt-get install libevent-dev libboost-system-dev libboost-filesystem-dev libboost-test-dev libboost-thread-dev libfmt-dev libdb++dev libssl-dev

Clone and build. We disable the GUI, running tests and benchmarks to reduce build time.

$ git clone https://github.com/litecoin-project/litecoin.git
$ cd litecoin/
$ ./autogen.sh
$ ./configure --without-gui --disable-tests --disable-bench --with-incompatible-bdb
$ make 

Set RPCUSER and RPCPASSWORD

$ mkdir ~/.litecoin
$ vi ~/.litecoin/litecoin.conf

Write the following to ~/.litecoin/litecoin.conf

rpcallowip=0.0.0.0/0
rpcuser=user
rpcpassword=password

Clean up any previous Regtest network

Delete previously created Regtest network and wallets (wallets don’t persist on restart unless you set a parameter on wallet creation)

$ rm -fr ~/.litecoin/regtest/

Start daemon in Regtest mode

Start in Regtest mode to create a private block chain. Enable TX indexing.

~/litecoin$ cd src
~/litecoin/src$ ./litecoind -regtest -daemon -txindex

Create wallet and address

Create a wallet with descriptors disabled. This allows dumping/importing private keys. We also set an empty passphrase.

$ ./litecoin-cli -regtest createwallet default false false '' false false

Import private key. This is just a random private key but keeps the addresses in this post the same.

$ ./litecoin-cli --regtest importprivkey cShn2dZmfaBVciRLWikeKW5MdERtje2S2HtnUgtTL5gtUhDqxNX6

Importing the private key creates these addresses (ignore the generated MWEB address as it will be different each time. We will generate another one).

$ ./litecoin-cli -regtest listreceivedbyaddress 0 true
[
  {
    "address": "mqnZPpp7uodvK42D28cLAd7VHbUDdcFScS",
    "amount": 0.00000000,
    "confirmations": 0,
    "label": "",
    "txids": [
    ]
  },
  {
    "address": "QQP6j7txv6BErhv3j1QaN5vaSc8JmEgVTy",
    "amount": 0.00000000,
    "confirmations": 0,
    "label": "",
    "txids": [
    ]
  },
  {
    "address": "rltc1qwzjvhl5u5szu6l3cn240lszuxm9rq8ne6a9k7y",
    "amount": 0.00000000,
    "confirmations": 0,
    "label": "",
    "txids": [
    ]
  },
  {
    "address": "tmweb1qqd4qan4hupmy0nham7r59elvgtte3nsl6dlnrwqm8ss42e37l0z7qqeyk8ys6qw3v74g3kh9g3a3knj8ntvz9z7pwn3xqxm4pgtwa9rnpcttq3yf",
    "amount": 0.00000000,
    "confirmations": 0,
    "label": "",
    "txids": [
    ]
  }
]

Set the Bech32 address (starts with rltc1) to the variable ADDRESS. Set a non-wallet Burn address to variable BURN ADDRESS, which will be used to mine additional funds to (this is just a random address so that these block reward UTXOs are discarded and tracked balances aren’t tainted):

$ ADDRESS=rltc1qwzjvhl5u5szu6l3cn240lszuxm9rq8ne6a9k7y
$ BURNADDRESS=rltc1qz5qdn6msnvj6266jxyzd3qlf7wxcudrwx2da8n

Create an MWEB address

Create an MWEB address and set the address to the variable MWEBADDRESS. This MWEB address will be different each time.

$ MWEBADDRESS=$(./litecoin-cli -regtest getnewaddress "" mweb) && echo $MWEBADDRESS
tmweb1qqdvsa0dku3sl4v09f2tu5ucdv8d40v8qp9u5mj67ky7gr8xaem68xqjnenprcga3mfd5etnh04z236utjukrrfl6sdy6kvdzmx2zmwappc6scg75

Generate 1 block and send mining rewards to ADDRESS. This is a 50 LTC block reward.

$ ./litecoin-cli -regtest generatetoaddress 1 $ADDRESS

Generate 500 blocks and send mining rewards to BURN ADDRESS. This generates all pre-MWEB blocks and errors out at block height 431. It needs a MWEB TX to continue.

$ ./litecoin-cli -regtest generatetoaddress 500 $BURNADDRESS
error code: -1
error message:
CreateNewBlock: TestBlockValidity failed: bad-txns-vin-empty, Transaction check failed (tx hash 58338ec7c9c4e6086f9eef6093d79a69d930d7ca695d1759b07180fef29d8f8e)

Note that the latest confirmed block does not have MWEB headers

$ ./litecoin-cli -regtest getblock $(./litecoin-cli -regtest getbestblockhash)
{
  "hash": "78a0395a49ef0aacae931156f55cc27a85772d32be62755543d76cf4c1497d85",
  "confirmations": 1,
  "strippedsize": 215,
  "size": 251,
  "weight": 896,
  "height": 431,
  "version": 805306384,
  "versionHex": "30000010",
  "merkleroot": "882ff74236f8eee1b62dc939bafbc3772d6e5f55661c3b15db6cc8185d4f9341",
  "tx": [
    "882ff74236f8eee1b62dc939bafbc3772d6e5f55661c3b15db6cc8185d4f9341"
  ],
  "time": 1658644349,
  "mediantime": 1658644348,
  "nonce": 0,
  "bits": "207fffff",
  "difficulty": 4.656542373906925e-10,
  "chainwork": "0000000000000000000000000000000000000000000000000000000000000360",
  "nTx": 1,
  "previousblockhash": "9532c5eff53f5e0848f6a0383a0d4c4d9b76edcd656b52bddb841474002dedf0"
}

Check balance. These are the funds we will work with.

$ ./litecoin-cli -regtest getbalance
50.00000000

Peg In transaction

Send 10 LTC to MWEB address. This is a Peg In transaction.

$ ./litecoin-cli -regtest sendtoaddress $MWEBADDRESS 10

Balance will be reduced, subtracting TX fee.

$ ./litecoin-cli -regtest getbalance
49.99963500

Generate 1 block to confirm the TX sent to MWEB

$ ./litecoin-cli -regtest generatetoaddress 1 $BURNADDRESS

Inspect block header of the latest block. It will also have MWEB headers.

$ ./litecoin-cli -regtest getblock $(./litecoin-cli -regtest getbestblockhash)

Inspect full block with TX details. It will have the confirmed MWEB TX.

$ ./litecoin-cli -regtest getblock $(./litecoin-cli -regtest getbestblockhash) 2

List unspent UTXOs will have 2 UTXOs now. The 10 LTC UTXO was received by our MWEB address:

$ ./litecoin-cli -regtest listunspent
[
  {
    "txid": "c4c8213803a9181973b0ef16781bcc21efb95567c0cfc50971cc3c0db1900409",
    "amount": 39.99963500,
    "confirmations": 1,
    "spendable": true,
    "address": "tmweb1qqwpnhqnaywjdefrr94vh6t0s4jdcgg4qyujxcntlq0qukk6k92knvqu5m36y0k2z3e5qhmchuex4cz59dmjyp87wv8jd59h3rcwgg37ga5e4we6t"
  },
  {
    "txid": "c4c8213803a9181973b0ef16781bcc21efb95567c0cfc50971cc3c0db1900409",
    "amount": 10.00000000,
    "confirmations": 1,
    "spendable": true,
    "address": "tmweb1qqdvsa0dku3sl4v09f2tu5ucdv8d40v8qp9u5mj67ky7gr8xaem68xqjnenprcga3mfd5etnh04z236utjukrrfl6sdy6kvdzmx2zmwappc6scg75",
    "label": ""
  }
]

Peg Out transaction

Send 41 LTC to ADDRESS. Since we have 2 UTXOs which are less than 41 LTC each, this transaction must use the MWEB UTXO. This is a Peg Out TX.

$ ./litecoin-cli -regtest sendtoaddress $ADDRESS 41
3a63849e790244078289a383c44e25cf9e7487c3e0e26be95f5f7953d72b3283

Generate 1 block to confirm TX

$ ./litecoin-cli -regtest generatetoaddress 1 $BURNADDRESS

Check the balances

$ ./litecoin-cli -regtest getbalances
{
  "mine": {
    "trusted": 8.99955100,
    "untrusted_pending": 0.00000000,
    "immature": 41.00000000
  }
}

Notice that the 41 LTC which includes the MWEB UTXO is still immature. MWEB needs 6 confirmations for Peg Out transactions to be mature and be spendable.

Generate 5 more blocks

$ ./litecoin-cli -regtest generatetoaddress 5 $BURNADDRESS

Check the balances

$ ./litecoin-cli -regtest getbalances
{
  "mine": {
    "trusted": 49.99955100,
    "untrusted_pending": 0.00000000,
    "immature": 0.00000000
  }
}

Stop the daemon

Stop the daemon

$ ./litecoin-cli -regtest stop
Litecoin Core stopping