首页
Preview

用Java创建你的第一个区块链 第二部分——交易

本教程系列的目的是帮助你建立如何开发区块链技术的概念。你可以在此处找到第1部分

在本第二部分教程中,我们将:

  • 创建一个简单的钱包。
  • 使用我们的区块链发送签名交易。
  • 感觉超级酷。

以上所有操作都将导致我们自己的加密货币!(有点)

别担心,这实际上将是相当简单的,但比上一个教程要长!tl;dr Github

这是区块链开发终极指南的一部分

继续上次的教程,我们有一个基本的可验证区块链。但是,当前我们的链仅存储相当无用的消息。今天,我们将使用交易(我们的块将能够容纳多个交易)替换此数据,从而可以创建一个非常简单的加密货币。我们将称这个新硬币为:“NoobCoin”。

1.准备钱包

在加密货币中,硬币所有权以交易的形式在区块链上传输,参与者拥有一个地址,可以将资金发送到该地址和从该地址发送。在基本形式下,钱包只能存储这些地址,但大多数钱包也是能够在区块链上创建新交易的软件。

不要担心交易中的信息,很快就会解释:)

因此,让我们创建一个钱包类来保存我们的公钥和私钥:

请务必导入java.security.*!!!

公钥和私钥是什么?

对于我们的“noobcoin”,_公钥_将充当我们的地址。可以与他人共享此公钥以接收付款。我们的私钥用于签署我们的交易,以便除私钥所有者之外的任何人都不能花费我们的noobcoin。**用户必须保持私钥机密!**我们还将我们的公钥与交易一起发送,它可用于验证我们的签名是否有效,并且数据未被篡改。

私钥用于签署我们不希望被篡改的数据。公钥用于验证签名。

我们在KeyPair中生成我们的私钥和公钥。我们将使用椭圆曲线加密生成我们的KeyPairs。让我们在构造函数中附加一个_generateKeyPair()_方法:

你需要理解这个方法的全部内容是它使用Java.security.KeyPairGenerator生成椭圆曲线KeyPair。此方法创建并设置我们的公钥和私钥。精明。

现在,我们已经了解了钱包类的概要,让我们来看看交易。

NoobCoin > 现金?:D

2.交易和签名

每个交易都将携带一定数量的数据:

  • 资金发送者的公钥(地址)。
  • 资金接收者的公钥(地址)。
  • 要转移的资金价值/金额。
  • 输入,这是对先前交易的引用,证明发送者有资金可发送。
  • 输出,显示交易中相关地址接收到的金额。 (这些输出在新交易中被引用为输入)
  • 密码签名,证明地址的所有者是发送此交易的人,并且数据没有被更改。 (例如:防止第三方更改发送的金额)

让我们创建这个新的Transaction类:

我们还应该创建空的TransactionInput和TransactionOutput类,不要担心,我们稍后可以填充它们。

我们的交易类还将包含有关生成/验证签名和验证交易的相关方法。

等等…

签名的目的是什么,它们如何工作?

签名在我们的区块链上执行两个非常重要的任务:首先,它们只允许所有者花费他们的硬币,其次,它们防止其他人在挖掘新块(在进入点)之前篡改提交的交易。

私钥用于签署数据,公钥可用于验证其完整性。

例如:Bob想将2个NoobCoins发送给Sally,因此他们的钱包软件生成此交易并将其提交给矿工以包含在下一个块中。矿工试图将2个硬币的接收者更改为John。但是,幸运的是,Bob已经使用他的私钥签署了交易数据,使任何人都可以使用Bob的公钥验证交易数据是否已更改(因为其他人的公钥将无法验证交易)。

我们可以从前面的代码块中看到,我们的签名将是一堆字节,所以让我们创建一个方法来生成它们。我们首先需要一些**_StringUtil_**类中的帮助函数:

不用太担心理解这些方法的内容。你真正需要知道的是:applyECDSASig接受发送者的私钥和字符串输入,对其进行签名并返回一个字节数组。verifyECDSASig接受签名、公钥和字符串数据,并根据签名是否有效返回true或false。getStringFromKey从任何密钥返回编码字符串。

现在让我们在Transaction类中利用这些签名方法,通过添加generateSignature()verifiySignature()方法:

实际上,你可能希望签名更多信息,例如使用的输出/输入和/或时间戳(现在我们只签署了最少的内容)。

当新交易添加到块中时,矿工将验证签名。

我们还可以在检查区块链的有效性时检查签名。

3.测试钱包和签名:

现在我们已经完成了一半的工作。在NoobChain类中,让我们添加一些新变量并替换我们的main方法的内容:

一定要记得将Bouncy Castle添加为安全提供程序。

我们创建了两个钱包,walletA_和_walletB,然后打印了_walletA_的私钥和公钥。生成一个_Transaction_并使用_walletA_的私钥对其进行签名。F̶i̶n̶a̶l̶l̶y̶ ̶w̶e̶ ̶c̶r̶o̶s̶s̶e̶d̶ ̶o̶u̶r̶ ̶f̶i̶n̶g̶e̶r̶s̶ ̶a̶n̶d̶ ̶h̶o̶p̶e̶d̶ ̶e̶v̶e̶r̶y̶t̶h̶i̶n̶g̶ ̶w̶o̶r̶k̶e̶d̶ ̶o̶u̶t̶.̶

你的输出应该类似于:

“Is signature verified”应该为true。希望如此。

现在是时候夸夸自己了。现在我们只需要创建/验证输出和输入,然后将交易存储在区块链中。

4.输入和输出1:加密货币的所有权...

要拥有1个比特币,你必须收到1个比特币。总账不会真正地向你添加1个比特币,并从发送方减去1个比特币,发送方会引用他/她先前收到的1个比特币,然后创建一个交易输出,显示向你的地址发送了1个比特币。(交易输入是对先前交易输出的引用)。

你的钱包余额是寄到你地址的所有未花费交易输出的总和。

从现在开始,我们将遵循比特币的惯例,将未花费的交易输出称为UTXO

因此,让我们创建一个TransactionInput类:

此类将用于引用尚未花费的TransactionOutputs。transactionOutputId将用于查找相关的TransactionOutput,从而允许矿工检查你的所有权。

和一个TransactionOutputs类:

交易输出将显示从交易中发送到每个方的最终金额。这些在新交易中作为输入引用时,作为你有币发送的证明。

5.输入和输出2:处理交易...

区块中可能收到许多交易,而区块链可能非常长,处理新交易可能需要很长时间,因为我们必须查找和检查其输入。为了避免这种情况,我们将保留所有未花费的交易的额外集合,这些交易可以用作输入。在我们的NoobChain类中添加所有UTXOs的集合:

HashMaps允许我们使用键查找值,但你需要导入java.util.HashMap;

好的,现在到了真正的问题...

让我们将所有内容组合起来,使用我们的Transaction类中的processTransaction布尔方法来处理交易:

我们还添加了一个getInputsValue浮点方法。

...在此方法中,我们执行一些检查以确保交易有效,然后收集输入并生成输出(有关更多信息,请参见代码中的注释行)。

重要的是,在最后,我们从我们的_UTXO's列表中丢弃Inputs,这意味着transaction output只能用作一次输入...因此必须使用输入的全部价值,因此发送方将“change”退回给自己。

红色箭头是输出。请注意,绿色输入是对先前输出的引用。

最后,让我们更新我们的钱包:

  • 通过循环遍历UTXOs列表并检查是否transaction output是我的,来收集我们的余额
  • 为我们生成交易...

可以随意向你的钱包添加一些其他功能,例如记录你的交易历史记录。

6.将交易添加到我们的块中:

现在我们有了一个工作的交易系统,我们需要将其实现到我们的区块链中。我们应该用一个交易的ArrayList替换我们块中无用的数据。然而,单个块中可能有数千个交易,包含在我们的哈希计算中太多了...但是不用担心,我们可以使用交易的默克尔根(你可以在此soon快速阅读默克尔树)。

让我们添加一个帮助方法在StringUtils中生成merkleroot:

  • 我们很快会用实际的Merkle根替换这个方法,但是现在这个方法也可以使用。

现在让我们实现我们的块(Block)_类_更改:

请注意,我们还更新了块构造函数,因为我们不再需要传入字符串数据,并在计算哈希方法中包含了Merkle根。

我们的addTransaction _boolean_方法将添加交易,仅当成功添加交易时才返回true。

太好了,我们需要在我们的区块链上进行交易的每个组件现在都已经实现了!

7. 大结局(起初没有比特币):

我们应该测试向钱包发送和接收硬币,并更新我们的区块链有效性检查。但首先,我们需要一种方法将新硬币引入混合物中。有许多创建新硬币的方法,例如在比特币区块链上:矿工可以将一个交易包含在每个挖掘的区块中,作为奖励。不过,现在我们将在第一个块(创世块)中释放我们希望拥有的所有硬币。就像比特币一样,我们将硬编码创世块。

让我们更新NoobChain类,使其具备以下所有内容:

  • 创世块,将100个Noobcoins发布到walletA。
  • 更新的链有效性检查,考虑交易。
  • 一些测试交易,以确保一切正常运行。

这些都是一些很长的方法… 😮

我们的输出应该如下所示:

现在,钱包能够安全地在你的区块链上发送资金,前提是他们有资金可以发送。这意味着你拥有自己的本地加密货币*。

你已经完成了区块链上的交易!

你已经成功地创建了自己的加密货币(有点像!)。你的区块链现在:

  • 允许用户使用'new Wallet();'创建钱包
  • 使用椭圆曲线加密为钱包提供公钥和私钥。
  • 通过使用数字签名算法来证明所有权,保护资金的转移。
  • 最后,允许用户使用'Block.addTransaction(walletA.sendFunds(walletB.publicKey,20));'在你的区块链上进行交易。
  • 你可以在Github上下载这些项目文件。


译自:https://medium.com/programmers-blockchain/creating-your-first-blockchain-with-java-part-2-transactions-2cdac335e0ce

版权声明:本文内容由TeHub注册用户自发贡献,版权归原作者所有,TeHub社区不拥有其著作权,亦不承担相应法律责任。 如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

点赞(0)
收藏(0)
阿波
The minute I see you, I want your clothes gone!

评论(0)

添加评论