BitcoinSand + 币付宝

全球第一家比特币银行“BitcoinSand”正式与币付宝合作,开展币付宝用户存款业务。

“BitcoinSand”作为全球第一家比特币银行,掀起了比特币金融业务向理性、繁荣发展的序幕。“BitcoinSand”采用相对专业的操作方法和业务模式(个人钱包、签名等)实现了比特币的稳定收益,但这同时又让很多普通用户望而却步。

现在,在比特基金的推动下,“BitcoinSand”正式与币付宝合作,彻底解决了这一问题。

币付宝凭借自身技术优势,实现了与“BitcoinSand”的平滑对接。简洁的操作方法、熟悉的传统金融业务模式,让比特币新手、老手、死多都能轻松实现长期获益。

特性

  • 操作简单
  • 投资门槛低(0.1BTC)
  • 随时提款(24小时到账)
  • 长期稳定收益 (截至2014年7月,BitcoinSand已平稳运营整整一年,发放利息总量 154.2 BTC)

使用介绍

  • 点击功能列表中的“理财”选项

  • 点击存款按钮,按提示操作即可

  • 最近7天利息收益图表(发放2次以上利息后显示)

  • 下图为手机浏览效果

  • 取款时请注意取款手续费和实际到账金额

  • 取款将于24小时后发送到您的币付宝钱包内

FAQ

  • 发放利息的时间?

    北京时间每天中午12:00开始发放利息。您也可以点击理财页面中的“查看详情”查看下次利息发放的时间。

  • 什么是最小起息金额?

    同一用户,发放利息的最小存款金额;即:只有当用户的存款金额大于最小起息金额时才会收到相应的利息。

  • 什么是最大存款金额?

    同一用户,允许存款的最大存款金额。

  • 什么是存款总上限?

    BitcoinSand总存款金额的上限。

  • 什么是取款等待时间?

    用户提交取款申请起,至取款操作执行的间隔时间。

  • 为什么取款要手续费?

    由于银行存款总量限制,为防止用户短时恶意存取款导致准备金不足,故引入取款手续费一项。

  • 取款时,为什么会超出等待时间?

    极少情况下,当用户大额提款时,BitcoinSand需要一定时间准备资金,请耐心等待,最多不会超过72小时。如有疑问,请您联系币付宝客服。




BitcoinSand: 全球第一家比特币银行

简介

  • BitcoinSand是由李笑来先生创立的全球第一家比特币银行,由比特基金做运营支持。

  • BitcoinSand自2013年7月13日创立至今,已平稳运营整整1年。

  • BitcoinSand一直秉持着公开、透明、极简的运营理念。

历史

数据

截至2014年7月,Bitcoinsand核心数据

总存款量:

11707.89 BTC

最大存款日及最大存款量:

2014年6月4日    6433.94 BTC

日均存款:

32.08 BTC

发放利息总量:

154.20 BTC

存款个体总量:

311(独立存款的比特币地址)

最大单笔存款:

600 BTC

什么是 callback_url, redirect_url

redirect_url

如果您填了这个选项,那么用户在支付完成后会显示一个"返回商家页面"的按钮,该按钮会链接到redirect_url。有了这个选项以后可以使整个支付流程更加的连贯。

callback_url

这个选项是为了有需要通过程序自动化监控您的订单的需求而设定的。如果您没有这样的需求,那么可以不用了解。

为了方便您和您自己的系统进行整合以及便于管理,我们提供了这个选项,当一个订单完成时,我们的后台会访问您提供的这个url。

系统访问这个url会有重试机制,为了让系统知道请求确实成功了,您在程序上应该原样返回一个参数,这个参数名是 _request_check_

我们采用了签名的方式(sha1)来让程序确认请求确实来自币付宝而并非其他的用户。

币付宝的公钥为

-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAqUSnx8dqJ0UC0jvFTEdL
gde7BSmKi8GzDnxvu/AMQw7TG3pRKAAKQJRYUSqpgMyOwUSrv3yfu3gBJwufjWJz
Kgtm8D9TOoYnZMJm4x5Lv9/EpYEg0zrAsmU/6rZJ9mYRaNPrt811Thju0/19fa77
XnsQ78UmvV4zCePkKAArO70SsU/hf1SinDX//t0a3/UOk0DhKoJZpzjb5mb+dcXM
GOJKpAONDGDK2UE1W67HmIG72b/R/G8CAFYbw4MGCjb0/Ee6obcAGK3Cj1JcuHjH
NzymBH0NuDvyz7fJuTg9Eplnh1blNeCJoG/vv7VLZNKetTMTx+H2X534RUQ4XheX
4QIDAQAB
-----END PUBLIC KEY-----

系统给您的程序提交的http请求里面包含了这个订单的信息,参数的列表参考示例程序。

php示例程序

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
<?php
/**
 * 币付宝回调示例程序
 * Bitfoo Callback Example
 * 
 * @author Panlilu
 * @copyright bifubao.com
 */


if (empty($_POST['_request_check_']) || empty($_POST['_signature_']) || 
    empty($_POST['_request_id_'])) {
  echo "invalid request_check or signature or request_id.";exit;
}

// bifubao rsa public, production

$bifubao_pubkey = "-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAqUSnx8dqJ0UC0jvFTEdL
gde7BSmKi8GzDnxvu/AMQw7TG3pRKAAKQJRYUSqpgMyOwUSrv3yfu3gBJwufjWJz
Kgtm8D9TOoYnZMJm4x5Lv9/EpYEg0zrAsmU/6rZJ9mYRaNPrt811Thju0/19fa77
XnsQ78UmvV4zCePkKAArO70SsU/hf1SinDX//t0a3/UOk0DhKoJZpzjb5mb+dcXM
GOJKpAONDGDK2UE1W67HmIG72b/R/G8CAFYbw4MGCjb0/Ee6obcAGK3Cj1JcuHjH
NzymBH0NuDvyz7fJuTg9Eplnh1blNeCJoG/vv7VLZNKetTMTx+H2X534RUQ4XheX
4QIDAQAB
-----END PUBLIC KEY-----";

$pubkey_id = openssl_pkey_get_public($bifubao_pubkey);

$signature_sha1 = base64_decode($_POST['_signature_sha1_']);
// verify
if (openssl_verify(bifubao_make_sign_data($_POST), $signature_sha1, 
                   $pubkey_id, OPENSSL_ALGO_SHA1) !== 1) {
  echo "openssl_verify failure(sha1)";exit;
}



$_order =  json_decode($_POST['content'],1);


/*
$order = array(
    // the order content
    'order_id'      => $_order['order_id'],
    'order_hash_id' => $_order['order_hash_id'],
    'external_order_id' => $_order['external_order_id'],
    'handle_status'     => $_order['handle_status'], 
    'external_info'     => $_order['external_info'],
    'display_name'      => $_order['display_name'],
    'display_desc'      => $_order['display_desc'],
    'pay_user_id'       => $_order['pay_user_id'],
    'quantity'          => $_order['quantity'],
    'discount'          => $_order['discount'],
    'price_btc'         => $_order['price_btc'],
    'price_cny'         => $_order['price_cny'],
    'pay_btc'           => $_order['pay_btc'],  // unit: satoshi
    'ratio_btc2cny'     => $_order['ratio_btc2cny'],
    'onchain_receive_btc_address' => $_order['onchain_receive_btc_address'],
    'onchain_leave_message'       => $_order['onchain_leave_message'],
    'offchain_leave_message'      => $_order['offchain_leave_message'],
    'order_receipt_id'            => $_order['order_receipt_id'],
    'product_id'                  => $_order['product_id'],
    'creation_time'               => $_order['creation_time'],
    'last_modify_time'            => $_order['last_modify_time'],
);
*/

if ($_order['handle_status'] < 1000) {
  // todo : handle the order when bitcoin recieved is correct
  // 在这里完成当收到的比特币数量不正确时候的处理逻辑
  exit;
}

// todo: handle the order content
// 在这里实现支付完成时的逻辑


// return _request_check_
echo $_POST['_request_check_'];

exit;

// generate sign data string
function bifubao_make_sign_data($arr) {
	unset($arr['_signature_']);
	unset($arr['_signature_sha1_']);
	ksort($arr);
	$sign_str = '';
	if (!empty($arr)) {
		foreach ($arr as $_k => $_v) {
			$sign_str .= $_k . $_v;
		}
	}
	return $sign_str;
}


?>

How to use callback_url & redirect_url

redirect_url

If you fill the redirect_url option, then a button called "return to merchant's website" will display right after the payment is completed. The button will link to this redirect_url. The entire payment process will be more consistent with this option.

callback_url

Please ignore this section, if you don't have needs to process your orders automatically.

We offer this option, so that you can integrate the payment button to your own system. While an order is complete, our system will access your callback_url with a POST REQUEST.

Our system will retry 3 times until the request is successfully made, while you should return the parameter _request_check_.

We use a parameter signature (sha1 encrypted) to identify the POST which is from our system.

Our Public Key is:

-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAqUSnx8dqJ0UC0jvFTEdL
gde7BSmKi8GzDnxvu/AMQw7TG3pRKAAKQJRYUSqpgMyOwUSrv3yfu3gBJwufjWJz
Kgtm8D9TOoYnZMJm4x5Lv9/EpYEg0zrAsmU/6rZJ9mYRaNPrt811Thju0/19fa77
XnsQ78UmvV4zCePkKAArO70SsU/hf1SinDX//t0a3/UOk0DhKoJZpzjb5mb+dcXM
GOJKpAONDGDK2UE1W67HmIG72b/R/G8CAFYbw4MGCjb0/Ee6obcAGK3Cj1JcuHjH
NzymBH0NuDvyz7fJuTg9Eplnh1blNeCJoG/vv7VLZNKetTMTx+H2X534RUQ4XheX
4QIDAQAB
-----END PUBLIC KEY-----

The POST contains a list of the infomation related to the order, you can check out the parameters in the sample code.

php sample code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
<?php
/**
 * 币付宝回调示例程序
 * Bitfoo Callback Example
 * 
 * @author Panlilu
 * @copyright bifubao.com
 */


if (empty($_POST['_request_check_']) || empty($_POST['_signature_']) || 
    empty($_POST['_request_id_'])) {
  echo "invalid request_check or signature or request_id.";exit;
}

// bifubao rsa public, production

$bifubao_pubkey = "-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAqUSnx8dqJ0UC0jvFTEdL
gde7BSmKi8GzDnxvu/AMQw7TG3pRKAAKQJRYUSqpgMyOwUSrv3yfu3gBJwufjWJz
Kgtm8D9TOoYnZMJm4x5Lv9/EpYEg0zrAsmU/6rZJ9mYRaNPrt811Thju0/19fa77
XnsQ78UmvV4zCePkKAArO70SsU/hf1SinDX//t0a3/UOk0DhKoJZpzjb5mb+dcXM
GOJKpAONDGDK2UE1W67HmIG72b/R/G8CAFYbw4MGCjb0/Ee6obcAGK3Cj1JcuHjH
NzymBH0NuDvyz7fJuTg9Eplnh1blNeCJoG/vv7VLZNKetTMTx+H2X534RUQ4XheX
4QIDAQAB
-----END PUBLIC KEY-----";

$pubkey_id = openssl_pkey_get_public($bifubao_pubkey);

$signature_sha1 = base64_decode($_POST['_signature_sha1_']);
// verify
if (openssl_verify(bifubao_make_sign_data($_POST), $signature_sha1, 
                   $pubkey_id, OPENSSL_ALGO_SHA1) !== 1) {
  echo "openssl_verify failure(sha1)";exit;
}



$_order =  json_decode($_POST['content'],1);


/*
$order = array(
    // the order content
    'order_id'      => $_order['order_id'],
    'order_hash_id' => $_order['order_hash_id'],
    'external_order_id' => $_order['external_order_id'],
    'handle_status'     => $_order['handle_status'], 
    'external_info'     => $_order['external_info'],
    'display_name'      => $_order['display_name'],
    'display_desc'      => $_order['display_desc'],
    'pay_user_id'       => $_order['pay_user_id'],
    'quantity'          => $_order['quantity'],
    'discount'          => $_order['discount'],
    'price_btc'         => $_order['price_btc'],
    'price_cny'         => $_order['price_cny'],
    'pay_btc'           => $_order['pay_btc'],  // unit: satoshi
    'ratio_btc2cny'     => $_order['ratio_btc2cny'],
    'onchain_receive_btc_address' => $_order['onchain_receive_btc_address'],
    'onchain_leave_message'       => $_order['onchain_leave_message'],
    'offchain_leave_message'      => $_order['offchain_leave_message'],
    'order_receipt_id'            => $_order['order_receipt_id'],
    'product_id'                  => $_order['product_id'],
    'creation_time'               => $_order['creation_time'],
    'last_modify_time'            => $_order['last_modify_time'],
);
*/

if ($_order['handle_status'] < 1000) {
  // todo : handle the order when bitcoin recieved is correct
  // 在这里完成当收到的比特币数量不正确时候的处理逻辑
  exit;
}

// todo: handle the order content
// 在这里实现支付完成时的逻辑


// return _request_check_
echo $_POST['_request_check_'];

exit;

// generate sign data string
function bifubao_make_sign_data($arr) {
	unset($arr['_signature_']);
	unset($arr['_signature_sha1_']);
	ksort($arr);
	$sign_str = '';
	if (!empty($arr)) {
		foreach ($arr as $_k => $_v) {
			$sign_str .= $_k . $_v;
		}
	}
	return $sign_str;
}


?>

个性化比特币地址

币付宝推出了个性化比特币地址定制服务!从今天起,您可以选择您喜欢的字母或数字组合作为个性地址的前端。您可以参考以下范例:

  • 1BifubaoCT6C7teCt4EtDHXiTYyQUZAPkZ
  • 1Love1bUmhSoTXozBRBEtRe8LeF9TGbZBN
  • 12345678Xge3bCCWyLxV86hPStT4EUAWT7

您的个性化比特币收款地址会显示在您的账户中,其他比特币用户可以直接将比特币发送至您的个性地址。币付宝团队已搭建了专门生成个性地址的矿机,您可以在生成新的收款地址时选择属于您的个性地址。

个性地址的价格由您所设置的个性化部分的长度决定(见下表):个性化部分越长,需要的算力就越强,价格也更高。币付宝支持3至8位的个性化定制,生成个性地址的时间不尽相同,下表中的地址平均生成时间仅供参考。个性地址使用人民币定价,比特币收款。

由于我们计算地址的原理实际上是进行不断的生成随机地址并校验,所以我们给出的预计生成时间仅供参考,实际出地址结果的时间也有很大的运气成分。举例说如果你生成一个预计3小时的地址,如果运气好可能1小时就出了而运气不好的话甚至需要12小时。整体而言服从正态分布

个性地址价格表:

个性化部分长度 平均生成时间 价格 (RMB)
1, 2, 3, 4 少于1分钟 6
4 3分钟 12
5 少于1分钟 6
5 3分钟 48
5 3小时 196
6 3分钟 98
6 3小时 388
6 7天 1,680
7 3小时 488
7 7天 1,880
8 7天 2,980

最后更新时间: 2014-03-26

我们会在您输入个性化部分时自动计算出生成该地址所需要的时间和价格。

定制个性地址时有以下5点需要注意:

  1. 每一个比特币地址的起始位为数字1,您选择的个性化定制部分从第二位开始(见范例)。您定制的个性化部分以外的部分随机产生,我们无法进行干预。
  2. 您定制的个性化部分并不唯一,例如,多个用户可同时购买1Love开头的比特币地址。因此,您在发款或收款时应格外注意输入的地址是否正确。
  3. 由于比特币地址的格式要求,我们仅支持字母和数字的组合(字母区分大小写),并且以下数字和字母不能作为地址的一部分:
    • I (大写字母i)
    • l (小写字母l)
    • O (大写字母o)
    • 0 (数字0)
  4. 个性化地址与您的币付宝账户绑定,您只能通过币付宝使用定制地址。
  5. 个性化地址一经售出,无法退款。

希望您喜欢我们的新功能!

币付宝团队

Bitcoin Vanity Addresses

You can now obtain your own bitcoin vanity address to use with your Bifubao account! A vanity address is a custom bitcoin address that includes a custom piece of text embedded in it as a prefix. The following are examples of vanity addresses:

  • 1BifubaoCT6C7teCt4EtDHXiTYyQUZAPkZ
  • 1Love1bUmhSoTXozBRBEtRe8LeF9TGbZBN
  • 12345678Xge3bCCWyLxV86hPStT4EUAWT7

People can send you bitcoins directly to this address, and it will show up on your Bifubao account. We've set aside a few dedicated miners to calculate these addresses, and you can order them right from your account page when creating a new address.

When you purchase a vanity address, we will directly debit your bitcoin account for the cost. The price for each vanity address varies depending on the length and the difficulty of the custom segment that you wish to have. Take a look at the table below, for reference. As the length of the segment increases, the mining power required to calculate this address increases exponentially. We support the custom prefixes of the lengths sent forth below. Keep in mind that the calculation times may vary significantly from the average time! We base the price on RMB, but we will take payment in bitcoins, of course.

Here is our pricing structure:

Prefix Length Average Calculation Time Cost (RMB)
1, 2, 3, 4 less than one minute 6
4 3 minutes 12
5 less than one minute 6
5 3 minutes 48
5 3 hours 196
6 3 minutes 98
6 3 hours 388
6 7 days 1,680
7 3 hours 488
7 7 days 1,880
8 7 days 2,980

last update: 2014-03-26

It looks complicated, but don't worry - we will calculate the price for you right as you type in your prefix.

Some things to keep in mind:

  1. Each bitcoin address necessarily starts with a 1. The prefix that you choose will show up directly after this 1, like the examples above. We have no way to predict the letters that come after your selected prefix.
  2. Your particular vanity address is unique, but other people could request the same prefix. For example, many people can purchase vanity addresses that start with 1Love. You should still take care to ensure that you are sending or receiving bitcoins to the correct address.
  3. Because of Bitcoin's address format, only letters and numbers are allowed, and the following characters are prohibited:
    • I (capital letter i)
    • l (lowercase l)
    • O (capital letter o)
    • 0 (the number 0)
  4. These custom addresses are tied to your Bifubao account. You won't be able to use these addresses with any other wallet.
  5. The purchases are nonrefundable.

We hope you like this new feature!

The Bifubao Team

币付宝Android客户端正式上线!

今天,币付宝正式推出了安卓手机客户端!用户可以随时随地通过手机客户端完成比特币的发款与收款。您可以单独使用网页版币付宝,或结合币付宝手机客户端一起使用——我们已将币付宝的基本功能嵌入手机客户端:

  • 币付宝用户之间发款瞬间到账且操作完全免费
  • 通过邮箱、手机号、比特币地址(含二维码)进行发款
  • 用户自定义头像
  • 联系人列表
  • 简约的操作界面

用户使用手机客户端发款时须设置独立的6位支付密码,此密码仅作为手机端支付使用。为增强应用的安全性,我们建议用户设置解锁图案,并从知名的手机应用市场下载我们的客户端。

快来体验币安卓手机客户端,让币付宝真正成为您的私人钱包!欢迎您将使用体验反馈给我们。

币付宝团队

下载安卓APK

或扫描以下二维码:

Bifubao's Android App is Here!

We're excited to announce that our Android app is now available! Now you can use the Bitfoo mobile app send and receive bitcoins anytime, anywhere. You can use the app independently or in conjunction with our web app - all of the your favorite Bitfoo functions are baked right in, including:

  • immediate and free transactions between Bitfoo users
  • send via email, mobile phone, or Bitcoin addresses (via QR codes)
  • Gravatar icons
  • simple, intuitive interface
  • Contact lists
  • And more!

Users will be required to set a six-digit payment password to send bitcoins using the app. For additional security, we encourage users to set an unlock code on their phone, install a virus scanner, and to make sure you download the application from a reputable source.

We hope you enjoy the Bitfoo mobile client! As always, let us know if you have any comments.

The Bitfoo Team

Download Android APK

Or just scan the QR code below:

中央电视台报导币付宝

央视新闻频道《朝闻天下》栏目在2014年3月15日的“比特币之争”节目中报导了币付宝!节目视频中,央视记者来到我们的办公室参观,对比特币以及币付宝进行了了解。币付宝联合创始人之中的两位 - 李笑来先生和潘志彪先生 - 也在节目中现身。您可以在这里. 这里观看该期节目。

感谢央视登门拜访,也欢迎您随时再来!

*在此更正节目中的一条错误信息,币付宝并未达到“每天的用户注册量都在1000人以上” —— 当然我们也希望这一天尽快到来!

CCTV visits Bifubao!

Bifubao was featured in a CCTV segment on Bitcoin! CCTV paid a visit to our humble office in the video and we were able to chat with them about what we are building and Bitcoin. Two of our cofounders, Li Xiao Lai and Pan Zhi Biao were featured. You can watch the segment here.

Thank you to CCTV for coming by and visiting our offices. Come back anytime!

*To correct a misstatement in the segment, we aren’t quite adding one thousand users per day just yet (although we certainly wouldn’t mind!).

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中的网页