Lessons Learned on Deploying Smart Contracts


Amid news of its recent spat with the United States Securities and Exchange Commission, relatively few people have likely heard about Telegram’s Open Network competition that occurred some weeks ago. It was a milestone event that transformed the once-miniscule TON developer community writing in Fift (TON’s general-purpose programming language), which differs greatly from common languages due to its low-level approach.

The contest attracted new developers, further built a community around the new platform, and solved existing issues concerning the lack of documentation on smart contracts by providing examples of them and how they are deployed on TON. My team, Button Wallet, and I also participated, and have summed up everything that happened during and after the TON contest.

Lack of documentation

FunC — TON’s other language for writing smart contracts is FunC, a high-level language similar to C with functions and variables that is much easier to read and write in than the general-purpose Fift. A similar comparison would be C# and CIL. However, prior to the contest, there was barely any documentation of FunC. This posed an issue, as most of the TON contest tasks required contestants to write a smart contract.

Due to the lack of documentation on writing for TON using FunC, contest participants needed to analyze and learn from existing examples, which had been uploaded to a small GitHub repository and the TON test website along with some theoretical details. While this wasn’t a difficult task overall, understanding the basic necessities of a language based on nothing but examples can prove challenging. Nevertheless, most contestants were able to start writing freely in FunC after the first few days.

Basics — When writing a smart contract using FunC, we needed to understand how to deploy and compile the smart contract, as well as how to call functions using arguments. The complete lack of detailed information on this fundamental aspect of the language — in addition to there not being any examples showing the full steps — was almost laughable for its irony. TON’s brief guideline was extremely helpful to those who participated in the competition, but it was only an introduction to writing smart contracts on TON that conveniently left out examples or detailed information on deploying and running function calls on smart contracts. Eventually, everyone figured out how to do all of this, but it took considerable time and effort.

Contest tasks

There were two tasks out of the five total that I want to highlight: the asynchronous payment channel and the synchronous one. But first, what is a payment channel?

A payment channel is a way to send transactions between two parties off-chain (i.e., outside of the blockchain) to make it faster, less expensive and more customized. Users have their own accounts on the blockchain and can send transactions between themselves using their deposited sums. For this, a special smart contract stores the deposited funds of the two parties while the payment channel is open. Withdrawals require a smart contract containing certain data, which will be discussed below.

Parties A and B send coins to the smart contract, making deposits to open a payment channel between them

To open the payment channel, funds need to be deposited to the smart contract from both sides.

Party A sends a transaction to Party B, changing the state of payment channel from (a, b) to a new one

Party A sends a transaction to Party B, changing the state of payment channel from (a, b) to a new one

If the payment channel is open, transactions can be sent between parties with a speed of more than 100,000 transactions per second. It is important to understand that this all happens off-chain and that at some point, the parties will need to reach an agreement and withdraw their funds from the smart contract.

An off-chain transaction from A to B through their synchronous payment channel

An off-chain transaction from A to B through their synchronous payment channel

It is assumed that the parties might try to unfairly withdraw all funds within the pool. Because of this, each party needs to prove that the sum they are going to withdraw belongs to them. To prove this, each party needs to send their signature, which correctly proves the state (sum A, sum B, and some other information).

The synchronous payment channel has a state number that does not change unless specific requirements, such as receiving Party B’s confirmation and signature, are met. Therefore, Party A cannot send several transactions to B in a row, as each new state requires a signature from both parties.

When sending a transaction to Party B, Party A needs to create a state that will change the amount that will belong to both A and B, sign this state using its own private key, and then send the new state and signature to B. Party B then signs this state and sends its signature back to Party A, thereby confirming the transaction status. Party A cannot send another transaction to Party B until B creates a new state. Due to this, it is called a synchronous channel.

An off-chain transaction from Party A to Party B through an asynchronous payment channel

An off-chain transaction from Party A to Party B through an asynchronous payment channel

In an asynchronous payment channel, each counterparty has its own group of states. Each state consists of the amount that Party A received from Party B, the number of transactions that Party A has sent to Party B, the amount that B sent to A, and the number of transactions that B has sent to A. Unlike in a synchronous payment channel, A and B do not need to wait for confirmation from one another, they just need to send a signed state.

The most difficult aspect for both channels is the withdrawal process. The smart contract needs to check that each party has provided the correct data before funds can be withdrawn. We need to check the signatures of state and also that this state is the latest. If there is a conflict between the parties, the smart contract needs to resolve it according to the latest state.

There must be protection against sending the same data to different payment channels, as well as a resolution for when one party does not provide any information. All of this must be written in FunC and thoroughly tested in order to be secure.

Solutions and competitors

According to the contest’s official channel, there are 68 submissions.

Most of the submissions were multisignature wallets and domain name system (or DNS) resolvers. However, several submissions are for payment channels. Writing payment channels was the competition’s most complex task, so the few strong teams (such as 363, 375, 381) that were able to produce such solutions were more prominent than the others.

What’s next?

Currently, there are about 10 to 20 teams with enough skills and knowledge to start building TON’s infrastructure, and they will likely transfer most of the successful Ethereum solutions to TON. The TON contest and its $200,000 prize pool incentive greatly boosted the number of teams that can work with the platform by providing an opportunity to gain experience with it first-hand. Now, the participating teams are all set to build their own projects or startups on TON.

Key takeaways for the Button Wallet team 

As early TON adopters and lovers of Telegram, my team and I decided to participate in the TON contest. We had a large team of eight people. For our solution, we decided to build synchronous and asynchronous payment channels. Although we made some mistakes during the contest, we did manage to make a synchronous payment channel with all the wrappers that allow deposits, withdrawals, and the transfer of transactions using our command-line interface. So, we made not only a smart contract but a lot of wrappers over it that allowed working with TON much easier. After we finished the synchronous channel, we leveraged knowledge from our Plasma developing experience and built another smart contract that implements asynchronous off-chain payments. However, we were unable to write all the wrappers to it before the deadline.

We thoroughly enjoyed all the tasks and wish that we’d had more time to implement all of them. Nevertheless, we won the first place for best synchronous payment channel as well as third place for best asynchronous payment channel.

The views, thoughts and opinions expressed here are the author’s alone and do not necessarily reflect or represent the views and opinions of Cointelegraph.

Nick Kozlov is the CTO of Button Wallet, a software developer and researcher, as well as one of the winners of the TON contest.