Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature - Upgradable trait #12

Open
bymoses opened this issue Jun 2, 2024 · 8 comments
Open

Feature - Upgradable trait #12

bymoses opened this issue Jun 2, 2024 · 8 comments
Assignees
Labels
enhancement New feature or request

Comments

@bymoses
Copy link

bymoses commented Jun 2, 2024

Disclaimer: Hi guys, I'm relative new to TON ecosystem but AFAIK there's no standardized approach for upgradable contracts in Tact.

Motivation

Motivation for this issue is to discuss some approaches for making contract upgrades here because tondynasty is relatively popular and it will be easier to find this information for newcomers.

Solution

A couple weeks ago @wedvjin created proof of concept repo.
Using his example and tondynasty's traits approach I've created a basic Upgradable trait:

@name(set_code)
native setCode(code: Cell);

@name(set_data)
native setData(d: Cell);

message UpgradeContract {
  code: Cell;
  data: Cell?;
}

trait Upgradable {
  owner: Address;

  // @dev  Upgrade
  receive(msg: UpgradeContract) {
    let ctx: Context = context();
    self._upgrade_validate(ctx, msg);
    self._upgrade(ctx, msg);
  }

  // @dev  _upgrade_validate conduct some custom validating before upgrade
  virtual inline fun _upgrade_validate(ctx: Context, msg: UpgradeContract) {
    require(ctx.sender == self.owner, "Upgradable: Sender is not a contract owner");
  }

  // @dev  _upgrade
  virtual inline fun _upgrade(ctx: Context, msg: UpgradeContract) {
    setCode(msg.code);
    if (msg.data != null) {
      setData(msg.data)
    }
  }
}

Limitations

https://github.com/wedvjin/ton-tact-contract-upgrade?tab=readme-ov-file#issue

@alan890104 @howardpen9 please take a look, maybe you have some different approaches for this

@alan890104
Copy link
Contributor

@bymoses brilliant! Let me take a look at it 😎

@bymoses
Copy link
Author

bymoses commented Jun 2, 2024

There's also comment in tact repo by @wedvjin himself tact-lang/tact#27 (comment)
It seems that devs has planned implementation of native upgrade mechanism to v1.4.0, but there's no assignee, so maybe we shouldn't rely on it

@alan890104
Copy link
Contributor

@bymoses This idea looks fantastic! Would you be willing to try writing this upgradeable contract pattern example and become one of the open-source contributors to tondynasty-contracts?

@bymoses
Copy link
Author

bymoses commented Jun 2, 2024

@alan890104 Sure, I've made basic commit at my fork 9e4ac70 . Issue with 11 exit code is there, could you take a look at compiled funC code? I need some assistance here because I don't have experience with this language.
Screenshot from 2024-06-03 00-53-16

@alan890104
Copy link
Contributor

I've got some matters to handle these days, so I might not be able to check this for you until after Wednesday. In the meantime, could you please take a look at this webpage?

@alan890104
Copy link
Contributor

@bymoses There's a strange issue: when I call the get counter method (a GET method) after upgrading to v3, I encounter an exit code 9. This is quite unusual and seems to suggest there might be something hidden within the mechanism of the Tact language.

@bymoses
Copy link
Author

bymoses commented Jun 6, 2024

Ok, as far as I can tell we now have two options:

a. Off-chain computation of new storage cells. e.g. When you send UpgradeContract, data field should be computed on your server and your storage will be overwriten with it.
Screenshot from 2024-06-06 18-41-13

b. On-chain migrations using lock mechanism:

  1. Lock contract
  2. Upgrade code with new overwritten _get_migrated_data method (asm SETCODE instruction shedule code upgrade when the contract execution finished, so we need two contract calls here)
  3. Call "Migrate storage" receiver to trigger newly upgraded _get_migrated_data method and update storage
  4. Unlock contract
    Screenshot from 2024-06-06 20-08-29

@alan890104 alan890104 added the enhancement New feature or request label Jun 13, 2024
@alan890104 alan890104 self-assigned this Jun 13, 2024
@alan890104
Copy link
Contributor

@bymoses Thank you for the time you have invested. After discussing with other teams, instead of incorporating the trait for upgrading contracts into the tondynasty contract, I would suggest that the Tact compiler team include this trait as a built-in feature. This way, everyone can use it upon installation.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

2 participants