区块链网站|NFTS 比特币地址 “区块链研究实验室”区块链技术的比特币交易地址(上)

“区块链研究实验室”区块链技术的比特币交易地址(上)

广告位

「区块链研究实验室」区块链技术之比特币交易地址(上)

在前言中,在最后一篇文章中,我们已经初步实现了交易。我相信你应该知道交易中的一些自然属性,这些属性没有丝毫的“个人”色彩:在比特币中,没有用户账户,个人数据(如姓名、护照号码或SSN)无需存储在任何地方。但是,总要有某种方法来确定你是交易输出的所有者(也就是说,你拥有锁定在这些输出上的货币)。这就是比特币地址需要完成的事情。在上一篇文章中,我们将用户定义的任意字符串作为地址。现在我们要实现像比特币一样的真实地址。

比特币地址这是一个真实的比特币地址:1a 1 ZP 1 EP 5 qgefi 2 DMP TTL 5 SLM V7 div FNA。这是历史上第一个比特币地址,据说属于中本聪。比特币地址是完全公开的。如果你想给某人寄钱,你只需要知道他的地址。然而,地址(虽然是唯一的)不是证明你是“钱包”主人的令牌。其实所谓的地址只是一种人类可读形式的公钥,因为原生公钥是人类难以读取的。在比特币中,你的身份是一对(或多对)公钥和私钥,存储在你的电脑上(或者你能得到的地方)。比特币基于一些加密算法的组合来创建这些密钥,并确保世界上没有其他人可以拿走你的硬币,除非他们得到你的密钥。现在,我们来讨论一下这些算法是什么。

公钥加密(公钥加密)算法使用成对的密钥:公钥和私钥。公钥不是敏感信息,可以告诉其他人。但是,绝对不能把私钥告诉别人:只有主人才能知道私钥,能够识别、认证、证明主人身份的就是私钥。在加密货币的世界里,你的私钥代表你,私钥就是一切。

本质上,比特币钱包就是这样一对钥匙。当您安装钱包应用程序或使用比特币客户端生成新地址时,它会为您生成一对密钥。在比特币中,谁拥有私钥,谁就可以控制发送到这个公钥的所有硬币。

私钥和公钥只是随机的字节序列,所以无法打印在屏幕上,人眼无法读取。这就是为什么比特币使用转换算法将公钥转换成人类可读的字符串(也就是我们看到的地址)。

如果你使用过比特币钱包应用程序,它很可能会为你生成一个助记符。这样的助记符可以用来代替私钥,也可以用来生成私钥。BIP-039已经实现了这个机制。

好了,现在我们知道了,在比特币中证明用户身份的是私钥。那么,比特币是如何检查交易输出(以及存储在其中的钱)的所有权的呢?

数字签名在数学和密码学中,有一个数字签名的概念,算法可以保证:

当数据从发送方传输到接收方时,数据不会被修改;

数据是由某个发送者创建的;

发送者不能否认数据已经被发送的事实。

通过对数据应用一个签名算法(也就是对数据进行签名),就可以得到一个签名,这个签名后面会进行验证。生成数字签名需要私钥,而验证签名需要公钥。签名有点像印章。比如我做了一幅画,盖上印章,就说明这幅画是我的作品。为数据生成签名就是给数据加戳。

为了签署数据,我们需要以下两样东西:

要签名的数据

私人密钥

可以通过应用签名算法来生成签名,并且该签名将被存储在事务输入中。为了验证签名,我们需要以下三样东西:

签名数据

符号

公开密钥

简单来说,验证过程可以描述为:检查签名是通过在已签名的数据上加上私钥得到的,而公钥恰好是由私钥生成的。

签名未加密,您无法从签名中重建数据。这有点像哈希:您对数据运行哈希算法,并获得该数据的唯一表示。签名和散列的区别在于密钥对:有了密钥对,签名验证就成为可能。但是密钥对也可以用于加密数据:私钥用于加密,公钥用于解密。但是,比特币不使用加密算法。

在比特币中,每一笔交易输入都由创建交易的人签名。在放入块中之前,每个事务都必须经过验证。除了一些其他步骤之外,验证还意味着:

检查事务输入是否有权使用以前事务的输出。

检查交易签名是否正确。

如图所示,签署数据和验证签名的过程大致如下:

现在让我们回顾一下事务的完整生命周期:

起初,创建块包含一个coinbase事务。在coinbase交易中,没有输入,所以不需要签名。coinbase事务的输出包含散列公钥(使用RIPEMD16(SHA256(PubKey))算法)

当一个人汇款时,交易就产生了。这个事务的输入将引用前一个事务的输出。每个输入将存储一个公钥(没有被散列)和整个事务的签名。

比特币网络中接收交易的其他节点将验证交易。除此之外,他们还会检查:在一个输入中,公钥哈希与引用的输出哈希匹配(这保证了发送方只能花自己的货币);签名是正确的(这保证了交易是由货币的实际所有者创建的)。

当一个矿工准备挖掘一个新的区块时,他会将事务放入该区块并开始挖掘。

当新的块被挖出时,网络中的所有其他节点将接收消息,告知其他节点该块已被挖出并被添加到区块链中。

当块被添加到区块链时,事务完成,并且其输出可以在新的事务中被引用。

椭圆加密如前所述,公钥和私钥都是随机字节序列。私钥可以用来证明持币人的身份,有一个条件:随机算法必须生成真正随机的字节。因为没有人愿意生成一个私钥,而这个私钥是别人不小心拥有的。

使用比特币椭圆曲线生成私钥。椭圆曲线是一个复杂的数学概念,我们不打算在这里过多解释(如果你真的很好奇,可以查看这篇文章,注意:有很多数学公式!我们只需要知道这些曲线可以产生非常大的随机数。比特币使用的曲线可以随机选择0到2 ^ 2 ^ 56之间的一个数(约为10 ^ 77,而整个可见宇宙的原子数在10 ^ 78到10 ^ 82之间)。有这么高的上限意味着几乎不可能两次生成同一个私钥。

比特币使用ECDSA(椭圆曲线数字签名算法)算法对交易进行签名,我们也会使用这个算法。

Base58返回上面提到的比特币地址:1a 1 ZP 1 EP 5 qgefi 2 DMP TTL 5s lm V7 div FNA。现在,我们已经知道这是公钥以人类可读的形式表达。如果我们对其进行解码,我们将看到公钥的真实性质(以十六进制表示的字节):

062 e 907 b 15 CBF 27d 5425399 ebf 6 f 0 b 50 EB 88 f 18 c 29 b 7d 93比特币使用Base58算法将公钥转换为人类可读的形式。这种算法类似于著名的Base64,只是它使用了更短的字母表:为了避免一些利用字母相似性的攻击,一些字母被从字母表中删除。也就是没有这样的符号:0(零)、O(大写O)、I(大写I)、L(小写L),因为这些字母看起来很像。此外,没有和/符号。

下图显示了从公钥获取地址的过程:

因此,上述公钥在解码后包含三个部分:

版本密钥哈希校验和00 62e 907 b 15 CBF 27d 5425399 ebf 6 f 0 b 50 EB 88 f 18 c 29 b 7d 93由于哈希函数是单向的(即不可反转),所以无法从哈希中提取公钥。但是,我们可以通过执行哈希函数和执行哈希比较来检查公钥是否用于生成哈希。

好了,所有细节都准备好了,我们来写代码吧。很多概念只有写代码才能理解得更透彻。

要实现地址,先从钱包钱包结构说起:

type Wallet struct { private key ECD sa。private key public key[]byte } type Wallets struct { Wallets map[string]* Wallet } func new Wallet()* Wallet { private,public:=newkey pair()Wallet:=Wallet { private,public } return Wallet } func newkey pair()(ECD sa。PrivateKey,[]字节){曲线:=椭圆。P256() private,err :=ecdsa。GenerateKey(曲线,rand。Reader) pubKey :=append(private。PublicKey.X.Bytes(),Private.publickey.y.bytes().)return * private,pubkey}一个钱包只有一个密钥对。我们需要钱包类型来保存多个钱包的组合,将它们保存到一个文件中,或者从一个文件中加载它们。Wallet的构造函数将生成新的密钥对。newKeyPair函数非常直观:ECDSA是基于椭圆曲线的,所以我们需要一条椭圆曲线。接下来,使用ellipse生成一个私钥,然后从私钥生成一个公钥。有一点需要注意:在基于椭圆曲线的算法中,公钥是曲线上的点。因此,公钥是x和y坐标的组合。在比特币中,这些坐标是相连的,然后形成一个公钥。

现在,要生成地址:

func(w Wallet)get address()[]byte { pubKeyHash:=hash pubkey(w . public key)version edpayload:=append([]byte { version },pubkey hash.)校验和:=校验和(版本有效负载)完整有效负载:=附加(版本有效负载,校验和.)地址:=Base58Encode(fullPayload)返回地址} func hash pubKey(pubKey[]byte)[]byte { public sha 256:=sha 256。sum 256(pubKey)ripemd 160 hasher:=ripemd 160。New() _,err :=RIPEMD160Hasher。write(public sha 256[:])public ripemd 160:=ripemd 160 hasher。sum(nil)return public ripemd 160 } func checksum(payload[]Byte)[]Byte { first sha:=sha 256 . sum 256(payload)second sha:=sha 256 . sum 256(first sha[:])return second sha[:AddressCheckSumlen]}将公钥转换为Base58地址需要以下步骤:

使用RIPEMD160(SHA256(PubKey))哈希算法,取公钥,哈希两次。

用地址生成算法版本作为哈希的前缀。

对于第二步中生成的结果,使用SHA256(SHA256(有效负载))进行哈希运算并计算校验和。校验和是结果哈希的前四个字节。

将校验和附加到版本PubKeyHash的组合中。

使用Base58对版本PubKeyHash校验和组合进行编码。

至此,你可以获得一个真实的比特币地址,你甚至可以在blockchain.info查看它的余额不过,我可以负责任地说,不管新地址生成多少次,查看它的余额都是0。这就是为什么选择一个合适的公钥加密算法如此重要:考虑到私钥是一个随机数,产生相同数的概率必须尽可能低。理想情况下,必须低到永远不会重复。

另外,请注意:您不需要连接到比特币节点来获取地址。地址生成算法中使用的各种开源算法可以通过许多编程语言和库来实现。

现在我们需要修改输入和输出以使用地址:

类型TXInput结构{ Txid[]字节想要int signature[]byte pubkey[]byte } func(in * tx input)use skey(pubkey hash[]byte)bool { locking hash:=hash pubkey(in).PubKey)返回字节Compare(lockingHash,pubkey hash)==0 } type tx output struct { value int pubkey hash[]byte } func(out * tx output)lock(address[]byte){ pubkey hash:=base 58 decode(address)pubkey hash=pubkey hash[1:len(pubkey hash)-4]out .pubkey hash=pubkey hash } func(out * tx output)islogdwithkey(pubkey hash[]byte)bool { return bytes .比较(输出)。PubKeyHash,pubKeyHash)==0}注意,现在我们已经不再需要ScriptPubKey和脚本先生字段,因为我们不会实现一个脚本语言。相反,脚本签名会被分为签个名和公钥(发布密钥)字段,ScriptPubKey被重命名为公钥哈希.我们会实现跟比特币里一样的输出锁定/解锁和输入签名逻辑,不同的是我们会通过方法(方法)来实现。

乌斯斯基方法检查输入使用了指定密钥来解锁一个输出。注意到输入存储的是原生的公钥(也就是没有被哈希的公钥),但是这个函数要求的是哈希后的公钥。islockedwithkey检查是否提供的公钥哈希被用于锁定输出。这是一个乌斯斯基的辅助函数,并且它们都被用于findunspenttransactions(查找未终止的事务)来形成交易之间的联系。

锁起来只是简单地锁定了一个输出。当我们给某个人发送币时,我们只知道他的地址,因为这个函数使用一个地址作为唯一的参数。然后,地址会被解码,从中提取出公钥哈希并保存在公钥哈希字段。

现在,来检查一下是否都能如期工作:

$区块链_ go createwalletyour新地址:13uu 7b 1 vdp 4 vixqhfswtbram 3 efq 3 ukwx $区块链_ go createwalltyour新地址:15 puhcbtrgh 3 jux 5 ihn jfpykhtml g5h $区块链_ go createwalltyour新地址:1 lhqun 1和9 zzzhoditqxfpqbcwr 1 cvdv 2和$区块链_ go创建区块链-地址13 uu 7b 1 vdp 4 viqhfsww$区块链_ go获取余额-地址13 uu 7 B1 vdp 4 vixqhfswtbram 3 efq 3 ukwx tbar \’ 13 uu 7 B1 vixqhfswtbram 3 efq 3 ukwx:10美元区块链_ go发送-from 15 puhcbtrgh 3 jux 5 ihnxjfpykhtml wvg 5h-to 13 uu 7 B1 vdp 4 viqhfswtbram 3 efq 3 ukwx-amount 527/09/12 13 $区块链_ go获取余额-地址13 uu 7 B1 vqhfswtbram 3 efq 3 ukwx tb13 uu 7 B1 vxqhfswtbram 3 efq 3 ukwx:4 $区块链_ go获取余额-地址15 puhcbtbr am美元很好! 下半部分我们将会实现如何交易签名。

广告位
本文来自网络,不代表区块链网站|NFTS立场,转载请注明出处:https://www.qklwz.com/btb/qianbao/2401.html

作者: 小王聊区块

上一篇
下一篇

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注

返回顶部