6-bct脚本

简介

交易实例

截屏2024-11-25 21.10.16

左边看见的output 是输入,也就是别人的输出,右边的是输出,可见有一个 spent 一个 unspent还没有花,已经被23个确认,回滚可能性很小了,下方可见输入输出脚本,输入脚本是把 两个很长的数,压入栈中,而输出脚本 的两行对应的是 上面的两个输出,每一个输出有一个单独的自己的脚本。

btc脚本语言其实只有一个栈操作。

交易结构

截屏2024-11-25 21.19.26

transaction id,hash,btc版本,locktime 锁多少个区块后再写入区块,输入,输出 ,交易所在的区块对应的区块hash值,这个交易已经有多少个确认信息,交易产生的时间,区块产生的时间1970XX年XX到现在过了多少秒。

交易的输入

截屏2024-11-25 21.26.40

交易输入就是要说明白来源。

txid 之前这个交易的hash 值,vout 是这个交易中的第几个输出。

输入脚本 scriptsig,输入脚本的最简单形式就是给出一个 signed签名,证明你有权用这个钱。如果一个交易有多个输入,每一个输入都需要说明币的来源,并都 给出签名。

交易的输出

截屏2024-11-25 21.34.52

value 多少钱,n 是这个交易的第几个输出,scriptpubkey 输出脚本,因为输出脚本最简单的形式就是输出一个 pubkey,reqsigs 这个输出需要多少个签名才能兑现,类型都是公钥hash,输出地址。

截屏2024-11-25 21.41.56

B 转给 C 的币的来源 是源自 A转给B的交易。

验证交易合法性

截屏2024-11-25 21.52.02

拼接运行。

return true 就是合法的。

最简单的输入输出脚本形式(重点)

这里必须先明确,脚本是脚本,写好了没有执行,执行的时候,不是按照 脚本从上到下执行,而是根据规则,拼接本交易脚本的一部分和另一个交易脚本的一部分执行。

这个是理解下面为代码的先决条件!

pay to public key(p2pk)

截屏2024-11-25 21.55.00

input 都是以付钱人的角度操作的,output还是以收钱人的角度操作的。

输出脚本中两个操作,直接给出 收款人的 pubkey公钥,以及check验证签名sig;

其实就是为了 公开告诉所有人收款人收到了这笔钱,把收款人公钥告诉大家,方便大家验证这个收款人的签名,因此把收款人的公钥压入栈中,并附带一个验证操作压到这个栈中,方便大家取用

输入脚本中直接给出 签名sig 即可,其实就是用付钱的人的私钥加密做一个签名,为自己的付钱行为背书;

这个sig 是由付钱人私钥对输入脚本所在交易,整个交易签名。

截屏2024-11-25 22.19.50

脚本拼接执行参考下图:

截屏2024-11-25 21.52.02

说人话,就是自己付钱的时候,要为自己钱的来源做验证,当年自己收这笔款的时候 就公布了自己的验证公钥和验证方法。花钱的时候 验证一下再花。

一个人的公钥都是能够对自己私钥加密过的东西进行解密的,用之前公布的pubkey可以对之后key加密的内容解密,这个是非对称加密的理论基础。

pay to public key hash(p2pkh)

截屏2024-11-25 22.55.10

这里就是把 p2pk 中的 输出脚本中的 收款人的pubkey 换成了收款人的 hash(pubkey) ,

而输入脚本给出了付款人的签名和付款人的公钥。

input还是 都是以付钱人的角度操作的,output还是以收钱人的角度操作的。

步骤:

截屏2024-11-25 23.10.12

截屏2024-11-25 23.10.46

截屏2024-11-25 23.11.17

我们可以知道,上面的一系列栈操作中,上方的pubkey是付款人 给的,后面的pubkeyhash 是收款人的pubkey经过hash计算来的,我们经过了一个 equal verify比较认证,看看他们相等吗?利用hash值的难以人为制造碰撞的特性,两个hash 值相等就视为首付款都是同一个人。

最后这个checksig就是验证是不是true,equalverify 会返回是不是true。

截屏2024-11-27 20.10.08

pay to script hash(p2sh)

截屏2024-11-27 20.14.41

用了一个赎回脚本,和赎回脚本的hash,在输入脚本中的付钱人给出的赎回脚本 要和 输出脚本中收款人给出的 赎回脚本的hash 值相匹配。

但是赎回脚本和 公钥 用法上有点递进的效果,因为赎回脚本 直接运行呢,可以验证 sig 签名的有效性。

截屏2024-11-27 20.20.00

截屏2024-11-27 20.25.07

其实 bct链的脚本 就是在一个 栈中操作,两个脚本 拼接 在 栈中操作而已。

上面这个 HASH160 其实就是一个对栈顶元素的操作,(栈这种数据结构就是 对栈顶操作,可见我以前的笔记。)

这一步就是 输出脚本中 对 输入脚本中付钱人压入的 redeemscript 做了 hash,下一步的 则是把 收钱人的 redeemscript 的 hash 也压入栈,最后对比一下。

截屏2024-11-27 20.33.38

截屏2024-11-27 20.33.51

多重签名

截屏2024-11-27 20.40.09

N=5,M=3,就是 5个人中 3个签名,就能认证。

红色的 x 是以前 留下的bug,会多弹出元素,所以这个我们多压入一个元素填入,但是由于bct链是一个分布式的系统,导致修改不了,只能硬分叉。

截屏2024-11-27 20.54.26

利用p2sh 实现 多重签名

截屏2024-11-27 21.06.14

利用多重签名,中本聪把 output脚本 中的 大量的操作,打包到了 input脚本 中,封装在了赎回脚本中,简化了输出脚本。

这样商家的收钱的时候要改动规则,如把 原来 5个人中3个人签名即可,改成5个人中2人签名即可,只需在输出中改动赎回脚本的hash 值,换句话就是改动 赎回脚本即可。

对 买家来说,仅仅是 付钱的时候 商家给出的这个 hash 值发生了变化,简化了买家需要跟着改的改动量。

截屏2024-11-27 21.14.46

截屏2024-11-27 21.15.36

截屏2024-11-27 21.19.19

燃烧证明

截屏2024-11-27 21.31.44

应用场景

1、一些小币,需要 燃烧一些 bct,才能发行。alt Coin。

2、往里面添加一些需要永久保存的内容,如:digital commitment数字承诺。

在这样的 return 后面 加上一些数字产权的hash ,不占空间,而已可以在不暴露只是产权内容的情况下,验证知识产权。

发布交易不需要有记账权,发布区块 才需要有记账权,像之前的 coinbase 中写入一些内容来记录 知识产权也行,但是对于用户要求太高了,一定要有记账权才行。而写在 output脚本中的 return 后面,可以让每一个用户都实现这样的用法。

截屏2024-11-27 21.46.41

这是一个 coinbase transaction,

这里输入是零,第一个输出12.655来自 p2pkh,就是block reward 和transaction fee,第二个输出是0,因为是return XXXX的形式,不会执行。

可见这个 output脚本 先是实现了一个 p2pkh的收款人的 巴拉巴拉到验证,但是后面紧接着一个return,来让记录一些内容。并且因为return,不会有 true的返回,也就是不会 被拼接验证通过。

截屏2024-11-27 21.50.43

普通的转账transaction。

输入 的0.05 btc 输出是0,说明钱都被用于支付交易费,转给miner了,但是输出脚本中 直接return,不会验证通过,后面的链也就断了。