├── README.md ├── opinions └── dtfo-0001.md └── specs ├── wtf-0001.md ├── wtf-0002.md ├── wtf-0003.md └── wtf-0004.md /README.md: -------------------------------------------------------------------------------- 1 | # Specifications for TONCOIN 2 | 3 | Various protocols and specifications for TONCOIN. 4 | 5 | * [WTF-0001: Basic introspection spec (rev 3)](/specs/wtf-0001.md) 6 | * [WTF-0002: Safe Signing](/specs/wtf-0002.md) 7 | * [WTF-0003: HD Keys Seed](/specs/wtf-0003.md) 8 | * [WTF-0004: Standard Interfaces](/specs/wtf-0004.md) 9 | 10 | Opinons: 11 | 12 | * [DTFO-0001: Opinon on Jettons](/opinions/dtfo-0001.md) 13 | 14 | # License 15 | Public domain -------------------------------------------------------------------------------- /opinions/dtfo-0001.md: -------------------------------------------------------------------------------- 1 | # Jettons initial version opinion 2 | 3 | Author: Steve Korshakov (steve@korshakov.com) 4 | 5 | Jettons spec aimed to be the first token contract and establish how tokens must work in the TON network. One of the most critical factors outlined by authors of Jettons specification is its scalability and avoiding blocking whole TON shard for massive contracts. We will prove that this goal is not achieved and put a lot of burden on everyone in the ecosystem. 6 | 7 | Jettons goes against what was stated in whitepapers and solves scalability issues in a non-natural way for what was expected to be solved by the network, not contract developers. 8 | 9 | Historically Jettons are descendants of an NFT contract that got its architecture from a wild idea that two people (me and N. Abovyan) had during one evening discussing what to do in TON at the bar: what if every NFT could be a separate contract. That was one of this ideas that smart people use as entertainment. In next days N. Abovyan published it's first contract to a testnet and Github. It was a joke contract and **never intended to be a standard**. For some reason, Ton Foundation and GetGems hired this engineer and continued to work on this contract. I believe that the only explanation is that it looks mathematically sound and an exciting task to solve, not something that solves any problem. 10 | 11 | NFT standards have huge flaws, and one of them - **they are not meant to be generated randomly**. This is the most crucial feature in NFT, yet the standard explicitly disallows it. Also, deploying a new collection takes about 2k$ in gas, and there is no way to reduce this cost. 12 | 13 | Jettons copy everything from NFT and inherit all its flaws. 14 | 15 | This document focuses on jettons. Everything is true for NFT contracts too. 16 | 17 | ## Differences TON from Ethereum-like networks 18 | 19 | One of the most significant differences between TON and ETH is that in TON, transactions are scoped only to a **single** contract. At the same time, in ETH, you can scatter transactions across many unrelated contracts. The second most significant difference is an inability to read data from an agreement that is not part of a transaction. 20 | 21 | In general, differences are pretty much the same as in classical (not blockchain) distributed computing (TON) and centralized (ETH). The first one is much harder to build if you need to interact with multiple contracts in the network, and no one figured out how to make them the easy way, while centralized computing is a solved problem. Decentralized computing requires an insane level of knowledge and experience that you can't expect from an open-to-the-public platform. Also, you need to control all contracts that interact with each other, which is impossible in the blockchains. Also, TON lacks some of the required mechanisms for successful distributed apps, which makes the interaction between contracts too complex to be feasible. 22 | 23 | ## How Jettons works 24 | NFT and Jettons consist of a master (collection) contract that creates a new contract per **owner**. If there are 1M of wallets with USDT, it will make 1M of extra contracts to be paid for storage, gas, etc. 25 | 26 | This architecture is incompatible with how TON works and generally complicates things without added benefits. 27 | 28 | ## What Jettons are suitable for 29 | 30 | It is suitable for meme-tokens without utility. It is easy to launch and doesn't need much coding, which would work for them. 31 | 32 | It will work for a while for stablecoins or other uncapped coins, and it lacks scalability bottlenecks and, in general, should work. 33 | 34 | ## What Jettons are bad for 35 | 36 | Jettons don't work well for stablecoins and utility tokens. The first one is simply expensive in terms of gas and wastes blockchain storage and throughput of the network. This is a tax for distributed systems, but Jettons amplified everything in its architecture. Jettons implemented transactions as a series of operations between different contracts, and doing a simple transfer takes about five transactions. Everything could fail in between. This is a very well-studied issue in distributed computing, and there are simply no solutions, and nothing is expected to improve anytime soon. 37 | 38 | For utility tokens, it is near impossible to build a contract in most cases. The simplest case is a DAO - you need to know the balances of all holders when the proposal is created or check the balance for certain operations, but you can't - there is no balance stored in the main contract. 39 | There are different ways to solve these issues, but they are not working for everyone and significantly increase complexity. There is no point in this complexity for the DAO of a few friends. Everything is simple when you have a single contract. 40 | 41 | ## Very complicated audit 42 | First of audit is very hard to audit multiple contracts that interact with each other the way they are in TON. 43 | 44 | It is tough to audit such systems and see how changes to reference implementations affect security. 45 | 46 | ## Alternative: Currencies 47 | TON has a built-in ability for currencies that requires zero coding and will be embedded to ALL addresses and contracts once deployed. It is scalable the way TON itself is, and it just involves the validator's consensus to launch a new coin on the TON network. Also, eventually, the network could be upgraded to use this currency to pay for gas. This would lead to pure stablecoin-based transactions, and users will be able to transfer USD by paying blockchain fees in USD, just like CELO. 48 | 49 | The only issue is that the network can't block transactions of these currencies and limit transfers until the network upgrades. 50 | 51 | This way, Jettons are good for initial deployment, but it is better to upgrade to a new mechanism. If Jettons are just the initial version for stablecoins then there is no point in making them that hard and expensive to use. A straightforward contract that is easy to audit is possible to use instead, and Jettons are hard to test and audit. 52 | 53 | ## Alternative: Single contract 54 | One of the critical use cases for tokens is a DAO. Jettons are almost impossible to use as DAO shares. 55 | 56 | DAO is a contract that allows its members to vote on what to do: transfer, change membership shares, etc. 57 | 58 | One of the main features is fair voting. A few strategies could provide fairness: members either stack coins and have a colossal grace period (30 days or more) or persist shares during proposal creation. The first option is not for everyone and could put DAO at risk when too many people withdraw their stakes, and the second one is impossible with jettons. 59 | 60 | Storing everything in a single contract is trivial and gives a lot of possibilities for DAO developers. Even the biggest DAOs in the wild don't have that many transactions (more like one in an hour) to hit any scalability issues that have to be solved, increasing this complexity. 61 | 62 | ## Monoculture of standards 63 | 64 | A culture of "official" standards is a poison in the community: everyone looks at what is official and sits and waits for a miracle instead of doing so. Ton Foundation does nothing to prevent this but does the opposite: simply ignoring existing developments and then promoting their own without reason. This forces everyone to wait for a few in Ton Foundation. This wait is usually counted in months, not days. This limits innovation and halts to stop new development. 65 | 66 | Tonkeeper team is also doing the same: no ability to interact with contracts from TonKeeper leads to enormous problems for developers: right now, you can't build **ANYTHING** because there is simply no support in the app. You have to wait for months and convince them to add some specific flows, and actually, no one outside succeeded in this. That was the one reason for Tonhub to be alive. Tonkeeper representative said they are not going to implement support for custom contracts. 67 | 68 | This Tonkeeper + Ton Foundation blend leads that you can't build your token standard (even with public discussions and well-maintained specifications) and expect to integrate it into major products and get marketing support. Everyone is just waiting for **MONTHS** for something to happen while building a good standard could be done in days. 69 | 70 | ## Summary 71 | Jettons are a workable standard, but it doesn't make sense for anyone except authors to use them. It dramatically complicates things, reduces the ability to build valuable something, never solves any problems that the authors stated, and goes against what was intended in original whitepapers for scalable contracts. 72 | 73 | I recommend using them only as a toy or as a temporary solution and start seeking alternatives. -------------------------------------------------------------------------------- /specs/wtf-0001.md: -------------------------------------------------------------------------------- 1 | # Contract introspection (rev 3) 2 | 3 | Authors: Steve Korshakov (steve@korshakov.com), Danila Volkov (danila@whalescorp.com), Narek Abovyan (xeroxaltox@gmail.com). 4 | 5 | This is highly valuable specification that is needed for almost any service in the ecosystem such as: indexers, wallets and marketplaces. This specification aims to helps to declare what contract supports while being very flexible and help individual developers from moving forward. 6 | 7 | ## Spec 8 | 9 | In order to support introspection contract should implement supports_interface GET method: 10 | 11 | ```(int...) supported_interfaces()``` 12 | 13 | Which returns list of supported interface codes. 14 | 15 | ### Interface 16 | 17 | Interface is a list of supported get methods, internal/external messages AND expected behaviour of a contract. 18 | 19 | `Interface definition` is in a free-form and up to interface author. 20 | 21 | `Interface name` is some globaly unique name in a reverse domain notation, for example: `org.ton.wallets.v3.r2`. 22 | 23 | `Interface ID` is calculated by getting first 16 bytes of a SHA256 of `Interface name`. 24 | 25 | For convenience provide [online tool](https://tondev.org/tools/interface-id) for value calculation. 26 | 27 | ### Introspection Interfcace 28 | 29 | Introspection interface is named `org.ton.introspection.v0` and it's ID id `123515602279859691144772641439386770278`. 30 | 31 | In order to implement it contract should implement `supported_interfaces` function. 32 | 33 | NOTE: `123515602279859691144772641439386770278` ALWAYS have to be the first value in this list. 34 | 35 | ```func 36 | _ supported_interfaces() method_id { 37 | return (123515602279859691144772641439386770278); 38 | } 39 | ``` 40 | -------------------------------------------------------------------------------- /specs/wtf-0002.md: -------------------------------------------------------------------------------- 1 | # Safe Signing 2 | 3 | Author: Steve Korshakov (steve@korshakov.com) 4 | 5 | To prove ownership of an address for off-chain services, it is required to provide signing of arbitrary data from wallets. Unfortunately, since key is the same we have to construct 6 | a safe way to sign to avoid malicilous signing of a transaction. This specifications does exactly that. 7 | 8 | ## Process 9 | 10 | To sign a transaction (or just a cell) for TON it is required to create **Cell Representation**, hash it and then sign. Our goal is to create prefix that would never lead for correct 11 | representation. 12 | 13 | From whitepaper: 14 | 15 | ``` 16 | 3.1.4. Standard cell representation. 17 | When a cell needs to be transferred by a network protocol or stored in a disk file, it must be serialized. 18 | The standard representation CellRepr(c) = CellRepr∞(c) of a cell c as an octet (byte) sequence is constructed as follows: 19 | 1. Two descriptor bytes d1 and d2 are serialized first. Byte d1 equals r+8s+32l, where 0 ≤ r ≤ 4 is the quantity of cell references 20 | contained in the cell, 0 ≤ l ≤ 3 is the level of the cell, and 0 ≤ s ≤ 1 is 1 for exotic cells and 0 for ordinary cells. Byte d2 equals 21 | ⌊b/8⌋+⌈b/8⌉, where 0 ≤ b ≤ 1023 is the quantity of data bits in c. 22 | 2. Then the data bits are serialized as ⌈b/8⌉ 8-bit octets (bytes). If b is not a multiple of eight, a binary 1 and up to six 23 | binary 0s are appended to the data bits. After that, the data is split into ⌈b/8⌉ eight-bit groups, and each group is interpreted as 24 | an unsigned big-endian integer 0 . . . 255 and stored into an octet. 25 | 3. Finally, each of the r cell references is represented by 32 bytes contain- ing the 256-bit representation hash Hash(ci), explained 26 | below in 3.1.5, of the cell ci referred to. 27 | In this way, 2 + ⌈b/8⌉ + 32r bytes of CellRepr(c) are obtained. 28 | ``` 29 | 30 | From documentation it is obvious that if we want to sign cell with a single reference it will have a form if ``. Now we need to construct prefix the way representation became invalid. It is obvious that values `5 ≤ r ≤ 7`, `2 ≤ s ≤ 3` and `4 ≤ l ≤ 7` are all invalid. We will pick maximum values and this would be `0xff` byte. While this already makes representation invalid we will strength it even further just in case if cell representation specification will be expanded. Second byte doesn't have invalid values so let's just pick the same `0xff` byte. This value would represent `1023` bits, to make it invalid we will simply write to buffer anything that is less than 127 bytes long. This standart defines this as binary representation of string `ton-safe-sign-magic`. 31 | 32 | ## Spec 33 | 34 | To sign an arbitrary cell that couldn't later used as a transaction in blockchain we compute data for signing next way: 35 | 36 | ```js 37 | let cell: Cell; // Incoming cell 38 | let hash = cell.hash(); // Hash of cell 39 | let data = sha256(Buffer.concat([Buffer.from([0xff, 0xff]), Buffer.from('ton-safe-sign-magic'), hash])); // Data to hash 40 | let signature = sign(data, publicKey); // Resulting signature 41 | ``` 42 | 43 | ## Customization 44 | 45 | For specific needs it is possible to change `ton-safe-sign-magic` for separating different signature usage, for example for signing "child" keys that could be used as proof of ownership off-chain or on-chain, but this string must be non-zero and not too big to form a 127 bytes string for signing. 46 | -------------------------------------------------------------------------------- /specs/wtf-0003.md: -------------------------------------------------------------------------------- 1 | # HD Keys Seed 2 | 3 | Authors: Steve Korshakov (steve@korshakov.com) 4 | 5 | Hierarchical Deterministic Keys are a useful feature of Bitcoin that allows you to backup a single seed phrase and have an access to virtually infinity number of keys. 6 | 7 | There are muliple HD keys for multiple algorithms, this proposal defines how to derive root seed for any possible algorithm and withoud sacrificing root wallet key. 8 | 9 | ## Spec 10 | 11 | To derive 64 byte seed from TON mnemonics just use seed text `TON HD Keys seed` instead of default one. -------------------------------------------------------------------------------- /specs/wtf-0004.md: -------------------------------------------------------------------------------- 1 | # List of standard interfaces 2 | 3 | Authors: Steve Korshakov (steve@korshakov.com) 4 | 5 | Standard interfaces are the one that is common enough to be widely integrated into explorers, wallets and dApps. 6 | 7 | ## Jettons 8 | 9 | Jettons have two contract types: wallets and master. 10 | 11 | Jetton master interface: `org.ton.jetton.master.v1` with ID `242422353946785872806511191513850808027`; 12 | 13 | Jetton wallet interface: `org.ton.jetton.wallet.v1` with ID `311736387032003861293477945447179662681`; --------------------------------------------------------------------------------