Progress pill
Element Federation

Element as a Side Chain

  • FederatedPegScript
  • Peg-in
  • Peg-Out
Elements is an open-source, general-purpose blockchain platform that can also be pegged to an existing blockchain, such as Bitcoin. When pegged to another blockchain, Elements is said to be operating as a sidechain. Sidechains enable the two-way transfer of assets from one chain to another. Implementing Elements as a sidechain allows you to work around some of the inherent limitations of the mainchain, while retaining a good degree of the security provided by assets secured on the mainchain.
While a sidechain is aware of the mainchain and its transaction history, the mainchain is unaware of the sidechain, and no awareness is required for its operation. This enables sidechains to innovate without restriction or the delays associated with mainchain protocol improvement proposals. Rather than trying to alter it directly, extending the main protocol allows the mainchain itself to remain secure and specialized, underpinning the smooth operation of the sidechain.
By extending the functionality of Bitcoin and leveraging its underlying security, an Elements-based sidechain can offer new capabilities that were previously unavailable to users of the mainchain. An example of an Elements-based sidechain in production use is the Liquid Network.
To initialize an Elements blockchain as a sidechain, we need to use the federated peg script parameter. This parameter can be set in a node's config file or passed in on startup.
The federated peg script defines which members of the strong federation are authorized to perform peg-in and peg-out functions. These functionaries are referred to as Watchmen because they monitor the mainchain and sidechain for valid peg-in and peg-out transactions and take action on them if they are valid. To peg-out means to move pegged assets out of the sidechain and into the mainchain, and to peg-in means to move pegged assets into the sidechain from the mainchain. When we say move into the sidechain, what we actually mean is that the funds are locked in a multi-signature address on the mainchain, and a corresponding amount of the asset is created on the Elements sidechain. When we say move out of the sidechain, what we mean is that assets are destroyed on the Elements sidechain, and the corresponding amount is released from the locked funds held on the mainchain. Permission to perform the peg-in and peg-out functions requires that functionaries prove ownership of the public keys used in the federated peg script. This is accomplished using the corresponding private keys.
To create a federated peg script, we first need each of our nodes to generate a public key. We also need to store the associated private keys for later use, as we'll need to wipe any existing chain data and initialize a new chain using the federated peg script. This is because the federated peg script forms part of the consensus rules of a sidechain, and it cannot be applied to an existing, non-pegged blockchain at a later date.
So let's generate an address for each of our nodes, store the relevant data for later use, and create the federated peg script, which we'll use to initialize our sidechain later.
First, we need each of our nodes, which will act as the Watchmen in our network, to generate a new address.
e1-cli getnewaddress e2-cli getnewaddress
Then we validate the address to obtain the public keys.
e1-cli getaddressinfo <e1-address> e2-cli getaddressinfo <e2-address>
And then retrieve the private keys associated with each address.
e1-cli dumpprivkey <e1-address> e2-cli dumpprivkey <e2-address>
Store the private and public keys for later use.
Now we need to wipe the existing blockchain and wallet data as we'll be initializing a new chain using a federated peg script. You can do this now. Don't forget to start the Bitcoin daemon, which we'll need to peg in.
Now we can initialize a new chain with a federated peg script created using the public keys we stored earlier. The numbers that we enter and that surround our public keys define and delimit the number of keys used, as well as the key ownership that must be proven in order to peg in and out of our sidechain.
e1-dae -fedpegscript=5221<e1-pubkey>21<e2-pubkey>52ae e2-dae -fedpegscript=5221<e1-pubkey>21<e2-pubkey>52ae
Now we will import the private keys that we saved before, so that our nodes can later sign and complete the transfer of assets between chains and satisfy the requirements of the federated peg script.
e1-cli importprivkey <priv-key-1> e2-cli importprivkey <priv-key-1>
We now need to mature some blocks on both chains. Maturity of blocks is a requirement of the peg process, as it protects against block reorganizations on the main chain, which can lead to inflation of the pegged asset supply within the side chain.
To keep this section focused on the federated peg, we will generate blocks without using the block signing model examined in the last section and return to using the 'generate' command to create new blocks.
b-cli generate 101 e1-cli generate 1
We don't necessarily need to generate blocks for elements at this time. But let's generate one anyway. It's good practice to avoid potential inconsistencies.
Now our chain is ready to peg in. To peg-in, we need to generate a special kind of address using the getpeginaddress command. Note that the duration between generating a peg-in address with getpeginaddress and claiming it with claimpegin should be kept as small as possible. Peg-in addresses are not long-term durable and should not be reused.
e1-cli getpeginaddress
You can see that the command creates a new mainchain address, as well as a new script that must be satisfied in order to claim the peg-in funds. The mainchain address is a pay to script hash address that will be used by functionaries performing the Watchmen role within the Elements network.
Like getnewaddress, getpeginaddress adds a new secret to the calling node's wallet, so it is important to factor in a backup of the wallet file into your node management process.
We'll now send some Bitcoin from the main chain to the side chain. Our mainchain regression test wallet already holds some funds.
b-cli getwalletinfo
We can see that the wallet holds 50 Bitcoin. We'll send one bitcoin from the main chain to the side chain. We need to send funds to the mainchain address our node generated earlier.
b-cli sendtoaddress <e1-pegin-address>
We need to keep a record of this transaction ID, as it will be required for proof of funding later.
We can now see that the mainchain wallet balance has decreased by the amount we sent, plus an additional small amount to cover the transaction fees.
b-cli getwalletinfo
We need to reprocess the transaction.
b-cli generate 101
To have our Elements node claim the peg-in funds, we need to obtain the proof that the peg-in transaction has been completed. The cryptographic proof uses the funding transaction ID to calculate the Merkle path and proves that the transaction is present in a confirmed block.
b-cli gettxoutproof '["<tx-id>"]'
We also need the raw transaction data.
b-cli getrawtransaction <tx-id>
With the proof and raw data for the peg-in transaction, our elements node can now claim the peg-in using the raw transaction and the transaction proof.
e1-cli claimpegin <raw> <proof>
Note that there is an optional third argument which we could have provided to claimpegin. This third parameter can be used to specify the sidechain address to which the claimed funds should be sent. This was not necessary in our example, as we were calling the command from the same node that owns the address to which the claimed funds are going.
Checking the balance of e1.
e1-cli getwalletinfo
Generating a block to confirm the claim.
e1-cli generate 1
Checking the balance of e1.
e1-cli getwalletinfo
We can see that the peg-in has been successfully claimed.
To peg out, the process is similar. In that an address is generated, funds are sent to it, and the funds are released if the transaction is valid. We won't cover the whole peg-out process as it involves work on the mainchain, which is beyond the scope of this course. The steps in terms of the Elements events involve generating an address on the mainchain.
b-cli getnewaddress
Funds are sent to the mainchain address from an Elements node using the sendtomainchain command.
e1-cli sendtomainchain <new-address> 1
Generating a block to confirm the transaction.
e1-cli generate 1
Check the balance of the node's wallet.
e1-cli getwalletinfo
And see that the balance has decreased.
In this section, we have seen how to:
  • Generate a federated peg script.
  • Initialize a new chain that uses the script as a network consensus parameter rule.
  • Send funds from the mainchain to the sidechain.
  • Claim the funds within the Elements sidechain.
  • Understand how sending funds back to the mainchain is started.

FederatedPegScript

To enable Elements to function as a sidechain, the genesis block in its blockchain must be created with a fedpegscript in place. This is achieved by passing the fedpegscript parameter during node startup. The script will then form part of the Elements blockchain's consensus rules, allowing peg-in and peg-out requests to be validated and executed.
The fedpegscript is made up of public keys controlled by those authorized to perform the peg actions. The following shows the example format of a 2-of-2 multisignature fedpegscript:
fedpegscript=5221<public key 1>21<public key 2>52ae
Note: The characters outside the public keys are delimiters that indicate the public key and n of m requirements. For example, the template for a 1-of-1 fedpegscript would be '5121<pub key 1>51ae'.

Peg-in

Before a peg-in can be accepted by an Elements sidechain, it must have sufficient confirmations on the mainchain. This is necessary to avoid inflation in the supply of the pegged asset on the Elements sidechain, which could be caused by a reorganization of the mainchain.
Short reorganizations of the Bitcoin blockchain's tip are expected as part of its normal operation, due to the Proof-of-Work (PoW) consensus mechanism. As such, Elements only accepts a peg-in to be valid when it has sufficient depth within the Bitcoin blockchain. This serves to prevent Elements from accepting the same peg-in more than once.

Peg-Out

A peg-out occurs when an Elements node calls the sendtomainchain command, which takes as input a mainchain address (the peg-out destination) as well as the amount of the pegged asset to be withdrawn. This creates a peg-out transaction on the sidechain. Once the Functionaries who are acting as Watchmen detect that the peg-out transaction has been confirmed on the sidechain, they take care of actually releasing the asset on the mainchain to the peg-out destination, as we learned in earlier sections of the course.