tact-lang / tact

Tact compiler main repository
https://tact-lang.org
MIT License
373 stars 104 forks source link

Impossible to create getters with TACT reserved keywords #858

Open imartemy1524 opened 1 week ago

imartemy1524 commented 1 week ago

The problem

Right now it's impossible to create getters which names are in TACT reserved keywords.

For example, lets look on this trait:

trait Lockable{
    lockedUntil: Int;
    inline fun requireNotLocked(){
        require(now() > self.lockedUntil || self.lockedUntil == 0, "Coins are locked");
    }
    inline fun requireLocked(){
        require(now() < self.lockedUntil, "Coins are locked");
    }
    get fun until(): Int{
        return self.lockedUntil;
    }
}

It seems logical and valid, but in fact it won't compile, because until is reserved keyword.

Possible solution

  1. Ignore system keywords in getter function names
  2. Make it able to annotate getters like this:
      get fun "until"(): Int{
          return self.lockedUntil;
      }
      get fun "getter with spaces"(): String{
          return "bob";
      }
anton-trunov commented 1 week ago

@imartemy1524 What is your use case for getters with names like that?

imartemy1524 commented 1 week ago

In my case, i have smart contract which locks coins/jettons/nfts, and it seems logical to have until getter, which would return the date, when the lock period ends.

Yes, I understand, that I can name it untilDate or get_until, but it seems weird for me, that I can't name getter as I want only because of tact issues with keywords resolving (not because TVM don't support it)

anton-trunov commented 1 week ago

Many programming languages won't let you use reserved words as identifiers. For instance, FunC won't let you use method_id as a getter name and "getter with spaces" is also not allowed there. Since currently Tact is implemented as a transpiler into FunC, supporting this feature for us would be more difficult than it needs to be, so I wouldn't except it to be resolved anytime soon.

imartemy1524 commented 1 week ago

I don't agree with you here.

supporting this feature for us would be more difficult than it needs to be FunC won't let you use method_id as a getter name and "getter with spaces" is also not allowed there

As i understood, tact compiles all getters into FunC method_id using their binary codes using getMethodId function (for example, methods get_nft_data and hlna_3 would return the same binary code (BTW you can try to call hlna_3 on any NFT item)

Thus, I don't understand, why it would be such a big problem to implement custom names.

Example

Lets take a string "getter with spaces" as an example. You can "hack" a system, find a hash collision (in our case it would be z3f8), create such method:

    get fun z3f8(): String{
        return "ok";
    }

And it would be available by its "collision":

    it('should call getter with spaces hash', async ()=>{
        const b = await blockchain.getContract(simpleCounter.address);
        const response = await b.get('getter with spaces', [])
        const stirng = response.stackReader.readString();
        expect(stirng == "ok");
    })
imartemy1524 commented 1 week ago

Related compiler bug: #859