[Done][doc] Chinese Translation ()

* Create grin4bitcoiners_ZH-CN

* Rename grin4bitcoiners_ZH-CN to grin4bitcoiners_ZH-CN.md

* Create contract_ideas_ZH-CN.md

Chinese translation

* Create coinbase_maturity_ZH-CN.md

* Create contracts_ZH-CN.md

* Create stratum_ZH-CN.md

* Create switch_commitment_ZH-CN.md

* Create table_of_contents_ZH-CN.md

* Update contracts_ZH-CN.md

* Update contracts.md

* Chinese Translation added

* Update coinbase_maturity_ZH-CN.md

* Update coinbase_maturity.md

* Update switch_commitment_ZH-CN.md

* Update switch_commitment.md

* Update switch_commitment_ZH-CN.md

* Update switch_commitment_ZH-CN.md

* Update contracts_ZH-CN.md

* Update coinbase_maturity_ZH-CN.md

* Update table_of_contents_ZH-CN.md

* Create table_of_contents.md

* Delete table_of_contents_.md

* Update switch_commitment_ZH-CN.md

* Update stratum_ZH-CN.md

* Update stratum.md

* Update coinbase_maturity_ZH-CN.md

* Update coinbase_maturity_ZH-CN.md

* Update contracts_ZH-CN.md

* Update switch_commitment_ZH-CN.md
This commit is contained in:
Leo Young 2020-01-08 23:53:47 +08:00 committed by Quentin Le Sceller
parent 81a2bbd5e8
commit a73a54a10e
12 changed files with 1339 additions and 6 deletions

View file

@ -1,6 +1,6 @@
# The Coinbase Maturity Rule (aka Output Lock Heights)
*Read this in other languages: [Korean](coinbase_maturity_KR.md).*
*Read this in other languages: [Korean](coinbase_maturity_KR.md), [简体中文](coinbase_maturity_ZH-CN).*
Coinbase outputs (block rewards & fees) are "locked" and require 1,440 confirmations (i.e 24 hours worth of blocks added to the chain) before they mature sufficiently to be spendable. This is to reduce the risk of later txs being reversed if a chain reorganization occurs.

View file

@ -0,0 +1,129 @@
# Coinbase 期限规则(亦即"输出锁定高度"
*阅读其它语言版本: [English](coinbase_maturity.md), [Korean](coinbase_maturity_KR.md).*
coinbase 输出(区块奖励和手续费)为“锁定”,需要有 1440 个确认(也就是经过约 24 小时在链上加上区块)才能到期花费。这是为了防止之后如果出现链上回滚的情况下,降低撤销之后交易的风险。
比特币也有类似设计,挖矿奖励需要经过 100 个确认比特币出块时间为十分钟Grin 出块时间为 60 秒)方可花费。
Grin 在交易池和区块验证管道中强行使用 coinbase 期限。包含花费 coinbase 输出的输入交易只有在 coinbase 完全到期(根据目前链高度和生成 coinbase 输出区块的高度)后才可以添加到交易池。同理,如果区块中包含花费 coinbase 输出的输入交易,根据含有输入的区块高度和最初生成 coinbase 输出区块的高度,若 coinbase 未到期,则区块无效。
期限规则*仅*适用于 coinbase 输出。普通交易输出的有效锁定高度为零。
输出包括 -
* 特征(目前为 coinbase 和 非 coinbase
* 秘诺 (commitment) `rG+vH`
* 范围证明
若要花费普通交易输出,需要满足两个条件。我们需要证明此输出之前并未花费,并证明输出所有权。
Grin 交易包含下列信息 -
* 一组输入。每个输入对应一个之前花费的输出。
* 一组新的输出包括 -
* 值 `v` 和盲因子(密钥) `r` 以曲线相乘,并算出总和 `rG+vH`
* 表明 `v` 并非为负数的范围证明。
* 公开的明确交易费。
* 一个签名。用额外盲因子值(全部输出加交易费减去输出)并将其用作私钥来计算。
我们可以寻找目前输出组中的秘诺来证明输出未花费。输出组具有权威性;若某个输出存在于输出组中,我们便知晓其并未花费。若某输出在输出组中不存在,我们便知道这一输出要么不存在,要么就是之前存在但现在已被花费(我们不会确知是哪种情况)。
可通过验证交易签名来证明所有权。*只有*交易之和为零*且*知道 `v``r` 的情况下方可对交易签名。
知道 `v``r` 便可(通过秘诺)特别确认输出。而且可以通过验证原始 coinbase 交易上的签名来证明输出所有权。
Grin 不允许在输出组中重复的秘诺同时存在。但只要输出被花费,就会从输出组中移除,且将复制的秘诺重新添加到输出组。不推荐这一操作,但 Grin 必须在不违反网络共识的情况下解决这一问题。
几个因素会让这一情况变复杂 -
1. 两个区块可获得相同奖励,尤其是空块的情况下,但有转账费的非空块也有可能。
1. 非 coinbase 输出可与 coinbase 有相同值。
1. 矿工可重复使用私钥(但不建议)。
Grin 不允许在输出组中重复的秘诺同时存在。但输出组特指特别的链分叉。有可能在不同并发分叉同时存在重复的*类似的* 秘诺。这些重复的秘诺可能到期“锁定高度”不同,且在不同分叉中可花费。
* 区块 B<sub>1</sub> 上确认的输出 O<sub>1</sub>,在高度 h<sub>1</sub>(分叉 f<sub>1</sub> 上)可花费
* 区块 B<sub>2</sub> 上确认的输出 O<sub>1</sub>',在高度 h<sub>2</sub>(分叉 f<sub>2</sub> 上)可花费
复杂之处是根据分叉链上区块含有输入 I<sub>1</sub>I<sub>1</sub> 就可花费 O<sub>1</sub> 或 O<sub>1</sub>'。特别是 I<sub>1</sub> 有可能在一条分叉上而不是在另一个分叉上的特定区块高度有效。
换言之,一个秘诺有可能指向多个输出,所有输出可能有不同区块高度。我们*还得*必须确保正确识别确实花费了哪个输出,还有根据目前的链状态正确执行 coinbase 到期规则。
按 coinbase 到期规则在指定区块高度锁定的 coinbase 输出无法独自识别,无法以秘诺单独安全花费 -
* coinbase 输出的来源区块
鉴于此我们可验证区块高度并推理出输出的“锁定高度”1000 以上区块)。
## 全存档节点
全存档节点就是个简单任务,用来识别输出来自哪个区块。全存档节点储存以下数据 -
* 链上所有区块的全区块数据
* 区块所有输出数据
我们可以轻易查看链上所有区块,找到含有自己关注的输出区块。
问题是我们需要用没有全区块数据的节点怎么办(修剪节点、非全存档节点)。[哪种节点?]
如果我们没有全区块数据怎么验证 coinbase 期限?
## 非存档节点
[术语?这些节点术语是什么?]
节点不一定有全区块数据。修剪节点或许只储存以下数据(请参考修剪文档)-
* 区块头部链。
* 所有交易内核。
* 所有未花费输出。
* 输出 MMR 和范围证明 MMR
数据组经过极简处理,那么如何知道一个输出来自哪个区块?
我们知道了多个输出(多个分叉、潜在不同锁定高度)可以有*相同*秘诺,为具体识别花费的输出还需要在输出中提供哪些额外信息?
进一步讲 - 我们是否可以在不存取所有输出数据的情况下完成识别?是否可以只使用输出 MMR
### 推荐方法
维护一个索引映射秘诺来定位输出 MMR。
如果对指定的秘诺索引中没有项目,或在输出 MMR 中没有项目,即可知道输出不可花费(要么之前已花费或从未存在)。
如果在输出 MMR 中找到一个项目,便知道在输出组中有可花费输出存在,但我们不知道是否正确。我们不知道其是否为 coinbase 输出,以及区块来源高度。
如果输出 MMR 中保存的哈希值包括秘诺和输出特征,而且我们需要输入提供秘诺和特征,那便可进行下步验证 -
* 输出存在于输出 MMR 中(根据秘诺),和
* MMR中的哈希值与输入中的输出数据匹配
有了这一步就可以知道输出是否为 coinbase 输出,还是基于指定功能的普通交易输出。除非输入特征与原始输出特征匹配,否则哈希值会不匹配。
普通的非 coinbase 输出就到此为止。我们知道输出目前可花费,无需再查看锁定高度。
对于 coinbase 输出,可以继续验证区块高度和期限。验证过程需要确认产生输出的区块。我们无法确定区块本身,但需要输入来指定区块(哈希值),之后可以根据区块头部的默克尔根证明区块完全准确。
[待确定 - 默克尔证明概览及如何根据区块头部默克尔根利用这些证明包容性]
总结 -
输出 MMR 根据 `秘诺|特征`(只有秘诺不够)储存输出哈希值。
不需要在生成输出哈希值中包含范围证明。
若要花费输出,我们需要 -
* `r``v` 构建秘诺和证明所有权
输出必须提供 -
* 秘诺(查询 MMR 中的输出)
* 输出特征(依赖`特征|秘诺`的输出 MMR 哈希值)
* 在原始区块中显示包含输出的默克尔证明
* 原始区块的区块哈希
* [待确定 - 根据默克尔证明维护索引?]
通过秘诺和特征确定正确的输出目前是否未花费。通过区块和输出特征确定锁定高度(如有)。

289
doc/contract_ideas_ZH-CN.md Normal file
View file

@ -0,0 +1,289 @@
# Contract Ideas
## Atomic Swaps
"On another chain, Igno sends coins to me that I can only redeem by revealing a hash preimage (which he knows, I don't). On the MW chain we do this exchange so that Igno can take my coins by revealing the preimage. When he takes his coins, he reveals it, enabling me to take my coins.
Note that this requires both chains to support hash preimages: all Bitcoin script derivatives, Ethereum, and now Mimblewimble support this." - Andrew Poelstra
- https://lists.launchpad.net/mimblewimble/msg00022.html
"At the [Stanford BPASE Conference](https://cyber.stanford.edu/blockchainconf) I gave a talk where I briefly mentioned that it was possible to do atomic swaps with no preimages at all."
"Ok, so algebraically how do atomic swaps work in a scriptless way? Suppose I'm trying to send Igno 1 MW1 coin on one chain in exchange for MW2 coin on another. Then:
1. As before we send our coins to 2-of-2 outputs on each chain. Each of us refuses to move our coin until the other has given us a locktimed "refund" transaction; we set our locktimes so I can retrieve my coin before he can retrieve his.
(So far this is the same as the classic Bitcoin atomic swap by Tier Nolan [3]; the difference in locktimes is because during part of the protocol Igno can take his coins but I can't yet take mine, so I want to be sure he can't do this and simultaneously back out. This way ff he takes the coins, I can take mine, but if he backs out then I've long since backed out, and these are his only possibilities.)
2. Igno and I construct transactions that move the locked coins to their final destinations. We agree on the kernels and signature nonces, and in particular on signature challenges e and e'.
3. Igno sends me a "conversion" keys sconv which satisfies
sconv * G = R - R' + eP - e'P'
4. I sign the MW1 transaction giving Igno his coin and send him the signature.
5. Now Igno signs the MW1 transaction, giving himself his coin. To do this he adds his signature
s = k + xe
where `k` is his secret nonce and `x` his secret key are values I don't know but which have been forced on him (their public counterparts are committed in the hash `e`).
6. I then compute s' = s + sconv, which is Igno's half of the MW2 transaction, and am able to take my coins.
Observe that I can verify sconv is legitimate in step (3), and that this verification equation is sufficient to force my computed s' to verify iff s does. Observe further that once the two signatures are public, anybody can compute "sconv" as s' - s, which gives us two properties:
1. It assures that sharing sconv does not harm the security of anyone's keys, since it's publicly computable anyway by anybody who has access to the final signatures.
2. This scheme is deniable, since it depends on Igno giving me sconv before I knew s', which neither of us can prove. In other words either of us could fabricate the above transcript for any pair of signatures.
My thinking is that this atomic linking of multiple transactions is a fairly general primitive that can be used to link lightning channels etc, and that we might not need hash preimages for this after all." - Andrew Poelstra
- https://lists.launchpad.net/mimblewimble/msg00036.html
"So the setting is that Igno holds some coins on the MW altchain, by knowing the blinding factor rI0 in an output rI0*G+a*H of a coins, while Andrew holds some coins on an MW' sidechain, by knowing the blinding factor rA0' in an output rA0'*G+a'*H of a' coins, and they'll like to swap these. Note that we require MW and MW' to use the same curve and generators G,H. We adopt a notation for quantities that start with a lower case letter for its role, followed by an uppercase letter for who
picked or computed it, a serial number, and an optional ' to distinguish the two chains.
For simplicity we ignore change outputs and fees. As Igno has pointed out, fees must also be listed and signed in the kernels, to prevent relays and miners from hijacking fees (a relay could take half the fee for itself by adding an output and kernel, while a miner could avoid the coinbase locktime on fees).
The plan is to
1) prepare transfers from original outputs into 2-of-2 outputs for holding
2) prepare locktimed refunds from the 2-of-2 outputs in case the swap fails
3) prepare the swapping transactions from the 2-of-2 outputs
4) verifiably link Igno's signatures for the transactions in 3)
5) let Igno obtain his swapping coins on MW'
6) let Andrew obtain his swapping coins on MW
Let's see how each step works in detail.
1) prepare transfers from original outputs into 2-of-2 outputs for holding
input blinding/output kernel nonce/challenge signature
MW Igno rI0*G+a*H rI1 rI1-rI0 kI1 sI1=kI1+e1*(rI1-rI0)
MW Andrew rA1 rA1 kA1 sA1=kA1+e1*rA1
MW tx1 (rI1+rA1)*G+a*H rI1+rA1-rI0 e1=H(kI1*G+kA1*G) s1=sI1+sA1
MW'Igno rI1' rI1' kI1' sI1'=kI1'+e1'*rI1'
MW'Andrew rA0'*G+a'*H rA1' rA1'-rA0' kA1' sA1'=kA1'+e1'*(rA1'-rA0')
MW'tx1' (rI1'+rA1')*G+a*H rI1'+rA1'-rA0' e1'=H(kI1'*G+kA1'*G) s1'=sI1'+sA1'
We assume that all commits to blinding factors and nonces are shared between them.
Both parties must also construct range proofs for the 2-of-2 outputs,
details of which we ignore.
The constituent signatures sI1,sA1,sI1', and sA1' are not yet shared,
since locking up funds is only safe if refunds are assured for a failing swap.
2) prepare locktimed refunds from the 2-of-2 outputs in case the swap fails
input output kernel nonce/challenge signature
MW Igno rI2*G+a*H rI2-rI1 kI2 sI2=kI2+e2*(rI2-rI1)
MW Andrew -rA1 kA2 sA2=kA2+e2*-rA1
MW tx2 (rI1+rA1)*G+a*H rI2-rI1-rA1 e2=H(L||kI2*G+kA2*G) s2=sI2+sA2
The constituent signatures sI2 and sA2 are shared and verified by both parties.
Transaction tx2' on MW' is prepared similarly, but with a somewhat earlier locktime L'.
Now that it's safe to share the constituent signatures sI1,sA1,sI1', and sA1',
they are summed into signatures s1 for tx1 and s1' for tx1'.
This step could be slightly simplified by picking rI2==rI1, and
omitting kI2 and sI2, taking s2=sA2. (Andrew remarked on this "it's
really easy to create footguns in MW reusing keys. Though I think in
this case it's actually safe, you're just directly reversing the first
transaction.")
When both tx1 and tx1' are confirmed, we can proceed with step 3).
If any remaining steps fail to complete for any reason,
then either party can issue their refund transaction.
3) prepare the swapping transactions from the 2-of-2 outputs
input output kernel nonce/challenge signature
MW Igno -rI1 kI3 sI3=kI3+e3*-rI1
MW Andrew rA3*G+a*H rA3-rA1 kA3 sA3=kA3+e3*(rA3-rA1)
MW tx3 (rI1+rA1)*G+a*H -rI1+rA3-rA1 e3=H(kI3*G+kA3*G) s3=sI3+sA3
input output kernel nonce/challenge signature
MW'Igno rI3'*G+a'*H rI3'-rI1' kI3' sI3'=kI3'+e3'*(rI3'-rI1')
MW'Andrew -rA1' kA3' sA3'=kA3'+e3'*-rA1'
MW'tx3' (rI1'+rA1')*G+a'*H rI3'-rI1'-rA1' e3'=H(kI3'*G+kA3'*G) s3'=sI3'+sA3'
At this point the atomic swap is reduced to the exchange of signature
s3' for s3. We need the revelation of s3' by Igno to reveal s3 to Andrew, which is
achieved by having Andres know the difference between sI3 and sI3'.
4) verifiably link Igno's signatures for the transactions in 3)
Igno reveals sconv = sI3-sI3' = kI3+e3*-rI1 - (kI3'+e3'*(rI3'-rI1')) and Andrew verifies that sconv*G = kI3*G-e3*rI1*G - kI3'*G+e3'*(rI3'-rI1')
5) let Igno obtain his swapping coins on MW'
Appearance of tx3' on MW' reveals s3'
6) let Andrew obtain his swapping coins on MW
Andrew computes s3 = sI3+sA3 = sconv+sI3'+sA3=sconv+s3'-sA3'+sA3 and issues tx3" - John Tromp
- https://lists.launchpad.net/mimblewimble/msg00047.html
## Secure Transaction Exchange
## LNs
"I talked with Thaddeus Dryja just now and showed him down to do locktime and hash preimages, and he said this should be sufficient to create HTLC's (hash-timelocked lightning channels), so I guess this gives us full lightning
support in principle." - Andrew Poelstra
- https://lists.launchpad.net/mimblewimble/msg00022.html
- https://lists.launchpad.net/mimblewimble/msg00029.html - bunch of replies, nothing super specific
"Recently I've found a different construction that behaves much more like
a hash preimage challenge, and this can actually be used for Lightning.
Further, it supports reblinding, so you can learn a preimage but hide
which one you're looking for. (Ethan, one might actually overlap with
TumbleBit, sorry :)).
It works like this. We'll treat x -> xG as a hash function, so x is the
preimage of xG. There are two separate but related things I can do: (a)
construct a signature which reveals the preimage; or (b) create a
"pre-signature" which can be turned into a signature with the help of
the preimage.
Here's how it works: suppose I send xG to Rusty and he wants to send
me coins conditional on my sending him x. Lets say I have key P1 and
nonce R1; he has key P2 and nonce R2. Together we're going to make a
multisignature with key P1 + P2 and Rusty is going to set things up
so that I can't complete the signature without telling him x.
Here we go.
0. We agree somehow on R1, R2, P1, P2.
1. We can both compute a challenge e = H(P1 + P2 || R1 + R2 || tx).
2. I send s' = k1 - x - x1e, where R1 = k1G and P1 = x1G. Note he
can verify I did so with the equation s'G = R1 - xG - eP1.
3. He now sends me s2 = k2 - x2e, which is his half of the multisig.
4. I complete the sig by adding s1 = k1 - x1e. The final sig is
(s1 + s2, R1 + R2).
Now as soon as this signature gets out, I can compute x = s1 - s'.
* * *
Ok, pretty nifty. But now suppose Rusty wants to receive coins conditioned
on him revealing x, say, because he's a middle hop in a Lightning channel.
You might think he could act the same as I did in step (2), computing
s' = k1 - x - x1e, but actually he can't, because he doesn't know x himself!
All good. Instead he does the following.
To put names on things, let's say he's taking coins from Tadge. The
protocol is almost the same as above.
0. They agree somehow on R1, R2, P1, P2. Tadge's key and nonce are
R1 and P1, but there's a catch: P1 = x1G as before, but now
R1 - xG = k1G. That is, his nonce is offset by k1G.
1. They can both compute a challenge e = H(P1 + P2 || R1 + R2 || tx).
2. Tadge sends the "presignature" s' = k1 - x1e. Rusty can verify this
with the equation s'G = R1 - xG - eP1.
3. Now whenever Rusty obtains x, he can compute s1 = s' - x, which is
Tadge's half of the final signature.
4. Rusty computes s2 himself and completes the signature.
* * *
Ok, even cooler. But the real Rusty complained about these stories, saying
that it's a privacy leak for him to use the same xG with me as he used with
Tadge. In a onion-routed Lightning channel, this xG-reuse would let all
any two participants in a path figure out that they were in one path, if
they were colluding, even if they weren't directly connected.
No worries, we can fix this very simply. Rusty chooses a reblinding factor
rG. I give him x, as before, but what Tadge demands from him is (x + r).
(I give xG to Rusty as a challenge; he forwards this as xG + rG to Tadge.)
Since Rusty knows r he's able to do the translation. The two challenges
appear uniformly independently random to any observers.
* * *
Let's put this together into my understanding of how Lightning is supposed
to work. Suppose Andrew is trying to send coins to Drew, through Bob and
Carol. He constructs a path
A --> B --> C --> D
where each arrow is a Lightning channel. Only Andrew knows the complete
path, and is onion-encrypting his connections to each participant (who
know the next and previous participants, but that's it).
He obtains a challenge T = xG from D, and reblinding factors U and V
from B and C. Using the above tricks,
1. A sends coins to B contingent on him learning the discrete logarithm
of T + U + V.
2. B sends coins to C contingent on him learning the discrete logarithm
of T + V. (He knows the discrete log of U, so this is sufficient for
him to meet Andrew's challenge.)
3. C sends to D contingent on him learning the discrete log of T, which
is D's original challenge. Again, because C knows the discrete log
of V, this is sufficient for her to meet B's challenge.
The resulting path consists of transactions which are signed with single
uniformly random independent Schnorr signatures. Even though they're all
part of an atomic Lightning path.
* * *
Note that the s' values need to be re-communicated every time the transaction
changes (as does the nonce). Because it depends on the other party's nonce,
this might require an additional round of interaction per channel update.
Note also that nothing I've said depends at all on what's being signed. This
means this works just as well for MimbleWimble as it would for Bitcoin+Schnorr
as it would for Monero (with a multisig ring-CT construction) as it would
for Ethereum+Schnorr. Further, it can link transactions across chains." - Andrew Poelstra
- https://lists.launchpad.net/mimblewimble/msg00086.html
## Lock-time
"Suppose that I want to send a Bitcoin to Igno conditioned on him revealing a hash preimage. He sends me the hash e. We do the following.
1. I send the coins to a multisignature output controlled by the 2-of-2 of both of us, though I don't complete my half of signing the resulting excess value.
2. Igno produces a transaction that sends the coins back to me, locktimed to some time in the future; we complete this transaction. (Well, Igno does his part and I can do mine later.)
2a. I broadcast the first transaction, so there are coins on the chain that can be spent only with both our our consents.
3. I produce a transaction which sends these coins to Igno. With the excess I sign the hash e, leave the locktime blank, and do my part to sign.
At this point Igno can either (a) complete the transaction, doing his part of the signature and revealing the preimage to the network, including me; or (b) do nothing, in which case I'll take the coin back after the lock time." - Andrew Poelstra
- https://lists.launchpad.net/mimblewimble/msg00022.html
- https://lists.launchpad.net/mimblewimble/msg00025.html
- https://lists.launchpad.net/mimblewimble/msg00034.html
- https://lists.launchpad.net/mimblewimble/msg00048.html
- https://lists.launchpad.net/mimblewimble/msg00050.html
- https://lists.launchpad.net/mimblewimble/msg00102.html
## ZKCP (Zero-Knowledge Contingent Payments)
"Recall ZKCP, as written up here
https://bitcoincore.org/en/2016/02/26/zero-knowledge-contingent-payments-announcement/
In this case, Igno produces a zero-knowledge proof that the hash preimage will decrypt the solution to some problem I care about. He gives me the encrypted solution and the hash and the proof, then we do the above exchange to trade the preimage for money."
- https://lists.launchpad.net/mimblewimble/msg00022.html
- https://lists.launchpad.net/mimblewimble/msg00037.html
## Scripting etc.
- https://lists.launchpad.net/mimblewimble/msg00025.html
- https://lists.launchpad.net/mimblewimble/msg00029.html

View file

@ -1,5 +1,7 @@
# Contracts
*Read this in other languages: [简体中文]( contracts_ZH-CN.md)*
This document describes smart contracts that can be setup using Grin even
though the Grin chain does not support scripting. All these contracts rely
on a few basic features that are built in the chain and compose them in

173
doc/contracts_ZH-CN.md Normal file
View file

@ -0,0 +1,173 @@
# 合约
本文说明使用 Grin 设置智能合约。尽管 Grin 链上不支持脚本,依靠一些链上内置基本功能,即可实现这些智能合约,而且编辑方式也会越来越巧妙。
这些构建方式并非本文作者或 Grin 开发团队原创。主要都是众多密码学家和研究者的结晶。其中包括Torben
Pryds Pedersen、Gregory Maxwell、Andrew Poelstra、John Tromp、Claus Peter
Schnorr。特此对未能列出名字的贡献者致歉我们认可多数计算机科学发现都意义非凡。
## 内置功能
本节提及 Grin 区块链的一些重要功能。我们需要预习一些知识,才能构建和使用这些功能。
### Pedersen Commitments
所有输出包括`r*G + v*H`公式的 Pedersen commitment。`r`是盲因子,`v`是值,`G``H` 是相同曲线组上两个不同的生成器点。
### 聚合签名(即 Schnorr 签名,多签)
我们假设有 SHA256 哈希函数和与上述相同的 G 曲线。最简单公式中,聚合签名构建需要以下条件:
* 待签名信息 `M`,本例中是交易费
* 私钥 `X`,对应公钥 `x*G`
* 随机数 `K`,仅用于构建签名
我们构建一个挑战 `e = SHA256(M | k*G | x*G)` 和标量 `s = k + e * x`。完整的聚合签名就为 `(s, k*G)`
检查签名可使用公钥 `x*G` ,使用签名对后半部分 M 和 `k*G` 重新计算 `e`,验证签名对第一部分 `s` 满足:
```
s*G = k*G + e * x*G
```
简单示例,甲给信任乙,给对方发起一笔转账(稍后举例无需信任的情况)。使用上述私钥 `X` 计算输出盲因子之和减去输入盲因子之和,可直接为 Grin 构建聚合签名。使用 `r` 和公钥 `r*G` 产生的聚合签名生成最终的交易核,允许验证所有 Grin 交易没有非法造币(并且给交易费签名)。
仅使用标量和公钥即可构建签名,那也可使用简单的数理构建不同的合约。
### (绝对)限时锁定交易
类似于比特币 [nLockTime](https://en.bitcoin.it/wiki/Timelock#nLockTime)。
仅需简单修改即可对交易进行限时锁定:
* 待签名信息 `M` 锁定在高度 (lock_height) `h`,交易即可花费,并添加交易费
* `M = fee | h`
* 锁定高度 `h` 写入交易核
* 锁定高度大于目前区块高度的交易核区块会被拒绝
### (相对)限时锁定交易
纳入可以确定相关锁定高度的交易核commitment就可以延伸交易的绝对限时锁定概念。
只要参照交易内核首先加入到链上状态,锁定高度就与区块高度关联。
只要(通过参照交易内核 commitment首先查看 Tx1 后 `h` 区块通过,可以限制 Tx2只有纳入一个区块后方可有效。
* 待签名信息 `M` 需要包含以下信息 -
* 与之前一样的 `fee`
* lock_height `h` (与之前一样,只是解释为相对值)
* 参照交易内核 commitment `C`
* M = `fee | h | C`
要让 Tx2 接受,就需要包含 Merkle 证明,验证区块包含 Tx1 的 `C`。这就证明已满足相对 lock_height 要求。
## 衍生合约
### 无需信任交易
涉及一方的聚合 (Schnorr) 签名相对简单,但没有展现架构的全部灵活性。下面我们来展示如何用于多方输出。
如 1.2 节所示,聚合签名需要信任收款方。由于 Grin 的输出完全通过 Pedersen Commitment 隐藏,付款方无法证明钱准确无误发给一方,因此收款方可以说自己没有收到钱。为了解决这个问题,我们需要收款方与付款方交互进行交易,特别是对交易内核签名。
Alice 想要给 Bob 支付 Grin. Alice 开始交易构建流程:
1. Alice 选择输入值,建立找零输出。所有盲因子之和(找零输出减去输入)为 `rs`
1. Alice 选择一个随机数 ks发送她这部分交易 `ks*G``rs*G` 给 Bob。
1. Bob 选出自己的随机数 `kr` 和输出盲因子 `rr`Bob 使用 `rr` 将自己的输出添加到交易。
1. Bob 算出信息 `M = fee | lock_height`Schnorr 挑战 `e = SHA256(M | kr*G + ks*G | rr*G + rs*G)` 以及最后他这边的签名 `sr = kr + e * rr`
1. Bob 将 `sr`, `kr*G``rr*G` 发给 Alice。
1. Alice 像 Bob 一样算出 `e`,然后检查 `sr*G = kr*G + e*rr*G`
1. Alice 将她的签名 `ss = ks + e * rs` 发给 Bob。
1. Bob 按第六步 Alice 验证 `sr*G` 一样来验证 `ss*G`,并生成最终签名 `s = (ss + sr, ks*G + kr*G)` 和包含 `s` 与公钥 `rr*G + rs*G` 的最终交易内核。
协议需要三步数据交换Alice 发送交易文件给 BobBob 再发送给 Alice最后 Alice 再发送给 Bob也就是上述所讲的交互。但交互也可以在特定时间内通过媒介来完成包括两周时间的“慢速邮递”pony express
本协议也可归纳为双方的任意数字 `i`。第一轮交互中,`ki*G``ri*G` 共享。第二轮中,双方都可以计算 `e = SHA256(M | sum(ki*G) | sum(ri*G))` 和自己的签名 `si`。最后确认方可以搜集全部分散签名 `si`,验证并生成 `s = (sum(si), sum(ki*G))`
### 多方输出(多签)
本节说明建立只有多方同意才能花费的交易。此构建与之前的无需信任交易类似,但本例中需要聚合签名和 Pedersen Commitment。
这次Alice 发起交易需要获得 Bob 和自己同意才能花费。Alice 正常发起交易,并以下列方式添加多方输出:
1. Bob 选出盲因子 `rb` 并发送 `rb*G` 给 Alice。
1. Alice 选出盲因子 `ra` 并建立秘诺 (commitment) `C = ra*G + rb*G + v*H`,并将秘诺发送给 Bob。
1. Bob 用 `C``rb` 建立 `v` 的范围证明 (range proof),并发送给 Alice。
1. Alice 生成自己的范围证明,并将其与 Bob 的聚合,确认多方输出 `Oab`
1. 之后与的操作“无需信任交易”一样。
我们注意到,双方都不知道新输出 `Oab` 的全部盲因子。要发起花费 Oab 的交易,就有人得知道 `ra + rb` 来生成交易核签名。Alice 和 Bob 需要合作才能要生成交易核。这又是利用与“无需信任交易”类似的协议完成。
### 多方限时锁定
本合约是其他多种合约的基础。本例中Alice 同意锁定一些基金,用于与 Bob 进行财务往来,并向 Bob 证明自己资金充足。合约设定如下:
* Alice 用与 Bob 分享的输出发起两人签名两份私钥多方交易,但他不参与发起交易内核签名。
* Bob 用限时锁定1440 区块之后约 24 小时)发起给 Alice 的退款交易。
* Alice 和 Bob 发起相应的交易内核完成两人签名交易,并向全网广播。
现在 Alice 和 Bob 可以用两人签名输出随意发起其他交易。如果 Bob 拒绝Alice 只需要在锁定到期后向全网广播退款交易。
此合约一般可用于单向支付通道。
### 限定条件输出限时锁定
类似于比特币的 [CheckLockTimeVerify](https://en.bitcoin.it/wiki/Timelock#CheckLockTimeVerify)。
我们目前交易中有限定条件 lock_heights (超过 lock_height 后交易无效且不会被接收)
私钥可相加。Key<sub>3</sub> = Key<sub>1</sub> + Key<sub>2</sub>
Commitments 可相加。C<sub>3</sub> = C<sub>1</sub> + C<sub>2</sub>
关于_交易限定条件限时锁定_ 我们可以利用这些特性将两笔相关交易的两笔输出关联来获得_限定条件输出限时锁定_。
我们可以以两笔关联的输出 Out<sub>1</sub> 和 Out<sub>2</sub> 构建两笔交易 (Tx<sub>1</sub>, Tx<sub>2</sub>),例如-
* 输出 Out<sub>1</sub> (commitment C<sub>1</sub>) 来自 Tx<sub>1</sub>,使用密钥 Key<sub>1</sub> 构建
* 输出 Out<sub>2</sub> (commitment C<sub>2</sub>) 来自 Tx<sub>2</sub>,使用 Key<sub>2</sub> 构建
* 交易 Tx<sub>2</sub> 有_限定条件_ lock_height
如果我们这样做(并按照需要管理密钥) -
* Out<sub>1</sub> + Out<sub>2</sub> _只能_ 使用密钥 Key<sub>3</sub> 匹配花费
* _只能_ 在 lock_height 后从 Tx<sub>2</sub> 花费
Tx<sub>1</sub> (包含 Out<sub>1</sub>) 可以立即广播到全网接收并在链上确认。Tx<sub>2</sub> 只有在超过 lock_height 后才能全网广播和接收。
如果 Alice 只知道 K<sub>3</sub>,不知道 Key<sub>1</sub> 或 Key<sub>2</sub>,那么在超过 lock_height 之后Alice 才能花费 输出 Out<sub>1</sub>。如果 Bob 知道 Key<sub>2</sub>,那么 Bob 可以立即花费输出 Out<sub>1</sub>
我们对输出 Out<sub>1</sub> 有_限定条件_限时锁定已在链上确认可以l使用私钥 Key<sub>3</sub> (lock_height 后) 或私钥 Key<sub>2</sub> 立即花费。
### (相对)限定条件输出限时锁定
类似于比特币的 [CheckSequenceVerify](https://en.bitcoin.it/wiki/Timelock#CheckSequenceVerify).
将“限定条件输出限时锁定”与“(相对)限定条件输出限时锁定”混合,我们可以得出有相对限时锁定的确认输出(相对于相关的交易内核)。
可立即全网广播、接受并链上确认交易 Tx<sub>1</sub> (包含输出 Out<sub>1</sub>)。 相对于之前交易 Tx<sub>1</sub> 的参照交易内核只有超过_相对_ lock_height才能广播和接受交易 Tx<sub>2</sub>
### 原子互换
原子互换可以在比特币、以太坊及其他可行的链上部署。这一功能依赖于限时锁定合约,外加检查两个公钥。比特币上这需要两份私钥两人签名,一份公钥是 Alice 的,一份是 Bob 必须公开的原像 (preimage) 哈希值。本设置中,我们要考虑公钥衍生 `x*G` 为哈希函数。而且 Bob 公开 `x`Alice 可提供完整签名证明她知道 `x`(除了自己的私钥)。
Alice 有 GrinBob 有比特币。他们要互换。我们假设 Bob 在比特币链上创建一个输出,允许 Alice 知道原像 `x` 后花费,或 Bob 在限定时间 `Tb` 到期后花费。Alice 准备在 Bob 公开 `x` 后将她的 Grin 发送给 Bob。
首先 Alice 要把她的 Grin 发送到一个多方限时锁定合约中,设定退款时间 `Ta < Tb`。若要将两人签名两份私钥输出发送给 Bob 并执行互换Alice 和 Bob 开始要按第 2.1 节所示发起正常无需信任交易。
1. Alice 挑选一个随机数 `ks` 和盲因子之和 `rs`,并发送 `ks*G``rs*G` 给 Bob。
1. Bob 挑选一个随机盲因子 `rr` 和随机数 `kr`。但这次 Bob 不再是仅仅发送 `sr = kr + e * rr` 和他的 `rr*G``kr*G`,而是发送 `sr' = kr + x + e * rr``x*G`
1. Alice 可验证 `sr'*G = kr*G + x*G + rr*G`。她也可以检查 Bob 在其他链用 `x*G` 锁定钱。
1. 既然 Alice 也可以计算 `e = SHA256(M | ks*G + kr*G)`Alice 按正常操作将 `ss = ks + e * xs` 发送回给 Bob。
1. 要完成签名,需要 Bob 计算 `sr = kr + e * rr`,最后的签名是 `(sr + ss, kr*G + ks*G)`
1. 只要 Bob 一广播最后的交易获得了他的 GrinAlice 就可计算 `sr' - sr` 获得 `x`
#### 比特币设置事项
在完成原子互换之前Bob 需要知道 Alice 的公钥。Bob 之后会在比特币链上创建一个输出,用类似 `alice_pubkey secret_pubkey 2 OP_CHECKMULTISIG` 的双私钥多签。输出会写入 `OP_IF`,这样在双方同意的时间内 Bob 可以拿回钱。而且所有甚至都可以写入 P2SH。此处 `secret_pubkey` 就是上节的 `x*G`
要验证输出Alice 需要接收 `x*G`,创建比特币脚本,算出哈希值,查看 P2SH 中的哈希匹配上节第二步。Alice 得到 `x`(第六步)后,即可建立花费双私钥多签输出的两个签名,获得两个私钥,最后获得比特币。
### 哈希限时锁定(闪电网络)
相对锁定时间待开发

View file

@ -1,3 +1,4 @@
# Grin/Mimblewimble 致比特币持有者
* 阅读其他语言版本:[Korean](grin4bitcoiners_KR.md)、 [English](grin4bitcoiners.md)
@ -24,6 +25,7 @@ Grin 链上交易有三个隐私特性:
## 脚本
或许你听说过 Mimblewimble 协议不支持脚本 (Script)。某种程度上这是事实。但利用密码学方法,许多需要脚本的比特币合约在 Grin 上可以使用椭圆曲线密码学 (Elliptic Curve Cryptography) 实现。迄今为止已知的方法有:
* 多签交易

View file

@ -1,6 +1,6 @@
# Grin Stratum RPC Protocol
*Read this in other languages: [Korean](stratum_KR.md).*
*Read this in other languages: [Korean](stratum_KR.md), [简体中文](stratum_ZH-CN.md).*
This document describes the current Stratum RPC protocol implemented in Grin.

534
doc/stratum_ZH-CN.md Normal file
View file

@ -0,0 +1,534 @@
# Grin Stratum RPC 协议
*阅读其它语言版本: [Korean](stratum_KR.md)[English](stratum.md).*
本文说明在 Grin 部署目前的 Stratum RPC 协议。
## 目录
1. [信息](#messages)
1. [获得工作模板](#getjobtemplate)
1. [工作](#job)
1. [保持在线](#keepalive)
1. [登录](#login)
1. [状态](#status)
1. [提交](#submit)
1. [错误信息](#error-messages)
1. [矿工行为](#miner-behavior)
1. [参考部署](#reference-implementation)
## 信息
本节我们讨论每种信息和可能的回复。
如果矿工随时最初以下请求(登录除外),且需要登录,矿工会收到以下错误信息。
| 栏位 | 内容 |
| :------ | :--------------------------------------- |
| id | ID of the request提出请求的 ID |
| jsonrpc | "2.0" |
| method | method sent by the miner矿工发送方法 |
| error | {"code":-32500,"message":"login first"} |
范例:
```JSON
{
"id":"10",
"jsonrpc":"2.0",
"method":"getjobtemplate",
"error":{
"code":-32500,
"message":"login first"
}
}
```
如果不是如下请求stratum 服务器会返回错误回复:
| Field | Content |
| :------ | :------------------------------------------- |
| id | ID of the request |
| jsonrpc | "2.0" |
| method | method sent by the miner |
| error | {"code":-32601,"message":"Method not found"} |
范例:
```JSON
{
"id":"10",
"jsonrpc":"2.0",
"method":"getgrins",
"error":{
"code":-32601,
"message":"Method not found"
}
}
```
### `getjobtemplate`
矿工发起的信息。
矿工可以这一信息申请工作。
#### 请求
| Field栏位 | Content |
| :-------- | :---------------- |
| id | ID of the request |
| jsonrpc | "2.0" |
| method | "getjobtemplate" |
| params | null |
范例:
``` JSON
{
"id":"2",
"jsonrpc":"2.0",
"method":"getjobtemplate",
"params":null
}
```
#### 回复
回复可分为两种类型:
##### 确认回复
范例:
``` JSON
{
"id":"0",
"jsonrpc":"2.0",
"method":"getjobtemplate",
"result":{
"difficulty":1,
"height":13726,
"job_id":4,
"pre_pow":"00010000000000003c4d0171369781424b39c81eb39de10cdf4a7cc27bbc6769203c7c9bc02cc6a1dfc6000000005b50f8210000000000395f123c6856055aab2369fe325c3d709b129dee5c96f2db60cdbc0dc123a80cb0b89e883ae2614f8dbd169888a95c0513b1ac7e069de82e5d479cf838281f7838b4bf75ea7c9222a1ad7406a4cab29af4e018c402f70dc8e9ef3d085169391c78741c656ec0f11f62d41b463c82737970afaa431c5cabb9b759cdfa52d761ac451276084366d1ba9efff2db9ed07eec1bcd8da352b32227f452dfa987ad249f689d9780000000000000b9e00000000000009954"
}
}
```
##### 错误回复
如果节点在同步,会发送如下信息:
| Field | Content |
| :------------ | :-------------------------------------------------------- |
| id | ID of the request |
| jsonrpc | "2.0" |
| method | "getjobtemplate" |
| error | {"code":-32701,"message":"Node is syncing - Please wait"} |
范例:
```JSON
{
"id":"10",
"jsonrpc":"2.0",
"method":"getjobtemplate",
"error":{
"code":-32000,
"message":"Node is syncing - Please wait"
}
}
```
### 工作
Stratum 服务器发起新消息。Stratum 服务器会自动发送工作给连接的矿工。如果 `job_id = 0` 矿工应该切断目前的工作,并且目前的图形完成后用这一个代替现有工作。
#### 请求
| Field | Content |
| :------------ | :------------------------------------------------------------------------- |
| id | ID of the request |
| jsonrpc | "2.0" |
| method | "job" |
| params | Int `difficulty`, `height`, `job_id` and string `pre_pow` |
范例:
``` JSON
{
"id":"Stratum",
"jsonrpc":"2.0",
"method":"job",
"params":{
"difficulty":1,
"height":16375,
"job_id":5,
"pre_pow":"00010000000000003ff723bc8c987b0c594794a0487e52260c5343288749c7e288de95a80afa558c5fb8000000005b51f15f00000000003cadef6a45edf92d2520bf45cbd4f36b5ef283c53d8266bbe9aa1b8daaa1458ce5578fcb0978b3995dd00e3bfc5a9277190bb9407a30d66aec26ff55a2b50214b22cdc1f3894f27374f568b2fe94d857b6b3808124888dd5eff7e8de7e451ac805a4ebd6551fa7a529a1b9f35f761719ed41bfef6ab081defc45a64a374dfd8321feac083741f29207b044071d93904986fa322df610e210c543c2f95522c9bdaef5f598000000000000c184000000000000a0cf"
}
}
```
#### 回复
本消息不需要回复
### 保持在线
为保持在线,矿工发起消息。
#### 请求
| Field | Content |
| :------------ | :--------------------- |
| id | ID of the request |
| jsonrpc | "2.0" |
| method | "keepalive" |
| params | null |
范例:
``` JSON
{
"id":"2",
"jsonrpc":"2.0",
"method":"keepalive",
"params":null
}
```
#### 回复
| Field | Content |
| :------------ | :----------------------------- |
| id | ID of the request |
| jsonrpc | "2.0" |
| method | "keepalive" |
| result | "ok" |
| error | null |
范例:
``` JSON
{
"id":"2",
"jsonrpc":"2.0",
"method":"keepalive",
"result":"ok",
"error":null
}
```
### 登录
***
矿工发起消息。矿工用用户名、密码和代理(通常由矿工程序设置)登录 Grin Stratum 服务器。
#### 请求
| Field | Content |
| :------------ | :----------------------------- |
| id | ID of the request |
| jsonrpc | "2.0" |
| method | "login" |
| params | Strings: login, pass and agent |
范例:
``` JSON
{
"id":"0",
"jsonrpc":"2.0",
"method":"login",
"params":{
"login":"login",
"pass":"password",
"agent":"grin-miner"
}
}
```
#### 回复
回复可为两种类型:
##### 确认回复
| Field | Content |
| :------------ | :----------------------------- |
| id | ID of the request |
| jsonrpc | "2.0" |
| method | "login" |
| result | "ok" |
| error | null |
范例:
``` JSON
{
"id":"1",
"jsonrpc":"2.0",
"method":"login",
"result":"ok",
"error":null
}
```
##### 错误回复
未部署。应该返回`error -32500`,若需要登录,“首先登录”。
### 状态
矿工发起消息。本消息允许矿工获得目前矿工和网络状态。
#### 请求
| Field | Content |
| :------------ | :--------------------- |
| id | ID of the request |
| jsonrpc | "2.0" |
| method | "status" |
| params | null |
范例:
``` JSON
{
"id":"2",
"jsonrpc":"2.0",
"method":"status",
"params":null
}
```
#### 回复
回复如下
| Field | Content |
| :------------ | :------------------------------------------------------------------------------------------------------- |
| id | ID of the request |
| jsonrpc | "2.0" |
| method | "status" |
| result | String `id`. Integers `height`, `difficulty`, `accepted`, `rejected` and `stale` |
| error | null |
范例:
```JSON
{
"id":"5",
"jsonrpc":"2.0",
"method":"status",
"result":{
"id":"5",
"height":13726,
"difficulty":1,
"accepted":0,
"rejected":0,
"stale":0
},
"error":null
}
```
### 提交
矿工发起消息。矿工挖到一份,会提交给节点。
#### 请求
矿工向 Stratum 服务器提交工作解决方案。
| Field | Content |
| :------------ | :-------------------------------------------------------------------------- |
| id | ID of the request |
| jsonrpc | "2.0" |
| method | "submit" |
| params | Int `edge_bits`,`nonce`, `height`, `job_id` and array of integers `pow` |
范例:
``` JSON
{
"id":"0",
"jsonrpc":"2.0",
"method":"submit",
"params":{
"edge_bits":29,
"height":16419,
"job_id":0,
"nonce":8895699060858340771,
"pow":[
4210040,10141596,13269632,24291934,28079062,84254573,84493890,100560174,100657333,120128285,130518226,140371663,142109188,159800646,163323737,171019100,176840047,191220010,192245584,198941444,209276164,216952635,217795152,225662613,230166736,231315079,248639876,263910393,293995691,298361937,326412694,330363619,414572127,424798984,426489226,466671748,466924466,490048497,495035248,496623057,502828197, 532838434
]
}
}
```
#### 回复
回复可为三种类型。
##### 确认回复
Stratum 接受份额,但不是目前网络目标难度的有效 cuck(at)oo 解决方案。
| Field | Content |
| :------------ | :----------------------------- |
| id | ID of the request |
| jsonrpc | "2.0" |
| method | "submit" |
| result | "ok" |
| error | null |
范例:
``` JSON
{
"id":"2",
"jsonrpc":"2.0",
"method":"submit",
"result":"ok",
"error":null
}
```
##### 发现区块回复
份额被 Stratum 接受,是目前网络目标难度的有效 cuck(at)oo 解决方案。
| Field | Content |
| :------------ | :----------------------------- |
| id | ID of the request |
| jsonrpc | "2.0" |
| method | "submit" |
| result | "block - " + hash of the block |
| error | null |
范例:
``` JSON
{
"id":"6",
"jsonrpc":"2.0",
"method":"submit",
"result":"blockfound - 23025af9032de812d15228121d5e4b0e977d30ad8036ab07131104787b9dcf10",
"error":null
}
```
##### 错误回复
错误回复有两种类型:过期和被拒绝。
##### 过期份额错误回复
份额是上一工作而不是目前工作的有效解决方案。
| Field | Content |
| :------------ | :-------------------------------------------------------- |
| id | ID of the request |
| jsonrpc | "2.0" |
| method | "submit" |
| error | {"code":-32503,"message":"Solution submitted too late"} |
范例:
```JSON
{
"id":"5",
"jsonrpc":"2.0",
"method":"submit",
"error":{
"code":-32503,
"message":"Solution submitted too late"
}
}
```
##### 拒绝份额错误回复
两种可能:解决方案无效或解决方案难度太低。
###### 未能验证解决方案错误
提交的解决方案无法验证。
| Field | Content |
| :------------ | :-------------------------------------------------------- |
| id | ID of the request |
| jsonrpc | "2.0" |
| method | "submit" |
| error | {"code":-32502,"message":"Failed to validate solution"} |
范例:
```JSON
{
"id":"5",
"jsonrpc":"2.0",
"method":"submit",
"error":{
"code":-32502,
"message":"Failed to validate solution"
}
}
```
###### 因低难度错误份额拒绝
提交的解决方案难度太低。
| Field | Content |
| :------------ | :--------------------------------------------------------------- |
| id | ID of the request |
| jsonrpc | "2.0" |
| method | "submit" |
| error | {"code":-32501,"message":"Share rejected due to low difficulty"} |
范例:
```JSON
{
"id":"5",
"jsonrpc":"2.0",
"method":"submit",
"error":{
"code":-32501,
"message":"Share rejected due to low difficulty"
}
}
```
## 错误信息
Grin Stratum 协议部署包含以下错误信息:
| Error code | Error Message |
| :---------- | :------------------------------------- |
| -32000 | Node is syncing - please wait |
| -32500 | Login first |
| -32501 | Share rejected due to low difficulty |
| -32502 | Failed to validate solution |
| -32503 | Solution Submitted too late |
| -32600 | Invalid Request |
| -32601 | Method not found |
## 矿工行为准则
矿工须遵守以下规则:
- 矿工开始挖矿前需要随机算工作随机数
- 矿工必须一直进行相同工作,直到服务器发送新的,尽管矿工有可能随时申请工作
- 矿工不得从服务器给工作请求发送 RPC 回复
- 矿工可设置 RPC "id" 并获得回复
- 矿工可发送保持在线信息
- 矿工可发送登录请求(确认哪个矿工在历史记录发现份额 / 解决方案),登录请求必须有三个参数
- 矿工提交信息必须提供 job_id
## 部署参考
挖矿部署请参阅:[mimblewimble/grin-miner](https://github.com/mimblewimble/grin-miner/blob/master/src/bin/client.rs)

View file

@ -1,5 +1,7 @@
# Introduction to Switch Commitments
*Read this in other languages: [简体中文](switch_commitment_ZH-CN.md).*
## General introduction
In cryptography a _Commitment_ (or _commitment scheme_) refers to a concept which can be imagined
@ -63,12 +65,12 @@ which can be weaker or stronger, depending on the type of commitment scheme:
- **Hidingness (or Confidentiality):** How good is the commitment scheme protecting the secret
commitment. Or speaking in terms of our example from above: what would an attacker need to
open the box (and learn the secret number) without having the key to unlock it?
- **Bindingness:** Is it possible at all (or how hard would it be) for an attacker to somehow
find a different secret, which would produce the same commitment, so that the attacker could
later open the commitment to a different secret, thus breaking the _binding_ of the
commitment.
### Security of these properties:
For these two properties different security levels can be identified.
@ -229,7 +231,7 @@ and create the Pedersen Commitment:
such that:
r = r' + hash( v*H + r'*G , r'*J )
(using the additional third generation point `J` on the curve) then `r` still is perfectly
valid as a blinding factor, as it's still randomly distributed, but now we see
that the part within the brackets of the hash function (`v*H + r'*G , r'*J`) is an
@ -280,6 +282,7 @@ But in this case users would still have a choice:
(but preserve their privacy, as their old transactions only validated the Pedersen commitment
which is perfectly hiding)
There are many cases where a privacy leak is much more dangerous to one's life than
some cryptocurrency might be worth. But this is a decision that should be left up to
the individual user and switch commitments enable this type of choice.

View file

@ -0,0 +1,164 @@
# 秘诺切换简介
*阅读其它语言版本: [English](switch_commitment.md)*
## 概述
密码学中_秘诺_ 或_秘诺方案_这个概念可以想像成一个加锁的盒子。可以在盒子里放东西例如一张写着密码的纸把盒子锁起来再交给另一个人或公示
另一个方不知道盒子里的密码,但是如果你决定之后按约定公开密码,并要证明这确实是最初你放在盒子里的密码(并未篡改),你仅把盒子钥匙交给另一个人即可证明。
另一个人可以打开盒子,对比盒子里的密码和你刚刚公开的密码,就可以确定盒子上锁后密码没有变更。你提前"**承诺**"密码,意味着在秘诺生成和公开之间,你不可以对其做任何修改。
## 范例
### 秘诺哈希计算
使用密码学哈希函数即可实现简单的秘诺方案 (commitment scheme)。例如Alice 和 Bob 想要玩“猜数游戏”。Alice 想出自己的密数 `29`,由 Bob 来猜。在游戏开始前Alice 做如下计算:
hash( 29 + r )
并把结果告诉给 Bob。`r` 是随机选择的_“致盲因子 (Blinding Factor)”_。之所以需要致盲因子是因为如果没有Bob 就可以尝试所有可能数字的哈希值,来对比原哈希值。
游戏结束时Alice 仅需公开自己的密数 `29` 和盲因子 `r`。Bob 自己哈希计算结果,即可验证 Alice 在游戏过程中是否更改过密数。
### Pedersen Commitment
另外,高阶秘诺方案还有其他特性。例如 Mimblewimble 和机密交易 (Confidential TransactionsCT) 大量使用_同态 (homomorphic)_ 秘诺的 _[Pedersen Commitments](https://link.springer.com/content/pdf/10.1007/3-540-46766-1_9.pdf)_。这里的“同态”是指引用上述“盒子”的比喻可以使用两个加锁盒子_盒子 1_ 和_盒子 2_而且可以将其_“合并”_一起。这样你就得到一个大盒子仍旧加锁如果之后打开这个含有密数的大盒子如上述范例最终的结果就是_盒子 1_ 和_盒子 2_ 的密数总和。
这个“盒子”的比喻在现实世界中看似不合理,但对椭圆曲线原理无可挑剔。
如需了解关于 Pedersen Commitment 的详情,请参阅[《Mimblewimble 和 Grin 简介》](intro_ZH-CN.md)
## 秘诺方案特性:
一般而言,秘诺有两大特性,强弱变化视秘诺方案类型而变。
- **隐匿性(或机密性):**秘诺方案保护秘诺的强度。或依上述范例:攻击者没有钥匙怎么能打开盒子(知道密数)?
- **绑定性:**攻击者是否可以找到匹配同一秘诺的不同密数攻击者之后通过秘诺打开的就是不同秘诺。这样秘诺的_致盲性_就被破解。
### 两种特性的安全性:
对于这两种特性,可以确认不同安全级别。
两种特性最重要的混合使用方式为
- **完美绑定**和**计算隐匿**秘诺方案,和
- **计算绑定**和**完美隐匿**
“_计算_”绑定或隐匿的基础数学难度很高以现有计算能力在合理时间内难以破解即以世界上的现有计算资源今天不可破解因此意味着这种特性绑定性隐匿性安全。
“_完美_”绑定或隐匿意味着即使有无限计算资源也不可能破解这一特性绑定性隐匿性
### 互不相容:
需要意识到重要的一点,秘诺方案**不可能**同时兼备_完美绑定_**和**_完美隐匿_。一个思想实验就可以明白假设攻击者有无限算力他可以对任意数值生成秘诺和致盲因子直到碰撞找到匹配原始秘诺的输出数值。进一步假设秘诺方案为_完美绑定_意味着不可能两个不同的数值生成相同秘诺匹配秘诺的数值独一无二那这样就会破坏隐匿性。
反之亦然。如果一个秘诺方案为_完美隐匿_那必然会有多个输入值生成相同秘诺否则有无限算力的攻击者只需如上所示计算任意数值。结果就是这一秘诺方案不可能是_完美绑定_。
#### 有所取舍
此处的要点就是:**总要有所取舍**无法兼备两种特性_隐匿性_和_绑定性_的_完美_安全性。如果一种是_完美_安全那另一种至多就是_计算_安全反之亦然
### 加密货币中的应用考虑
在设计加密货币时,这些特性扮演了哪些作用?
**隐匿性**
对于 Grin 这类注重隐私的加密货币秘诺方案用以保护交易数据。发送者执行发送一定数量的币但对于他人具体金额保密秘诺方案中的_隐匿性_特性
**绑定性**
同时,交易发起者之后也无法更改秘诺为不同的交易金额。如果更改秘诺成功,攻击者就可以花费比之前在一个 UTXO 生成的币多的金额,这样就凭空造出“假币”。更糟的是,由于金额隐藏,这种情况有可能无法被发现。
所以保持两种特性安全可靠是根本所在。
只要一个加密货币始终维持这两种特性,就得选择使用哪种秘诺方案。
#### 难以选择?
哪种特性需要_完美_安全哪种足以_计算性_安全换句话说如果秘诺方案被意外攻破应该提高哪种特性安全级别是经济稳定性无通胀可能还是保证隐私性隐私不被侵犯
这似乎是个难题。
深入了解我们意识到秘诺方案被攻破时需要_完美_绑定。那时候即使只有_计算_绑定也会安全。
同时隐私加密货币需要**永远**保证_隐匿性_。_绑定_特性只有在创建交易且不会影响过去交易的情况下才重要。不同的是需要始终保持_隐匿性_。否则遇到意外秘诺方案被攻破的情况下攻击者会链上回滚解绑历史交易进而破坏隐私性。
## Pedersen Commitments 特性
Pedersen Commitments 是**计算绑定**和**完美隐匿**。预设秘诺值为 `v`: `v*H + r*G`,会存在一组不同的值 `r1``v1` 其和与预设秘诺值相同。即使有无限算力可以尝试所有可能的值攻击者也无法分辨哪一个是原始秘诺因而是_完美隐匿_
## 秘诺切换简介
如果 Pedersen Commitment 的绑定性被意外破解那会发生什么?
一般而言,加密货币的秘诺方案被破解,就会更改加密方案。但问题是更改加密方案就需要使用新的方案创建新的交易输出,来保证资金安全。这就需要每位持币者将币转到新的交易输出。如果没有转币到新交易输出,那就不会受到新秘诺方案的保护。而且一定要在就方案被大规模攻破**之前**转币,否则现有 UTXO 不会记录正确的交易值。
遇到这种情况,[_Switch Commitments_](https://eprint.iacr.org/2017/237.pdf) 给出了简洁的解决方案。这种秘诺仅靠更改公开验证程序来变更秘诺特性而无须变更秘诺创建方式。“_切换_”到新验证方案可与在“_切换_”倩生成的秘诺兼容。
### 工作方案
首先来介绍新的秘诺方案:**ElGamal commitment** 方案。其为_完美绑定_由于不能二者兼具所以是_计算隐匿_。其特征与 Pedersen Commitments 极其类似,只是添加了新元素,致盲因子 `r``J` 相乘计算得出:
v*H + r*G , r*J
如果我们储存额外的域 `r*J`,并且暂时忽略,我们可以将其视作 Pedersen Commitments 对待,未来随时可以激活完整 ElGamal commitment。主网上线前[Grin 早期版本](https://github.com/mimblewimble/grin/blob/5a47a1710112153fb38e4406251c9874c366f1c0/core/src/core/transaction.rs#L812)就是这样部署。详情为:哈希值 `r*J`
(_switch\_commit\_hash_) 添加到交易输出,但造成每个输出大小增加 32 字节。
幸运的是,之后 Mimblewimble 邮件列表成员 Tim Ruffing 提出一个[绝妙的解决方案](https://lists.launchpad.net/mimblewimble/msg00479.html)(最初是 Pieter Wuille 所建议)。这一方案保持了相同优势,但不会对交易输出造成额外体积负担。
方案内容如下:
普通的 Pedersen Commitment 是这样:
v*H + r*G
`v` 是输入/输出值,`r` 是随机致盲因子,`H``G` 是椭圆曲线上的两个生成点)。
如果加以更改,让 `r` 变为非随机数,但使用另一个随机数 `r`,来创建 Pedersen Commitment
v*H + r*G
例如:
r = r' + hash( v*H + r'*G , r'*J )
(使用椭圆曲线上的另外第三生成点 `J`),然后 `r` 因为仍旧随机分布,所以作为致盲因子仍完美有效,但我们现在看到的括号内哈希函数 (`v*H + r'*G , r'*J`) 是 **ElGamal commitment**
这一绝妙的方案就从输出中移除了秘诺切换哈希(详情请参阅 [pull requests](https://github.com/mimblewimble/grin/issues/998)),这样就可以轻松纳入 Pedersen Commitment。
这就是 Grin 目前的秘诺部署方案。Pedersen Commitment 用作机密交易 (Confidential Transaction),但没有单纯随机选择致盲因子 `r`,而是在一个随机数 `r` 添加 ElGamal commitment 函数来计算(详情请参阅 [main_impl.h#L267](https://github.com/mimblewimble/secp256k1-zkp/blob/73617d0fcc4f51896cce4f9a1a6977a6958297f8/src/modules/commitment/main_impl.h#L267))。
总之,秘诺切换是在论文[《秘诺切换:安全切换机密交易》](https://eprint.iacr.org/2017/237.pdf)中首次提出。“切换”一词来源于未来可以随意“扳动开关”这一想法。仅仅变更验证程序就可以更改秘诺绑定性和隐匿性特性强弱,未来的更改甚至可与创建的历史秘诺兼容。
## 结语
Grin 和其他加密货币一样,都使用 Pedersen Commitments。唯一的区别就是随机致盲因子 `r` 是利用 ElGamal
commitment 方案生成。
这种方案看上去没有差别,但有重要的安全措施:
Pedersen Commitments 已经是_完美绑定_。所以无论发生什么无需用户任何操作就可保证无隐私泄露风险。若遇到意外秘诺方案的绑定性被破解需要所有新交易通过验证所有 ElGamal 秘诺,证明他们的秘诺没有破解绑定性,就可以启用秘诺切换(通过软分叉)。
但这种情况下用户仍有选择:
- 用户可决定继续创建新交易。即使因为 ElGamal 秘诺方案仅为计算隐匿,有可能破坏隐私性(只对**上一个** UTXO但用户至少仍旧可以存取自己的币。
- 或者用户可决定不管钱,不做任何交易(但是保留隐私性,因为他们的交易仅验证有完美隐匿性的 Pedersen 秘诺)
有些情况下,隐私泄露对某个人的生命安全威胁要高过一定加密货币的损失。但决策权应该留给个人用户,秘诺切换就实现了这种选择。
需要明确的是,这一安全措施只有在遇到意外灾难的情况下才会启用。若计算有所进步,离散对数难题受到质疑,那包括加密货币在内的众多其他加密系统都需要紧急更新原语,抵抗未来潜在威胁。秘诺切换只是在 Pedersen Commitments 被意外破解情况下,提供额外的安全保护方案。

View file

@ -1,6 +1,6 @@
# Documentation structure
*Read this in other languages: [Korean](table_of_contents_KR.md).*
*Read this in other languages: [Korean](table_of_contents_KR.md), [简体中文](table_of_contents_ZH-CN.md).*
## Explaining grin

View file

@ -0,0 +1,37 @@
# 文档结构
*阅读其它语言版本: [English](table_of_contents.md)[Korean](table_of_contents_KR.md)*
## Grin 详解
- [Grin 简介](intro.md) - Grin 技术介绍文档
- [致比特币持有者](grin4bitcoiners_ZH-CN.md) - 从比特币的视角讲解 Grin
## 理解 Grin 部署
- [chain_sync](chain/chain_sync.md) - 关于 Grin 区块链如何同步
- [blocks_and_headers](chain/blocks_and_headers.md) - Grin 如何链上追踪区块和块头
- [contract_ideas](contract_ideas.md) - 部署合约的想法
- [dandelion/dandelion](dandelion/dandelion.md) - 关于交易生成和核销。生成枝干和扩散
- [dandelion/simulation](dandelion/simulation.md) - 蒲公英模拟 - 无需区块高度枝干和扩散即可聚合交易
- [internal/pool](internal/pool.md) - 交易池技术说明
- [merkle](merkle_ZH-CN.md) - Grin 偏好的默克尔树类型讲解
- [merkle_proof graph](merkle_proof/merkle_proof.png) - 应用修剪的默克尔树证明范例
- [pruning](pruning_ZH-CN.md) - 修剪技术说明
- [stratum](stratum.md) - Grin Stratum RPC 协议技术说明
- [transaction UML](https://github.com/mimblewimble/grin-wallet/blob/master/doc/transaction/basic-transaction-wf.png) - 交互交易 UML (无需 `lock_height` 的聚合交易)
## 构建和使用
- [api](api/api.md) - 讲解 Grin 的 不同 API及使用说明
- [构建](build_ZH-CN.md) - 讲解构建和运行 Grin 二进制软件
- [release](release_instruction.md) - 发行版本说明
- [usage](usage.md) - 如何在 Testnet3 使用 Grin
- [wallet](wallet/usage.md) - 讲解钱包设计和 `grin wallet` 次命令
## 其他 (wiki)
- [FAQ](https://github.com/mimblewimble/docs/wiki/FAQ) - 常见问题
- [构建 Grin](https://github.com/mimblewimble/docs/wiki/Building)
- [如何使用 Grin](https://github.com/mimblewimble/docs/wiki/How-to-use-grin)
- [开发和贡献](https://github.com/mimblewimble/docs/wiki/Hacking-and-contributing)