当前位置: 首页 > news >正文

ERC20 和 XCM Precompile|详解背后技术逻辑

1@2x.jpg

1.png

Precompile 的扩展

深度详解 Revive 和 Precompile 技术路径给大家介绍了 precompile 的实现原理和调用之后。本文我们接下来介绍 ERC20 和 XCM precompile 是如何来实现的,通过对它们的理解,你也可以把任何 Pallet 里面的方法,包装成智能合约,暴露给外部就可以调用。

为了方便理解,我们还是沿用几个关键的英文词汇,它们定义如下:

Precompile: 预编译智能合约

Builtin: 内置的预编译智能合约

External: 外部预编译智能合约

Multiple:一组预编译智能合约

我们要介绍的 ERC20 和 XCM 都属于是 external。

2.png

Assets Pallet 和 REC20

Assets pallet 是在 Polkadot SDK 里面用来表示一个 fungible 的资产,它实现的方法和对资产的管理是和ERC20标准一致的。使用一个 precompile 来实现 ERC20 标准的接口也比较简单,需要注意的主要是地址转换,U256 数据类型的转换和溢出处理。weights 的计算和扣除等等。

ERC20 最特别的是,它是一个最典型的 multiple 合约的例子。它使用到了我们在上一篇文章中提到的特殊地址方式,将地址的高 32 位映射到了 Asset ID。对于不熟悉 Assets pallet,这里解释一下,Asset ID 是用来表示不同的资产,类似不同的 ERC20 的地址。

在以太坊中,ERC20 的地址是分散的。但是在Polkadot SDK通过 ERC20 precompile 暴露出来的地址是有自己的区间的。由于Asset ID 只使用了前面的四个字节,那么第 5 字节到 16 个字节都应该是 0. 17 18 字节是 ERC20 在 runtime 定义的自己的  index。19 20 字节也是 0。

那么从地址很容易就能识别 external 以及 ERC20。

我们来看下具体的代码实现。

图片

代码分析

合约地址到 Asset ID 的转换。通过定义一个 InlineAssetIdExtractor 定义一个的数据结构,来进行转换。它地址的前面四个字节,将它转换成一个 u32 类型的数据

截屏2025-07-08 23.31.21.png

对于 ERC20,它和其他所有 precompile 一样,需要实现一个 Precompile 的 trait。里面只有一个 call 方法,在 call 方法里面,它要获取 Asset ID,然后就通过 selector 来分发到不同的具体实现中去。

截屏2025-07-08 23.32.45.png

这里我们只选取一个 Transfer 方法,来看一下它的代码。首先,它通过环境变量 env 来得到调用者的地址,然后从参数中得到目的地址,和转账数量,最终调用的是 Asset Pallet 里面的 do_transfer 方法。

截屏2025-07-08 23.34.06.png

XCM pallet 和 XCM precompile

XCM 是 Polkadot 里面用来在不同的链之间传递消息的格式规范。消息可以是在 parachain 之间,或者和 relaychain。具体的实现和规范比较复杂,这里不做太多介绍。有兴趣可以参考文档

XCM 的整体实现,包含了几个不同的 Pallet,其中最主要的接口,执行 XCM 消息和发送 XCM 消息都是定义在 XCM Pallet 里面的。首先来看 Solidity 的接口,它和 Pallet 的实现一致,包含了执行一个 XCM 消息,发送 XCM 消息二个基本方法。最后一个比较特殊,它是用来返回一个 XCM 需要的 weight。它类似于在 EVM 中 gas estimation。

截屏2025-07-08 23.35.58.png

对于 precompile 的具体实现也比较简单,就是解码和调用Pallet里面的方法。这里只粘贴出 weightMessage 的实现,我们一会要和它交互。它的作用就是解析一个只含有 weight 信息的 XCM 消息的编码,返回 proofSize 和 refTime。这二个分别是 polkadot 里面对一个交易对应存贮和时间上的消耗。

截屏2025-07-08 23.37.36.png

截屏2025-07-08 23.37.45.png

4.png

Runtime 的定义

在 Runtime 中,我们可以把 ERC20 和 XCM precompile 加进去。代码如下

截屏2025-07-08 23.39.14.png

代码中 0x120 和 0x320 就是二个 ERC20 multiple 的 suffix。这里有二个是因为 Assets Pallet 本身是一个可以多实例化的 Pallet,因此 ERC20 的地址也可以是二个不同的。调用的时候一定要找到对应关系。另外这个值也不是固定的,比如在 substrate node 中,就把这二个值定义为 1 和 2. 在调用具体的链的时候,需要查询代码才能知道。这个也不太合理,应该使用 Pallet 的常量来定义它比较好。

而 XCM 没有地址 index 定义,直接写死在 Pallet 代码中,值是 10.

5.png

如何调用 ERC20 和 XCM

ERC20 的调用

我们在 Passet Hub contract 链来调用 ERC20。首先我们要确定它的地址,从 Runtime 中我们知道它的地址后面的 8 个字节。然后我们需要新建一个 Asset,这个可以通过 polkadot app 的接口,来创建一个 ID 为 7 的资产。

截屏2025-07-08 23.42.43.png

有了这个资产之后,我们就可以通过合约来调用。我们打开 polkaVM 的 remix,在浏览器中输入 https://remix.polkadot.io,把下面这个合约部署到  Passet Hub。

截屏2025-07-08 23.43.42.png

截屏2025-07-08 23.43.47.png

我们来调用 getBalance 取得这个 Asset 的总的数量。第一次调用,我们发现它的值为 0.因为我们创建之后,还没有 Mint 过任何资产。我们回到 Apps,调用 mint

截屏2025-07-08 23.45.04.png

然后再次调用 getBalance 方法,就能得到我们刚才 mint 的数量

截屏2025-07-08 23.45.56.png

这样我们就完成了和 Assets Pallet 通过 ERC20 precompile 来交互,更多的方法大家可以自己尝试。有了它,我们可以不部署自己的 ERC20 合约。当然中使用它的时候,需要有直接和 pallet 交互的部分,也会提高应用程序的复杂度。

XCM 的调用

XCM precompile 的地址是在 pallet 实现就定义好了的,编号为 10. 地址是 “0x00000000000000000000000000000000000a0000”

首先,我们写一个简单的合约来调用它。

截屏2025-07-08 23.47.28.png

截屏2025-07-08 23.47.34.png

把这个合约加到一个源文件中,并编译和部署。得到地址后,调用 callWeightMessage 函数,输入 “0x050c0004000000281300000028000d010204000101000101010101010101010101010101010101010101010101010101010101010101”。测试数据可以从这个文件得到, 通过打印单元测试里面的输出。 运行结果截图如下

截屏2025-07-08 23.48.51.png

6.png

总结

在这个文章中,我们介绍了 ERC20 和 XCM 二个 precompile 的实现细节,以及如何和他们通过合约来交互。precompile 是一个十分强大的功能,它可以高效的实现一些底层的方法,还可以把所有 runtime 里面的功能通过 EVM 接口暴露出来。最新的 Revive 实现也让我们看到了 Pallet 想要把它的方法封装到 precompile 是多么的简单,它将成为 PolkaVM 最强大的功能之一。

http://www.dtcms.com/a/302534.html

相关文章:

  • 学习Python中Selenium模块的基本用法(2:下载浏览器驱动)
  • js的学习2
  • JavaScript:数组常用操作方法的总结表格
  • Webhook技术深度解析:从原理到实现全指南
  • Item17:以独立语句将newed对象置入智能指针
  • MDM五十万台设备高并发场景解决方案【后台管理】
  • Taro 位置相关 API 介绍
  • C# 状态机以及状态机编程模式
  • Java设计模式-通俗举例
  • 【智慧物联网平台】编译jar环境 Linux 系统Maven 安装——仙盟创梦IDE
  • Leaflet 综合案例-聚类图层控制
  • django ManyToManyField 如何添加数据
  • Django缓存机制详解:从配置到实战应用
  • MGRE 实验
  • Django 视图详解(View):处理请求与返回响应的核心
  • Linux IPC实战:管道与命名管道的进程对话术
  • 语音识别数据增强
  • llama系列
  • 1688寻源通接口接入要点||电商API接口
  • 电脑ip地址在哪里看
  • 如何提升 TCP 传输数据的性能?详解
  • 信息收集工具ARL资产侦察灯塔系统搭建教程
  • 最新的前端技术和趋势(2025)
  • STM32启动流程
  • 防水医用无人机市场报告:现状、趋势与洞察
  • 无人机喷洒系统技术要点与难点解析
  • Go性能优化深度指南:从原理到实战
  • 机器学习与深度学习评价指标
  • 实战经验总结:如何快速理解一套完整的移动端设计规范
  • 代理 ARP 的三种应用场景:端口隔离、VLAN聚合、单臂路由