Integrating Blockstream’s Liquid payments on SideShift AI
Blockstream’s Liquid product is a fork of Bitcoin that replaces the consensus model from proof-of-work to a federated consensus model. Most users are familiar with the federated consensus model from other payment networks such as Ripple.
Bitfinex and BitMEX were announced by Blockstream as partnering exchanges, but I was unable to find deposit/withdrawal of L-BTC on either exchange. Perhaps SideShift AI will be the first to integrate Liquid.
I deploy a Ubuntu 18.04 instance on Amazon AWS with these modest specs:
- t2.smal (1 vCPU, 2 GB RAM)
- OS volume: 20 GB SSD
- Data volume: 250 GB SSD
The reason for the low specs is that Liquid is new and won’t have to deal with a large mempool or transaction throughput.
I habitually use a separate volume for the node data, which includes configuration file, blockchain data, wallet data. This allows me to easily switch over to a new machine if the OS should suffer a catastrophic event.
Liquid requires both a
liquidd node and a
bitcoind node. This is because Liquid is a sidechain that’s able to receive BTC from the Bitcoin chain and return BTC to the Bitcoin chain.
Over at the releases page on the Liquid Github I find the latest release, v184.108.40.206, download and extract it:
$ wget https://github.com/Blockstream/liquid/releases/download/liquid.220.127.116.11/liquid-18.104.22.168-x86_64-linux-gnu.tar.gz
$ tar zxf liquid*.tar.gz
$ ln -s `realpath liquid-22.214.171.124` `realpath liquid`
$ pushd /usr/local/bin
$ sudo ln -s /home/ubuntu/liquid/bin/* .
I’ve now created symbolic links like this:
/usr/local/bin/liquidd -> /home/ubuntu/liquid/bin/liquidd -> /home/ubuntu/liquid-126.96.36.199/bin/liquidd
This symlink chain makes it convenient to upgrade Liquid in the future. I just need to replace the link to
I replace this procedure for the latest version of Bitcoin Core, such that
/usr/local/bin/bitcoind links to
You can see in the
systemd unit files that
liquidd have their data directories set to
/opt/liquid respectively. The
/opt directory is the data volume I described previously.
The Bitcoin configuration file,
/opt/bitcoin/bitcoin.conf is quite straight forward:
The Liquid daemon must be able to speak to the Bitcoin daemon, which we configure in
Liquid is now able to speak to Bitcoin over RPC.
Starting the instances
I first enable and start the
bitcoind system service:
$ sudo systemctl enable bitcoind● bitcoind.service - Bitcoin Daemon
$ sudo systemctl start bitcoind
$ sudo systemctl status bitcoind
Loaded: loaded (/etc/systemd/system/bitcoind.service; enabled; vendor preset: enabled)
Active: active (running) since Mon 2018-11-12 01:05:18 UTC; 1 day ago
Main PID: 1624 (bitcoind)
Tasks: 13 (limit: 2362)
└─1624 /usr/local/bin/bitcoind -datadir=/opt/bitcoin
Jan 17 20:49:46 sideshift-liquid bitcoind: 2019-01-17T20:49:46Z Pre-allocating up to position 0x1000000 in blk01498.dat
Jan 17 20:49:46 sideshift-liquid bitcoind: 2019-01-17T20:49:46Z Pre-allocating up to position 0x100000 in rev01498.dat
and for the
$ sudo systemctl enable liquidd● liquidd.service - Liquid Daemon
$ sudo systemctl start liquidd
$ sudo systemctl status liquidd
Loaded: loaded (/etc/systemd/system/liquidd.service; enabled; vendor preset: enabled)
Active: active (running) since Mon 2018-11-12 01:07:30 UTC; 1 day ago
Main PID: 1766 (liquidd)
Tasks: 14 (limit: 2362)
└─1766 /usr/local/bin/liquidd -datadir=/opt/liquid
Jan 17 22:01:36 sideshift-liquid liquidd: 2019-01-17 22:01:36 UpdateTip: new best=f3a5b642f9e0347642c3a4412d4f7425f1e97fd3e3a5600e1ca45d38a92773d5 height=142622 version=0x20000000 log2_work=17.121
Obtaining some L-BTC
The native currency of the Liquid network is
L-BTC, which means BTC that is stored in the Liquid sidechain. We could have a friend send us some
L-BTC, buy it on an exchange, or send from the Bitcoin network using the peg-in process. The latter is obviously cooler.
To make my life a little easier, create these two aliases in my shell:
alias btc="bitcoin-cli -datadir=/opt/bitcoin"
alias lq="liquid-cli -datadir=/opt/liquid"
I generate a new Bitcoin address:
$ btc getnewaddress
And I send it 0.02669942 BTC (around $100). Storing the funds using a Bitcoin Core wallet will make this process much simpler.
We then obtain a
peg-in address for Liquid:
$ lq getpeginaddress
And send the funds to the peg-in address:
$ btc sendtoaddress 31oQLrR1qeGSdJxFMeTVuXkqxjd9gJ1E6s `btc getbalance` "" "" true
This transaction is the peg-in transaction. We’ll need its raw transaction data to claim the peg-in transaction later:
$ btc getrawtransaction 8954038936ec3d96a283fd7e5336ec17e4ad06876ad2a765ceef31778f70a5b0 > tx.txt
And the transaction proof
btc gettxoutproof '["8954038936ec3d96a283fd7e5336ec17e4ad06876ad2a765ceef31778f70a5b0"]' > proof.txt
There’s quite a few strings to deal with now, and we’ll need to use them when we claim the peg-in transaction. But there’s catch! We’ll need to wait for 102 confirmations (~17 hours) to be able to claim the peg-in.
| Name | Value |
| Peg-in address | 31oQLrR1qeGSdJxFMeTVuXkqxjd9gJ1E6s |
| Claim-script | 0014af097f4f55cc5245a9c71dc5f0d24be01e84b873 |
| Peg-in tx hash | 8954038936ec3d96a283fd7e5336ec17e4ad06876... |
| Peg-in tx proof| Stored in proof.txt |
| Peg-in tx raw | Stored in tx.txt |
102 confirmations later
We can now claim the peg-in transaction.
$ lq claimpegin `cat tx.txt` `cat proof.txt` 0014af097f4f55cc5245a9c71dc5f0d24be01e84b873
After a few minutes we can verify that the L-BTC was received.
$ lq getbalance
bitcoind users will notice that
getbalance returns key-values instead of just a number. This is because Liquid supports issuing custom tokens, like you’re probably used to with ERC20s. A major difference is that Liquid uses a technology called Confidential Assets, which provides privacy.
You can read more about Confidential Assets in its whitepaper.
Integrating sending/receiving payments
SideShift AI will support only the native L-BTC token until some interesting assets become available on the Liquid network. Perhaps we should issue our SAI token as an asset on Liquid?
Integration work for L-BTC is identical to that of Bitcoin:
for every new block with at least 1 confirmation
for every transaction in that block
for every output in that transaction
- Was it sent to a SideShift AI deposit address?
- Credit the user unless it has previously been credited
sendtoaddress RPC call, or
sendtomany if using batching.
Notable differences from Bitcoin
getbalanceRPC call returns a hashmap (currency->balance)
getnewaddressRPC call returns a bech32 address. Can be converted to old-school using
Integrating Liquid and pegging in was easier than expected and easily manageable for a developer experienced with Bitcoin. I’m curious to see how integrating Confidential Assets will differ.
SideShift AI is in its TEST PILOT STAGE. Want to become a TEST PILOT?