秘钥生成和作用
- 私钥
- 私钥是一个256位的2进制随机数,可以取从0到2²⁵⁶-1之间的任意值
- 私钥可以根据不同的编码标准,生成不同编码的私钥格式,不同格式之间可以相互转换(Raw、WIF、WIF-compressed)
- 私钥生成公钥,所以根据私钥是可以推导出公钥的,但是公钥不能推出私钥
- 私钥用来生成数字签名用的
- 公钥
- 对私钥进行椭圆曲线加密处理,得到的公钥
- 公钥在交易的时候:P2PKH的账户之间交易,scriptSig里面需要有公钥信息,用来解锁output,因为output里面有 pubkHASH
- 公钥用来不可逆的生成公钥哈希
- 公钥哈希值
- 公钥哈希值=RIMPED160(SHA256(公钥))
- 为了保护公钥,所以有pubkHash的概念,用在output.scriptPubKey的脚本里面,作为收款人的地址
- 公钥哈希值可以根据不同的编码方式,生成不同的地址,编码方式不同,交易的锁定脚本和解锁脚本不同
Address
https://en.bitcoin.it/wiki/Address
- 根据地址的生成算法不同,有3种类型的地址算法,和对应的开头: 1、3、bc1
There are currently three address formats in use:
- P2PKH which begin with the number 1, eg: 1BvBMSEYstWetqTFn5Au4m4GFg7xJaNVN2.
- P2SH type starting with the number 3, eg: 3J98t1WpEZ73CNmQviecrnyiWrnqRhWNLy.
- Bech32 type starting with bc1, eg: bc1qar0srrr7xfkvy5l643lydnw9re59gtzzwf5mdq.
- 比特币地址是一串由字母和数字组成的26-35位字符串,看起来有些像乱码,长短不同时因为前置的0,被省略了
- 比特币用户和比特币地址是一对多的关系,一个用户可以生成多个比特币地址(甚至可以离线生成),但是一个比特币地址只指向一个用户。
- 不同算法的scriptPubKey不同
P2PKH地址的生成方式
https://www.cnblogs.com/zhaoweiwei/p/address.html
生成方式:
- 计算出pubKeyHash:公钥哈希值=RIMPED160(SHA256(公钥))
- 计算出校验码:校验码=前四字节(SHA256(SHA256(000+公钥哈希值))) 如比特币主网版本号“0x00"
- 最后计算出Address: 比特币地址=1+Base58(0+公钥哈希值+校验码) //16UwLL9Risc3QfPqBUvKofHmBQ7wMtjvM
P2PKH的交易脚本
- scriptPubKey: OP_DUP OP_HASH160 <pubKeyHash> OP_EQUALVERIFY OP_CHECKSIG
- scriptSig: <sig> <pubKey>
举个真实的例子:
ScriptSig:
PUSHDATA(72)[3045022100f8df16671995baaecab5a8d91fc3c78f22c156918cefb90dd1092fcd8578567d022041395667d7e99d131bffcb908904a2417cfb74b46df8bded2517a02beda0279701] PUSHDATA(33)
[021fc349da71680b2482e4c307adbd7aa2fc16d2cd564843ab873a8efff748d87b]
这里面的一个scriptSig由2部分组成,第一部分是签名,第二部分是公钥,PUSHDATA(N),表示要压入栈顶的byte,1个byte表示2个字符,PUSHDATA(72)表示压入144个字符
Output Scripts
HASH160 PUSHDATA(20)[d3ecd0e0d42d4b617767d9d1b966216c77ebb513] EQUAL
DUP HASH160 PUSHDATA(20)[7c45023433aea27b48251d4c5a52b1d73caba74e] EQUALVERIFY CHECKSIG
第二个找零output地址因为是P2PKH开头的,所以格式和描述的一样
Pay-to-Script-Hash
https://www.hibtc.org/2428.html
结合多重签名一起使用
scriptSig: ..signatures... <serialized script>
scriptPubKey: OP_HASH160 <scriptHash> OP_EQUAL
表示一共有n个参与方,只要有m个参与方同意了这笔交易,则这笔交易就生效了,具体的规则是通过scriptHash里面的脚本内容决定的
m-of-n multi-signature transaction:
scriptSig: 0 <sig1> ... <script>
script: OP_m <pubKey1> ... OP_n OP_CHECKMULTISIG
ScriptSig:
0[] PUSHDATA(72)[30450221009b37b97eb11341a5fa69d191312df12a41449cf922dbf8e72e93eb6ca7515cb60220759126a28f69525903da3e79e873c59ee7355b6a4874eed06ed6f616712ee51201] PUSHDATA(71)[304402202da30a860b7a2ee3cf614aae2ae8fb5a75de3ea9d5274701ef0ceebc94f75801022063155b788bfb7cada4e8050992b23340d9324306fbd6a201a169ff4a676ea9d701] PUSHDATA1[52210246ccf4de0c54cc7f3354cdd993c2c50cf965fd82238b89659fbd73a1b4bf05a121024fc59f72272a897fe43803374969f396058152fe4765a8d15216f94624257b1b21022593bc69ecbf3bbcc3c58082267cb49dadaf4ca8dbf1b2297338a9d628c4297653ae]
HASH160 PUSHDATA(20)[d3ecd0e0d42d4b617767d9d1b966216c77ebb513] EQUAL
结合P2SH的新特征
- 多重签名
多重签名是一种允许多个公钥共同签署一笔比特币交易的技术。比如说,使用多重签名技术,爱丽丝,鲍勃和查理可以共同监管一个比特币,这样,要动用该比特币,至少需要他们之中的两个人的同意。
- 比如类似于淘宝、京东这种中间商平台介入的平台, 实现2-3的支付模式
- 防止单方擅用资产,2-2的模式,只有2方同时同意才可以动用资产
- 延迟交易
新的支付方式允许交易输出在未来的某个时间点之前不可使用,OP_CHECKLOCKTIMEVERIFY
P2PKH账户的交易认证
https://en.bitcoin.it/wiki/Transaction
目前比特币支持两种类型的交易:Pay-to-PubkeyHash、Pay-to-Script-Hash
- txid
- Input[] inputs
- Output[] outputs
- Input的构成
- preTxid (该笔余额的来源交易hash)
- index(属于该笔交易的output[]下标)
- scriptSig (<sig> <pubk>)(用秘钥生成的签名信息,和自己的公钥信息)
- Output的构成
- value
- scriptPubKey (pubkHash)
验证一笔P2PKH交易的一个输入是否合法:
- 先遍历,根据每个Input的 Previous tx和Index,找到这笔input的输出来源为哪笔交易的哪个输出。
- 并且把input的scriptSig ,pubkey 按照顺序入栈
- 首先执行OP_DUP,这条指令是把栈顶元素pubkey 复制一份(scriptSig ,pubkey,pubkey)
- 紧接着执行OP_HASH160,表示对栈顶进行SHA256/RipeMD160,实际就是计算公钥hash:(scriptSig ,pubkey,pubkeyHash)
- 然后下一条是直接把数据46af3fb4…6829入栈(也就是对应output里面的 pubkHash)
- 然后执行OP_EQUALVERIFY,比较栈顶两个元素是否相等,如果不相等,整个脚本就执行失败
- 如果成功:最后执行OP_CHECKSIG栈顶两个元素进行签名校验,如果相等,出栈返回成功
总结:先验证这笔output是不是属于该用户,再验证该用户的签名是否有效
参考:
https://blog.csdn.net/jerry81333/article/details/56824166
初级版的比特币交易
https://www.jianshu.com/p/a57795ec562c