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

Example of programmatic update of JS Smart Contract #287

Merged
merged 6 commits into from
Nov 22, 2022

Conversation

nsejim
Copy link
Contributor

@nsejim nsejim commented Nov 7, 2022

Tried to implement the programmatic update with JS SDK to be used after locking the contract.
However this not working. The problem is on how to pass wasm code when calling the call update method and how to get the code in the smart contract.

To test this:

  • cd examples
  • yarn
  • yarn build:programmatic-update
  • yarn test:programmatic-update

The working RUST version is available
https://github.com/near-examples/update-migrate-rust/blob/main/contracts/self-updates/base/src/update.rs#L10-L28#


// QUESTION: IN WHICH FORMAT SHOULD WE PASS THE WASM CODE AS ARGS? THE CODE IS OF TYPE BUFFER
const result = await ali.callRaw(programmaticUpdate, "updateContract", {
code
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it cannot be in json. As contract is raw bytes, it can contains ascii " and ending json string unexpectedly. However, our high level API only takes json serialized contract arguments and this is not customizable.

So, currently it's only possible to use low level APIs to implement your awesome example. Check test_promise_batch_deploy_call in tests/src/test_promise_batch_api.js, use promiseBatchActionDeployContract, parsing the raw bytes of the as input (passing Uint8Array to callRaw, and that'll be available in contract from near.input())

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The other way is expanding our high level API, more specifically, in near-bindgen.ts, _getArgs use hard coded way to deserialize the arg with JSON.parse. Making that customizable with option can handle your case specially!

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks. Let me try the above low level API solution based on your reference

assert(near.predecessorAccountId() === this.manager, "Only the manager can update the code")

// QUESTION: HOW DO WE GET A WASM CODE PASSED AS ARGS?
const args = JSON.parse(near.input());
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just near.input(), without JSON.parse it

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK

const promise = near.promiseBatchCreate(near.currentAccountId());

// QUESTION: DO WE NEED TO RESOLVE THIS PROMISE FOR IT TO RUN?
near.promiseBatchActionDeployContract(promise, args.code)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In the high level API, promise need to be returned to let the runtime handle the promise: return promise. In low level API, it's near.promiseReturn(promise_index)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Noted

@ailisp
Copy link
Member

ailisp commented Nov 8, 2022

@nsejim Great idea and good experiment on the example! Thank you! The problem is our high level API doesn't yet support this, please see my comment above for details. If you are interested to work on it, it will be great! Or we'll add it to our road map to add it in future.

@nsejim
Copy link
Contributor Author

nsejim commented Nov 9, 2022

@ailisp Thank you for the comments. I am interested to try to work on it. Putting it on the roadmap is good because it is an important feature to eliminate some convincing arguments to go for RUST.

@nsejim
Copy link
Contributor Author

nsejim commented Nov 17, 2022

@ailisp following your suggestion to use the low level APIs, the programmatic update works very well. Thank you.

@nsejim nsejim changed the title WIP: Example of programmatic update of JS Smart Contract Example of programmatic update of JS Smart Contract Nov 18, 2022
@ailisp
Copy link
Member

ailisp commented Nov 21, 2022

@nsejim Your code looks good! It's a quite helpful example indeed! Could you add your example to CI here: https://github.com/near/near-sdk-js/blob/develop/.github/workflows/examples.yml ? Thank you!

@nsejim
Copy link
Contributor Author

nsejim commented Nov 21, 2022

@nsejim Your code looks good! It's a quite helpful example indeed! Could you add your example to CI here: https://github.com/near/near-sdk-js/blob/develop/.github/workflows/examples.yml ? Thank you!

Thanks :) Example added to CI

@ailisp
Copy link
Member

ailisp commented Nov 22, 2022

@nsejim seems ci is unhappy. Please yarn lint & yarn format, then commit & push the changed files. Thanks!

@volovyks
Copy link
Collaborator

Great contribution @nsejim ! Thank you.

@volovyks volovyks merged commit e90d9bf into near:develop Nov 22, 2022
@nsejim
Copy link
Contributor Author

nsejim commented Nov 22, 2022

Great contribution @nsejim ! Thank you.

Welcome. Thank you for the hint!

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

Successfully merging this pull request may close these issues.

3 participants