熵成本计算

在编写,测试和调试智能合约的过程中,需要关注到 OpCode 的调用成本。 本文介绍熵消耗的计算细节,并提供相关参考链接。

关于熵成本及价格计算,可以直接在上链前先通过测试网部署,查询transaction后根据消耗细节租赁熵,避免燃烧VS。

OpCode 消耗

不同 OpCode 的熵消耗分为不同级别,成本等级分类及对应熵消耗如下:

public enum Tier {
    ZeroTier(0),
    BaseTier(2),
    VeryLowTier(3),
    LowTier(5),
    MidTier(8),
    HighTier(10),
    ExtTier(20),
    SpecialTier(1),
    InvalidTier(0);
  }

不同 OpCode 对应的消耗可以参考已开源的代码 OpCode.java。

虚拟机存在 memory 和 storage 的概念,对应这两类操作的 OpCode 消耗熵需要额外计算。

  • 对于 memory 类别的 OpCode 而言,操作的 memory 大小会影响具体的消耗,例如 MLOAD, MSTORE OpCode, 此时的消耗与所操作内存的字长相关。
  • 对于 storage 类别的 SSTORE OpCode 而言,消耗熵不止与操作字长有关,还需要区分操作是重置,新增,还是删除。
val当前值操作熵消耗操作类别
为空,即 val == 0x0sstore(val, n) n != 0 即 val = n20000SET/设置
非空, val != 0x0sstore(val, n) n != 0 即 val = n5000RESET/重置
非空, val != 0x0sstore(val, 0) 即 val = 05000CLEAR

其他较高消耗操作

  • 尽量避免通过合约给未激活账户转账 VS 或 VRC10 创建账户,该操作会多消耗25000熵,替代没有0.1VS的账户创建费用。
  • 当使用 CALL, DELEGATECALL 等操作调用其他合约时,且附加转账操作时,会多消耗 9000 熵。
  • 当使用 CREATE, CREATE2 在合约中动态创建合约时,消耗 32000 熵。
  • 当使用预编译合约 (precompiled contracts) 时,不同调用操作消耗不同,请参考 已开源的代码 PrecompiledContracts.java。

部署合约的熵消耗

部署合约时,合约代码每字节消耗 200 熵。

  • 部署合约时所提供的字节码一般分为两部分,一部分叫部署代码(creation code),一部分是合约的运行时代码(runtime code)。

  • 部署代码一般用于执行合约构造函数逻辑,并返回真正的合约运行时代码。计算部署合约时熵消耗,需要使用运行时代码长度。一般是部署代码字节码第二个 6060 或 6080 为起始。