区块链技术与应用【肖臻老师】笔记整理之------09-BTC-脚本

注:没有全部复原,抽取了主体知识,加入了一些自己的理解,强烈建议去学习肖臻老师的课程,这绝对算得上是国内区块链讲解的顶级教程,纯学术和技术

BTC使用的脚本语言是非常简单的,唯一能访问的内存空间就是一个堆栈 ,不像C,C++那样有全局变量和局部变量还有动态分配的内存空间

所以叫基于栈的语言

stack base language

看一下交易的宏观信息,

在这里插入图片描述

  • size:交易的大小

  • locktime:用来表示交易的生效时间,0表示立即生效,10表示10个区块之后才能写进区块里面

  • time:交易产生的时间

  • blocktime:区块产生的时间
    在这里插入图片描述

  • 输出最简单的形式就是给出一个Public Key

  • reqSigs:需要的签名数量

在这里插入图片描述

有一个交叉,后面的交易的输入要放在前面,前面的交易的输出要放在后面

早期的BTC脚本中这两个脚本是拼接在一起的,从头到尾执行一遍

出于安全因素的考虑,现在这两个脚本分开执行,首先执行输入脚本,如果没有出错,再执行输出脚本,

最后栈顶的结果为非0值,也就是true,那么验证通过 ,这个交易就是合法的,如果执行过程中出现任何错误,这个交易就是非法的

如果一个交易有多个输入脚本,那么所有的输入脚本都要与对应的输出脚本匹配之后来进行验证,全都验证通过这个交易才是合法的

输入输出的形式:

1.最简单的形式: P2PK,Pay to Pubic Key

在这里插入图片描述

输出脚本里直接给出收款人的公钥

CHECKSIG是检查签名的操作

输入脚本直接给出签名就可以,私钥对输入脚本所在的整个交易的签名

在这里插入图片描述

注:拼接起来,第一行是输入脚本,后两行是输出脚本,实际执行中是分开执行的,PPT是为了方便,拼接在一起显示

流程:

  1. 把输入脚本提供的签名压入栈中,
  2. 把输出的公钥压入栈,
  3. 把栈顶的两个元素弹出来,用公钥检查一下签名是否正确,如果正确返回TRUE,说明验证通过,否则出错

2.最常用的形式:P2PKH:Pay to Public Key Hash

在这里插入图片描述

与第一种的区别是输出脚本里没有直接给出收款人的公钥

给出的是公钥的哈希

公钥是在输入脚本里给出的

输入脚本既要给出签名也要给出公钥

输出脚本里的DUP,HASH160都是为了验证签名的正确性

在这里插入图片描述

流程:

  1. 把签名压入栈中
  2. 把公钥压入栈中
  3. DUP:含义是把栈顶的元素复制一遍,所以栈顶又多了一个公钥
  4. HASH160是把栈顶元素弹出来取哈希,然后把得到的哈希值再压入栈中,所以栈顶变成了公钥的哈希值
  5. 把输出脚本中提供的哈希值压入栈,这时栈顶有两个哈希值
  6. EQUALVERIFY是弹出栈顶的两个元素,即刚刚的两个哈希值,比较它们是否相等,防止有人冒名顶替(用自己公钥冒充接受者的公钥)
  7. 弹出栈顶的两个元素,用公钥检查签名是否正确

3.最复杂的形式:P2SH: Pay to Script Hash

在这里插入图片描述

输出脚本给出的是一个接收者提供的脚本的哈希,这个脚本叫redeemScriptHash,赎回脚本

输入脚本要给出赎回脚本的具体内容,同时要给出能让这个赎回脚本正确运行的签名

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

第一阶段步骤

  1. 把输入脚本的签名压入栈

  2. 把赎回脚本压入栈

  3. 得到赎回脚本的哈希

  4. 将输出脚本的哈希值压入栈,RSH是指redeemsrcipt hash

  5. 判断两个赎回脚本的哈希值是否相等

    在这里插入图片描述

第二阶段步骤:

  1. 将输入脚本里提供的序列化的赎回脚本进行反序列化,反序列化的操作由每个节点自己完成,并不在PPT中展示,之后执行赎回脚本,将Public Key压入栈
  2. 然后验证输入脚本里给出的签名的正确性

在传输前需要将数据结构转换成方便网络传输的 字节流 形式,这个过程称为 序列化

从字节流“恢复”数据成数据结构的形式,这个过程称为 反序列化

在这里插入图片描述

输出脚本中需要N个,输入脚本只需要提供M个合法签名就可以验证通过,N>=M,N>1/2M

输入脚本有一个BUG,执行的时候会从堆栈中多弹出一个元素,所以第一个为多余的元素

M个签名的顺序要在N个公钥中签名的顺序一致才可以

在这里插入图片描述

  1. FALSE就是多余的元素

  2. 将输入脚本的两个签名压入栈中

  3. 将阈值M=2压入栈

  4. 将三个公钥压入栈

  5. 将N=3压入栈

  6. 执行CHECKMULTISIG,看看是不是符合多重签名

在这里插入图片描述

本质是将复杂度从输出脚本转移到输入脚本

在这里插入图片描述

步骤:

  1. FALSE还是应对那个BUG
  2. 两个签名压入栈
  3. 序列化的数据压入栈
  4. 取Hash
  5. 将输出脚本里面的RSH压入栈中
  6. 最后判断这两个赎回脚本的hash值是否相同

至此,第一阶段的验证就结束了,下面是第二阶段的验证

在这里插入图片描述

  1. 把M压入栈
  2. 将三个公钥压入栈
  3. 将N压入栈
  4. 检查多重签名的正确性

在这里插入图片描述

只有RETURN操作,后面的都不执行,无论输入的什么内容,到输出脚本就RETURN,不再执行任何操作

这个脚本是证明销毁BTC的一种方法

为什么要销毁BTC?

两种应用场景:

  1. 其余的系统会要求销毁一些来进行置换其自己的
  2. 往区块链里面写入一些内容,比如要存一个知识产权的HASH,就可以放到RETURN 后面的[zero or more ops or text]里面,虽然不会执行,但是如果出现纠纷,就可以使用它

发布消息不需要记账权,发布区块需要记账权,任何用户都可以使用这种方法销毁少量的BTC

这种操作对全节点是比较友好的,因为不需要写入UTXO中,手续费全部都用来写入脚本,输出为0

coinbase脚本里面也可以写东西【前面讲的】

OP_CHECKSIG,PPT里都省略了OP

BTC的脚本不支持循环,也就不会陷入死循环

不像以太坊是图灵完备的,但是其密码学的功能很强大,比如CHECKMULTISIG一句话就可以支持多重签名验证,所以比特币的脚本看上去很简单,但是针对比特币的应用场景做了很好的优化

因为不需要写入UTXO中,交易费用全部都用来写入脚本,输出为0

coinbase脚本里面也可以写东西【前面讲的】

OP_CHECKSIG,PPT里都省略了OP

比特币的script不支持循环,也就不会陷入死循环

不像以太坊是图灵完备的,但是其密码学的功能很强大,比如CHECKMULTISIG一句话就可以支持多重签名验证,所以BTC的脚本看上去很简单,但是针对BTC的应用场景做了很好的优化

  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值