简介
区块链可以看作一种分布式数据库技术,它是以区块为单位节点的链式数据结构,每个区块 中包含前一个区块的数字摘要,用于对前一个区块(节点)的连接以及数据校验。通过维护 这个链式结构,可以维持 持续增长的、不可篡改的 数据记录,适合分布式记账场景下防篡 改和可扩展性的需求。
三个基本概念:
Transaction | 一次对账本的操作,导致账本状态的一次改变,比如添加一条转账记录 |
---|---|
Block | 记录一段时间内发生的所有交易和状态结果等,是对当前账本状态的一次共识 |
Chain | 由区块按照发生顺序串联而成,是整个账本状态变化的日志记录 |
技术特点:
- 维护一条不断增长的链,只可能添加记录,而且记录一旦确认则不可篡改;
- 非中心化的共识,无需集中的控制,实现上尽量为分布式;
- 通过密码学的机制来确保交易无法被抵赖和破坏,并尽量保护用户信息和记录的隐私性。
技术分类:
-
公有链:任何人都可以参与使用和维护,参与者多为匿名。比如比特币和以太坊区块链,信息是完全公开的。
-
私有链:由集中管理者进行管理限制,只有内部少数人可以使用,信息不公开。一般认 为跟传统中心化记账系统的差异不明显。
-
联盟链:由若干组织(如供应链机构或银行联盟等)一起合作维护一条区块链,该区块 链的使用 必须是带有权限的限制访问 ,相关信息会得到保护,比如超级账本项目。
区块结构
区块头
数据项 | 描述 | 长度(字节) |
---|---|---|
---------------- | ---------------------------------------------------------- | ------------ |
Version | 版本号,用于跟踪软件/协议的更新 | 4 |
Prev Block Hash | 前一个区块的 256 位哈希值 | 32 |
Time | 从`1970-01-01 00:00 UTC`开始到现在,以秒为单位的当前时间戳 | 4 |
Bits | 压缩格式的当前目标哈希值,用于标注挖矿难度 | 4 |
Nonce | 从 0 开始的 32 位随机数 | 4 |
Merkle Root Hash | 基于一个区块中所有交易的 256 位哈希值 | 32 |
Merkle 树结构
Merkle 树(哈系树)是一种典型的二叉树结构,其主要特点为:
- 最下面的叶节点包含存储数据或其哈希值。
- 非叶子节点(包括中间节点和根节点)都是它的两个孩子节点内容的哈希值。
Merkle 树的特点导致了它的一个性质,就是每一个叶子节点的改变都会沿着路径传递到根 节点,所以根节点的值可以看作整棵树的“数字摘要”,借此可以快速比较大量数据。
区块体
数据项 | 描述 | 长度(字节) |
---|---|---|
------------------- | --------------------------------- | ------------ |
Magic Number | 0xD9B4BEF9 | 4 |
Block Size | 区块大小 | 4 |
Block Header | 区块头,包含 6 个数据项 | 80 |
Transaction Counter | 交易单数量,Variable Integer 类型 | 1-9 |
Transactions | 交易单内容(非空) | 不固定 |
比特币
比特币网络是一个分布式的点对点网络,网络中的矿工通过“挖矿”来完成对交易记录的记 账过程,维护网络的正常运行。
交易过程
交易 | 目的 | 输入 | 输出 | 签名 | 差额 |
---|---|---|---|---|---|
---- | -------- | ------------------- | -------------------- | ---------- | -------------------------- |
T0 | A 转给 B | 他人向 A 交易的输出 | B 账户可以使用该交易 | A 签名确认 | 输入减输出,作为交易服务费 |
T1 | B 转给 C | T0 的输出 | C 账户可以使用该交易 | B 签名确认 | 输入减输出,作为交易服务费 |
… | X 转给 Y | 他人向 X 交易的输出 | Y 账户可以使用该交易 | X 签名确认 | 输入减输出,作为交易服务费 |
正常情况下,每个交易需要包括若干输入和输出,而且总输入不能少于总输出,总输入中多
余的部分称为交易费用(Transaction Fee),由矿工获取。矿工获取挖矿奖励的 coinbase
交易则只有输出。
未经使用的交易的输出(Unspent Transaction Outputs,UTXO)可以被新的交易使用(引 用)作为其合法的输入;被使用过的交易的输出(Spent Transaction Outputs,STXO), 则无法被引用作为合法输入。
比特币交易中,付款方通过“签名脚本”来证明所引用的 UTXO 的合法性,并指定“输出脚 本”来限定将来能使用新 UTXO 的收款方。
基本概念
账户/地址
比特币的账户地址其实就是用户公钥经过一系列 Hash( HASH160
,或先进行 SHA256
,然
后进行 RIPEMD160
)及编码运算后生成的 160 位的字符串。
一般情况下,会对账户地址串进行 Base58Check
编码,并添加前导字节(表明支持哪种脚
本)和长度为 4 的校验字节,以提高可读性和准确性。
交易
一条交易记录可能包括以下信息:
付款人地址 | 合法的地址,公钥经过 SHA256 和 RIPEMD160 两次 Hash,得到的 160 位 Hash 串 |
---|---|
付款人对交易的签字确认 | 确保交易内容不被篡改 |
付款人资金的来源交易 ID | 从哪个交易的输出作为本次交易的输入 |
交易的金额 | 多少钱,跟输入的差额将作为交易的服务费 |
收款人地址 | 合法的地址 |
时间戳 | 交易何时能生效 |
网络中的节点收到交易信息后,将进行以下检查:
-
交易是否已经通过;
-
交易是否合法,包括地址是否合法、发起交易者是否是输入地址的合法拥有者、是否是 UTXO;
-
交易的输入之和是否大于输出之和。
检查都通过,则将交易标记为合法的 未确认 交易,并在网络内进行广播。
交易脚本
交易脚本的作用是验证交易的合法性,当所依附的交易发生时被触发。通过脚本机制而非写 死交易过程,比特币网络实现了一定的可扩展性。
一般每个交易都会包括两个脚本:
-
负责输出的锁定脚本(scriptPubKey)
一般由付款方设置锁定,用来对能动用这笔交易的输出的对象(收款方)进行权限控制。 例如,限制必须是某个公钥的拥有者才能花费这笔交易。
-
负责输入的解锁脚本(scriptSig)
用来证明自己可以满足交易输出脚本的锁定条件,即对某个交易的输出(比特币)的拥有权。
输出脚本目前支持两种类型:
-
Pay-To-Public-Key-Hash(P2PKH) — 允许用户将比特币发送到一个或多个典型的比特币 地址上(证明拥有该公钥),前导字节一般为
0x00
。 -
Pay-To-Script-Hash(P2SH) — 支付者创建一个输出脚本,里边包含另一个脚本(认领 脚本)的哈希,一般用于需要多人签名的场景,前导字节一般为
0x05
。
一个完整的交易指令如下:
<sig> <pubKey> | 签名和公钥,属于 scriptSig |
---|---|
OP_DUP | 复制栈顶元素 |
OP_HASH160 | 计算 hash 值 |
OP_EQUALVERIFY | 判断栈顶两元素是否相等 |
OP_CHECKSIG | 判断签名是否合法 |