储备金证明

随时证明您的资金安全无虞。

快照日期

BTC icon

BTC

储备金率*

100.3%

ETH icon

ETH

储备金率*

101.3%

SOL icon

SOL

储备金率*

101.1%

USDC icon

USDC

储备金率*

105%+

USDT icon

USDT

储备金率*

105%+

XRP icon

XRP

储备金率*

100.6%

ADA icon

ADA

储备金率*

102.2%

采取问责制,定期审核

Kraken 不仅为您提供交易前沿数字资产的能力,更致力于发挥这些资产运行所在的开源区块链的透明度。

我们定期的储备金证明(Proof of Reserves )审核可便于您验证您所持有的余额是否有实际资产支持,只需在账户上轻松点击几下即可。

“储备金证明”是一个由值得信赖的会计师定期进行的先进的加密会计程序,它让您验证 Kraken 是否满足了严格的责任标准,并提供超过了传统金融公司的透明度。

常见问题

什么是储备金证明?

准备金证明 (PoR) 审核是一个由独立第三方会计师执行的程序。其旨在核实托管人确实持有其声称代表客户持有的资产。该会计师会对持有的所有余额拍摄匿名化快照,并将它们汇总到一个 Merkle Tree 中 —— 一个隐私友好的数据结构,其中封装了所有客户的余额。

Merkle Root Hash

从那里,会计师会获取一个 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),导航到“准备金证明”页面(账户图标 > 准备金证明)。 

Kraken Proof of Reserves review list

2.选择准备金证明选项卡。页面会显示我们最近已验证的储备金率,以及与您账户相关的特定信息。您的账户将显示近期已验证账户余额的储备金证明报告,包括报告日期、审核提供方以及评估范围。 

Kraken Proof of Reserves review list

3.选择日期,然后点击自行验证。在此页面,您将看到审核时所持有余额的确认信息,以及有关如何验证个人信息的完整指引。

Kraken audit details

与第三方会计师审核

  • 使用您的 Merkle Leaf ID - 复制前 16 个字符,并粘贴到第三方会计师的审核工具中,即可检索您的余额并在 Merkle Tree 路径中查看您的 ID。第三方会计师的审核工具将在单独的窗口中打开。 

注意:Kraken Futures 目前不对美国和其他国家/地区的客户开放。此功能适用于自 2023 年起的审核。对于早期的审核,请前往我们合作伙伴的网页查找相应审核工具。

Kraken audit details

通过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 audit details
Kraken audit details
Kraken audit details

高级验证

技术熟练的用户可能不想依赖 Kraken 或第三方会计师提供的可视化工具,而是以编程方式自行重建特定的 Merkle Tree Leaf 节点哈希并在 Merkle Tree 中查询余额。 

您可以通过代码执行以下验证步骤:

  1. 您可以按照以下步骤,验证自己账户的 Merkle Tree Leaf ID 的生成过程。  

  2. 然后再验证该 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

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

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

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

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 的储备金证明报告,上文标注星号 (*) 的储备金率数据,可能会因产品更迭及托管基础设施的持续升级而发生重大变化,此类变化可能会影响部分钱包内资产的分类方式。根据现行惯例,所有报告中均包含对储备金证明核算方法的详细说明。