虚拟机 抽象

admin
admin 2024年12月08日
  • 在其它设备中阅读本文章

通用高级的抽象的合约虚拟机设计规范

账户抽象

  1. 账户信息由字节码(Code)和存储(Storage)构成
  2. 使用 20 长度字节数组类型的值来唯一标识(ID)账户
  3. 以账户 ID 为键,以 Code 和 Storage 为值,构建 Verkle 树来保存所有账户的状态
  4. 任何账户都可以接收输入(Input),在虚拟机里执行代码并保存新的执行结果(比如转账)
  5. 如果账户的字节码为空,将使用具有默认接口功能的代码替代(这个代码可以采用硬编码的方式提供)
  6. 因为所有账户都可以有字节码和存储,所以账户都可以视为合约
  7. 预先部署一个代币合约,作为原生数字货币,用于矿工奖励发放和用户费用支付
  8. 预先部署一个共识合约,接收区块输入,并验证、执行和存储它

合约虚拟机

在虚拟机中,所有账户统称为合约,合约执行代码需要消耗燃料(Gas),按照代码的复杂度来收取

硬编码合约

将区块链的一些核心功能转化为硬编码的合约实现,有以下优势

  1. 相比字节码的方式合约调用能带来一致性的体验
  2. 有效减少字节码的数量
  3. 可以采用硬编码的方式实现,性能不会有太大影响

从账户 0x1 开始分配

特殊字节码

  1. 购买 Gas:共识合约会提供一个支付代币购买的接口,经过接口验证后内部调用此字节码为其增加 Gas,仅共识合约可以调用
  2. 重置合约:清空合约存储数据并使用新的字节码初始化(可以指定为空),类似以太坊合约部署,仅限重置账户自己
  3. 创建合约:使用指定的字节码去初始化一个随机的合约,类似以太坊 CREATE2 字节码

合约可以自定义代码来关闭重置功能,类似以太坊账户的合约销毁机制:不存在调用销毁字节码逻辑的合约是无法被销毁的

交易执行

  1. 用户指定一个目标合约和输入(符合一定规则的,一般会包含签名以及合约调用),发送到虚拟机中
  2. 加载合约对应的代码开始执行,初始时虚拟机会暂借一定量的 Gas(MinGas),这些 Gas 主要用调用购买 Gas 接口
  3. 交易可以在耗尽 MinGas 之前调用共识合约提供的 Gas 购买接口添加更多 Gas,否则交易会失败
  4. 失败的交易会回滚状态,但不返还消耗来购买 Gas 的代币;不管成功或失败,多余的 Gas 会进行返还处理
  5. 如果一笔交易没有购买过 Gas,则不应该打包进区块中(取决于矿工逻辑)
  6. 在交易结束(不管成功或失败)前都没有购买 Gas 的交易可以视为垃圾交易,理应直接丢弃

垃圾交易
为了避免无效交易的 DOS 攻击,需要在交易执行消耗少量 Gas 的时候就进行判断,如果还没有账户为这笔交易买单,则应该终止执行并将其视为垃圾交易。因为矿工激励规则,没有账户付 Gas 的交易矿工收益为零,所以矿工有权拒绝打包这类交易。

灵活收费
将 Gas 收费逻辑转移到虚拟机中实现,只要交易目标合约调用了共识合约的购买 Gas 接口即可,目标合约可以在购买 Gas 之前执行一些自定义代码(比如签名验证或其它一些检查),共识合约可以自定义购买 Gas 费的逻辑(比如某些账户免费或阶梯购买)

交易安全
合约有默认的接口,使用对应的私钥进行控制,用户可以更新代码实现自定义的规则,实现多签、托管、恢复等等功能,达到灵活控制账户的目的,后期还能采用升级默认的合约接口来提高安全性。

重放攻击由账户自行防御,可采用类似 nonce 的机制或其它方法

默认合约接口

链合约

  1. 存储区块(调用共识合约验证)
  2. 查询区块
  3. 参数配置查询

共识合约

  1. 验证一个新的区块
  2. 执行其中的交易
  3. 执行激励规则
  4. 验证一笔交易

系统合约

  1. 重置账户
  2. 创建账户
  3. 删除账户