与其他加密货币不同,Grin不使用地址。要发送或接收Grin,发件人和收件人必须在彼此之间来回发送信息。
方法是通过文件共享。此文件可以在几秒,几天,几年或其他任何时间段内共享。
让我们深入探究一下这个Grin事务文件的内容。
探索GRIN事务文件
假设你想给Bob发送10.25个GRIN,你们两个想通过一个文件交换这个交易的必要信息。运行:
grin wallet send -m file -d my_grin_transaction.tx 10.25
这会生成一个名为my_grin_transaction.tx的文件,您需要将该文件发送给Bob,以便他可以向您提供其响应文件。
让我们打开这个my_grin_transaction.tx文件。
{
“num_participants”: 2,
“id”: “56709cfe-8584-4a02-b94e-bb7e79cfae66”,
“tx”: {
“offset”: [62, 48, 100, 178, 。。。],
“body”: {
“inputs”: [{
“features”: “Plain”,
“commit”: [8, 95, 99, 251, 。。。]
}],
“outputs”: [{
“features”: “Plain”,
“commit”: [8, 216, 52, 10, 。。。],
“proof”: [13, 107, 82, 188, 。。。]
}],
“kernels”: [{
“features”: “HeightLocked”,
“fee”: 8000000,
“lock_height”: 22023,
“excess”: [0, 0, 0, 0, 。。。],
“excess_sig”: [0, 0, 0, 0, 。。。]
}]
}
},
“amount”: 10250000000,
“fee”: 8000000,
“height”: 22023,
“lock_height”: 22023,
“participant_data”: [{
“id”: 0,
“public_blind_excess”: [2, 66, 。。。],
“public_nonce”: [2, 102, 。。。],
“part_sig”: null,
“message”: null,
“message_sig”: null
}]
}
按照顺序,我们有:
· num_participants:此交易涉及的人数。 Alice到Bob意味着2个参与者。 Alice到Bob和Charlie意味着有3个参与者。
· id:此事务的唯一标识符。这允许我们在从Bob接收文件时跟踪事务。
接下来,我们有一个tx对象,简称事务。这包括:
1. 内核偏移量(此处命名为offset)。
2. 一个body对象,包含有此事务中使用的输入,此事务的输出(当前,只是我们的更改)和事务内核。
让我们深入研究这些。
· offset:内核偏移量。这是一个随机值,我们选择从我们的盲目因子中减去,以使任何人更难以在区块链上跟踪此交易。
此tx对象中的下一个是输入对象。此对象包含有关我们在此事务中花费的输出的信息。
“inputs”: [{
“features”: “Plain”,
“commit”: [8, 95, 99, 251, 。。。]
}],
· feature:在此示例中,我们正在花费的输出功能(此事务的输入)设置为“Plain”。此功能变量可以是“Plain”或“Coinbase”。
CoinBase输出是从挖掘奖励中生成的输出。一个普通的输出仅仅意味着它不是一个coinbase输出。
· commit:我们要花费的输出。Grin的输出是Pedersen承诺。要了解这些是如何工作的,您可以阅读Grin wiki。
在tx对象中,我们继续到输出数组。
“outputs”: [{
“features”: “Plain”,
“commit”: [8, 216, 52, 10, 。。。],
“proof”: [13, 107, 82, 188, 。。。]
}],
你会注意到这个输出数组已经有了我们交易的输出。如果我们花费10.25 Grin,我们在这个事务中只使用一个输入,那么该输入至少包含10.25 Grin。例如如果此输入包含20 Grin,则此事务还需要输出以将9.75 Grin发送回给我们!
Grin的独特之处在于Bob需要参与任何输出,但由于我们尚未将此文件发送给Bob,我们还没有准备好创建交易的那部分。我们的更改输出与Bob无关,这就是为什么我们已经能够计算我们的更改输出。
除了feature和commit,此输出还包含一个证明。这是一个输出的范围证明,它证明了该输出中的Grin量是非负的。范围证明允许我们以加密方式证明输出是非负的,而不会显示实际输出的内容。
此事务文件的下一部分是内核数组。
“kernels”: [{
“features”: “HeightLocked”,
“fee”: 8000000,
“lock_height”: 22023,
“excess”: [0, 0, 0, 0, 。。。],
“excess_sig”: [0, 0, 0, 0, 。。。]
}]
事务内核也从features变量开始。这一部分可能有点令人困惑:正如我前面解释的,您看到的任何输出的features变量要么是“plain”,要么是“coinbase”。但在事务内核中,features变量可以是“plain”、“coinbase”或“heightlocked”。
事务内核中的三种不同“特性”:Coinbase,Plain和HeightLocked
“plain”事务意味着lock_height为0。换句话说,一旦将此事务广播到网络,节点就可以开始挖掘它。一旦挖掘到任何Grin事务,就可以使用其输出。相反,HeightLocked事务意味着在某个块编号之前无法挖掘事务。
挖掘后的输出将具有“plain”或“Coinbase”的特征,如上所述,因为它在挖掘之前可能已经被HeightLocked。
“outputs”: [{
“features”: “Plain”,
“commit”: [8, 216, 52, 10, 。。。],
“proof”: [13, 107, 82, 188, 。。。]
}],
接下来,事务内核还包含fee和lock_height,内核过剩(此处表示为多余)以及事务的签名(此处表示为excess_sig)。
当我们在收到Bob的响应文件之前,我们还不能计算excess和excess_sig的值。这就是为什么这些数组都用0填充的原因。
在tx对象之后,我们有剩下的一些字段:
“amount”: 10250000000,
“fee”: 8000000,
“height”: 22023,
“lock_height”: 22023,
“participant_data”: [{
“id”: 0,
“public_blind_excess”: [2, 66, 。。。],
“public_nonce”: [2, 102, 。。。],
“part_sig”: null,
“message”: null,
“message_sig”: null
}]
· amount:转移的Grin量,为原子单位1 nanoGrin的倍数。nanoGrin是Grin的十亿分之一。只有发送人和接收人才会看到此金额。
· fee:交易的采矿费,也是1 nanoGrin的倍数。
· height:创建此事务文件的块编号。
· lock_height:此事务的输出变得可用的块编号。在这种情况下,您会注意到lock_height等于height变量,这意味着可以立即挖掘此事务。
接下来,我们有一个participant_data数组。
“participant_data”: [{
“id”: 0,
“public_blind_excess”: [2, 66, 。。。],
“public_nonce”: [2, 102, 。。。],
“part_sig”: null,
“message”: null,
“message_sig”: null
}]
这包含事务参与者之间来回传递的信息。到目前为止,这只包含我们的数据,因为我们还没有与Bob共享这个文件。
· id:此交易中参与者的ID。ID为0对应于交易的发送人,即我们。
· public_blind_excess:对我们致盲因素总和的承诺。
· public_nonce:对我们的随机数的承诺。这用于构建事务签名。
· part_sig:我们的部分签名是空的,因为在从Bob接收到数据之前,我们无法创建它。
· message:可以添加到您的交易中的额外“消息”。如果使用-g标志创建此文件并在之后添加任意字符串,则此消息将显示在此处。
注意:当人们通常引用Grin交易的“message”时,它们通常表示交易费(如果有的话)和lock_height(如果有的话)。这个额外的“message”字段是完全独立的:您可以添加一个字符串发送给Bob,反之亦然,它永远不会在链上发布。
· message_sig:我刚才提到的额外“message”字段是由你所有盲目因素的总和签名的。该签名放在这里,Bob可以通过使用您对所有致盲因素总和的承诺来验证该消息。Bob收到此文件后,可以将自己的额外message和message_sig添加到文件中。我们可以用同样的方式验证他的信息。
我们将此文件发送给Bob,并等待他的响应文件。
Bob的响应文件
Bob使用以下命令在他的Grin客户端中接受此文件:
grin wallet receive -I my_grin_transaction.tx
此命令为Bob生成一个my_grin_transaction.tx.response文件,Bob将发送回我们。
让我们打开这个文件。
{
“num_participants”: 2,
“id”: “56709cfe-8584-4a02-b94e-bb7e79cfae66”,
“tx”: {
“offset”: [62, 48, 100, 。。。],
“body”: {
“inputs”: [{
“features”: “Plain”,
“commit”: [8, 95, 99, 。。。]
}],
“outputs”: [{
“features”: “Plain”,
“commit”: [8, 206, 65, 。。。],
“proof”: [36, 101, 181, 。。。]
}, {
“features”: “Plain”,
“commit”: [8, 216, 52, 。。。],
“proof”: [13, 107, 82, 。。。]
}],
“kernels”: [{
“features”: “HeightLocked”,
“fee”: 8000000,
“lock_height”: 22023,
“excess”: [0, 0, 0, 。。。],
“excess_sig”: [0, 0, 0, 。。。]
}]
}
},
“amount”: 10250000000,
“fee”: 8000000,
“height”: 22023,
“lock_height”: 22023,
“participant_data”: [{
“id”: 0,
“public_blind_excess”: [2, 66, 3, 。。。],
“public_nonce”: [2, 102, 201, 。。。],
“part_sig”: null,
“message”: null,
“message_sig”: null
}, {
“id”: 1,
“public_blind_excess”: [3, 99, 72, 。。。],
“public_nonce”: [3, 246, 48, 。。。],
“part_sig”: [90, 35, 157, 。。。],
“message”: null,
“message_sig”: null
}]
}
我们可以看到,这个文件是我们发送给Bob的所有内容,还有他自己添加的一些数据。
在参与者数据数组中,我们看到id为1(Bob)的参与者的新条目。 Bob加上他对他的盲目因素的承诺,以及他对他的nonce的承诺,以及最后他的部分签名。
完成交易
当我们收到Bob的响应文件时,我们运行以下命令来完成事务:
grin wallet finalize -i my_grin_transaction.tx.response
我们实际上并没有看到填充的缺失部分 - 相反,我们看到:
现在我们拥有了Bob创建输出并将其添加到输出数组所需的所有信息。在背后,我们的GRIN客户机填充丢失的部分(比如excess和excess_signature),将这些数据序列化为一个字节数组,并通过GRIN网络发送数据以进行验证。
很快,这个GRIN交易将被挖掘,Bob将收到他的10.25 GRIN,我们将收到我们的零钱。
『本文转载自网络,版权归原作者所有,如有侵权请联系删除』