# MW(Mimble-Wimble)协议

## 1. 背景
任何货币系统，包括电子现金，数字资产等，都需要满足两个条件，

* 接收的货币等于发送的货币，不凭空产生货币
* 只能发送自己账户的货币

比特币交易通过暴露3个属性：发送方地址、发送比特币的数量、接收方地址来满足，而Mimblewimble则可以在不暴露这3个属性的情况下，满足货币系统的这两个条件

## 2. 特点
Mimblewimble协议是一种优化比特币的隐私保护协议，它能节省存储容量，提供更强的隐私保护能力，有以下特点：

* 区块链中没有地址和账户，每次转账中接收方都要构建新的交易见证。
* 交易金额隐藏，只验证输入等于输出，没有多余货币产生
* 中间状态的交易可以合并，更少的信息使得追踪更加困难   

> 交易合并是指如果在要打包到区块的所有交易中，先有A转给B钱，后又有B转给C一定的钱，那么不需要全部记录这两笔交易，只需要记录A转给C多少钱，合并交易的中间状态，同时附上B的签名，就可以既保证交易的安全又确保不双花的同时减小UTXO集合大小，显著减少区块存储所需空间

## 3. 实现
### 3.1 交易金额隐藏
实现主要基于椭圆曲线不可逆的特性。假设有交易输入vi1和vi2，输出vo3，椭圆曲线H，我们可以将交易中描述为v*H。 由于ECC加法特性，我们可以验证交易的输出总和等于输入总和：

    vi1 + vi2 = vo3 => vi1*H + vi2*H = vo3*H

验证每笔交易的这个属性允许协议验证交易不会凭空创造出金钱，而无需了解实际的交易值是多少。但是，可用数值是有限的，攻击者可以尝试每一个可能的数值来猜测你的交易值。 另外，知道vi1和vi1*H，就等于在整个区块链中揭露了等于vi1的交易。 出于这些原因，我们引入了第二个椭圆曲线 G和私钥r用作致盲因子(blinding factor)。

交易中的输入或输出值可以表示为：

    r*G + v*H

其中：   

* r 是一个私钥，用作致盲因子， G 是一个椭圆曲线点，他们的乘积 `r * G` 是 r 在 G 上的公钥。
* v 是输入或输出值，H 是另一个椭圆曲线点。

无论是v还是r都不能被推导出来，从而利用了椭圆曲线密码学的基本属性。 `r * G + v * H`被称为 Pedersen Commitment

为每个输入值生成一个私钥作为致盲因子，将上面的等式替换每个值为他们各自的 Pedersen Commitments，我们获得：

    (ri1*G + vi1*H) + (ri2*G + vi2*H) = (ro3*G + vo3*H)

并且要求:   

    ri1 + ri2 = ro3

通过致盲因子，交易金额被隐藏在Commitment中，节点验证的时候只需验证输出和输入的Commitment之差是否为零即可，无需了解交易金额

### 3.2 所有权
用来掩盖实际交易值的致盲因子是一个私钥，这个私钥可以用来证明值的所有权

假如Alice给你发了3个币并且隐藏了这个数字，你选择了28作为你的致盲因子（在实际中是一个非常大的数字）。 区块链上的某处显示以下交易输出，并只能由你来用（做交易输入）：

    X = 28*G + 3*H

X, 上述加法的输出值，是对所有人可见的。 但是值3只有你和 Alice 知道，而28就只有你自己知道了。

为了再次转移这3个币，协议要求（交易者）以某种方式知道28。 为了演示这是如何工作的，假设你想将这3个相同的币转移给Carol。 你需要构建一个简单的交易，以便：

    Xi => Y

其中 Xi 是一个输入，它花掉你之前得到的输出值 X ，而 Y 是 Carol 的输出。如果不知道你的私钥28，就没有办法建立这笔交易。的确，如果Carol要平衡这个交易，她既需要知道发送的值，也需要知道你的私钥， 以便：

    Y – Xi = (28*G + 3*H) – (28*G + 3*H) = 0*G + 0*H

但是你需要和Carol共享私钥28，为此，我们允许Carol增加她选择的另一个值，比如113，那么最后在区块链上的结果变成了：

    Y – Xi = (113*G + 3*H) – (28*G + 3*H) = 85*G + 0*H

现在交易不会再归零了，我们在G上有一个excess value（85），这是所有致盲因子总和的结果。 这个地方85*G是椭圆曲线G上的一个公钥，而85则是对应的私钥

因此，协议需要验证的其实就是：（Y – Xi）是G上的一个有效公钥，以及交易者知道私钥（85）。最简单的方法就是要求使用excess value（85）进行签名，然后验证：

* 交易者知道这个交易输出的私钥   
* 交易输出的和，减去输入，加起来等于0   

这个关联到每笔交易的签名，附加一些额外数据（比如交易费），被称为交易核（transaction kernel）

### 3.3 核销
区块让矿工将多个交易组合成一个单个集合添加到链中。 在下面的区块表示中，包含3个交易，我们只显示交易的输入和输出。 输入关联其花费的输出。 前一个区块中包含的输出标记为小写字母x。

    I1(x1) --- O1
            |- O2

    I2(x2) --- O3
    I3(O2) -|

    I4(O3) --- O4
            |- O5

我们注意到以下两个属性：

在这个区块内，一些输出直接被包含的输入消耗（I3花费O2并且I4花费O3）。
每笔交易的结构并不重要。 由于所有的单个交易均归于零，因此所有交易输入和输出的总和也必须为零。
与单个交易类似，所有需要在一个区块中进行检查的是所有权已经被证实（来自交易内核 transaction kernels），并且整个区块没有增加任何货币供应（除了coinbase所允许的之外）。 因此，匹配输入和输出可以被消除，因为它们对总和的贡献被抵消了。 这导致了以下更紧凑的块：

    I1(x1) | O1
    I2(x2) | O4
           | O5

所有的交易结构已被消除，输入和输出的顺序已无关紧要。 但是，该块中所有输出的总和减去输入，仍然保证为零。

一个块的建立来自：

* 块头
* 核销后剩余的输入列表
* 核销后剩余的输出列表
* 每个交易的交易核包含：
  * 从所有commitments总和中获得的公钥r * G
  * 使用excess value生成的签名
  * 挖矿费用 (fee)

当区块以这种方式构建时，MimbleWimble区块提供了非常好的隐私保证：

* 更多的交易可能已经完成，但不会显式出现（在区块中）
* 所有的输出看起来都是一样的：只是一些非常大的数字，不可能相互区分。 如果有人想排除某些输出，他们将不得不排除所有输出
* 所有的交易结构已被删除，使得区分哪个输出与哪个输入匹配成为不可能任务

然而，区块仍然可验证！
## 4. MW交易
### 4.1 MimbleWimble交易包括以下内容
* 一组输入，参考和花费一组以前的输出
* 一组新的输出包括：   
  * 一个值和一个致盲因子（它只是一个新的私钥）在曲线上相乘并相加为r.G + v.H   
  * 范围证明显示v是非负的   
  * 明确的交易费用
* 一个签名，通过采取excess value（所有输出加费用之和减去输入）并将其用作私钥来计算

### 4.2 交易构建
以Grin交易为例

![transaction](resource/basic-transaction-wf.png)

### 4.3 交易上链
以Beam交易为例

![beam](resource/beam.png)

## 5. 钱包
mw协议中并没有地址，也没有账户，发送交易一般需要使用钱包监听ip和端口，或者通过其他安全通道传递交易文件。当前实现mw协议的匿名币主要是grin和beam，beam的钱包在mw协议外实现了一个叫SBBS的插件，该插件可以生成动态地址(也可以生成永久地址，一般矿池和交易所才会)，交易转账会比原生的mw协议相对友好。在sbbs插件中，beam的钱包和一般的以太坊钱包类似，但是要求交易的时候，双方钱包都要同时在线，否则默认24小时候地址就会失效。
![wallet](resource/033.jpg)

## 6. 区块
上面提到过，mw协议的交易仅仅包含携带致盲因子的输入输出，手续费，以及签名，在mw区块中，包含区块头，输入输出列表和transaction kernel集合

* 区块信息
![block1](resource/block1.png)

* 输入输出
![block2](resource/block2.png)

* kernel
![block3](resource/block3.png)

## 7. 小结
mw协议具有强大的隐私保护能力和强匿名，但是同时，交易构建需要发送接收方配合，无论是在其他安全通道交易文件发送，还是是同时在线监听，都给使用场景带来一定的局限性。并且mw协议对智能合约的支持并不友好，grin号称能支持及简单的只能合约定义，beam没有看到有相关的描述。mw协议在纯匿名币上会有很好的应用，在公链上可能意义不大。反倒是其中使用到的类似schnorr签名，蒲公英协议这些隐私保护技术或许可以在公链上尝试。