6-bct脚本
简介
交易实例
左边看见的output 是输入,也就是别人的输出,右边的是输出,可见有一个 spent 一个 unspent还没有花,已经被23个确认,回滚可能性很小了,下方可见输入输出脚本,输入脚本是把 两个很长的数,压入栈中,而输出脚本 的两行对应的是 上面的两个输出,每一个输出有一个单独的自己的脚本。
btc脚本语言其实只有一个栈操作。
交易结构
transaction id,hash,btc版本,locktime 锁多少个区块后再写入区块,输入,输出 ,交易所在的区块对应的区块hash值,这个交易已经有多少个确认信息,交易产生的时间,区块产生的时间1970XX年XX到现在过了多少秒。
交易的输入
交易输入就是要说明白来源。
txid 之前这个交易的hash 值,vout 是这个交易中的第几个输出。
输入脚本 scriptsig,输入脚本的最简单形式就是给出一个 signed签名,证明你有权用这个钱。如果一个交易有多个输入,每一个输入都需要说明币的来源,并都 给出签名。
交易的输出
value 多少钱,n 是这个交易的第几个输出,scriptpubkey 输出脚本,因为输出脚本最简单的形式就是输出一个 pubkey,reqsigs 这个输出需要多少个签名才能兑现,类型都是公钥hash,输出地址。
B 转给 C 的币的来源 是源自 A转给B的交易。
验证交易合法性
拼接运行。
return true 就是合法的。
最简单的输入输出脚本形式(重点)
这里必须先明确,脚本是脚本,写好了没有执行,执行的时候,不是按照 脚本从上到下执行,而是根据规则,拼接本交易脚本的一部分和另一个交易脚本的一部分执行。
这个是理解下面为代码的先决条件!
pay to public key(p2pk)
input 都是以付钱人的角度操作的,output还是以收钱人的角度操作的。
输出脚本中两个操作,直接给出 收款人的 pubkey公钥,以及check验证签名sig;
其实就是为了 公开告诉所有人收款人收到了这笔钱,把收款人公钥告诉大家,方便大家验证这个收款人的签名,因此把收款人的公钥压入栈中,并附带一个验证操作压到这个栈中,方便大家取用
输入脚本中直接给出 签名sig 即可,其实就是用付钱的人的私钥加密做一个签名,为自己的付钱行为背书;
这个sig 是由付钱人私钥对输入脚本所在交易,整个交易签名。
脚本拼接执行参考下图:
说人话,就是自己付钱的时候,要为自己钱的来源做验证,当年自己收这笔款的时候 就公布了自己的验证公钥和验证方法。花钱的时候 验证一下再花。
一个人的公钥都是能够对自己私钥加密过的东西进行解密的,用之前公布的pubkey可以对之后key加密的内容解密,这个是非对称加密的理论基础。
pay to public key hash(p2pkh)
这里就是把 p2pk 中的 输出脚本中的 收款人的pubkey 换成了收款人的 hash(pubkey) ,
而输入脚本给出了付款人的签名和付款人的公钥。
input还是 都是以付钱人的角度操作的,output还是以收钱人的角度操作的。
步骤:
我们可以知道,上面的一系列栈操作中,上方的pubkey是付款人 给的,后面的pubkeyhash 是收款人的pubkey经过hash计算来的,我们经过了一个 equal verify比较认证,看看他们相等吗?利用hash值的难以人为制造碰撞的特性,两个hash 值相等就视为首付款都是同一个人。
最后这个checksig就是验证是不是true,equalverify 会返回是不是true。
pay to script hash(p2sh)
用了一个赎回脚本,和赎回脚本的hash,在输入脚本中的付钱人给出的赎回脚本 要和 输出脚本中收款人给出的 赎回脚本的hash 值相匹配。
但是赎回脚本和 公钥 用法上有点递进的效果,因为赎回脚本 直接运行呢,可以验证 sig 签名的有效性。
其实 bct链的脚本 就是在一个 栈中操作,两个脚本 拼接 在 栈中操作而已。
上面这个 HASH160 其实就是一个对栈顶元素的操作,(栈这种数据结构就是 对栈顶操作,可见我以前的笔记。)
这一步就是 输出脚本中 对 输入脚本中付钱人压入的 redeemscript 做了 hash,下一步的 则是把 收钱人的 redeemscript 的 hash 也压入栈,最后对比一下。
多重签名
N=5,M=3,就是 5个人中 3个签名,就能认证。
红色的 x 是以前 留下的bug,会多弹出元素,所以这个我们多压入一个元素填入,但是由于bct链是一个分布式的系统,导致修改不了,只能硬分叉。
利用p2sh 实现 多重签名
利用多重签名,中本聪把 output脚本 中的 大量的操作,打包到了 input脚本 中,封装在了赎回脚本中,简化了输出脚本。
这样商家的收钱的时候要改动规则,如把 原来 5个人中3个人签名即可,改成5个人中2人签名即可,只需在输出中改动赎回脚本的hash 值,换句话就是改动 赎回脚本即可。
对 买家来说,仅仅是 付钱的时候 商家给出的这个 hash 值发生了变化,简化了买家需要跟着改的改动量。
燃烧证明
应用场景:
1、一些小币,需要 燃烧一些 bct,才能发行。alt Coin。
2、往里面添加一些需要永久保存的内容,如:digital commitment数字承诺。
在这样的 return 后面 加上一些数字产权的hash ,不占空间,而已可以在不暴露只是产权内容的情况下,验证知识产权。
发布交易不需要有记账权,发布区块 才需要有记账权,像之前的 coinbase 中写入一些内容来记录 知识产权也行,但是对于用户要求太高了,一定要有记账权才行。而写在 output脚本中的 return 后面,可以让每一个用户都实现这样的用法。
这是一个 coinbase transaction,
这里输入是零,第一个输出12.655来自 p2pkh,就是block reward 和transaction fee,第二个输出是0,因为是return XXXX的形式,不会执行。
可见这个 output脚本 先是实现了一个 p2pkh的收款人的 巴拉巴拉到验证,但是后面紧接着一个return,来让记录一些内容。并且因为return,不会有 true的返回,也就是不会 被拼接验证通过。
普通的转账transaction。
输入 的0.05 btc 输出是0,说明钱都被用于支付交易费,转给miner了,但是输出脚本中 直接return,不会验证通过,后面的链也就断了。