By (back to Gram TON) 2019

Send any questions to e-mail:
A new Telegram coding competition is starting today. The task is to build smart contracts for a blockchain platform.

1. Build one or more smart contracts as described in TON Contest.txt below.
2. Suggest improvements for FunC / TON VM (optional).
3. Find issues and suggest fixes for TON Testnet (optional).

The prize fund for these 3 tasks is $200,000–400,000.

The contest ends on October, 15 at 23:00 CET.

We’ll publish how to submit your code on soon

--- 1. Smart-contract implementation contest

1.1. General information

The goal is to implement at least one of the smart contracts listed below in 1.2. for the TON Blockchain, using the tools provided in the TON Blockchain distribution (cf. ), especially the Fift interpreter (its sources are located in the subdirectory `crypto/fift` in the source tree; the corresponding binary file is usually located as `crypto/fift` in the build directory) and the FunC compiler (its sources are located in the subdirectory `crypto/func` in the source tree; the corresponding binary is usually located as `crypto/func` with respect to the build directory). Some examples of smart contracts are located in the subdirectory `crypto/smartcont` in the source tree. In most cases, the FunC source code of a smart contract is located in a file with the suffix `.fc`; another file with the same name with the suffix `.fif` is automatically generated from the source file by invoking the `func` binary with appropriate command line options. This automatically-generated file contains TVM assembly instructions, which, when interpreted by the Fift assembler (a TON VM assembler implemented in Fift), generate the code of the smart contract in binary form.
You may opt to write the code of your smart contract directly in Fift assembler; however, only the simplest smart contracts can be reasonably implemented and tested in this way. We expect that you would rather use the FunC compiler.
Apart from the code of your smart contract, you will need to implement some scripts (usually in Fift) that enable the user to create, properly configure, and control new instances of your smart contract. An example of such a script is given in `crypto/smartcont/new-wallet.fif`, which creates a new simple wallet; the procedure to use this script is outlined in the LiteClient HOWTO ( ), and in `crypto/smartcont/wallet.fif`, which enables the owner of the wallet to control it (to make the wallet smart contract to transfer funds to any desired address). Notice that `new-wallet.fif` contains the (Fift assembler) code of the wallet directly in the same source file; larger smart contracts would use the `"wallet-code.fif" include` (or similar) phrase instead to include a separate file with the source code of the smart contract, either written directly or automatically generated by the FunC compiler.
A description of Fift is available at . No documentation of FunC is available at the moment. You'll have to deduce the properties of FunC language and its compiler from the sample FunC sources (in `crypto/smartcont/*.fc` and `crypto/func/test/*.fc`) and from the C++ source code of the FunC compiler itself (in `crypto/func/*.cpp`). Essentially, FunC is a simple C-style statically typed language with polymorphism (Miller-Rabin type system) adapted to the basic data types (int, cell, slice, builder, tuple) supported by the TON VM (TVM). A list of all TVM instructions can be found in Appendix A to the TVM documentation ( ). If you need to use any of these instructions directly from your FunC smart contract source, check whether a suitable built-in function is already defined in `crypto/smartcont/stdlib.fc` or `crypto/func/builtins.cpp`. If there is none, you can add your own "assembler built-in" in the beginning of the code of your smart contract similarly to the examples from `crypto/smartcont/stdlib.fc`. It is also helpful to study the Fift assembler TVM code generated by the FunC compiler from your FunC source to understand what is going on when in doubt.
Typically your implementation will consist of several .fif and .fc files in one directory, along with some build instructions (usually consisting in invoking func several times for building `your-smc-code.fif` from `your-smc-code.fc`) and some usage instructions in the Fift scripts (you can partially implement them as help messages shown when your script is invoked without any command line arguments or with the command line option `-h`).
The quality of the source code of your implementation of the smart contract (i.e., its readability and correctness) will affect your final score. The compactness (i.e., the persistent smart-contract storage consumed by the code and data of your implementation when deployed in the blockchain) and the efficiency (i.e., gas consumed during the creation and other actions of the smart contract) will be also compared among different implementations of the same smart contract. Earlier submissions are also more likely to obtain prizes among several submissions of similar quality.
All smart contracts are to follow the TON Smart contract guidelines ( ) as closely as possible. Some general information on the TON Blockchain and the way smart contracts are invoked may be found in the TON Blockchain documentation ( ).
1.2. List of smart contracts to be implemented

You are expected to implement at least one of the smart contracts listed below. You can implement several of them. Notice, however, that submitting poor implementations of several smartcontracts from this list is less likely to earn you a prize than submitting the best implementation (among the submissions of all participants) of just one smart contract. On the other hand, given enough submissions in each category, there may be prizes independently allocated in each of them, and you might win several prizes by submitting several good smart contracts.

* Multi-signature wallet (at least k of n signatures are required for a transfer order to be processed by the multisig wallet, where 1 <= k <= 10 are specified during the wallet creation).
* Simple TON DNS Resolver smart contract with automatic registration of new subdomains (any unregistered subdomain can be automatically registered by sending a message with the new subdomain record carrying a predetermined amount of Grams as payment).
* Simple TON DNS Resolver smart contract with manual registration of new subdomains (new subdomains are registered whenever an external message correctly signed by the smart contract owner is received).
* A synchronous two-party payment channel as explained in Chapter 5. of the TON Whitepaper ( ).
* An asynchronous two-party payment channel as explained in Chapter 5. of the TON Whitepaper ( ).

Notice that implementing one of these smart contracts may simplify the implementation of the others (e.g., by reusing code).

1.3. Separate comments on each of the smart contracts


1) A multi-signature wallet typically contains a list of *n* 256-bit (Ed25519) public keys in its persistent data, along with a sequence number, parameters *n* and *k* (0 < k <= n <= 100), and possibly a list of partially signed orders (that have at least one, but less than *k* valid signatures). Each order has an expiration Unix time, so that if it is still unsigned after expiration, it can never be sent even if missing signatures arrive. Your smart contract can garbage collect such expired orders the next time it is invoked. New orders are created by receiving external messages containing several (at least one) valid signatures, the expiration time, and the proposed internal message body (which will be sent once the order collects enough signatures). If a new order has at least *k* valid signatures from the very beginning, it is executed immediately (i.e., the included internal message is sent immediately from the multisig wallet smart contract to the intended destination). Otherwise it is stored in the persistent data of the smart contract. Such partially signed orders may accumulate more signatures when other external new order messages with the same body but different signature sets arrive.

Apart from this basic functionality of the smart contract, you have to implement get-methods that list all pending (partially signed) orders, and get-methods that list all pending orders signed or not signed by a particular public key. Your interface Fift scripts should help the user to create (BoC files with serialized) external messages with completely new orders (similarly to `wallet.fif` used by the simple wallet smart contract), to extract and show the internal message (especially its destination address and value) and the list of signatures from a previously serialized external messages (loaded from a file), to add new signatures to such external messages using a local private key file (so that the holder of one private key might create an external message and send it by e-mail to the holder of another private key, who could add the second signature to the next holder and so on until the necessary amount of signatures is collected offline), to merge two external messages with the same body, but with different signature sets, into one external message with the union of these signature sets, and to create and sign a "new order" external message corresponding to a partially signed order recovered from the current state of the blockchain using one of the get-methods indicated above.

2) Any TON DNS Resolver smart contract (automatic or not) must implement get-method "dnsresolve" that accepts two arguments: a 8n-bit Slice containing an n-character string with the subdomain name, or with several subdomain names each followed by a zero byte; and a signed 16-bit integer with the "category" to be looked up (or 0, if a dictionary with all "categories" is to be returned), and looks it up in a table stored in the persistent data of the smart contract. The output consists of one Integer and one Cell or Null. If the subdomain is not found, the smart contract should return (0, null). If the subdomain is found, the smart contract should return (8m, dns-record-value), where *m* is one plus the number of bytes in the subdomain found. If m is less than the length of the original string, then 8m bits are removed from the beginning of the original string, and the DNS query is repeated for this string using DNS resolver information from dns-record-value, which is a Cell corresponding to value category "-1" (next resolver) regardless of the original category requested. Otherwise m is equal to the length of the original string, and dns-record-value is either a cell representing (HashmapE 16 ^DNSRecord) (i.e., a dictionary with 16-bit signed integer keys equal to record categories), if the requested category was zero, or just a DNSRecord containing the record for the requested category (a Cell or a Null, if there is no record of this category for the requested subdomain).

In most cases, the persistent data of a TON DNS Resolver smart contract contains a prefix dictionary with keys equal to the defined subdomain names (with terminating zero byte) and values equal to a (HashmapE 16 ^DNSRecord), i.e., a fixed-key-length dictionary with 16-bit signed integer keys equal to the categories and with DNSRecord values. However, a specific TON DNS Resolver smart contract may use other data structures instead of or in addition to such a prefix dictionary.

3) An automatic DNS resolver smart contract has an extra get-method, which returns the standard payment for registering a new subdomain, the length of this period of time in seconds (e.g., a year), and the price paid for each cell and bit of the value stored for the subdomain in addition to the standard method. Whenever a suitable internal message (with 32-bit method id equal to a predefined value) arrives, the subdomain name and the value (i.e., a (HashmapE 16 ^DNSRecord) are extracted from its body, and if the message carries enough Grams, a new subdomain record is created in the persistent data of the smart contract. If a DNSRecord of category "-2" (owner) is defined in the value for the new record, it contains either the address of the controlling smart contract; in this case, further internal messages from this address may be used to modify the value stored for the subdomain or to extend the registration of the subdomain. A special get-method may be defined to inspect the expiration time of any registered subdomain.

4) A manual DNS resolver smart contract does not create subdomains automatically on receipt of internal messages from arbitrary senders. Instead, it processes only requests arriving in external messages signed by the DNS resolver owner. The public key of the owner is stored into the resolver smart contract during its creation, similarly to the simple wallet smart contract. However, in contrast to the simple wallet smart contract, there must be a way to change the public key by means of a specially-formed external message signed by the old public key.
5) When a two-party payment channel smart contract is created, several parameters have to be fixed, such as the amount to be frozen by each party, the public keys of each party, the creation timeout of the payment channel (if the payment channel is not created by this time, the amount frozen by any already participating party is returned on their request; when all participants recover their frozen amounts, the payment channel smart contract is destroyed), the closure time of the payment channel, and the timeout for the one-sided closure of the payment channel in seconds (if one-sided closure of the payment channel is attempted by a special message signed by one of the parties and containing their opinion of the final state of the payment channel, then after this timeout the payment channel is closed according to the state of the payment channel known at this point, and all parties can recover their dues).
A payment channel consists not only of a smart contract, but also of an off-chain network protocol used to communicate data related to the "virtual blockchain" between the two parties involved. You do not have to implement a full-fledged network protocol over ADNL in this task. Instead, you have to write Fift scripts that will generate outbound "network" messages as files and read inbound "network" messages from other files, with their filenames passed as command line arguments. The files themselves might be communicated between the two parties in any fashion (e.g., by email).
2. FunC / TON VM improvement contest

If you have implemented at least one smart contract in the previous contest, you can participate in the FunC / TON VM improvement contest, by suggesting a patch to the FunC and/or TON VM sources, and writing a better (shorter or more expressive) implementation of the same smart contract using the newly-added FunC features (to be enabled by a special command-line option `-X` of the FunC executable). This implementation will be compared with the original implementation of the same smart contract by the same participant. A short description of the suggested (and implemented) improvement is also expected.
3. TON Blockchain bug bounty contest
If you find a bug in the TON Blockchain, you can submit its description and a suggested scenario of its exploitation to participate in the TON Blockchain bug bounty contest. If you manage to actually exploit this bug in the test network ("testnet") of the TON Blockchain (e.g., by stealing some funds from the wallet of another person) and attach an explanation (and proof) with your bug description, you are likely to obtain a larger prize (up to $200,000 in addition to the $200,000 prize fund distributed among smart contract developers).
Denial of Service (DoS/DDoS), Brute Force, Physical attacks and Social engineering attacks will not be awarded. Only vulnerabilities with security impact will be considered.

Back to