快照日期
BTC
储备金率*
100.3%
ETH
储备金率*
101.3%
SOL
储备金率*
101.1%
USDC
储备金率*
105%+
USDT
储备金率*
105%+
XRP
储备金率*
100.6%
ADA
储备金率*
102.2%
采取问责制,定期审核
Kraken 不仅为您提供交易前沿数字资产的能力,更致力于发挥这些资产运行所在的开源区块链的透明度。
我们定期的储备金证明(Proof of Reserves )审核可便于您验证您所持有的余额是否有实际资产支持,只需在账户上轻松点击几下即可。
“储备金证明”是一个由值得信赖的会计师定期进行的先进的加密会计程序,它让您验证 Kraken 是否满足了严格的责任标准,并提供超过了传统金融公司的透明度。
常见问题
什么是储备金证明?
准备金证明 (PoR) 审核是一个由独立第三方会计师执行的程序。其旨在核实托管人确实持有其声称代表客户持有的资产。该会计师会对持有的所有余额拍摄匿名化快照,并将它们汇总到一个 Merkle Tree 中 —— 一个隐私友好的数据结构,其中封装了所有客户的余额。
从那里,会计师会获取一个 Merkle Root:一个在创建快照时唯一标识这些余额组合的加密指纹。
然后,会计师收集由 Kraken 生成的数字签名,这些签名证明了对链上地址的所有权,并且这些地址的余额是可以公开验证的。最后,会计师比较并验证这些余额是否超过或匹配默克尔树中所表示的客户余额,从而确保客户的资产在 Kraken 的控制之下。
任何客户都可以通过将某些数据片段与 Merkle Root 进行比较,来独立验证自己的余额是否包含在“储备金证明”程序中。对其余数据所做的任何更改,无论多小,都会影响根——使篡改变得明显。
请参阅此处查阅我们的准备金证明报告。
“储备金证明”涵盖了什么?
现货余额
审核将包含您在拍摄快照时所持有的所有范围内的资产余额。最新一轮审核所涵盖的资产如下:Bitcoin (BTC)、Ether (ETH)、Solana (SOL)、USD Coin (USDC)、Tether (USDT) 和 Ripple (XRP)。
质押余额
如果您在拍摄快照时有余额参与链上质押,该质押余额的价值将与您的现货余额合并为一个总余额。
保证金交易
如果您在拍摄快照时持有保证金头寸,那么您的总余额会根据头寸的正向值进行调整。
示例 1
如果您通过保证金买入了 1 BTC/USD,价格为 30,000 美元,且您的头寸尚未平仓,那么您的储备金证明余额将体现出 BTC 余额 +1 BTC 的正向调整。美元余额不会产生任何负向调整。您在 Kraken Custody 下持有的 BTC 资产余额将包含您当时的 BTC 余额,并且保证金头寸将根据 +1 BTC 的正向调整进行调整。您的美元资产余额将保持不变。
示例 2
如果您通过保证金卖出了 1 BTC/ETH,且您的头寸尚未平仓,那么您的储备金证明余额将体现出 ETH 余额 +15 ETH 的正向调整。BTC 余额不会产生任何负向调整。您在 Kraken Custody 下持有的 ETH 资产余额将包含您当时的 ETH 余额,并且保证金头寸将根据 +15 ETH 的正向调整进行调整。您在 Kraken Custody 下持有的 BTC 资产余额保持不变。
注意:Kraken Futures 目前不对美国和其他国家/地区的客户开放。上述期货计算方法自 2023 年 5 月的储备金证明审核起正式生效。
期货余额
如果您在审核时期货钱包中有余额,将为您单独生成一份针对期货抵押品余额的储备金证明记录。对于单抵押品期货交易,余额会根据未实现盈亏进行调整。其中包括与现货和保证金相同的范围内资产,并纳入同一 Merkle Tree(但拥有其自己的 Merkle Leaf ID)。
示例 1
如果您的期货钱包中有 1 BTC,您以单抵押品 BTC 永续合约开立了一个头寸,当前未实现盈亏为 -0.1 BTC,那么您在 Kraken Custody 下持有的 BTC 余额将为 0.9 BTC(您的 1 BTC 将根据 -0.1 BTC 的未实现盈亏进行调整)。
示例 2
如果您的期货钱包中有 1 BTC,您以多抵押品 BTC 永续合约开立了一个头寸,当前未实现盈亏为 -100.0 美元,那么您在 Kraken Custody 下持有的 BTC 余额将为 1 BTC(由于以美元计价,而美元不在本次审核的范围内,故而无需根据未实现盈亏调整您的 1 BTC)。
注意:Kraken Futures 目前不对美国和其他国家/地区的客户开放。上述期货计算方法自 2023 年 5 月的储备金证明审核起正式生效。
如何确认我的账户是否已纳入储备金证明审核的范围?
简单验证
请按照以下步骤,通过密码学方式验证您的 Kraken 账户余额是否已包含在最新的储备金证明审核中。
注意:Kraken Futures 目前不对美国和其他国家/地区的客户开放。本次验证仅体现审核时您账户范围内资产的余额。不会体现之后的任何交易,也不会体现不在范围内的资产余额。
1.登录您的 Kraken 账户,进入 Kraken Pro 界面 (pro.kraken.com),导航到“准备金证明”页面(账户图标 > 准备金证明)。
2.选择准备金证明选项卡。页面会显示我们最近已验证的储备金率,以及与您账户相关的特定信息。您的账户将显示近期已验证账户余额的储备金证明报告,包括报告日期、审核提供方以及评估范围。
3.选择日期,然后点击自行验证。在此页面,您将看到审核时所持有余额的确认信息,以及有关如何验证个人信息的完整指引。
与第三方会计师审核
-
使用您的 Merkle Leaf ID - 复制前 16 个字符,并粘贴到第三方会计师的审核工具中,即可检索您的余额并在 Merkle Tree 路径中查看您的 ID。第三方会计师的审核工具将在单独的窗口中打开。
注意:Kraken Futures 目前不对美国和其他国家/地区的客户开放。此功能适用于自 2023 年起的审核。对于早期的审核,请前往我们合作伙伴的网页查找相应审核工具。
通过Kraken进行验证
- 验证您的记录 ID - 按照步骤重新生成您的记录 ID,该 ID 将唯一标识您的账户详情以及审核 ID(每个报告日期唯一所有)
- 验证您的 Merkle Leaf ID - 按照步骤重新生成您的 Merkle Leaf ID,该 ID 将唯一标识您的账户及其在拍摄审核快照时持有的余额
- 在 Merkle Tree 中确认您的 Merkle Leaf ID - 确认您的 ID 属于 Merkle Tree,并校验到 Merkle Tree Root 的路径,该 Root 由我们的第三方会计师验证,并由所有客户共享
注意:此功能适用于自 2023 年起的审核。对于早期的审核,请前往我们合作伙伴的网页查找相应审核工具。
高级验证
技术熟练的用户可能不想依赖 Kraken 或第三方会计师提供的可视化工具,而是以编程方式自行重建特定的 Merkle Tree Leaf 节点哈希并在 Merkle Tree 中查询余额。
您可以通过代码执行以下验证步骤:
-
您可以按照以下步骤,验证自己账户的 Merkle Tree Leaf ID 的生成过程。
-
然后再验证该 Leaf ID 的 Merkle Tree 路径,并重建从您的位置到根节点的完整路径。我们将提供完全的透明度,并同时给出兄弟 Leaf ID。
下面概述了根据您的账户代码、Kraken IIBAN、审核 ID 以及余额,用伪代码重建记录 ID 和 Merkle Leaf 的必要步骤。请注意:结果对余额的字符串格式以及“准备金证明”页面显示的已审核资产的顺序极为敏感。
- 记录 ID = SHA256(concatenate(Account Code, Kraken IIBAN, Review ID))
- 余额 = ""
- 对于每一周资产:
- 余额 = concatenate(Asset, ":", AssetBalances[asset])
- Merkle 哈希 = concatenate(Record ID, “,”, Balances)
- Merkle Leaf = substring(SHA256(Merkle Hash), 0, 16)
在确定您的 Merkle Leaf 后,可通过采用十六进制值的 SHA256 验证重建 MMerkle Tree 路径。
下方的代码片段中也提供了具体示例。计算所得的 Merkle Leaf 同样会显示在审核详情中,供您确认是否正确重建。
Python
import hashlib
# Merkle Leaf ID calculation
account_code = "8dc20f34da8cea8dd0f46b001694f5123ecd30d786c5eb92ad1a013703a4f8d1"
iiban = "AB12C34DEFG5KSQI"
review_id = "PR30SEP24"
record_id = hashlib.sha256((account_code + iiban + review_id).encode('utf-8')).hexdigest()
balances = "BTC:0.00093799,ETH:0.0422125592,SOL:0.0,USDC:0.0,USDT:6.72754,XRP:0.0"
print("Record ID: {}".format(record_id))
print("Merkle Hash: {}".format((record_id + "," + balances)))
hash_result = hashlib.sha256((record_id + "," + balances).encode('utf-8')).hexdigest()
print("SHA Result: {}".format(hash_result))
print("Merkle Leaf: {}".format(hash_result[0:16]))
#Merkle Tree Path function
def mix(x, y):
a = bytes.fromhex(x)
b = bytes.fromhex(y)
d = hashlib.sha256()
d.update(a)
d.update(b)
return d.hexdigest()Rust
use sha2::{Digest, Sha256};
//Merkle Leaf ID calculation
const ACCOUNT_CODE: &str = "8dc20f34da8cea8dd0f46b001694f5123ecd30d786c5eb92ad1a013703a4f8d1";
const IIBAN: &str = "AB12C34DEFG5KSQI";
const REVIEW_ID: &str = "PR30SEP24";
const BALANCES: &str = "BTC:0.00093799,ETH:0.0422125592,SOL:0.0,USDC:0.0,USDT:6.72754,XRP:0.0";
fn main() {
let mut record_hasher: Sha256 = Default::default();
record_hasher.update(ACCOUNT_CODE);
record_hasher.update(IIBAN);
record_hasher.update(REVIEW_ID);
let record_id = format!("{:x}", record_hasher.finalize());
let merkle_hash = format!("{},{}", record_id, BALANCES);
let mut merkle_hasher: Sha256 = Default::default();
merkle_hasher.update(&merkle_hash);
let merkle_result = format!("{:x}", merkle_hasher.finalize());
println!("Record ID: {}", record_id);
println!("Merkle Hash: {}", merkle_hash);
println!("SHA Result: {}", merkle_result);
println!("Merkle Leaf: {}", &merkle_result[..16]);
}
//Merkle Tree Path function
fn mix(x: &str, y: &str) -> Result<String, hex::FromHexError> {
let mut leaves_hasher: Sha256 = Default::default();
let a = hex::decode(x)?;
let b = hex::decode(y)?;
leaves_hasher.update(&a);
leaves_hasher.update(&b);
Ok(hex::encode(leaves_hasher.finalize()))
}
fn main() {
println!("{}", mix("f42372aeb1be7296", "dfcced6ec3235f5e").unwrap());
assert_eq!(
mix("f42372aeb1be7296", "dfcced6ec3235f5e").unwrap(),
"ad86a5ee2f21347403ce07e365530604690454fa76787e76be9d2f6efdceeabf"
);
}Go
package main
import (
"crypto/sha256"
"fmt"
)
//Merkle Leaf ID Calculation
func main() {
accountCode := "8dc20f34da8cea8dd0f46b001694f5123ecd30d786c5eb92ad1a013703a4f8d1"
iiban := "AB12C34DEFG5KSQI"
reviewId := "PR30SEP24"
secret := accountCode + iiban + reviewId
data := []byte(secret)
hash := sha256.Sum256(data)
recordId := string(hash[:])
fmt.Printf("Record ID: %x\n", recordId)
balances := "BTC:0.00093799,ETH:0.0422125592,SOL:0.0,USDC:0.0,USDT:6.72754,XRP:0.0"
merkleHash := fmt.Sprintf("%x%s%s", recordId, ",", balances)
fmt.Printf("Merkle Hash: %s\n", merkleHash)
hashResult := sha256.Sum256([]byte(merkleHash))
hashResultStr := string(hashResult[:])
fmt.Printf("SHA Result: %x\n", hashResultStr)
fmt.Printf("Merkle Leaf: %x\n", hashResultStr[0:8])
}
//Merkle Tree path hashing
func mix(x, y string) (string, error) {
// Convert the hex strings to bytes
a, err := hex.DecodeString(x)
if err != nil {
return "", err
}
b, err := hex.DecodeString(y)
if err != nil {
return "", err
}
h := sha256.New()
h.Write(a)
h.Write(b)
// Get the final hash value as a byte slice
hashed := h.Sum(nil)
// Convert the hash to a hex string and return it
return hex.EncodeToString(hashed), nil
}
func main() {
result, _ := mix("f42372aeb1be7296", "dfcced6ec3235f5e")
fmt.Println(result)
}Bash
#!/bin/bash
#Merkle Leaf ID calculation
ACCOUNT_CODE="8dc20f34da8cea8dd0f46b001694f5123ecd30d786c5eb92ad1a013703a4f8d1"
IIBAN="AB12C34DEFG5KSQI"
REVIEW_ID="PR30SEP24"
RECORD_ID=$(echo -n "${ACCOUNT_CODE}${IIBAN}${REVIEW_ID}" | sha256sum | head -c 64)
BALANCES="BTC:0.00093799,ETH:0.0422125592,SOL:0.0,USDC:0.0,USDT:6.72754,XRP:0.0"
MERKLE_HASH="${RECORD_ID},${BALANCES}"
HASH_RESULT=$(echo -n ${MERKLE_HASH} | sha256sum | head -c 64)
echo "Record ID: ${RECORD_ID}"
echo "Merkle Hash: ${MERKLE_HASH}"
echo "SHA Result: ${HASH_RESULT}"
echo "Merkle Leaf: $(echo -n ${HASH_RESULT} | head -c 16)"
#Merkle Tree Path function
hex_string1="f42372aeb1be7296"
hex_string2="dfcced6ec3235f5e"
# convert hex strings to binary, concatenate them and then hash
hash_result=$(echo -n "$(echo -n $hex_string1 | xxd -r -p)$(echo -n $hex_string2 | xxd -r -p)" | sha256sum | awk '{ print $1 }')
echo $hash_result不足之处与未来改进
对比 Kraken 的储备金证明报告,上文标注星号 (*) 的储备金率数据,可能会因产品更迭及托管基础设施的持续升级而发生重大变化,此类变化可能会影响部分钱包内资产的分类方式。根据现行惯例,所有报告中均包含对储备金证明核算方法的详细说明。