在刚刚结束的 2021 Sub0 在线会议中,Patract Labs 教育负责人 CryptoJedi 围绕「Patract Labs 上的 Wasm 智能合约」这个主题,通过演示开发者如何使用 Patract Labs 的开发工具 Redspot(合约开发脚手架)、Metis(Wasm 合约标准库)和 Europa(本地测试开发节点),推动智能合约的开发。包括工具安装以及在 Ink! 和 Ask! 中编写简单的合约,由 Metis 提供自动部署和测试。最后,他向大家展示了如何使用 Jupiter 测试网部署合约并与之交互。

Patract Labs 的成立旨在为基于 Substrate 的智能合约开发提供全栈支持。我们知道 Substrate 是一个快速增长的生态系统,适用于各种不同的区块链,它们都具有不同的目的。我们看到各种基于 Substrate 的项目不断涌现并蓬勃发展。

然而,通过观察我们发现以太坊、Solana 和 EOS 等其他区块链中呈指数增长的项目,在底层生态系统中发挥重要作用。尽管许多项目只是简单的智能合约,但它们为其生态系统带来了巨大的价值。例如,以太坊上的 Uniswap、Solana 上的 Serum 等 Defi 项目。他们现在在区块链行业中发挥着至关重要的作用,并为他们所建立的区块链创造了流动性和实际用例。而所有这些成功的项目都得到了开发者工具和服务的支持,例如 Traffle、etherscan 和 Ganache。因此,我们相信通过提供成熟且安全的开发者工具和服务,将进一步惠及整个 Substrate 社区,让更多的开发者参与进来。

因此,Patract Labs 致力于为 Substrate 生态系统提供各种工具和服务,以满足 Substrate 中智能合约开发者的需求。我们非常高兴能够通过提供以下产品参与到「Sub0 Online 2021」 研讨会中。

Jupiter


我今天要介绍的第一个产品叫做 Jupiter,Jupiter 旨在成为一个开放的区块链网络,它为所有的智能合约提供广泛的支持,只要它们是在Frame pallet-contract上运行。Jupiter 一直活跃在 Substrate 网络中,任何人都可以免费使用它来测试他们的智能合约。

Ask!


第二个产品叫 Ask! 。Ask! 是一种嵌入式特定领域语言(eDSL),它允许开发者在汇编脚本中编写 Wasm智能合约。我们将在后面介绍相关细节。

Redspot


Redspot 是合约开发者的脚手架。它的目标是将开发者从繁琐而繁琐的工作中解放出来,例如合约编译、部署、测试。我们希望合约开发者可以在一个地方完成他们需要的所有任务。

Metis


Metis,类似于以太坊生态系统中的 OpenZepplin,是标准合约库。它为 ink! 中的常用组件提供了安全且经过审核的实施方案。有了 Metis,开发者不必一遍又一遍地重复编写或复制/粘贴相同的代码。

Europa


Europa 是专为合约开发而设计的合约沙盒环境。它从 Subtrate 中删除了一些不必要的组件,并在合约执行过程中显示了更多细节。

Parascan


Parascan 是专门为检查智能合约日志和基于 Subtrate 链的执行情况而设计的区块链浏览器。从理论上讲,Parascan 可以连接和缓存任何底层区块链并提供及时的浏览器服务。

Himalia


目前,大多数 Substrate 的 SDK 都是用 JS(JavaScript)编写的。然而,许多需要与 Substrate 通信的项目和服务都是用 Go、Java 和 Python 等其他编程语言编写的。Himalia 是提供多语言支持的 SDK。
让我们深入了解我们今天将演示的产品。

Ask! ——将 AssemblyScript 引入 Substrate

我们中的许多人都玩过 Ink!。然而,WASM 的一大优势是 WASM 支持编译成它的编程语言。墨水!很好,但它需要开发人员熟悉 Rust 作为先决条件。因此,我们创建了 Ask! 这是一种类似于ink! 的eDSL。有了 ask!,任何有 typescript 或 AssemblyScript 经验的人都可以轻松开发 WASM 智能合约。总的来说,我们正在努力将 Solidity 风格的开发引入 Substrate。

eDSL

  • 整体布局类似 ink!
  • AssemblyScript中的语法

Decorator

  • 类似于ink!中的宏,Ask!提供装饰器。这给出了非常相似的代码布局。
  • 高水平的抽象,开发者可以专注于合约逻辑,而不必学习如何与主机函数和 pallet-contract 进行交互。所有复杂的东西都由 Ask!在引擎盖下完成。

Storage

更多存储类型:

  • SpreadStorableMap
  • SpreadStorableArray
  • PackedStorableMap
  • PackedStorableArray 当需要存储大量数据时,应该使用 Spread。当你存储少量数据,并需要访问大部分内容时,比如搜索或统计逻辑,选择Packed可能会更好。

接口和继承


由于 Rust 不支持继承,Solidity 中使用的类似计算机编程模型将不起作用。有了Ask!:

  • Solidity 开发人员可以很快习惯使用Ask!
  • 支持类似于 Openzeppelin 的标准合约库。

正在开发中

  • 目前我们的版本是 v0.2,很快就会发布 v0.3。

Redspot

Redspot 是一个开发环境,用于编译、部署和调试基于 Substrate 链的 Wasm 智能合约。Redspot 帮助开发者在编写智能合约和 DApp 的过程中管理和自动化重复的步骤。与 Hardhat 的架构类似,Redspot 建立在任务和插件之上。

模板

  • 基于合约标准,自动生成合约样本、部署脚本、测试脚本和 Redspot 配置。例如。npx redspot-new erc20将创建一个带有 ERC20 代码、部署和测试的目录。你不不要手动编写部署和配置。我们正在将更多的模板集成到 Redspot 中。所以在未来,你可以用一个命令启动任何合约站。
  • npx 支持,无需额外设置。

编译

  • 包装 cargo-contract。
  • npx redspot compile
  • npx redspot 编译器将编译代码并放入对应的目录进行部署。

部署

  • 上传合约并使用脚本将其实例化。
  • npx redspot run scripts/deploy.ts --no-compile

测试

  • 使用脚本测试合约方法。
  • npx redspot test --no-compile

控制台

  • 用于集成测试的强大 JavaScript 交互式控制台。
  • 控制区块链操作。
  • 在编写详细的测试代码之前,你可以在控制台中进行发挥,了解 Redspot 的工作原理。了解如何测试你的合约等。
  • npx redspot explorer

Docker

  • 很多时候,一个合约将部署在多个区块链上,Redspot 与 Docker 集成,允许一个合约在多个平台上进行测试。
  • 启动 Docker: npx redspot testnet
  • 在 Docker 上编译:npx redspot compile --docker true

插入

  • 不足以满足你的开发需求。
  • 用自定义插件扩展 Redspot,增加更多功能,与其他开发工具集成。
  • 通过简单地编写你的自定义插件扩展类型,来保持与自定义Substrate链的兼容

浏览器 GUI

  • @polkadot/apps ,但重点是合约。
  • 与 Redspot 配置完全集成,一旦你设置了测试区块链,就不需要更多的操作。

Metis —  标准合约库的 Rust 解决方案

目前在 ink! 开发时的问题

  • 缺乏标准库使得智能合约不安全。由于智能合约中的错误,2016 年的 DAO 攻击窃取了 360 万个 ETH。这次攻击对以太坊主网非标准化合约强制硬分叉,造成了巨大的经济损失,并进一步影响区块链的共识。想象一下,在 2021 年,人们真的会质疑你的区块链的安全性,即使那是由合约开发者造成的。

开发者必须手动复制/粘贴现有的实现

  • 源代码可能是未经审计的,且使用起来不安全。
  • 想象一下从另一个智能合约项目复制代码。他们的合约可能有尚未被注意到的错误。肆无忌惮地复制他们的代码可能会在未来造成巨大的问题。
  • 在此过程中费时费力,且容易出错。
  • 复制粘贴时可能会漏掉一些逻辑。
  • 或者你误解了他们的逻辑,因为他们可能没有正确地命名他们的函数。
  • 你浪费了大量时间来更新他们的合约,每次发布都重复复制和粘贴

介绍 Metis

  • 为了彻底解决上述问题,我们创建了 Metis。
  • 基于可重复使用的组件的标准合约库。
  • 与 Openzeppelin 的继承模型不同,Metis 是基于组件的,这意味着用户不会直接继承标准实现。相反,Metis 提供了一组可重用的组件供用户组装。

Metis vs OpenZepplin

  • 继承——由 Openzeppelin 使用
  • 优点:简单—— 最小化为开发人员编写的代码。
  • 缺点:模糊性——隐藏方法的定义;不确定的继承树与多个继承关系。
  • 例如,在 OpenZepplin 中,当你有多个继承时,你可能很难确定该方法是从哪个父合约中继承的。
  • 组合——由 Metis 使用
  • 优点:明确性——提高代码可读性和可听性,用户可以交互的所有功能都被编码到位,这使得代码审计更容易。
  • 缺点:重复性——为现有实现重复编写相同的代码。

MCCI 架构

  • 数据模型——存储。
  • 组件——实现。
  • 控制器——结合不同的组件,ERC20Pausbale -> ERC20, pausable, ownable。
  • 接口——不可变和可变功能,用户交互。

Metis—vs Native ink!(Storage)

  • 用户不再需要自己声明变量了。
  • 标准化数据结构。
  • 让 Dapp 的开发者更容易熟悉接口。

Metis—vs Native ink!(Constructor)

  • 跳过变量初始化的过程。
  • 无需手动触发事件。
  • 开发者可能会忘记触发事件,这将导致区块链浏览器无法捕捉更改,并让用户很难验证他们的交易。

Metis—vs 原生 ink!(Event)

  • 由于 ink! 的当前设计,Event 的写法几乎保持不变。在不久的将来会有所缓解。
  • 我们将使用宏来自动生成基于 Metis 组件的事件。例如,如果你有一个名为 ERC20Pausable 的合约,我们将生成包括在存储声明中的所有事件。

ink!Metis—vs 原生 ink!(Message)

  • Metis实现包含默认方法实现,确保余额转移的安全性。
  • 例如,检查余额。
  • 注意实现中可能存在的所有注意事项。
  • 允许开发者更多地关注他们的核心逻辑。

设计原则

  • 在软件设计中重写函数显得很愚蠢。
  • 在右侧写代码。
  • 更加自然。
  • 跳过编写所有冗余的代码。
  • 实例化是指在区块链上创建一个智能合约的实例。
  • 调用另一个实例的方法意味着调用另一个合约方法。
  • 跨合约调用以最终会产生错误的结果。

多个组件的组成

  • 无需在存储中列出所有需要的变量。
  • 按需组合,创造更多可能性。


Europa

开箱即用的本地测试网

  • Europa 是 Subtrate 区块链的另一个实现,特别关注于智能合约的开发。
  • 为了更好的开发体验,我们去掉了共识。原因是当我们使用 Canvas 开发合约时,我们发现自动生成的区块真的很困扰我们。因此,Europa 只有在收到新的用户签名交易时才会生成区块。
  • 没有 Wasm Runtime 。虽然 Wasm Runtime 很好,因为它不允许硬分叉区块链升级,但它给调试合约执行带来了更多困难。
  • 状态 KV 数据库。当新的区块被挖掘时,这个额外的数据库会跟踪所有的状态变化。当我们在调试智能合约时非常有用,因为我们可以确定合约真正改变了区块链的底层状态。
  • 修改 contract-pallet。现在,运行 Wasm 智能合约对于合约开发者来说就像一个黑匣子,因为它不会打印出所有的执行细节。因此,我们修改contract-pallet ,允许节点打印出所有执行细节。

Europa UI


我们认为运行测试节点应该尽可能的简单,并且不应该涉及任何设置。这将使 Wasm 智能合约开发对所有行业的开发者更具吸引力。

Europa UI 的图形界面是专为合约开发而设计的,以方便浏览/调试智能合约。与其他 Substrate 链不同,你必须在本地编译它。你可以下载二进制版本,一键启动你自己的节点。因此,你不用手动安装所有的依赖项。这将为合约开发者节省大量时间在本地运行节点。

Europa UI 是用 Electron 构建的,可以通过所有主流平台使用,包括 Windows、Mac 和 Ubuntu。但它对操作系统版本有一些限制,所以在下载之前检查你的操作系统版本。

Europa UI - 演示


合约:

  • 检查所有状态变化。
  • 进行 RPC 调用。
  • 使用跟踪进行 RPC 调用,以获取更多关于合约执行的见解。
  • 嵌套合约调用可能非常混乱。
  • 清楚地说明了跨合约调用的工作原理。

Europa  CLI

  • 自定义 RPC
  • europa_forwardToHeight:将区块链转发到一个指定的高度。
  • europa_backwardToHeight:将区块链还原到一个指定高度,并删除该高度之后的所有区块链状态。
  • europa_modifiedStateKvs:获取所有区块链状态变化。
  • 自定义命令
  • 状态 - kv:与 RPC 相同:europa_modifiedStateKvs -> 获取所有区块链状态变化。
  • 工作区 - 允许开发者针对不同的测试场景切换到不同的工作区。
  • 合约执行的详细日志记录:
  • 它将在合约执行期间跟踪和打印所有参数和区块链变化。
  • 提供 Wasm panic 回溯以准确定位智能合约中发生错误的位置。

演示


1.使用 Redspot 模板启动你的 Redspot 项目

npx redspot-new erc20
记得修改cargo.toml中的依赖关系,从crate.io拉取,否则会与polkadot.js产生兼容问题。ink!更新速度很快,如果我们直接从 ink! git 拉取,会产生兼容问题。我们也看到 Polkadot/app 的问题,但通常它很快就会被修复。
ink_primitives = { version = "3.0.0-rc5", default-features = false }
  • redspot.config.ts: 包含 Redspot 的所有配置,例如网络配置。
  • scripts/deploy.ts: 是将合约部署到区块链的部署脚本。
  • tests: 包含所有为集成测试编写的测试。

2.下载 Europa-UI


详细的发布信息可以在这里找到 Release v0.3.32(https://github.com/patractlabs/europa-ui/releases/tag/v0.3.32)。目前支持 3 种操作系统:

  • Windows 10 (21H1 及以上) europa-ui-v0.3.32-x86_64-win.exe(https://github.com/patractlabs/europa-ui/releases/download/v0.3.32/europa-ui-v0.3.32-x86_64-win.exe)。
  • MacOS(10.15.7 及以上)europa-ui-v0.3.32-x86_64-darwin.dmg(https://github.com/patractlabs/europa-ui/releases/download/v0.3.32/europa-ui-v0.3.32-x86_64-darwin.dmg)。
  • Ubuntu(20.04 及以上)europa-ui-v0.3.32-x86_64-linux.AppImage(https://github.com/patractlabs/europa-ui/releases/download/v0.3.32/europa-ui-v0.3.32-x86_64-linux.AppImage)。
对于 Ubuntu,记得给它权限

chmod +x europa-ui-v0.3.32-x86_64-linux.AppImage

3.启动 Europa-UI

  • 只需双击该图标即可启动它。确保默认端口没有被占用。
  • 单击开始以启动节点。

4.使用模板化合约和配置测试 Redspot + Europa

px redspot run scripts/deploy.ts


它将编译合约并更新合约 + 元数据到 Europa-UI。如果元数据没有被正确上传,你可以手动添加。

  • 打开 Europa-UI,你应该可以看到合约已经部署成功。
  • 你可以使用back to Block 来恢复区块链并删除已部署的测试合约。

5.将 Cargo.toml 中(https://github.com/bonanyuan/sub0_erc20_pausable/blob/main/contracts/Cargo.toml)的依赖项和 lib.rs 中(https://github.com/bonanyuan/sub0_erc20_pausable/blob/main/contracts/Cargo.toml)的合约代码复制到 erc20/contracts/Cargo.toml 和 erc20/contracts/lib.rs 。

cp -R contracts ink_contracts

  • 让我们细致的研究下引入metis后合约代码实现的区别:
  • Cargo.toml:导入我们将使用的 Metis 组件。注意 metis_lang 是使用 Metis 的项目的必备条件。另外,注意我们使用的是分支,因为 ink! 的更新非常频繁,为了与 ink! 保持兼容,我们有相应的 Metis 版本。

lib.rs:

  • 我们从 Metis 导入所有依赖项,而不仅仅是use ink_lang as ink;
  • Storage:我们不再声明我们自己的变量,而是复合了多个 Metis 组件。
  • Event:不幸的是,我们仍然需要为事件编写所有代码。在 Metis 的下一个版本中,我们将使 Metis 生成这些事件,只要我们在存储中声明了它们。

Message:我们不再需要自己去实现函数,我们可以使用 Metis 的默认植入方式。

  • Constructor:这些函数没有暴露给区块链上的用户,Metis 的宏会自动生成其中的大部分。所以我们不再需要自己编写它们。
  • Metis 的组成特点:
  • 正如我们在PPT中提到的,Metis 允许用户根据需要轻松地将不同的组件组合起来。

扩展:

  • hook:你可能会问为什么我们没有在我们的方法实现中添加特定的逻辑来暂停传输。那是因为我们在 Metis 中使用 hook,并且对于每个组件,我们都有一个实现 hook 的扩展列表。
  • ERC20 扩展:https://github.com/patractlabs/metis/blob/main/crates/components/token/erc20/src/extensions/pausable.rs。该扩展覆盖了before_token_transferhook ,并在其中添加了逻辑。所以我们不再需要在拥有的每个传递函数中实现可暂停的逻辑。

6.通过以下方式建立你的合约

cd contracts

然后把它复制到 ERC20 目录下的 artifacts 目录。

这将在调试模式下构建合约并保留所有调试符号。
mkdir ../artifacts

7.编写部署脚本。

  • 从deploy.ts复制代码。
  • npx redspot run scripts/deploy.ts --no-compile
  • 打开 Europa-UI, 查看合约是否部署成功。
    8.编写测试:
  • 从test(https://github.com/bonanyuan/sub0_erc20_pausable/blob/main/tests)中复制所有代码文件。
  • npx redspot test ./tests/erc20_pausable_init.test.ts --no-compile
  • 测试合约实例化。
  • npx redspot test ./tests/erc20_pausable_ownable.test.ts --no-compile
  • 所有者被初始化为发件人的地址。
  • 非所有者将能够放弃所有权。
  • 所有者应该能够放弃所有权。
  • 非所有者不能够转让所有权。
  • 所有者可以转让其所有权。
  • npx redspot test ./tests/erc20_pausable_init.test.ts --no-compile
  • 默认暂停状态为 false。
  • 非所有者应该能够暂停。
  • 所有者应该能够暂停。
  • 所有者可以取消暂停。
  • 没有暂停的传输应该是成功的。
  • 有暂停的传输应该是失败的。

About Patract

Patract为波卡Wasm合约生态的平行链和DApp开发提供解决方案。我们帮助社区平行链设计和开发链上合约模块和Runtime支持,并且为DApp开发者提供覆盖开发、测试、调试、部署、监控、数据提供和前端开发等阶段的全栈工具和服务支持。

How to join Patract

1.对于合约开发者,可以访问官网 ,熟悉测试链和工具套件。欢迎加入官方开发群:Element|Discord,或搜索 “Patract 开放平台” 关注 Patract 微信公众号。

2.对于将要集成 Wasm 合约功能的平行链项目方,或者使用 Wasm 合约开发的 DApp 项目方,商务合作欢迎联系 [email protected]

3.对于用户,欢迎加入:TelegramTwitter

4.对于求职者,我们在招聘区块链开发工程师、前端/全栈开发工程师、云平台架构师、数据产品经理、产品经理等岗位,可以联系 [email protected]