That is the second article in our sequence on integrating cost channels on Telegram Open Community. Within the first half, we introduced the community, detailed our expertise of the competition, and defined how synchronous and asynchronous sensible contracts work. As the subsequent addition to the sequence, this text particulars how we constructed a synchronous cost channel on the community throughout TON’s contest again in September. Right here, we will probably be speaking solely about Fift (TON’s general-purpose programming language) and FunC (TON’s programming language for writing sensible contracts).
The TON white paper provides extra in-depth details about cost channels, however we are going to briefly clarify them once more.
A synchronous cost channel permits sending transactions between two customers off-chain utilizing on-chain belongings. In our case — GRAMs. It’s not possible for one get together to cheat the opposite off-chain, and transactions are made a lot quicker than executing layer-one blockchain transactions, as solely person units are used to finish them with out having to jot down to the blockchain. There are two primary operations: deposit and withdraw. The withdrawal is essentially the most difficult one to implement.
To make an accurate withdrawal, customers want to offer the newest details about the state of their channel. The state consists of the steps and digital signatures of every participant, which suggests it’s not doable to offer an accurate state with knowledge that has not been permitted by each events.
To deploy a wise contract, you’ll want to write a deploy script in Fift and compile it to a .boc (bag of cells) file. Doing this makes a number of cells that will probably be linked to one another. GRAMs then must be despatched to the handle that was acquired throughout deploy script execution. As soon as GRAMs are on the handle, ship the .boc file to the community and the contract will probably be deployed.
To make a perform name, write a script that can ship an exterior message to the deployed sensible contract.
Mainly, something on TON is a cell with some references. A bag of cells is a knowledge construction that was designed by the Telegram crew. It’s an actor mannequin. Extra particulars are at TON whitepaper: “the whole lot is a bag of cells.” You’re constructing a cell that can work together with one other cell when it’s deployed.
Every peer-to-peer cost channel is a single sensible contract. Let’s check out the segments of a wise contract.
A serialized Fift script is used to deploy a contract. It’s saved to a .boc file and despatched to the community by way of TON Cli, the community’s mild consumer.
The most recent cell on the stack is the results of executing the above Fift script.
The same old segments of a Fift deploy script embody (however will not be restricted to):
- Code of the sensible contract as a single cell (often written in FunC, then compiled into Fift ASM code and included in the principle .fif file utilizing path-to-compiled-asm.fif).
- Preliminary storage of the sensible contract (see under).
- New sensible contract handle (the hash from the preliminary state of the sensible contract that additionally contains the sensible contract code cell and the preliminary storage cell).
- Arguments of the primary name of the recv_external perform (the quantity of arguments and kind is dependent upon the contract).
- An exterior message cell for initialization, which will probably be serialized into bytes and packed to the .boc file, which consists of all the information from factors 1–four and a few extra ones which are nonetheless missing documentation.
When the .boc is compiled, a certain amount of GRAMs must be despatched to the sensible contract handle. The .boc file have to be despatched to the community to initialize the sensible contract. The quantity of GRAMs is dependent upon the dimensions and quantity of calculations of the deployed sensible contract’s exterior message cell (not solely the code of it). Fuel × gasoline value is taken from the deployed sensible contract stability. This quantity is the minimal wanted to pay for gasoline throughout the deployment.
A illustration of the storage:
- seqno 32 bits
- contract_status four bits
- first_user_pubkey. The primary get together’s public key 256 bits
- second_user_pubkey. The second get together’s public key 256 bits
- time_to_send. Time to ship after the very first state being submitted 32 bits (legitimate till 2038)
- depositSum. The deposited sum of two individuals as much as 121 bits
- state_num 64 bits. The present quantity of states that occurred
A cell accommodates as much as 1023 bits and 4 references to different cells. We had been in a position to match your entire storage onto one cell with no single reference. Our storage can take up a most of 765 bits.
All sensible contract states
0x0 — Deployment state
0x1 — Channel opened and prepared for deposit
0x2 — Deposit by person 1
0x3 — Deposit by person 2
0x4 — The deposit is blocked. It’s doable to offer a state to the sensible contract
0x5 — Consumer 1 has supplied the state
0x6 — Consumer 2 has supplied the state
0x7 — The channel is closed
The deposit perform receives a message from a easy pockets (switch) with an extra physique payload.
Depositing GRAMs to the channel:
- The person generates an extra physique payload that features a message (for instance, 1 bit) and its signature in a separate .fif file.
- Physique payload is compiled to a .boc file.
- Physique payload is loaded from this .boc file right into a .fif file as a body-cell “transferring” reference (the .fif is accountable for transferring GRAMs from the pockets).
- The recv_external perform is named with arguments (the deposit quantity and the vacation spot handle of the channel) when the compiled .fif file is distributed to the community.
- The send_raw_message perform is executed. Deposited GRAMs and extra physique payload is distributed to a P2P channel sensible contract vacation spot handle.
- The recv_internal perform of the P2P channel sensible contract is named. GRAMs are acquired by channel contracts.
The deposit perform could be referred to as if the state of the P2P channel sensible contract is 0x1 or 0x2 or 0x3.
FunC code that checks the state:
Solely the homeowners of the general public keys (written within the preliminary storage) are allowed to make a deposit. The sensible contract checks the signature of every inside message that will probably be acquired by way of the recv_internal perform. If the message is signed by one of many public key homeowners, the contract standing modifications to 0x2 or 0x3 (0x2 whether it is public key 1 and 0x3 whether it is public key 2). If all customers have made a deposit, the contract standing modifications to 0x4 on the identical perform name.
The FunC code accountable for altering contract standing:
Funds could be returned if a counterparty has not made a deposit on time.
To try this, a person wants to offer their handle and signature by way of exterior message. The funds will probably be refunded if the supplied signature belongs to public key 1 or public key 2 (individuals who made a deposit) and the contract standing is 0x2 or 0x3.
FunC code that’s accountable for verifying the refund utility:
Every individual ought to present an exit state, the signature of this state, and signature of the physique message.
- Good contract handle (to exclude the opportunity of coming into the proper state from the earlier P2P channel with the identical individuals).
- The ultimate stability of the primary participant.
- The ultimate stability of the second participant.
- State quantity.
The physique message signature is saved in the principle slice, the state is saved in a separate reference, and state signatures are saved as references to a “signatures” reference to keep away from cell overflow.
Verify the physique message signature and decide the participant.
Verify that it’s the flip of the participant or 24 hours have handed for the reason that final entered state. Write the flip of the present participant (0x5 or 0x6) to the contract standing.
An instance of an accurate signature of the physique message for the proprietor of first_user_pubkey:
We then have to confirm that the sensible contract handle written to the state is the precise contract handle:
Subsequent, we have to confirm signatures underneath the state:
After that, there are two assertions:
- The deposited quantity from the storage ought to be equal to the sum of the entire balances of the individuals.
- The brand new entered state quantity have to be higher than or equal to the earlier one.
In case of new_state_num > state_num we have to retailer new_state_num with the brand new time_to_send equaling to now() + 86401 (24 hours from the present time), and likewise write the precise contract standing (0x5 if first participant made a name, in any other case 0x6).
In one other case, if new_state_num == state_num we have to put an extra two references to the “signatures” reference with addresses of every participant and signatures underneath their addresses.
If the signatures are appropriate, GRAMs are withdrawn from one handle and put into the proprietor’s handle.
Every time a profitable name occurs, we have to retailer all storage knowledge even when it doesn’t change.
The belief is that the primary person deployed the contract and the individuals agreed on commissions. The settlement on commissions in our case is reaching off-chain.
We’ve not but found out learn how to calculate the entire fee, making an allowance for the truth that gamers can write an irrelevant state and report precise states after that. Needless to say we have to pay charges from the P2P channel sensible contract every time we efficiently name recv_internal or recv_external capabilities.
As talked about earlier, we have to add some quantity of GRAMs to a non-bounceable future sensible contract handle with a purpose to initialize it.
On the final day of the competitors, TON’s builders made a decide to the stdlib.fc library with a brand new perform that enables getting the precise sensible contract stability.
Options for doable options to this drawback are welcome!
FunC and Fift permit any developer entry to the low-level world of software program engineering, opening new alternatives and options for blockchain builders who’ve already gotten used to Ethereum or every other sensible contract platform. It will be important that TON is a sharded blockchain, so implementing sensible contracts on it is more difficult. For instance, Ethereum’s contracts run synchronously and don’t require dealing with conditions resembling ready for a solution from one other contract.
The asynchronous manner of sensible contract communication is the one choice to make it scalable, and TON has these choices. Our answer ended up being harder to implement than Solidity, however there may be all the time a trade-off. It’s positively doable to construct a sophisticated sensible contract on TON, and the best way that TON’s crew dealt with it is rather spectacular. We’re trying ahead to seeing extra libraries and instruments that can assist to deploy and construct FunC contracts.
We completely loved all of the duties and want that we’d had extra time to implement all of them. Nonetheless, we gained two prizes at TON Contest: first place for greatest synchronous cost channel in addition to third place for greatest asynchronous cost channel.
We’ll share our personal private suggestions partly three.
The views, ideas and opinions expressed listed below are the authors’ alone and don’t essentially mirror or characterize the views and opinions of Cointelegraph.