测试使用,见part14
----------------------------------------------------------------------------------------------------------------
1
Bitcoin address类型
P2PKH:
支付到比特币地址的交易包含支付公钥哈希脚本(P2PKH)。由 P2PKH 脚本锁定的交易输出可以通过给出由相应私钥创建的公钥和数字签名来解锁(消费)。1开头P2SH:
P2SH 是一种强大的、新型的、且能大大简化复杂交易脚本的交易类型而引入。通过使用 P2SH,详细描述花费输出条件的复杂脚本(赎回脚本)将不会出现在锁定脚本中。相反,只有赎回脚本哈希包含在锁定脚本中。3开头Bench32:
新的交易有效标准,但没有被广泛应用,交易类型使用P2PKH或P2SH其一。----------------------------------------------------------------------------------------------------------------
2
由公钥(66字节,264位)生成比特币地址时使用的算法是SHA256和RIPEMD160
A = RIPEMD160(SHA256(K)) A,称为公钥哈希,长度为20个字节,160位。 公式中,K 是公钥,A 是生成的公钥哈希。通常用户见到的比特币地址是经过公钥哈希的“Base58Check”编码的。
Base58:Base58 是 Base64 编码格式的子集。不包括(0,O,l,I)以及“+”和“/”。https://blog.csdn.net/idwtwt/article/details/80740474
Base58Check:BitcoinAddress = Base58(1 || A || first4byte(SHA256(SHA256(1 || A))))
1表示地址类型P2PKH。 BitcoinAddress,34字节。----------------------------------------------------------------------------------------------------------------
3
未压缩格式公钥使用 04 作为前缀,而压缩格式公钥是以 02 或 03 作为前缀。
具体参考博文:BX(bitcoin explorer)比特币密钥与地址生成----------------------------------------------------------------------------------------------------------------
4
1.确定性钱包:HD钱包。通过设置种子(由助记词产生512位的种子,使用BIP-39标准生成助记词),推导出私钥,常用推导结构为树状。Mycelium钱包就是HD钱包,APP,
2.非确定性钱包:JBOK钱包。私钥直接使用随机数生成。
----------------------------------------------------------------------------------------------------------------
5
使用BIP-39标准(由随机数生成12(或24)个单词的标准过程),再使用密钥延伸函数PBKDF2,将助记词和盐(常数)生成512位的种子。根种子输入到HMAC-SHA512算法中,得到512位输出,左边 主私钥 和 右边 主链代码 。由主私钥可以得到主公钥。
使用CKD函数从主私钥衍生出子私钥:
主公钥 + 主链代码 + 索引号 -> HMAC-SHA512 -> 子私钥 + 子链代码 (子私钥又可以作为主私钥继续向下衍生) 私钥可以得到公钥,公钥可以生成地址,用于交易。子私钥、对应的公钥以及比特币地址都不能从随机创造的密钥和地址中被区 分出来。 子私钥被称作扩展私钥每一个母扩展密钥有 40 亿个子密钥:20亿个常规子私钥和 20 亿个强化子私钥。
强化子私钥过程与衍生子私钥类似,只是用主私钥代替主公钥,如下: 主私钥 + 主链代码 + 索引号 -> HMAC-SHA512 -> 子私钥 + 子链代码BIP-43,HD 钱包应该使用且只用第一层级的树的分支。
BIP-44 指定了包含 5 个预定义树状层级。----------------------------------------------------------------------------------------------------------------
6
P2PKH( Pay-to-Public-Key-Hash ),比特币网络处理的大多数交易花费的都是由“付款至公钥哈希” 。P2PKH( Pay-to-Public-Key-Hash ),比特币网络处理的大多数交易花费的都是由“付款至公钥哈希” 。
原始交易内容,每个节点会进行验证
{
"version": 1, "locktime": 0, "vin": [{ "txid": "7957a35fe64f80d234d76d83a2a8f1a0d8149a41d81de548f0a65a8a999f6f18 ", "vout": 0, "scriptSig": "3045022100884d142d86652a3f47ba4746ec719bbfbd040a570b1deccbb6498c75c4ae24cb02204b9f039ff08df09cbe9f6addac960298cad530a863ea8f53982c09db8f6e381301 0484ecc0d46f1918b30928fa0e4ed99f16a0fb4fde0735e7ade8416ab9fe423cc5412336376789 d172787ec3457eee41c04f4938de5cc17b4a10fa336a8d752adf", "sequence": 4294967295 }], "vout": [{ "value": 0.01500000, "scriptPubKey": "OP_DUP OP_HASH160 ab68025513c3dbd2f7b92a94e0581f5d50f654e7 OP_EQUALVERIFY OP_CHECKSIG " }, { "value": 0.08450000, "scriptPubKey": "OP_DUP OP_HASH160 7f9b1a7fb68d60c536c2fd8aeaa53a8f3cc025a8 OP_EQUALVERIFY OP_CHECKSIG " } ] }txid:锁使用的 UTXO 的交易,UTXO见part7
vout:标识来自该交易的哪个 UTXO 被引用 scriptSig:解锁脚本,作用,它将允许输出(UTXO)被消费,形如<Signature> <公钥> sequence:序列号value:量
scriptPubKey:锁定脚本,更一般地说,它是一个加密难题, 形如OP_DUP OP_HASH160 <公钥哈希> OP_EQUALVERIFY OP_CHECKSIG,上述: ab68025513c3dbd2f7b92a94e0581f5d50f654e7:表示比特币地址的公钥哈希值都显示为十六进制码,而不是大家所熟知的以 1 开头的基于 Bsase58Check 编码的比特币地址。 锁定脚本的作用是,设定成只有 比特币地址的公钥哈希值 才能使用这笔输出。将两个脚本结合起来可以形成如下组合验证脚本:
<Signature> <公钥(part2所述)> OP_DUP OP_HASH160 <公钥哈希> OP_EQUALVERIFY OP_CHECKSIG OP_DUP,复制栈顶 OP_HASH160,计算栈顶公钥的公钥哈希值 OP_EQUALVERIFY,判断该公钥的公钥哈希是否是txid中锁定的公钥哈希,得到true或false OP_CHECKSIG,检查用交易人的签名验证该公钥是否是他本人的如果从解锁脚本中复制而来的堆栈数据执行锁定脚本的结果为“TRUE",那么解锁脚本就成功地满足了锁定脚本(上次交易中)所设置的条件,因此,该输入是一个能使用该 UTXO的有效授权。
具体交易过程必须参考:比特币的交易实例详述
----------------------------------------------------------------------------------------------------------------
7
UTXO未花费的交易输出:部分余额。用户所有的UTXO才是钱包“余额”。比特币钱包通过扫描区块链并聚集所有属于该用户的 UTXO 来计算该用户的余额 。大多数钱包维护一个数据库或使用数据库服务来存储所有 UTXO 的快速参考集。
交易费按字节数计算,一般采用动态计费,https://bitcoinfees.earn.com/,该接口可以看到实时的字节锁需要的交易费。
交易时需要指出两个输出,一个支付给对方的,一个“找零”给自己的,否则,旷工认为“不用找了”,并且这笔交易拥有较高的优先级,最快给你处理对于需要使用大量UTXO才能支付的交易中,相应地会产生较大的字节数,所需要的交易费就高些。
----------------------------------------------------------------------------------------------------------------
8
数字签名ECDSA
比特币中使用的数字签名算法是椭圆曲线数字签名算法ECDSA,part6所述解锁脚本中的<Signature>
数字签名作用:不揭示私钥的情况下提供私钥的所有权证明。Sig = ECDSA(私钥 + 消息)
签名结果分为R、S,Sig = (R, S),再使用
签名序列化 DER 的国际标准编码方案序列化为字节流part6中,
30450221 00884d142d86652a3f47ba4746ec719bbfbd040a570b1deccbb6498c75c4ae24cb 0220 4b9f039ff08df09cbe9f6addac960298cad530a863ea8f53982c09db8f6e3813 01即为序列化字节流
0x30 表示 DER 序列的开始 0x45 - 序列的长度(69 字节) 0x02 - 一个整数值 0x21 - 整数的长度(33 字节) R-00884d142d86652a3f47ba4746ec719bbfbd040a570b1deccbb6498c75c4ae24cb 0x02 - 接下来是一个整数 0x20 - 整数的长度(32 字节) S-4b9f039ff08df09cbe9f6addac960298cad530a863ea8f53982c09db8f6e3813 后缀(0x01)指示使用的哈希的类型(SIGHASH_ALL)重要的数字是 R 和 S; 数据的其余部分是 DER 编码方案的一部分。
验证算法采用消息(交易或其部分的哈希值)、签名者的公钥和签名(R 和S 值)
验证过程,即解锁脚本的作用,证明txid输出的UTXO是否属于该公钥持有者。
那么如何证明txid属于该公钥持有者呢? 因为在part6中txid所指的UTXO,在上一个交易中将交易输出锁定到了发起本次交易人的公钥哈希上,用公钥的RIPEMD160(SHA256(公钥))与txid交易(上一个交易)的锁定脚本的公钥哈希对比,说明txid属于该公钥持有者,再检查公钥与签名是否匹配,即是否持有者是否本人。----------------------------------------------------------------------------------------------------------------
9
多重签名
作用,把UTXO锁定到指定个数公钥上,并指定解锁资金的签名数,使用UTXO时,签名数必须要达到指定解锁资金的签名数时,才能花费UTXO。
锁定脚本
2 <Public Key A> <Public Key B> <Public Key C> 3 CHECKMULTISIG解锁脚本
0 <Signature B> <Signature C> 2 <Public Key A> <Public Key B> <Public Key C> 3 CHECKMULTISIG注:保证例子中有 3 个私钥签名(其中 2 有效签名,其中 1个为 0 的无效签名)对应 3 个公钥用于检查多重签名,从而保证脚本不产生 bug。
----------------------------------------------------------------------------------------------------------------
10
P2SH( Pay-to-Script-Hash ),“付款给脚本哈希”。
part9中的,用户付款给商家,商家需要多重签名以保证多个合伙人共同管理资金,此时用户需要承担大量的旷工费,因为用户需要填上很长的锁定脚本。
如果把多重签名的锁定脚本经过 RIPEMD160( SH256(多重签名的锁定脚本)),得到脚本哈希,用户只需要在锁定脚本里填入脚本哈希,而商家在花费时在解锁脚本里附上多重签名的解锁脚本,那么大量的旷工费就转移到了商家身上。用户的付款类型为P2SH,即向脚本哈希付款。锁定脚本
HASH160 54c557e07dde5bb6cb791c7a540e0a4796f5e97e EQUAL解锁脚本
<Sig1> <Sig2> <2 PK1 PK2 PK3 PK4 PK5 5 CHECKMULTISIG>----------------------------------------------------------------------------------------------------------------
11
Bloom过滤器
Bloom 过滤器是一个允许用户描述特定的关键词组合而不必精确表述的基于概率的过滤方法。人话就是类似模糊搜索的方式得到想要的结果,而不暴露隐私。用于防止用户交易信息与交易地址的暴露。bloom 过滤器是减少隐私损失的一种方式。
SPV(简易支付验证,一种无需存储完整区块链数据的轻量级节点,常用于钱包),通过设置Bloom过滤条件,发送给对等网络节点(拥有完整比特币区块链的节点),该节点过滤信息,找到与过滤条件相同的信息返回给SPV节点,对于SPV节点没有直接向完整节点索要具体交易信息,即保护了信息隐私。
实现原理参考:
----------------------------------------------------------------------------------------------------------------
12
区块结构
区块整体结构:
字节长度 字段 说明
4 区块大小 用字节表示的该字段之后的区块大小 80 区块头 组成区块头的几个字段 1-9 交易计数器 该区块包含的交易数量,包含coinbase交易 不定 交易列表 记录在区块里的交易信息 区块头结构: 字节长度 字段 说明 4 区块版本号 区块版本号 32 父区块头哈希值 前一个区块头的哈希值 32 Merkle根哈希 交易列表生成的默克尔树根哈希 4 时间戳 该区块产生的近似时间,精确到秒的UNIX时间戳 4 难度目标 难度目标,挖矿难度值 4 Nonce 挖矿过程中使用的随机值----------------------------------------------------------------------------------------------------------------
13
Merkle树
区块链中的每个区块都包含了产生于该区块的所有交易,且以 Merkle 树表示。
作用:通过从一个满节点回溯一条小的 Merkle 路径就能认证一笔交易的存在
double-SHA256:
HA = SHA256(SHA256(Transaction A))
HAB = SHA256(SHA256(H~A~ + H~B~))----------------------------------------------------------------------------------------------------------------
14
使用
首次看见的比特币区块链
----------------------------------------------------------------------------------------------------------------
15
难度目标
根据part12中的,难度目标为4字节,即32位,例如, 0x1903a30c
前两位十六进制数字为幂(exponent),接下来得六位为系数(coefficient) target = coefficient * 2^(8 * (exponent – 3)) 转化为十六进制后为: => target = 0x0000000000000003A30C00000000000000000000000000000000000000000000 难度目标的由来:每 2,016 个区块中的所有节点都会调整难度。
难度的调整公式是由最新 2,016 个区块的花费时长与 20,160 分钟(即 这些区块以 10 分钟一个速率所期望花费的时长)比较得出的。New Difficulty = Old Difficulty * (Actual Time of Last 2016 Blocks / 20160 minutes)
旷工不停的穷举随机数Nonce,放进区块头,使区块头通过SHA512得到的区块头hash值小于或等于目标值target----------------------------------------------------------------------------------------------------------------
16
当一个节点接收到一个新的区块,它将对照一个长长的标准清单对该区块进行验证,若没有通过验证,这个区块将被拒绝。
标准清单参考:区块链节点交易的独立校验