TEPs icon indicating copy to clipboard operation
TEPs copied to clipboard

TEP: Contract Introspection

Open ex3ndr opened this issue 3 years ago • 1 comments

ex3ndr avatar Sep 12 '22 12:09 ex3ndr

Current proposal suggests to use a set of opaque numbers which user somehow should match with actual "interfaces" (the term used the same way it is described in TEP, in particular as a set of behavioral traits). The issues of such approach are as following:

  • ton.tonwhales.staking after hashing will give absolutely no information to user
  • 128bit are too short to be id in TON Storage (or IPFS)
  • at the same time 128bit looks like excessive: in ethereum's solidity 32bit ids for method names looks ok (there will be much fewer interfaces than method names, so theoretically even less than 32bit would be ok)
  • system is quite specific and thus rigid: if we will want to switch to new system where interfaces are formally described technically it will violate this standard

Instead this proposal can be loosen a bit: in particular supported_interface will be allowed to return arbitrary number of arbitrary TVM-types. Initial interpretation of some types can be proposed:

  • integers below 65536 are considered as TEP-standard numbers which contract state to implement
  • higher integers are considered as hashes
  • slices are considered as ASCII strings with domains itself, like org.ton

Accordingly, the first number which supported_interface returns should be 94 (contract state that it implement TEP-94).

This will allow contract to return both opaque number (if it wants), some human-readable description like "disintar-nft", urls or adnl addresses with descriptions, TON Storage ids and other currently not specified formats (cells, tuples etc can be used for that)

EmelyanenkoK avatar Sep 12 '22 13:09 EmelyanenkoK

I suggest to use multihash: https://github.com/multiformats/multihash

mr-tron avatar Dec 15 '22 21:12 mr-tron

In general I think this concept is important. Introspection is important and declaring interfaces provides value.

My main issue with this TEP is that as proposed, the interfaces are free form and informal. This reduces the value they give to almost zero. Unless they're formal, they're not actionable. Wallets will be too scared to show UI based on them because they're informal, so it will be better not to show them at all to users. I actually can't imagine where they can be used.

If we instead make the interfaces formal - detailed enough to understand the TLB of the ops and arguments of the getters, this will now provide significant value to our ecosystem. Because it will reduce dependency on complex UI for accessing contracts.

What is "safe" practice with smart contracts?

You want to deposit money in a contract. You or somebody you trust needs to do due diligence on the smart contract source code to make sure your money will not be abused. Luckily, smart contracts are relatively short (200-2000 lines of code on average) so this isn't too insane to do. Uniswap V2 contract is a joy to read.

Unfortunately this is not enough. You need to do due diligence on the client code as well, to make sure that there's an available client for you to take your money out. Unfortunately, doing due diligence on client code means reading monstrous react apps that have tens of thousands of lines of code with dependencies. Uniswap V2 JavaScript client is not a joy to read.

On Ethereum, the "solution" is ABI. The ABI gives you confidence that even without the monstrous JavaScript client, you will still always be able to take your money out. Because you have a formal interface. Etherscan can even build the UI automatically to let you interact with the contract directly.

We're missing something like this in TON. We don't have an ABI and to reverse engineer the TLBs from the source is a very difficult task. Certainly no tool like Etherscan can do it automatically to generate UI.

This is where this proposal comes in. If the interface is formal, this will replace the ABI for TON and will allow tools to create UI automatically so you're not dependent on the fat client.

Making a formal interface

Many ways to do this, for example write down the TLBs as text one after the other and SHA128 the result.

Then we can have off-chain registries (like the contract verifier and contract source registry) where people publish this TLB text file. Very easy to verify that this TLB conforms to the contract, just run the supported_interfaces getter and see if the TLB file matches the hash.

This format is actually an improvement over Ethereum's ABI. Instead of one big interface, we have multiple small ones. This encourages reuse of interfaces.

What about security? It's true that the contract writer can lie about the TLB and report a fraudulent one. But this will come up when the community does due diligence over the contract code. Even with ABI, the contract writer can mislabel and switch between a "from" and "to" fields and nobody will notice unless they do proper due diligence and review the full code.

talkol avatar Dec 19 '22 18:12 talkol

I think supporting arbitrary TVM types makes this suggestion too complex. If we're ok with slices, perhaps all interfaces should be slices containing strings.

Although I think the suggestion to have a registry for interfaces (similar to contract verifier) is better and then we can use the original proposal of 128-bit hash.

mrbonezy avatar Dec 20 '22 08:12 mrbonezy

One way to offer a secure ABI is to standardize some specific contract implementations and make them composable with the custom logic. E.g. you may have a standard "Timelock" and "Allowance" contracts that have fixed and trusted behavior. Apps would combine them with their custom decision-making contracts, while the wallet will know basic parameters: how many units of what asset are going to be where and for how long.

We could do that on the level of individual contracts, but that might create expensive chains of transactions. One way to optimize them would be to compose predicates within one contract. See also my comment on safe RUNVM composition: https://github.com/ton-blockchain/TEPs/pull/88#issuecomment-1359086810

oleganza avatar Dec 20 '22 09:12 oleganza

Can we please stop this nonsense about the lack of ABI? It is a solved problem in TACT already. It is distributed (no central authority) and works well. It just requires some more formal specifications and refining.

ex3ndr avatar Dec 20 '22 10:12 ex3ndr

ABI is also not about this interfaces, it is about learning about unknown contract and checking if they implement specific set of functions, for example, staking, stopping a contract, ownable, etc.

Also forcing binary specification of methods to interface id is completely delusional about how it works. Such things woulr work only for some very well-established interfaces (that i personally don't care at all) and this interfaces would STILL REQUIRE YOUR CONTRACT TO BEHAVE.

But imagine TF would craete a "Stoppable" standart about being able to stop a contract in the case of emergency. They would define that contract can receive a message "Stop" to make it stop. What next? Should it send a reply to sender? Should it send it to other parties? Should it cost something for sender? I, as contract developer, don't care about how it works somewhere else. They would have the same IDs.

"Forcing people to reuse interfaces", may be not forcing but giving useful tools? I am starting to get Stalin vibes about such discussions since they are aimed to lock everyone to a specific pattern.

ex3ndr avatar Dec 20 '22 11:12 ex3ndr

I agree with @ex3ndr that forcing binary specifications for contracts is impossible. You can't guarantee that different implementations do the exact same thing.

Regarding the ABI support in TACT, it doesn't matter since TACT is not out yet and we're probably not going to disallow func anyways and there'd an ABI problem with func.

Formal interfaces that specify the TLB of the different ops and the arguments of getters is useful. It's certainly more useful than informal interfaces that don't say anything actionable.

talkol avatar Dec 20 '22 12:12 talkol

TACT is out, it just stuck with the bureaucracy loop within FS/TF.

And yes, we need to ditch func and make it the internal language of TON (just like solidity compiles to another language first). It makes zero sense to do anything in func even in the short term.

ex3ndr avatar Dec 20 '22 13:12 ex3ndr

Well, it will be nice to involve the community in TACT release and ask for feedback. Not just TF and FS

talkol avatar Dec 20 '22 13:12 talkol

I literally reached everyone around. It turns out that dev community is just quite defunct and there are no single channel to open a discussions.

ex3ndr avatar Dec 20 '22 13:12 ex3ndr

There's one official channel for TON standards which is the TEP, if you want feedback, ask for it through the TEP channel and work to make TACT a standard, it's certainly a bigger issue than discussing interfaces. On the same note, TON Connect should have been published in TEP channel as well. You are contributing to the mess by working on major standards outside of TEP

talkol avatar Dec 20 '22 13:12 talkol

TACT is a compiler, not a standard and it requires this one TEP to be finalized since it already has built in way to specify interfaces.

ex3ndr avatar Dec 20 '22 13:12 ex3ndr

TACT is a language, a language is a standard for developers. Publish the language specifications as a TEP to discuss how the language works. We don't need to discuss implementation details of the compiler. If the materials are external, place a link of where the external discussions take place. Right now for example I'm not involved in TACT specifications and I would like to be.

talkol avatar Dec 20 '22 13:12 talkol

No, it is too slow.

ex3ndr avatar Dec 20 '22 13:12 ex3ndr