查看原文
其他

使用 JavaScript 升级互联网计算机上的智能合约

Dfifans Internet Computer 2023-05-02


在 Papyrs(一个 web3 开源博客平台)上,每个用户在登录时都会获得两个智能合约容器,一个包含私人数据,另一个是用户在互联网上的个人博客空间。


直到我(希望)将所有容器的控制权交给 SNS 和社区的那一天,我可能不得不自己在用户的智能合约中安装新版本的代码 —— 例如,解决问题或部署新功能。


本文介绍了我如何使用 NodeJS 脚本安装代码,以及你如何像我一样安装代码。


入门


今年早些时候,我发表了两篇相关文章:



这些文章导致了本教程,第一个解释了如何在 NodeJS 中查询容器,第二个解释了如何动态创建智能合约 —— 即,如何创建容器,我可以在其中安装更新版本的代码。


子容器


我使用上面两个帖子中的第一个来创建一个本地示例项目,在编译和部署到本地模拟 IC 网络之后,我打开浏览器并动态创建一个子容器 renrk-eyaaa-aaaaa-aaada-cai


这个示例智能合约是我打算在接下来的章节中更新的,这就是为什么我通过如下修改它的源代码来提升它的版本:



修改后,我必须重新生成将要安装的 WebAssembly(Wasm)二进制文件 —— 部署到 IC,为此,我必须遵循我在上一篇文章中分享的解决方法,因为目前“没有其他方法可以将导入类的 Wasm 作为单独的非嵌入式事物生成”。


  • 编辑配置 dfx.json 以列出存储桶参与者。


  • 运行 dfx deploy 命令生成文件,该命令将以错误结束,“错误 - 无效数据:预期的参数,但没有找到”,可以安全地忽略。


  • dfx.json 中还原更改。


后端


只有容器的控制器可以安装新版本的代码,由于子容器是由主要 actor 创建的 —— 我将其命名为 manager —— 我必须注意将其主体添加到控制器列表中,同时更新我之前教程中的设置。


所以在这个解决方案中,这个参与者将安装代码,NodeJS 脚本将仅作为调用者。



安装代码的后端功能 —— install_code —— 是 IC 接口规范的一部分,因此,我可以在我的 manager 中添加一个功能,作为代理接收信息并调用  IC的核心功能。


重要提示:以下代码片段是公共函数,如果您在 mainnet 智能合约中实施此类功能,请采取适当的安全预防措施。



要在我的目标容器中安装代码,我需要四个参数:


  • 目标容器 ID。


  • Wasm 模块 —— 我在前一章中构建的 Wasm 代码的新版本以及我的解决方法。


  • 一个 mode 用于 #upgrade 执行容器升级中描述的更新 —— 目标是保持状态。


  • 参数 —— 用于初始化容器的参数。


NodeJS 脚本


我可以在我命名为 installcode.mjs 的 NodeJS 模块脚本中实现对 manager 端点的调用,该脚本将在有效调用我的 actor(函数 upgradeBucket)之前收集上述参数。



第一个参数是作为 Principal 的目标容器 ID,当我在浏览器控制台中打印本地子容器的 id — renrk-eyaaa-aaaaa-aaada-cai — 时,我将本地子容器收集为 string,我需要在 Principal.fromText() 的帮助下对其进行转换。


我需要的第二个参数是 Wasm 模块,为了收集它,我可以读取之前运行 dfx deploy 时生成的文件,并将其转换为 ArrayBuffer —— 与后端参与者代码中定义的 Blob 匹配的预期类型。



第三个参数是与那些用于动态创建容器的参数相匹配的参数,具体来说,本教程的 bucket 的 actors 是用一个 user 参数:



因此,要安装代码,我需要提供必须用 Candid 编码的相同参数(否则参数将被拒绝):



请注意,IDL 支持各种格式 —— 例如,如果 Motoko 参数是一个 Principal,我可以将其编码如下:



要实例化 manager actor,一旦我找到它的容器 ID,我可以像通常使用 agent-js 一样继续:



但是,有一个微妙之处:因为我正在编写一个模块脚本 - .mjs - 我无法将 dfx 自动生成的 idlFactory 脚本作为 .js 文件 import


为了克服这个问题,我只需要复制它来更改它的扩展名,幸运的是,这可以解决问题。



部署在本地模拟 IC 上的 manager 的主体 ID 可以在 .dfx 文件夹中找到。



最终,如果您要在 mainnet 上部署,您将能够在项目根目录下的 canister_ids.json 中找到相同的信息。



请注意,您还必须注释 fetchRootKey 并在 HttpAgent 初始化中更改 host 属性。


终于可以用我收集的参数来实现安装代码的有效调用了。



测试


一切都准备好了,我可以调用我的 NodeJS 脚本 —— node installcode.mjs



安装成功,为了确定代码已部署,然后我调用了容器(已更新)以检查它现在确实返回了新版本 v2 —— 我期待,现在它确实成功了。


结论和样本 repo


您可以在我在 GitHub 上发布的示例 repo 中找到本教程的源代码:


  • github.com/peterpeterparker/manager


我希望它对社区有用,如果您有改进的想法,请告诉我,如需更多冒险,请在 Twitter(@daviddalbusco)上关注我。


到无限和超越,David。


在 internetcomputer.org 上开始构建,并在 forum.dfinity.org 加入开发者社区。



作者:David Dal Busco

翻译:Catherine



-              -


Azle:适用于互联网计算机上 JavaScript 开发人员的 TypeScript CDK

无处可通的链桥 - 为什么链桥会被黑客入侵以及 IC 将如何解决桥接困境?

桥接协议竞相去赢得消费者信任





你关心的 DFINITY 内容
技术进展 | 项目信息 | 全球活动


长按关注 DFINITY 微信公众号

随时答疑解惑


*添加小助手微信 comiocn 进交流社群


您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存