Classes Realized on Deploying Good Contracts, Half 2
That is the second article in our sequence on integrating cost channels on Telegram Open Community. Within the first half, we launched 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 likely 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 gives 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 inconceivable for one celebration to cheat the opposite off-chain, and transactions are made a lot sooner than executing layer-one blockchain transactions, as solely consumer gadgets are used to finish them with out having to put in writing to the blockchain. There are two fundamental operations: deposit and withdraw. The withdrawal is essentially the most difficult one to implement.
To make an accurate withdrawal, customers want to supply the newest details about the state of their channel. The state consists of the steps and digital signatures of every participant, which implies it’s not doable to supply an accurate state with knowledge that has not been authorized by each events.
To deploy a sensible 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 likely be linked to one another. GRAMs then must be despatched to the tackle that was obtained throughout deploy script execution. As soon as GRAMs are on the tackle, ship the .boc file to the community and the contract will likely be deployed.
To make a perform name, write a script that may ship an exterior message to the deployed sensible contract.
Principally, something on TON is a cell with some references. A bag of cells is an information construction that was designed by the Telegram staff. 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 may 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 sensible contract.
A serialized Fift script is used to deploy a contract. It’s saved to a .boc file and despatched to the community through TON Cli, the community’s gentle shopper.
The newest cell on the stack is the results of executing the above Fift script.
The same old segments of a Fift deploy script embrace (however should not restricted to):
- Code of the sensible contract as a single cell (normally 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 beneath).
- New sensible contract tackle (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 sort depends upon the contract).
- An exterior message cell for initialization, which will likely 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 can be nonetheless missing documentation.
When the .boc is compiled, a certain quantity of GRAMs must be despatched to the sensible contract tackle. The .boc file should be despatched to the community to initialize the sensible contract. The quantity of GRAMs depends upon the dimensions and quantity of calculations of the deployed sensible contract’s exterior message cell (not solely the code of it). Gasoline × gasoline worth is taken from the deployed sensible contract steadiness. This quantity is the minimal wanted to pay for gasoline in the course of the deployment.
A illustration of the storage:
- seqno 32 bits
- contract_status four bits
- first_user_pubkey. The primary celebration’s public key 256 bits
- second_user_pubkey. The second celebration’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 members as much as 121 bits
- state_num 64 bits. The present quantity of states that occurred
A cell comprises as much as 1023 bits and 4 references to different cells. We have been in a position to match the whole 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 consumer 1
0x3 — Deposit by consumer 2
0x4 — The deposit is blocked. It’s doable to supply 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 consumer 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 answerable for transferring GRAMs from the pockets).
- The recv_external perform is named with arguments (the deposit quantity and the vacation spot tackle of the channel) when the compiled .fif file is shipped to the community.
- The send_raw_message perform is executed. Deposited GRAMs and extra physique payload is shipped to a P2P channel sensible contract vacation spot tackle.
- The recv_internal perform of the P2P channel sensible contract is named. GRAMs are obtained by channel contracts.
The deposit perform might 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 inner message that will likely be obtained via 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 answerable for altering contract standing:
Funds might be returned if a counterparty has not made a deposit on time.
To do this, a consumer wants to supply their tackle and signature through exterior message. The funds will likely 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 answerable for verifying the refund utility:
Every particular person ought to present an exit state, the signature of this state, and signature of the physique message.
- Good contract tackle (to exclude the potential for coming into the right state from the earlier P2P channel with the identical members).
- The ultimate steadiness of the primary participant.
- The ultimate steadiness 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 because the 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 tackle written to the state is the precise contract tackle:
Subsequent, we have to confirm signatures beneath the state:
After that, there are two assertions:
- The deposited quantity from the storage ought to be equal to the sum of the overall balances of the members.
- The brand new entered state quantity should be better 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 in addition 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 beneath their addresses.
If the signatures are right, GRAMs are withdrawn from one tackle and put into the proprietor’s tackle.
Every time a profitable name occurs, we have to retailer all storage knowledge even when it doesn’t change.
The idea is that the primary consumer deployed the contract and the members agreed on commissions. The settlement on commissions in our case is reaching off-chain.
We’ve got not but discovered how one can calculate the overall fee, making an allowance for the truth that gamers can write an irrelevant state and document 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 features.
As talked about earlier, we have to add some quantity of GRAMs to a non-bounceable future sensible contract tackle as a way 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 permits getting the precise sensible contract steadiness.
Strategies for doable options to this downside are welcome!
FunC and Fift enable 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 some other sensible contract platform. It will be significant that TON is a sharded blockchain, so implementing sensible contracts on it is tougher. For instance, Ethereum’s contracts run synchronously and don’t require dealing with conditions similar to ready for a solution from one other contract.
The asynchronous approach of sensible contract communication is the one choice to make it scalable, and TON has these choices. Our resolution ended up being tougher to implement than Solidity, however there’s at all times a trade-off. It’s positively doable to construct a complicated sensible contract on TON, and the best way that TON’s staff dealt with it is rather spectacular. We’re trying ahead to seeing extra libraries and instruments that may 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 received two prizes at TON Contest: first place for finest synchronous cost channel in addition to third place for finest asynchronous cost channel.
We are going to share our personal private suggestions partly three.
The views, ideas and opinions expressed listed here are the authors’ alone and don’t essentially replicate or symbolize the views and opinions of Cointelegraph.