cover_image

去中心化交易原理

Origheart 该账号已冻结
2017年08月06日 06:02

图片

比特币的交易是一种无需信任中介参与的P2P交易。传统的电子交易必须通过银行这样的信任机构进行交易,这样可以保证交易的安全性。因为银行记录了双方的交易资金,能保证在一笔交易中要么保证成功要么交易无效,不存在一方到账而另一方没有付款的情况。

但是在比特币这种去中心化P2P网络中并没有像银行这样的信任机构存在。要想在两个节点之间达成交易,我们就必须实现一种在零信任的情况下安全交易的机制

创建交易有两种方法,我们假设小明和小红希望达成一笔交易。一种创建交易的方法是,小红声称小明给了她一万块钱,显然这是不可信的。还有一种创建交易的方法是,小明声称他给了小红一万块钱,只要能验证这个声明确实是小明做出的,并且小明真的有一万块钱,那么这笔交易就被认为是有效的。

如何验证这个声明确实是小明做出的呢?数字签名可以验证这个签名是否是小明做出的,并且一旦验证通过,小明是无法抵赖的。在比特币交易中付款方就是通过数字签名来证明自己拥有某一笔比特币,并且要把这笔比特币转移指定的收款方。

数字签名

使用签名是为了验证某个声明确实是有某个人做出的。比如,在付款合同中签名,可以通过验证笔迹的功能来核对身份。在计算机中,用密码学理论设计的数字签名算法比验证笔迹要更加可靠。使用数字签名时,每个人都可以生存一个密钥对。这个密钥对包含一个私钥和一个公钥

  • SK: Secret Key / Private Key (保密)

  • PK: Public Key(公开)

私钥必须严格保密,不能泄露给其他人。公钥可以公开给任何人。

当私钥持有人,例如小明,希望对某个消息进行签名的时候,他可以用自己的私钥进行签名,然后把消息、签名、自己的公钥发送出去,其他任何人都可以通过公钥对签名进行验证,如果验证通过就可以肯定该消息是由小明发出的。

图片
数字签名算法在电子商务、在线支付这些领域有非常重要的作用:

  • 签名不可伪造。因为私钥只有签名人自己知道,其他人无法伪造签名。

  • 消息不可篡改。如果原始消息被人篡改了,那么对签名进行校验就会失败。

  • 签名不可抵赖。如果签名被验证通过了,那么说明该消息肯定是签名人自己发出的,他不能抵赖自己曾经发过这条消息。

常用数字签名算法:

  • RSA

  • DSA

  • ECDSA

比特币采用的签名算法是是椭圆曲线签名算法:ECDSA。使用椭圆曲线,是一个已经定义好的标准椭圆曲线:secp256k1。

公钥和私钥

比特币采用ECDSA签名算法

  • 私钥是1 ~ 2^256的随机数

  • 公钥是由私钥根据ECDSA算法推算出来的

  • 通过私钥可以很容易推算出公钥,不必保存公钥

  • 通过公钥无法反推私钥,只能暴力破解

比特币的私钥是一个256位整数,比特币的公钥是根据私钥推算出的两个256位整数。如果用银行卡做比较的话,那么比特币的公钥相当于银行卡卡号,是两个256位的整数,而比特币的私钥相当于银行卡密码,是一个256位的整数。由于比特币的账本是全网公开的,所以任何人都可以通过公钥查询余额,但是持卡人是谁是不知道的。这就是比特币的匿名特性

图片
如果丢失了私钥,就永远无法花费对应公钥的比特币。丢失了私钥和忘记了银行卡密码不一样,忘记了银行卡密码和身份证到银行重新设置一个密码,这是因为银行卡密码是存储在银行的计算机中的。而比特币的P2P网络不存在中央节点,私钥只有持有人自己才知道,因此丢失了私钥,对应的比特币就永远无法花费。如果私钥被盗,黑客就可以花费对应公钥的比特币,并且无法追回

钱包

比特币钱包实际上是帮助用户管理私钥的软件。因为比特币钱包是给普通用户使用的,它有几种分类:

  • 本地钱包:把私钥保存在本地计算机硬盘的钱包软件。

  • 在线钱包:把私钥委托给第三方在线服务商保存的。

  • 纸钱包:是指把私钥打印出来保存在纸上。

  • 脑钱包:是指把私钥记住在脑袋里。对大多数普通人来说想要记住私钥是非常困难的,所以不建议使用脑钱包。

因为钱包保存的就是一组私钥,而私钥是一个256位的二进制整数,用16进制表示也需要64个字符,使用起来很不直观,而且无法检查是否写错了某些数字。所以比特币有一种表示私钥和公钥地址的编码方法。

非压缩格式的私钥地址

它其实是一种如何将一个整数编码为字符串。首先,我们把表示私钥的256位整数在计算机内存中表示出来是一个32字节的整数。

然后,我们在整数前面加一个字节的标识符(0x80)得到33字节,对这33字节进行两次SHA256哈希运算,计算出32字节的哈希。

紧接着,取32字节哈希的前4个字节作为校验码拼在第二步,也就是33字节的后面,总计37个字节。

最后,对这37字节进行base58编码得到一个总是以5开头的字符串编码。这个字符串就是需要我们非常小心的保存的私钥地址,又称钱包导入地址
图片

压缩格式的私钥地址

另一种压缩格式的私钥编码和非压缩格式的私钥编码非常类似,唯一不同的是压缩格式的私钥编码会在原始的32位字节整数的签名添加一个0x80的前缀和一个0x01的后缀,这样编码出来的字符串总是以K或者L开头。
图片

非压缩格式的公钥地址

比特币的公钥是2个256位的二进制整数,使用非压缩格式的公钥地址时,我们首先把两个二进制256位的整数,也就是2个32字节的整数拼起来,然后在签名加上0x40的前缀,对这65个字节先计算SHA256,再计算repemd160,得到20字节的哈希,然后,在20字节的哈希签名加上0x00的前缀。对这21字节进行两次SHA256得到校验码。取校验码的头4个字节拼在后面,一共是25个字节。最后使用base58编码得到总是以1开头的公钥地址。这个地址就是以字符串表示的公钥地址
图片

压缩格式的公钥地址

压缩格式的公钥地址只需要公钥的第一个256位整数,第二个整数实际上是可以根据第一个整数推算出来的。但是推算第二个整数要根据它是奇数还是偶数才能确定。所以在去掉第二个整数的同时,需要给第一个整数添加一个0x02或者0x03的前缀,如果第二个整数是偶数,那么就添加0x02的前缀,如果第二个整数是奇数,那么久添加0x03的前缀,然后再计算SHA256repemd160的哈希,加上0x00的前缀,取校验码的前4个字节,最后用base58编码得到了压缩格式的公钥,仍然是以1开头的地址。
图片

总的来说:

  • 私钥本质上就是一个256位的随机整数

  • 公钥本质上就是通过ECDSA算法从私钥推算出来的两个256位的整数

  • 非压缩格式的私钥是通过添加80前缀,然后进行base58编码得到的字符串,该字符串永远以5开头

  • 非压缩格式的公钥是通过添加40前缀,然后进行base58编码得到的字符串,该字符串永远以1开头

  • 压缩格式的私钥是通过添加80前缀和01后缀,然后进行base58编码得到的字符串,该字符串以K或L开头

  • 压缩格式的公钥是通过添加02或03前缀,然后进行base58编码得到的字符串,该字符串也是以1开头,这是因为公钥有2个256位的整数,通过第一个整数又可以推算第二个整数,所以压缩格式的公钥只保留第一个整数,如果只看公钥的base58编码是无法区分以1开头的字符串到底是压缩格式的还是非压缩格式的

和银行账户不同,比特币网络没有用户的概念。任何人都可以从区块链查询到任意公钥对应的比特币余额,但是并不知道这些公钥是由谁持有的,也就无法根据用户查询到比特币余额。

作为用户可以生成任意数量的私钥-公钥对。公钥是接受别人转账的地址,而私钥是花费比特币的唯一手段。钱包程序可以帮助用户管理私钥-公钥对。

交易

我们再来看记录在区块链上的交易,每个区块都记录了至少一笔交易。一笔交易就是从一定金额的比特币从一个输入转移到一个输出。例如小明把2个比特币转移给小红,这笔交易的输入是小明,输出就是小红,实际记录的是双方的公钥地址

如果小明有50个比特币,他要转给小红2个比特币,那么剩下的48个比特币应该记录在哪儿呢?

比特币规定,一个输出必须一次性花完,所以小明给小红的2个比特币交易必须表述成小明给小红2个比特币,同时又给了自己48个比特币,这48个比特币就是找零。所以,一个交易中,一个输入可以对应多个输出

当小红有2笔收入时,一笔是2个比特币,一笔是1.5个比特币,她想给小白转3.5个比特币时就不能单用一笔输出,她必须把2笔钱合起来再花掉。这种情况下,就是一个交易对应多个输入和一个输出

如果存在找零,这笔交易既包含多个输入也包含多个输出。

在实际交易中,输入笔输出稍微大一点点。这个差额就是隐含的交易费用。交易费用会算入当前交易的矿工收入中作为矿工奖励的一部分。
图片

比特币的交易记录是由一系列的交易构成的。每一个交易都包含多个输入以及一个或多个输出。当我们要简单验证某个交易的时候,例如对于交易f36abd,它记录的输入是3f96ab,索引号是1。我们就根据3f6ab找到前面已经发生过的交易,再根据索引号找到对应的输出是0.5个比特币。

所以这笔交易总计是0.5个比特币,输出分别是0.4个比特币和0.09个比特币,隐含的交易费用是0.01个比特币。这里要注意索引号是从0开始的,因此索引号是1的输出实际上第二个输出:
图片

结论

  • 比特币使用数字签名保证零信任的可靠P2P交易

  • 私钥是花费比特币的唯一手段

  • 钱包软件用来帮助用户管理私钥

  • 所有交易被记录在区块链中,可以通过公钥查询到所有交易信息

下次我们继续探讨PoW机制与挖矿原理。敬请期待!

继续滑动看下一个
该账号已冻结
向上滑动看下一个