区块链技术

[译]恢复禁用的脚本操作代码

2018-02-12  本文已影响18人  wolf4j

Version 0.1, 2018-01-19 - 草案供讨论

讨论草案

为了讨论这个草案,附加说明包含在标题草案的标题中。这些打算从这个文件的finalalized版本被删除。
可选规则由RULE OPTION表示,其中预期将在工作组内达成共识之后采用所呈现的选项。

引言

本文档描述了重新激活几个脚本操作码的建议要求。 2011年,在OP_LSHIFT和OP_RETURN中发现了两个严重的错误,提示禁用这些和另外13个操作码。 以下的禁用操作码列表按类别细分。

拼接操作

Word OpCode Hex Input Output Description
OP_CAT 126 0x7e x1 x2 out 连接两个字节的字符串
OP_SUBSTR 127 0x7f in begin size out 返回一个字符串的一部分
OP_LEFT 128 0x80 in size out 只保留字符串中指定点左侧的字符
OP_RIGHT 129 0x81 in size out 只保留字符串中指定点的右侧字符

按位逻辑

Word OpCode Hex Input Output Description
OP_INVERT 131 0x83 in out 翻转输入的所有位
OP_AND 132 0x84 x1 x2 out 布尔AND在输入的每一位之间
OP_OR 133 0x85 x1 x2 out 布尔OR在输入的每一位之间
OP_XOR 134 0x86 x1 x2 out 布尔 EXCLUSIVE OR 在输入的每一位之间

算术

Word OpCode Hex Input Output Description
OP_2MUL 141 0x8d in out 输入乘以2
OP_2DIV 142 0x8e in out 输入除以2
OP_MUL 149 0x95 a b out a 乘以 b
OP_DIV 150 0x96 a b out a 除以 b
OP_MOD 151 0x97 a b out 返回 a 除以 b 后的余数
OP_LSHIFT 152 0x98 a b out a 左移 b 位,保留符号
OP_RSHIFT 152 0x99 a b out a 右移 b 位,保留符号
建议操作码重新启用

建议在分阶段过程中重新引入这些操作码(或等效功能)。第一阶段是在五月硬叉中启用一个有限的子集。

拼接操作:OP_CAT, OP_SPLIT
按位逻辑:OP_AND, OP_OR, OP_XOR
算术:OP_DIV, OP_MOD

New:

提出了一个新的操作OP_SPLIT,作为OP_SUBSTROP_LEFTOP_RIGHT的替代。所有三种操作都可以用OP_SPLITOP_SWAPOP_DROP的不同组合来模拟。

在按位操作下进一步讨论这些新操作的目的。

脚本数据类型

应该注意的是,在脚本操作中,堆栈中的数据值被解释为二进制字符串(即字节数组)或数字。 除非特别声明为解释为数字,否则堆栈上的所有数据都被解释为一个字节数组。

数字类型有特定的限制:

  1. 使用的编码是带有明确的符号位(最后一个字节的最高位)的小端。
  2. 它们的长度不能超过4个字节。
  3. 它们必须使用尽可能最短的字节长度进行编码(没有零填充)3.规则3有一个例外:如果有多于一个字节并且第二个最重要字节的最高有效位被设置, 与符号位冲突。 在这种情况下,左边允许单个0x00或0x80字节。
  4. 负零不被允许。

新提出的opcode x OP_BIN2NUM - > out可以用来在需要时将二进制数组转换为规范的数字。

新提出的操作码x OP_NUM2BIN可用于将数字转换为长度为n的零填充二进制数组,同时保留符号位。

Endian符号

为了便于阅读,本文档中使用了十六进制字符串,其中使用了大端符号。即:0x0100表示十进制256而不是十进制1。

风险和哲学方法

一般而言,采取的方法是尽可能地限制边缘案例的极简主义方法。 在可能的情况下,与现有的操作码结合使用的原始操作码可能被组合,以产生比一组更复杂的操作码更优选的更复杂的操作。 导致模糊或未定义行为的输入条件应该快速失败。

应针对以下风险状况检查每个操作代码并明确定义缓解行为:

定义

拼接操作

OP_CAT

Opcode (decimal): 126
Opcode (hex): 0x7e

连接两个操作数。

x1 x2 OP_CAT → out

例如:

Ox11 0x2233 OP_CAT -> 0x112233

这个操作会失败如果:
0 <= len(out)<= MAX_SCRIPT_ELEMENT_SIZE - 操作无法输出违反元素大小约束的元素

请注意,零长度操作数的连接是有效的

成功执行的影响:

输出长度的限制可以防止内存耗尽攻击,导致操作对堆栈大小的影响比现有的OP_DUP操作符小。

单元测试:

  1. a b OP_DIV - > failure 其中! isnum(a)或 !isnum(b) - 两个操作数都必须是有效的数字
  2. 0 OP_DIV - > failure - 除以正零(所有大小),负零(所有大小),OP_0
  3. a b OP_DIV - > out 其中a <0的结果必须是负数或任何形式的零。
  4. 检查不同长度1..4的操作数的有效结果

OP_MOD

Opcode (decimal): 151
Opcode (hex): 0x97

返回除以b后的余数。输出将使用所需的最少字节数来表示。

a b OP_MOD → out

where a and b are interpreted as numbers

这个操作会失败如果:

  1. !isnum(a)|| !isnum(b) - 两个操作数都不是有效的数字
  2. b == 0 - b是负数或等于任何类型的零

成功执行的影响:

单元测试:

  1. a b OP_MOD - > failure其中!isnum(a)!isnum(b) - 两个操作数都必须是有效的数字
  2. a 0 OP_MOD -> failure - 除以正零(所有大小),负零(所有大小),OP_0
    3.a b OP_MOD -> failure其中 a < 0, b < 0 - 两个操作数都必须是正数
  3. 检查不同长度1..4的操作数的有效结果

新操作

草案讨论
为了便于按位逻辑的“操作数必须等长”规则。 需要额外的操作员为脚本作者提供填充操作数的合理方式。 填充字节数组和填充数字之间必须有明确的区别。
结束草案讨论

OP_BIN2NUM

OP_BIN2NUM取代OP_LEFT并使用它的操作码

Opcode (decimal): 128
Opcode (hex): 0x80

另见OP_NUM2BIN

例如:

0x0000000002 OP_BIN2NUM -> 0x02
0x800005 OP_BIN2NUM -> 0x85

这个操作会失败,如果:

  1. 数字值超出可接受的数值范围(当前大小限制为4个字节)

OP_NUM2BIN

OP_NUM2BIN取代OP_RIGHT并使用它的操作码

Opcode (decimal): 129
Opcode (hex): 0x81

将数字值转换为特定大小的二进制数组,考虑符号位。

n m OP_NUM2BIN -> x

where m and n are interpreted as numbers

另见OP_BIN2NUM

例如:

0x02 4 OP_NUM2BIN -> 0x00000002
0x85 4 OP_NUM2BIN -> 0x80000005

这个操作会失败,如果:

  1. n或m不是有效的数字值
  2. m <len(n)。 n是一个有效的数值,因此它已经以最小的表示
  3. m> MAX_SCRIPT_ELEMENT_SIZE - 结果太大

参考实现

TODO

参考

[1] https://en.bitcoin.it/wiki/Script#Opcodes


本文由 Copernicus 团队 冉小龙翻译,转载无需授权。

上一篇下一篇

猜你喜欢

热点阅读