100%准备金证明

什么是准备金

说白了,准备金就是平台留存的钱。100%准备金率就是用户存100块,平台必须保留100块;10%就是存100块,平台可以只保留10块,另外的90块可以做别的事情,通常银行通过放贷等进行盈利,所以银行需要拼命吸储。

为何Off-Chain钱包需要证明

Off-Chain(链下)机制是用户的币在平台只做登记,币由平台完全控制。On-Chain(链上)机制是用户的币由自己通过私钥管理,平台无法动用。所以,只有Off-Chain才有可能低于100%准备金且需要证明,On-Chain总是保持100%准备金率。

证明机制

最简单的证明方法就是公布所有用户数据,平台的准备金率即:平台储蓄地址 / 用户总余额。该方式很直接,但易伪造。

欲保障逻辑完备性,需要证明:

  1. 没有伪造
    1. 伪造假用户
    2. 伪造用户余额
  2. 没有遗漏
    1. 直接遗漏用户:某个用户在公布的数据里找不到自己
    2. 间接遗漏用户:两个或两个以上用户对应的是同一条数据

先说伪造,伪造假用户的结果是:准备金率下降,打自己耳光;伪造用户余额的结果是:任一用户发现余额与公布的不一致即说明平台造假。还有一种就是仅伪造平台控制的用户数据(自己人的账户),若往多了吹,造成准备金率下降;若往少了说,没意义。但无法防止的情形是:伪造大量的零余额的用户,但这个不影响准备金率。

第二个点是遗漏,直接遗漏也没法弄,一旦某用户发现找不到自己则立即露馅;通常是间接遗漏,防止间接遗漏最直接的方法是公布用户Email地址,但会暴露用户隐私,通常需要设计一个Hash算法,例如:hash_value = HASH(user_id + nonce + balance)user_id这个字段必须每个用户唯一且固定不变,通常是选择email或者手机号码,因为天然具有唯一性且不可伪造。确定HASH算法后,用户的识别由Email地址改为hash_value

证明方法

证明主要过程是构建Merkle Tree,当构建完该树,且根节点的余额与公布的储蓄地址余额相同,即可100%储备。证明算法参考了Proving Your Bitcoin Reserves,少许修改。

构建的树结构

单个用户看到的结构

隐私问题

用户

必须在证明的同时可以保障用户财务隐私不被泄露。

  1. user_id的选取,上文已阐述,不再重复
  2. 每次构建时,用户的Nonce均为随机,即使用户两次余额不发生变化,hash_value依然是不一样的

上述两点可最大限度保护用户财务隐私,虽然别人可能看到你的节点数据,但他不知道你是谁。

平台

对平台来说,敏感的数据是:总储蓄额,总用户数。

总储蓄额必然公开,无需讨论。总用户数若不想那么公开,可以通过一些方法掩饰。通常Merkle Tree是平衡二叉树,根据用户树的高度可以推测用户数量(误差在2倍以内),那么就可以通过构建非常不平衡的二叉树(每次可以是任意形状)来掩饰平衡构建树的真实高度,且不破坏验证机制。例如,平衡二叉树的高度为10,则平台用户数范围是:512~1024之间(2^9=512, 2^10=1024),若构建一个高度为20的非平衡树(2^20=1048576)就可以成功掩饰实际用户数。

其他保护平台隐私方法:

  1. 降低公开频率,例如从每天公开一次降低为每周、每月公开一次
  2. 利用自有资金进出,干扰资金流向跟踪

币付宝的证明机制

我们理念是保护用户隐私的情况下,公开所有平台数据:总储蓄额、总用户数,用户可以下载所有节点数据。构建满平衡二叉树的过程是:构建用户节点 -> 迭代向上构建父节点 -> 至根节点,树构建完毕。若某一层节点数为奇数,则将最后一个节点复制,该节点称为填充节点(padding node)。

示例用户数据

User Email/ Mobile Phone Nonce Balance (Satoshi)
panzhibiao@bifubao.com 139853 100047062
support@bifubao.com 982361 88086042
13800138000 093823 3343103669

用户节点

用户节点hash值的算法:

1
2
3
4
5
hexstr(
    first8bytes(
        sha256(str(user_id) + sprintf("%06d", nonce) + sprintf("%016lld", balance))
    )
)

构建一个用户节点,由于字符串直接拼接,我们把user_idnonce合成为下面函数中的uid示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
typedef struct Node_ {
  long long         sum;
  unsigned char hash[8];
  
  bool operator < (const struct Node_ &right) const {
    return memcmp(this->hash, right.hash, 8) < 0 ? true : false;
  }
} Node;

// make_user_node
void make_user_node(const char *uid, long long balance, Node *node) {
  unsigned char hash[SHA256_DIGEST_LENGTH];
  char buf[17] = {0};
  node->sum = balance;
  sprintf(buf, "%016lld", balance);

  SHA256_CTX sha256;
  SHA256_Init(&sha256);
  SHA256_Update(&sha256, uid, strlen(uid));
  SHA256_Update(&sha256, buf, 16);
  SHA256_Final(hash, &sha256);
  
  memcpy(node->hash, hash, 8);
}

用户节点都创建完毕后,按照hash值进行排序。

父节点Hash值计算函数

将两两相邻的节点进行汇总,得到父节点,若当前层的节点数为奇数,则将最后一个节点复制,补充为偶数。

父节点的余额为左子节点与右子节点之和,父节点hash值算法:

1
2
3
4
5
hexstr(
    first8bytes(
        sha256(_8bytes(left.sum + right.sum) + _8bytes(left.hash) + _8bytes(right.hash))
    )
)

代码示例:

1
2
3
4
5
6
7
8
9
10
11
12
// make_parent_node
void make_parent_node(const Node *l, const Node *r, Node *p) {
  unsigned char hash[SHA256_DIGEST_LENGTH];
  unsigned char buf[24]= {0};
  
  p->sum = l->sum + r->sum;
  memcpy(buf,    (unsigned char *)&(p->sum),  8);
  memcpy(buf+8,  (unsigned char *)l->hash, 8);
  memcpy(buf+16, (unsigned char *)r->hash, 8);
  SHA256(buf, 24, hash);
  memcpy(p->hash, hash, 8);
}

Merkle Tree

构建Merkle Tree的过程,即向上递归两两合成父节点,至该层节点数为1时停止。

冷钱包地址

  1. 1PufBJk2c2HYq5wNap9yjmjSw6G3iD6mr5
  2. 1EQvpVvPVtZrwwrSoXY1mMrdVuCqaiVKEy

地址签名

1
2
3
4
5
6
7
8
# plain text
this address belongs to bifubao.com, 2014-03-04
 
# signature of 1PufBJk2c2HYq5wNap9yjmjSw6G3iD6mr5
HGcRqoJUq3iINmQ1jCA59KD6Iv0DzcaQxxtkIL9l/+wWo1bREPmh3h35IowYv0DU7lRT54O2wQtQ2rE7AVUxiVk=
 
# signature of 1EQvpVvPVtZrwwrSoXY1mMrdVuCqaiVKEy
G/AMpYGw6aW2gLHdHwkCh+PIHz6gwybXEostNCSmF8RBzEwAOYUFNBD5oI6XFkLRGvFrs58KRP/7Ok9GATZONW0=

数据与源码

  1. 构建树源码:https://github.com/bifubao/proof_of_reserves

示例树结构

参考

  1. prove-how-(non)-fractional-your-Bitcoin-reserves-are scheme https://iwilcox.me.uk/2014/nofrac-orig
  2. Proving Your Bitcoin Reserves https://iwilcox.me.uk/2014/proving-bitcoin-reserves
  3. 图片来自:参考2中的网页