In this article, I’ll show you step by step how to configure and deploy a custom chain with the Ark framework. Oh, and as I love portability and containers, I’ve decided to write the Docker image.

Let’s go 🚀

⚠️ This is an experimental deployment.

🚧 At the time I’m writing this article (Dec-18), Ark developers just released the second version of the Ark protocol core (not fully backward compatible). These major upgrades break deployment tools, that’s why I’ll need to update some source code files.️️️

0. Ecosystem overview

Ark ecosystem is composed of multiple projects.

The main project is called core and is in version 2 (version 1 can be found here). Naming is good enough to understand that it’s the core part of the ecosystem (👍). Inside, you’ll find the implementation of all concepts of the protocol like chain structure, the network layer, transaction management, consensus, vote management,… The power of version 2 is that everything is a module (called a plugin). It means that it’s “quite simple” to customize the core for your needs.

The desktop and mobile wallet projects are apps for users connecting to a running node via HTTP (RPC). It does not start an Ark node, so it’s called a light wallet. You can choose your node whenever you want and switch from one to another. With these wallets, you can create, generate, manage accounts, and connect to multiple chains. When you generate an account, you get a seed phrase (12 mnemonic English words) that you have to remember and store securely. It’s your unique password which is requested every time you want to make a transaction. This key is not stored by the app. On the mobile app, the private key is protected by a pin code.

The explorer project is a web app where users can get all blockchain data (all blocks and their transactions, all wallets history, information about delegates (forging and others) like name, number of forged block, productivity…). It connects the same way than wallets, to a running node. There is an official ark main chain explorer and also community ones. Because this service is centralized, you have to trust the server (and its owner) hosting the app. If you want to be sure that your transaction is really effective, you can consult as much explorer as you like.

The commander project is an interactive command line tool to help running and to manage a node. From this tool, you can install easily all dependencies, choose the chain you want to connect to, setup database, setup forgers, … Bellow is a screen of the v2 commander (you got it, to deploy a core v2 node).

Ark commander CLI v2

The deployer project is a set of bash scripts easing deployment of custom chains for developers. It automatizes the procedure of fetching core project sources, installing dependencies and starting node from a configuration file.

1. Check out project

First of all, you’ll need to clone the deployer project (on the host machine).

Then, check out a specific commit of the deployer-v2 branch, that I used to write this article.

> cd deployer

> git checkout e02484b

You can notice that we’re working with a development version of the deployer . This version is the beginning of an upgrade to fit core v2 needs. It'll continue to live and to be updated.

Create a docker folder for all configuration files and scripts.

> mkdir docker

2. Dockerfile initialization

Let’s initialize our Dockerfile ( docker/Dockerfile ).

As explained in the minimum requirements guide, scripts have been developed and tested under Ubuntu 16, so make a new docker image extending xenial (first line of the Dockerfile).

FROM ubuntu:xenial

3. Define some variables

Here is the list of environment variables used by docker script (and commented 🙂)

# name given to our os user

ENV USER deployer # path to our custom chain properties file

ENV CONFIG_PATH docker/config.json # path where nvm is available

ENV NVM_DIR $HOME/.nvm # node version to install

ENV NODE_VERSION 10.14.2

NOTE: node version is frozen to 10.14.2 to simplify the script

4. Install dependencies

Install dependencies used to get and install ark tools.

RUN apt-get update && \

apt-get install -y jq git curl sudo apt-transport-https

Ark deployer project uses yarn as dependency manager so we need to install it

curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg

| sudo apt-key add - && \



echo "deb https://dl.yarnpkg.com/debian/ stable main"

| sudo tee /etc/apt/sources.list.d/yarn.list && \



apt-get update && \

apt-get install -y yarn

According to the installation instructions, Node 10 is required to install and start Ark tools. So, we install node version manager ( nvm ) to get it.

RUN curl -o-

https://raw.githubusercontent.com/creationix/nvm/v0.33.8/install.sh

| bash && \

. $NVM_DIR/nvm.sh && \

nvm install $NODE_VERSION # add node and npm to path so the commands are available

ENV NODE_PATH $NVM_DIR/v$NODE_VERSION/lib/node_modules ENV PATH $NVM_DIR/versions/node/v$NODE_VERSION/bin:$PATH

5. Prepare custom chain sources

Here it is, the more interesting part of this article. We’ll need to configure our chain and set its characteristics.

To do so, you need to create a configuration file into docker/config.json .

In this config file, I can set several properties like :

platform token name : used to identify the token when using tools or apps managing multiple ones. You can customize its name ( token ) and its symbol ( symbol ) like ₿ for Bitcoin, Ξ for Ether or Ѧ for Ark.

: used to identify the token when using tools or apps managing multiple ones. You can customize its name ( ) and its symbol ( ) like ₿ for Bitcoin, Ξ for Ether or Ѧ for Ark. the name of the chain : in the p2p network, nodes of the same chain must be able to find each other broadcasting discovery requests to all nodes using the same protocol. To distinguish requests, the chain identifier is used as a parameter. From a higher level, you have to start your node with the chain name ( chainName ) parameter if you want to find peers and sync.

: in the p2p network, nodes of the same chain must be able to find each other broadcasting discovery requests to all nodes using the same protocol. To distinguish requests, the chain identifier is used as a parameter. From a higher level, you have to start your node with the chain name ( ) parameter if you want to find peers and sync. the number of pre-mined tokens : some use-cases requires tokens to be available at the beginning of the chain. They could be used to rewards early adopters, developers, control the market, use a fixed number of tokens equally distributed among identified actors or automatic mechanisms to unlock/spend these tokens under conditions. In that case, you can set the number of platform tokens ( totalPremine ) available at block 0. These tokens will be affected to a unique wallet generated for the need (no ways to set it directly from this config file). The wallet seed-phrase will be printed in the logs during the node install (see app-node.sh) and also be made available in the genesisWallet.json file.

: some use-cases requires tokens to be available at the beginning of the chain. They could be used to rewards early adopters, developers, control the market, use a fixed number of tokens equally distributed among identified actors or automatic mechanisms to unlock/spend these tokens under conditions. In that case, you can set the number of platform tokens ( ) available at block 0. These tokens will be affected to a unique wallet generated for the need (no ways to set it directly from this config file). The wallet seed-phrase will be printed in the logs during the node install (see app-node.sh) and also be made available in the file. the number of delegates : Ark consensus protocol is DPoS (delegated proof of stake). These delegated “nodes” (actually it’s more accurate to identify them as wallets) are also called validators, forgers, forging delegates or active delegates due to their role to validate transactions and add blocks to the chain. You can set the number of forging delegates in your network ( forgers parameter) in order to distribute authority among many identified actors. As for the genesis wallet, you can't set forger public address directly from this file. A wallet will be generated for each and seed phrases will be made available in the deleguates.json file (same path than genesisWallet.json ). NB: forging delegates is a subset of delegates .

: Ark consensus protocol is DPoS (delegated proof of stake). These delegated “nodes” (actually it’s more accurate to identify them as wallets) are also called validators, forgers, forging delegates or active delegates due to their role to validate transactions and add blocks to the chain. You can set the number of forging delegates in your network ( parameter) in order to distribute authority among many identified actors. As for the genesis wallet, you can't set forger public address directly from this file. A wallet will be generated for each and seed phrases will be made available in the file (same path than ). NB: is a subset of . delegate reward : every time a delegate forge a new block, he can be incentivized with platform tokens ( rewardPerBlock ).

: every time a delegate forge a new block, he be incentivized with platform tokens ( ). fees amounts : Ark transactions are not costless so you must pay fees based on transactions type. Thereby, you can set fee amount for regular token transfer ( feeTransfer ), vote for a delegate ( feeVote ), enhance wallet security with second seed-phrase ( feeSecondSignature ), register on the list of delegates ( feeDelegateRegistration ), do a transfer from a multi-signature wallet ( feeMultiSignature ). The configured fees are the default accepted by delegates. Due to Ark v2 dynamic fees , each forging delegate has the ability to update these values on its own, even after chain initialization.

: Ark transactions are not costless so you must pay fees based on transactions type. Thereby, you can set fee amount for regular token transfer ( ), vote for a delegate ( ), enhance wallet security with second seed-phrase ( ), register on the list of delegates ( ), do a transfer from a multi-signature wallet ( ). The configured fees are the default accepted by delegates. Due to Ark v2 , each forging delegate has the ability to update these values on its own, even after chain initialization. block characteristics : define the maximum number of transactions a block can contain ( txsPerBlock ) and the block creation rate ( blockTime ). To help you define these values for your use case, you can read this article explaining the Bitcoin case.

: define the number of transactions a block can contain ( ) and the block creation rate ( ). To help you define these values for your use case, you can read this article explaining the Bitcoin case. wallet address prefix : define the symbol prefixing wallet addresses handled by your chain. Here is a list of possible symbols. For example, Ark main chain uses the letter A and dev chain uses D .

: define the symbol prefixing wallet addresses handled by your chain. Here is a list of possible symbols. For example, Ark main chain uses the letter and dev chain uses . other technical properties: like listening interfaces ( nodeIp , explorerIp ) and ports ( p2pPort , apiPort , explorerPort ), database parameters ( databaseHost , databasePort , databaseName ) and other stuffs ( updateEpoch , rewardHeightStart , bridgechainPath , explorerPath ).

Here is an example of the configuration file I used to start my blockchain:

Due to v2 breaking changes, to make deployer work we’ll need to :

replace line 34 by ( DB_USER="ark" )

) remove line 88 ( --rewardHeight "$REWARD_HEIGHT_START" )

⚠️ These are quick & dirty fixes for encountered bugs which will be fixed soon by dev team as we can see in their roadmap (ARK Deployer GUI : 84%). But for now, let’s update these lines 🙂.

This is a huge work to find the perfect parameters combination for your use-case (number of delegates, pre-mined tokens, block time,…).

You deserved a break 🤯.

Grab your ☕️ then we’re ready to go to the next step.

6. Install the customized node

The first step is to get the deployer modified sources from the host.

COPY . $HOME

Then move to your home folder for next commands.

WORKDIR $HOME

Deployer project is composed of bash scripts easing custom Ark nodes and explorer deployment.

The entry point script is called bridgechain.sh and accepts a configuration file path as a parameter.

Here you can find the list of accepted arguments.

RUN ./bridgechain.sh install-node --config docker/config.json --autoinstall-deps --non-interactive

You can see that we call install-node command which:

installs environment dependencies clone Ark core project and install it, initialize database, generate wallets (genesis and forging delegates) and forge the first block according to the given configuration file.

7. Install the customized explorer

For now, explorer app can’t manage multiple chains. So we have to configure and start a new explorer for our custom chain.

RUN ./bridgechain.sh install-explorer

--config "docker/config.json"

--skip-deps

--non-interactive

Here we call the install-explorer command of bridgechain script and pass the same configuration file path.

If you remember, the configuration file contains parameters for the explorer. It’s mainly the custom Ark node listening IP and port.

From this information, when explorer starts, it syncs with the given node and fetches chain configuration in order to properly show the custom parts (token name, number of delegates, rewards,…).

8. Setup start script

For now, we’ve written the script to install the environment (node + explorer) and freeze the installation in a docker image.

But when we start the docker container, we want to start the node and the explorer automatically. So we have to write a little script to execute when the container starts.

For that, create a file called docker/docker-entrypoint.sh .

Here is the script :

The script does 4 things :

start the database start the node ( start-node command of bridgechain script) and redirect outputs to a file start the explorer ( start-explorer command of bridgechain script) and redirect outputs to another file connect to node logs ( logs-node command of bridgechain script) and output them as container logs.

NOTE: the echo N | ... is used to prevent interactive mode when the script asks if we want to connect to node logs in foreground

9. Finalize

To finish we must tell to docker to start by the execution of the docker/docker-entrypoint.sh script and to expose some ports to the world.

We copy the script into the image, add execution permission to our container user and declare it as bash command entry point.

COPY ./docker/docker-entrypoint.sh / RUN sudo chmod +x /docker-entrypoint.sh && \

sudo chown $USER /docker-entrypoint.sh ENTRYPOINT ["/bin/bash", "-c"] CMD ["/docker-entrypoint.sh"]

We expose several ports to the outside world:

EXPOSE 4102

EXPOSE 4103

EXPOSE 4200

node p2p port , in order to be reachable by other peers of the network (which has been set to 4102 in our config file),

, in order to be reachable by other peers of the network (which has been set to in our config file), node API port , in order to be called remotely by apps: get blocks data, control wallets, make transactions,… (which has been set to 4103 ),

, in order to be called remotely by apps: get blocks data, control wallets, make transactions,… (which has been set to ), explorer web app port, in order to open it from a browser, which has been set to 4200 .

10. Build and start

From the Dockerfile, we build the image of the configured chain, and tag it as deployer :

> docker build -f docker/Dockerfile . -t deployer

From the logs, I’ve screened important steps illustrating previous explanations.

At the end of node installation, the script prints the genesis wallet details (passphrase and address), where pre-mined tokens have been sent. We can also see the genesis wallet address prefixed by the letter we’ve set in the configuration file.

When explorer has been installed you must see the following log

Finally, I can start a container from the deployer image and call it arkv2-spacelephantlabs . I also map ports to the same host ports.

> docker run -ti

-p 4200:4200

-p 4103:4103

-p 4102:4102

--name arkv2-spacelephantlabs

deployer

Node logs are more interesting.

First of all, the database connection and initialization.

Then, p2p protocol starts, and prints details about node connectivity and clock synchronization (NTP).

You can notice that peer discovery has been disabled. It’s because the node has been started in what they called genesis-start mode. It's a mode used to start the first node of the network. Indeed, a blockchain always emerges from a single node. Then, other nodes will connect to it thanks to its known IP/port creating a network of nodes. The first node is called a bootstrap node for others. If they enable the peer discovery, they will connect to the node connected to the bootstrap node to form a peer to peer network. To enable it, add --no-autoforger option to the ./bridgechain.sh start-node command.

During node start, the client check database state and verify its integrity (via SPV) to prevent from corrupted data. In the screen above, no blocks have been found in the database that’s why SPV is so quick 🙂

Consensus protocol starts from the initialized wallets found in the database and load the list of forgers. In the logs, we can see all the delegates name and public key.

And finally, forgers start producing blocks at a regular time interval. Here we can see that the second block ( heigh 2 ) with no transactions has been forged by a random delegate ( genesis_30 ), broadcasted to 0 peers (what an active chain !!).

Now, you can connect to the explorer through your browser at localhost:4200 and gaze at this newly born chain composed of empty blocks. Have fun.

Bonus 🎁

Start exchanging your platform tokens now using existing wallets. For that, you need to configure them.

As an example, I’ll use the desktop app, but you can do the same with the mobile one 👍.

Open the desktop wallet and declare a new network (chain)

Give it a name, a description and the URL of the node API ( 4103 ), in order to fetch network details like the symbol, delegates, explorer URL, etc... (see below).

Then, it’s not over. You have to define a new profile for your custom chain. Click on the avatar (bottom/left), then New profile and set its characteristics (name, avatar, language,...). On the network step, click on the "More icon" ( ... ) and select your custom network. And you can continue the process with Next .

Now that you’ve switched to the new profile, you can see that the app is unconnected.

You have to set a network peer API URL http://localhost / 4103

And then, you’re really ready to go!

Before leaving 🚪

In this article I’ve dissected the Dockerfile I used to deploy a custom chain and I’ve explained several things about the Ark ecosystem. I tried to add a maximum of references to justify my understanding. I’m far from mastering Ark ecosystem and I’m not pretending to do so.

This Dockerfile is not production ready, do not try to use it in a final environment.

In my point of view, Ark is not so far from building the Wordpress of blockchain.

As a developer, I found good scripts, command line tools, easy to read documentation, and most importantly a great community, reactive, comprehensive and really ready to help. All these things really made my work easier and I could progress faster. I worked with feature branch, during a transitive period (Ark core v2, typescript migration,…) so tools weren’t ready to use out-of-the-box. I had to read the code and talk to the community to progress and to be honest, I’ve really appreciated that.