Getting in on the fun — a personal guide to deploying smart contracts on Concordium

Keld Stehr Nielsen
Concordium
Published in
8 min readMay 28, 2022

--

By Keld Stehr Nielsen

This is a beautified version of my notes while I went through Concordium’s developer documentation. The online documentation is comprehensive and written by engineers who know their field but perhaps an outside-in perspective from a non-engineer can be helpful to people just arriving at Concordium. Maybe they have used Remix to deploy Solidity smart contracts.

Also, I found a few shortcomings in the documentation the hard way that others can save time by knowing.

The below is a rather personal journey through the concordium developer documentation from scratch to deploying the piggy bank and cis1-wccd example smart contract on testnet. Also I should say that the journey took place late May 2022 with the documentation available at that time. No promises are made about the below being updated as the documentation available is updated.

The developer documentation I am referring to is found here: https://developer.concordium.software/en/mainnet/net/guides/developer-page.html and can also be reached from the main page: https://developer.concordium.software/en/mainnet/index.html .

I went for the Ubuntu distribution for Linux and installed it on a virtual machine in the cloud. You will need a cloud setup unless you want to keep your own computer running 24/7. If you don’t know Linux it is a good idea to take a small get started tutorial.

The topics covered below are: Getting set up — Getting a node running on Concordium testnet — Getting a testnet account and import to the concordium-client — Deploying the PiggyBank Smart Contract module on testnet — Deploying the wccd smart contract module example

Getting set up:

This section describes the tools I installed and configured to get started. You can use other tools or installation methods. Much of it is described in the concordium documentation, but in different places.

This is probably the section that I would have liked to have before I started, because I spent most of the time, by far, on finding the right tools and getting them to work. In particular, I had problems running Docker as a non-root user which would allow me to get the Concordium node up and running. As always, when it works, it is trivial.

Get a virtual machine in the cloud: You will have to run a testnet node to deploy on the testnet and for it not to get behind all the time, it must run 24/7. I purchased a monthly subscription for a virtual Linux machine in a cloud setup. I used Contabo which is fairly cheap and simple, but you can use your preferred provider.

Create a non-root sudo user: Once you are logged in to your virtual machine in the cloud, make sure to create a non-root linux user. Run the rest of the process logged in as that non-root user. Otherwise you will get in trouble getting the node running.

Install programming language prerequisites: Install rustup, Cargo and wasm target on your Linux machine. Follow the instructions here https://developer.concordium.software/en/mainnet/smart-contracts/guides/setup-tools.html#setup-tools — only the ‘Rust and Cargo’ section.

Install and configure Docker: Next install docker https://docs.docker.com/engine/install/ubuntu/ on your Linux machine.

Then follow the instructions on how to manage docker as a non-root user. This step was a tough one for me: Running the docker daemon as non-root user/rootless https://docs.docker.com/engine/security/rootless/. I just could not get the installation to work in a way that allowed me to run a Concordium node. Here are a few tricks that got me through:

  • Make sure that you are switched to non-root: non-root-user@xxxxxx
  • I used the –force option (dockerd-rootless-setuptool.sh install –force). Didn’t find anyone who had replied to whether that was ok, but it seemed to work.
  • I ran ‘service docker restart’ when the Concordium testnet node installation failed yet another time. That turned out to do the trick! Kudos https://docs.oracle.com/cd/E37670_01/E75728/html/section_rdz_hmw_2q.html

I now had a cloud based virtual linux machine with Rust and Docker installed and was running Docker as a non-root user. The road was so much more bumpy than described above. Now a few tools needed to be installed on my own computer so that I could interact with the files and programs on the virtual machine.

Install and configure a tool to work with files: You will need to move files between your local computer and your linux machine. I installed FileZilla on my local machine — which runs Windows — so that I could drag files from my laptop’s repositories to the repositories on my Linux machine.

Install a code editor and connect to your Linux machine: Since you will be working with files and writing a bit of code — or copying it like I did :-) — you will need a code editor. I installed Atom on my Windows machine and also the ‘remote ftp’ package. With this I could connect remotely to my Linux virtual machine.

Connecting Filezilla and Atom on my laptop to my cloud machine required a few extra steps, because I needed to set up an ssh connection. I used Putty for that.

Now you are ready.

Getting a node running on Concordium testnet:

Download the Concordium testnet suite: Download the full suite for running a testnet node on Linux using Docker. https://developer.concordium.software/en/mainnet/net/installation/downloads-testnet.html#linux-docker. Use (tar -xvf [filename]) to unpack.

Add the directory to path so you can run the cargo and concordium-client commands anywhere: Add ‘export PATH=”your-dir:$PATH” ‘ to the last line of your home directory’s .bashrc file, where ‘your-dir’ is the directory of the unpacked suite. See e.g. https://linuxize.com/post/how-to-add-directory-to-path-in-linux/

Follow the instructions for running/upgrading a node: The program needed for this is concordium-node: https://developer.concordium.software/en/mainnet/net/guides/run-node.html#running-upgrading-a-node

This is where I spent considerable time. Concordium-node checks 3 conditions and I just couldn’t pass the last one. ‘Service docker restart’ proved to be the command that solved the issue. But the real problem in my view lies with the poor explanation of how to run Docker as a non-root user. It contains essential information, but I don’t like this page https://docs.docker.com/engine/security/rootless/

Before moving on, I familiarized myself with querying a node https://developer.concordium.software/en/mainnet/net/references/query-node.html#testnet-query-node . Note to self: Be careful not to stop the node unintentionally. Follow the status here: https://dashboard.testnet.concordium.com/

Now you have a node running on the testnet and it will take a while for it to catch up to the latest block of the chain. It took me more than 36 hours and I believe my connection is ok. Note, that you cannot deploy your smart contracts before your node has caught up.

Getting a testnet account and import to the concordium-client

Export account keys to your laptop: Next step is to download the Concordium testnet wallet, create an account, export the keys and send them to your linux machine. https://developer.concordium.software/en/mainnet/net/installation/downloads-testnet.html#concordium-mobile-wallet . Remember that it has to be a testnet wallet and it has to be the mobile version. You will not need to use the account until later but it is good to have one already. Also get 2000 ccd from the faucet in the wallet.

For the transfer, I created an export file in the mobile wallet and sent it to my laptop. Then I used Filezilla to send it to my linux machine.

Import account keys to concordium-client: Once the file is on your Linux machine, follow these instructions to import it to concordium-client. https://developer.concordium.software/en/mainnet/net/references/concordium-client.html#concordium-client-import-accounts-keys

Test concordium client transactions: The concordium-client is the tool used to perform transactions. Since deploying to chain is a transaction, it will be needed by then. I played around with different commands to get a feel for the concordium-client. https://developer.concordium.software/en/mainnet/net/references/transactions.html

By this stage you should have

  • all the prerequisite tools installed on your computer,
  • a concordium testnet node running and catching up on the chain, and
  • concordium-client holding an account with ccd to pay for transactions.

So far the concordium-node and concordium-client have been in use. Now it is time to use cargo-concordium.

Deploying the PiggyBank Smart Contract module on testnet

Before you start building the smart contract, you should read the ‘Smart contracts V1 — testnet only’ — sections ‘introduction’ and ‘Contract development guides’.

Set up tools for development: Follow these instructions for setting up cargo-concordium: https://developer.concordium.software/en/mainnet/smart-contracts/guides/setup-tools.html#cargo-concordium

Set up a smart contract project: follow these instructions https://developer.concordium.software/en/mainnet/smart-contracts/guides/setup-tools.html#cargo-concordium

Write the piggy bank smart contract: Follow the instructions or just copy the code as you progress. https://developer.concordium.software/en/mainnet/smart-contracts/tutorials/piggy-bank/writing.html#piggy-bank-contract
Note: Maybe don’t spend too much time here. When I reached the test stage (see below) I deleted all the code written at this stage and instead copied the whole code from the Concordium github.

Build the piggy bank smart contract: When I got to the build step, there were problems: The code didn’t compile correctly and the version referenced in the github had the same problem: “error: linker `cc` not found”. I found this solution, https://unixcop.com/how-to-fix-rust-linker-cc-not-found-error-on-linux/ , which solved my problem!

Testing the piggy bank smart contract: I followed the test document and copied the tests to my file, but ‘cargo concordium test’ didn’t run successfully. The guide turned out to be outdated. Instead of the code in the guide, you need the code from this example: https://github.com/Concordium/concordium-rust-smart-contracts/blob/main/examples/piggy-bank/part2/src/lib.rs . Not only the test code. You also need to copy the program code and the cargo.toml file. Now the test works also!!

The tutorial is completed and you have a smart contract ready to be deployed on the testnet

Simulate locally: Since I had to wait with deployment until my node was fully up to speed, it tried locally simulating contract functions. https://developer.concordium.software/en/mainnet/smart-contracts/guides/local-simulate.html# Couldn’t get it to work on the piggy bank contract, though.

Deploy the piggy bank smart contract: When my node caught up, I followed the deployment guide https://developer.concordium.software/en/mainnet/smart-contracts/guides/deploy-module.html and it went quite smoothly.
You need to use concordium-client, the account that you have imported, and the correct file. The file to deploy has the type ‘filename.wasm.v1’ and is located quite deeply in the folder structure. I found it in the ‘target’ folder generated by the build process: “~/target/concordium/wasm32-unknown-unknown/release$”

You have now deployed a smart contract on the concordium testnet!

Deploying the wccd smart contract module example

In addition to the piggy bank smart contract, the concordium engineering team has created several examples of smart contracts that are a bit more substantial. https://github.com/Concordium/concordium-rust-smart-contracts/tree/main/examples . With all the steps above completed, it is quite easy to try them out.

Create the smart contract: I tried the ‘cis1_wccd’. To begin, I created a smart contract project. See above for how it is done. Next I copied all the code from lib.rs in Github to my project’s lib.rs. Then I copied github’s Cargo.toml file’s content to my project’s Cargo.toml file.

Copy dependencies: the contract will not work unless you also make it possible for it to access its dependencies.
From the Cargo.toml file, you see that these are ‘concordium-std’ and ‘concordium-cis1’. I created a separate folder for the dependencies called ‘crates’, downloaded them from Github and copied them to my Linux machine using Filezilla. I then changed the path in Cargo.toml to point to the downloaded and unzipped files. Here is my path for inspiration: “concordium-std = {path = “/home/ccdtest/ccdtest/crates/concordium-rust-smart-contracts-main/concordium-std”, default-features = false}”.
It turns out there is another dependency to ‘concordium-contracts-common’. So I also copied that one from Github to my ‘crates’ folder.

Deploy the cis1-wccd smart contract: With all code and dependencies copied and connected, I could build and deploy the smart contract.

--

--