操作码 OP_BIN2NUM 和 OP_NUM2BIN

BSV 脚本提供了两个操作码,能让你“显式”的对栈上的字节序列和整数做“类型”转换。

请在继续阅读前,先弄清楚 BSV 脚本里整数的编码规则

OP_BIN2NUM

操作码 OP_BIN2NUM 会将字节序列 a 按小端原码解释成整数 x(其实还是字节序列)。

a  OP_BIN2NUM  ->  x

其中,

  • a 不要求最短编码(minimal encoding)。这点很好理解,如果必须是最短编码,那么 a 可以直接被解释成整数,不再需要额外的操作码
  • x 是最短编码的,且长度不能超过 maxscriptnumlengthpolicy 的限制

执行脚本 { 0x03 0x02 0x00 0x00 OP_BIN2NUM },字节序列 0x000002 会被转成整数 2,所以栈顶结果为 0x02。

执行脚本 { 0x04 0x01 0x00 0x00 0x80 OP_BIN2NUM },字节序列 0x80000001 会被转成整数 -1,所以栈顶结果为 0x81。

执行脚本 { 0x01 0x00 OP_BIN2NUM },字节序列 0x00 会被转成整数 0,所以栈顶结果为空的字节序列。

执行脚本 { 0x01 0x80 OP_BIN2NUM },字节序列 0x80(-0)也会被转成整数 0,所以栈顶结果为空的字节序列。

OP_NUM2BIN

操作码 OP_NUM2BIN 会根据字节序列 a 对应的整数值,生成长度为 b 字节的字节序列 x。

a  b  OP_NUM2BIN  ->  x

其中,

  • a 不要求最短编码
  • b 必须是最短编码,且长度不能超过 maxscriptnumlengthpolicy 的限制
  • b 的值,不能小于 a 对应整数的最短编码的长度

请注意,虽然这个操作码的名字叫 NUM2BIN,但并没有要求 a 最短编码,所以它更像是一种 BIN2BIN,在保证 a 和 x 对应的整数值不变的前提下,让用户能自由的缩放字节序列的长度。

执行脚本 { OP_0 OP_1 OP_NUM2BIN },整数 0(OP_0)会被转成 1(OP_1)个字节的序列,所以栈顶结果为 0x00。

执行脚本 { OP_0 OP_2 OP_NUM2BIN },整数 0(OP_0)会被转成 2(OP_2)个字节的序列,所以栈顶结果为 0x0000。

执行脚本 { 0x02 0x80 0x00 OP_1 OP_NUM2BIN },会出错,因为整数 128(0x0080)无法用 1(OP_1)个字节来编码。

执行脚本 { 0x02 0x80 0x00 OP_2 OP_NUM2BIN },整数 128(0x0080)会被转成 2(OP_2)个字节的序列,所以栈顶结果为 0x0080。

执行脚本 { 0x02 0x80 0x00 OP_3 OP_NUM2BIN },整数 128(0x0080)会被转成 3(OP_3)个字节的序列,所以栈顶结果为 0x000080。

执行脚本 { 0x03 0x80 0x00 0x00 OP_2 OP_NUM2BIN },整数 128(0x000080)会被转成 2(OP_2)个字节的序列,所以栈顶结果为 0x0080。

参考