比特币的交易模型
模型基本描述
前面一篇学习笔记 01 提到了一个交易模型(第三章的内容), 在第五章中, 除了对这个模型做个详细介绍之外, 其实和我上一篇理解的交易模型差不多, 一个交易包含输入与输出, 比特币是在各个地址之间转移, 不想中心化系统例如银行有个服务器, 记录了每个人的账户, 账户这个结构体包含: 交易记录, 账户余额等一切信息, 但是在比特币交易网络这种去中心化的体系中, 比特币的交易记录, 一个账户拥有多少比特币等信息存储在了区块链中, 要像银行账户一样, 查询自己账户的相关信息, 只能通过查区块链中的区块获取, 就像从数据库里查询数据一样, 就像下面比特币的交易模型描述
模型图有几个重点:
个人可用的比特币是以账单形式存在的, 在发起交易时, 查询区块链中个人可用账单(账单输出账户是你), 使用账单来支付相应比特币, 产生输出, 实际上, 是比特币在比特币地址之间的转移
本次交易的输入就是上次交易输出, 比特币账户 (地址) 查询余额和交易, 就是对区块链里账单里对你账户输出的查询(上图中, 对 A 可支配比特币的查询账单输出: 退给 A 的金额, 对 B 可支配比特币的查询账单输出: 转账给 B 的金额)
本次交易的输入可以只有一张账单的输出 (如果这张账单上的比特币足够), 也可以包含几张账单的输出(几张账单加起来比特币>= 此次需要支付金额), 注意到, 上面的>= 比交付, 因为不太可能利用已有账单完全无误差地凑出本次需支付对应金额, 因为账单里的输出金额是不可拆分的, 只能利用账单来支付, 要将银行里控制的个人账户余额(一串数字) 与比特币个人账户余额 (账户下的账单输出) 区分开来
生成的账单三中有给矿工的奖励, 这个奖励是你自定的, 给不给, 给多少都行, 这个奖励影响的是交易的优先级, 奖励越多, 越能尽早地将账单加入区块链中, 以保证交易的完成账单将会被保存在矿工的矿池中, 按照奖励优先级来处理账单
交易输出的锁定与解锁 (重点) 锁定脚本与解锁脚本
上面提到了, 一个账户可支配的比特币来源于账单的输出, 而账单是公开的, 每个比特币账户都能知道这笔交易以及交易的输出, 那么怎么保证输出只有对应的比特币的账户能用呢?
比特币的锁机制是通过一种类 Forth 语言脚本来, 该脚本语言是种非图灵完备的语言, 什么是图灵完备的语言呢, 当一门编程语言在不限制内存和不限制时间下, 能够解决所有问题, 就称为图灵完备的, 例如: C/C++,JAVA 都是图灵完备语言, 反之就是图灵非完备, 比特币脚本里没有循环, 所以这个脚本不能解决: 在满足某种条件下退出循环, 否则无限制地循环的问题比特币的脚本语言是一种简单低级的语言, 它的很多功能已经被编译成立二进制文件, 即使我们不了解这种语言, 只要能够调用接口就行了, 或者可以直接使用 C/C++,JAVA 这样的语言来完成锁定和解锁的功能那么为什么不直接用 C++ 等图灵完备的语言呢? 这是出于安全考虑的, 因为 C++,JAVA 等语言与内存操作系统等运行环境, 息息相关, 而比特币脚本不需要任何运行环境都能运行, 这就能抵抗基于内存的攻击或者其他透过系统漏洞的攻击(书上是这样解释的, 我觉得, 比特币脚本更像一串机器语言的 0-1 串, 由于低级机器语言的限制, 很难进行高级编程, 同样的, 也保证了安全性, 因为 0-1 机器语言很难入侵更改)
下面是锁定脚本与解锁脚本的例子, 以说明锁的交互机制
假设这笔交易为 A 向 B 支付比特币, 在交易双方完成交易, 生成账单时(非矿工加的解锁和锁定脚本),A 向这个账单加上了锁定脚本, 这个锁定脚本包含 B 的比特币地址 C, 因为 B 只公开了经过对公钥 HASH 后的比特币地址 C, 因为 HASH 函数的性质, 比特币网络上的任何人, 都不能通过 C 逆向得到 B 的公钥, 也就是说, 只有 B 知道自己的公钥能够构建解锁脚本, 即只有 B 的公钥, 才能通过 HASH 运算出地址 C, 只有能运算出地址 C 的比特币账户, 才能支配这笔比特币
脚本语言运行
该脚本语言仅由常数以及操作构成, 从前往后遍历脚本, 若遇到常数, 则将常数入栈, 若遇到操作, 根据操作的具体要求, 对栈顶元素进行弹出, 或者弹出两个元素进行运算, 再入栈, 当一句脚本运行完毕后, 仅只剩下栈顶元素, 其取值为 True\False, 很清楚地, True 代表验证成功, 代表执行脚本的用户具有该账单输出比特币的支配权, 用户能够使用该账单作为下笔交易 (账单) 的输入, 下面是个具体例子
锁定 / 解锁脚本类型
1)P2PKH (Pay-to-Public-Key-Hash)比特币网络上大多数交易都属于此类型
解锁脚本, 锁定脚本
2)P2PK(Pay-to-Public-Key)
写成收款方的公钥, 收款方通过自己的私钥生成相应公钥来获取支配权
3)P2SH(Pay-to-Script-Hash)
这个脚本类型用于多重签名才能支付, 比如, 一个公司的账户, 由 5 个人支配, 但只要有 2 个人以上的签名就能进行比特币支付
我们考虑使用 2)的方式来写多重签名命令:
就是说, 再使用上图方式多重签名的时候, 需要将所有人的公钥都加在锁定脚本里, 因为 Attorney Public Key 时是所有人的公钥运算的结果, 而 Public Key(公钥)有 260bit 长, 这样下来, 在人很多的情况下, 甚至会使锁定脚本容量超过账单本身, 而且这样的脚本也难以维护, 并暴露所有人之间的联系(尽管比特币地址是匿名的)
P2SH 很好地解决了这个问题, P2SH 分为除了锁定脚本解锁脚本之外, 多出了赎回脚本:
使用方法是分两步: 使用赎回脚本确认用户能在属于定义好的群组; 使用解锁脚本解锁(Sig1 Sig2 是 2 个群组用户的签名)
来源: https://www.cnblogs.com/BrotherXiang/p/8556175.html