验证 Pedersen 承诺值

Oracle Blockchain Platform Digital Assets Edition 使用 Pedersen 承诺来确保保密性和不可变性。以下 API 可帮助根据实际原始文本值验证 Pedersen 承诺。

在 Oracle Blockchain Platform 中,通过连接到 Oracle Database,数据可以持久存储在富历史记录数据库中。帐户和事务作为键/值对存储在状态数据库中,可以随着时间的推移在富历史记录数据库中进行跟踪。在保密模式下,帐户和事务都存储在富历史记录数据库的历史记录表中的私有和公共两部分。

丰富的历史记录数据库的历史记录表中提供了组织的所有公共和专用数据。表名使用以下格式:<obp_instance_name>_<channel_name>_hist。例如,CentralBank_default_hist

公共账户数据(状态数据库)
  • 存储在链代码 ID 下:<chaincode_name>
  • 可供所有网络参与者使用
  • 常规账户属性,例如 org_idtoken_namebalance/onhold_balance(作为 Pedersen 承诺)和其他非机密元数据
私人账户数据(私人数据收集)
  • 存储在链代码 ID 下:<chaincode_name>$$_implicit_org_<Oracle_Blockchain_Platform_instance_name>
  • 仅可访问拥有专用数据收集的组织
  • 敏感字段,例如 balance/onhold_balance(原始值)、balanceBlindingFactoronHoldBalanceBlindingFactor 和每日限制
公共事务处理数据(状态数据库)
  • 存储在链代码 ID 下:<chaincode_name>
  • 可供所有网络参与者使用
  • 常规账户属性,如发送方和接收方账户 ID、from_account_balance/from_account_onhold_balance/to_account_balance/to_account_onhold_balance/交易金额(作为 Pedersen 承诺)和其他非机密元数据
私有事务处理数据(私有数据收集)
  • 存储在链代码 ID 下:<chaincode_name>$$_implicit_org_<Oracle_Blockchain_Platform_instance_name>
  • 仅可访问拥有专用数据收集的组织
  • 敏感字段,如 from_account_balance/from_account_onhold_balance/to_account_balance/to_account_onhold_balance/事务处理金额(原始值)和相应的盲法系数

Pedersen 承诺 API

您可以使用链码的控制器文件中包含的以下 API 来验证和处理 Pedersen 承诺。

generateCommitment
此方法为指定值和致盲因子生成 Pedersen 承诺。此方法只能由 Token AdminOrg Admin 调用。
@Validator(yup.string(), yup.string())
 public async generateCommitment(value: string, blinding_factor: string) {
   await this.Ctx.Auth.checkAuthorization("ACCOUNT.processSendersAndReceivers", "TOKEN");
   const result = await this.Ctx.PedersonCommitments.generateCommitment(value, blinding_factor);
   return result;
 }
参数:
  • value: string- 用于生成 Pedersen 承诺的数值。
  • blinding_factor: string- 用于生成 Pedersen 承诺的随机数。
返回:
  • 散列值,即指定值和盲法因子的 Pedersen 承诺。
返回值示例:
"0212f6b676da244eee000a9106060cf3a3a4bb5a9b61be23dd467e557156c40be8"
addCommitment
此方法添加两个指定的 Pedersen 承诺散列值。由于 Pedersen 承诺是同态的,因此它们支持执行数学运算,例如对承诺的加法和减法,同时保留基本值之间的关系。此方法只能由 Token AdminOrg Admin 调用。
@Validator(yup.string(), yup.string())
 public async addCommitment(value1: string, value2: string) {
  await this.Ctx.Auth.checkAuthorization("ACCOUNT.processSendersAndReceivers", "TOKEN");
  const result = await this.Ctx.PedersonCommitments.add(value1, value2);
  return result;
 }
参数:
  • value1: string - 要添加的第一个 Pedersen 承诺散列值。
  • value2: string - 要添加的第二个 Pedersen 承诺散列值。
返回:
  • 散列值,即针对两个指定的 Pedersen 承诺值之和的 Pedersen 承诺。
返回值示例:
"03a9c138b76e7d56f799108a46f665f53a42f55008b31e0fec071019aa5c37344a"
subCommitment
此方法从第一个方法中减去指定的第二个 Pedersen 承诺散列值。由于 Pedersen 承诺是同态的,因此它们支持执行数学运算,例如对承诺的加法和减法,同时保留基本值之间的关系。此方法只能由 Token AdminOrg Admin 调用。
@Validator(yup.string(), yup.string())
 public async subCommitment(value1: string, value2: string) {
  await this.Ctx.Auth.checkAuthorization("ACCOUNT.processSendersAndReceivers", "TOKEN");
  const result = await this.Ctx.PedersonCommitments.sub(value1, value2);
  return result;
 }
参数:
  • value1: string - 减法中的第一个 Pedersen 承诺散列值(最小值)。
  • value2: string —第二个 Pedersen 承诺散列值,用于从第一个值(相差)中减去。
返回:
  • 散列值,即针对两个指定的 Pedersen 承诺值的差值的 Pedersen 承诺。
返回值示例:
"0212f6b676da244eee000a9106060cf3a3a4bb5a9b61be23dd467e557156c40be8"

验证帐户和暂挂余额

  1. 使用以下查询获取余额的 Pedersen 承诺,即公共数据。
    SELECT JSON_VALUE(h."VALUEJSON", '$.balance') AS balance_commitment
    FROM "<OBP_instance_name>_<channel>_hist" h
    WHERE h."CHAINCODEID" = '<chaincode_name>'
      AND h."KEY" = '<account_id>'
    ORDER BY h."BLOCKNO" DESC, h."TXNNO" DESC
    FETCH FIRST 1 ROW ONLY;
  2. 使用以下查询从专用数据收集中获取余额和致盲系数。
    SELECT
        JSON_VALUE(h."VALUEJSON", '$.balance') AS balance,
        JSON_VALUE(h."VALUEJSON", '$.balanceBlindingFactor') AS blinding_factor
    FROM "<OBP_instance_name>_<channel>_hist" h
    WHERE h."CHAINCODEID" = '<chaincode_name>$$_implicit_org_<OBP_instance_name>'
      AND h."KEY" = '<account_id>'
    ORDER BY h."BLOCKNO" DESC, h."TXNNO" DESC
    FETCH FIRST 1 ROW ONLY;
  3. 将先前定义的 generateCommitment 方法添加到位于 src 文件夹 (src/controller/<Chaincode_name>.controller.ts) 中的控制器文件。
  4. balance(作为 value)和 blinding_factor(作为 blinding_factor)值从第二步传递到 generateCommitment 方法。
  5. 验证第一步中的 balance_commitment 值是否与 generateCommitment 方法的输出匹配。
  6. 要验证暂挂余额,请针对 onhold_balance Pedersen 承诺以及 onhold_balanceonHoldBalanceBlindingFactor 值重复这些步骤。

验证事务处理数量

  1. 使用以下查询获取数量(即公共数据)的 Pedersen 承诺。
    SELECT JSON_VALUE(h."VALUEJSON", '$.amount') AS quantity_commitment
    FROM "<OBP_instance_name>_<channel>_hist" h
    WHERE h."CHAINCODEID" = '<chaincode_name>'
      AND h."KEY" = '<transaction_id>'
    ORDER BY h."BLOCKNO" DESC, h."TXNNO" DESC
    FETCH FIRST 1 ROW ONLY;
    以下文本显示了示例查询。
    SELECT JSON_VALUE(h."VALUEJSON", '$.amount') AS quantity_commitment
    FROM "AdamsCentralBank_adams_hist" h
    WHERE h."CHAINCODEID" = 'confDev'
      AND h."KEY" = 'otransaction~d5e08934fd520554162d694476bae8521803e4bf7272e8709fe34dd3eeecbfe4'
    ORDER BY h."BLOCKNO" DESC, h."TXNNO" DESC
    FETCH FIRST 1 ROW ONLY;
    以下文本显示了示例响应。
    quantity_commitment
    036a1d71b658b592a4261bc76d28b5a08b17cf553c67de2943d769741f8f23dd63
  2. 使用以下查询从专用数据收集中获取数量和致盲系数。
    SELECT
        JSON_VALUE(h."VALUEJSON", '$.amount') AS quantity,
        JSON_VALUE(h."VALUEJSON", '$.blindingFactor') AS blinding_factor
    FROM "<OBP_instance_name>_<channel>_hist" h
    WHERE h."CHAINCODEID" = '<chaincode_name>$$_implicit_org_<OBP_instance_name>'
      AND h."KEY" = '<transaction_id>'
    ORDER BY h."BLOCKNO" DESC, h."TXNNO" DESC
    FETCH FIRST 1 ROW ONLY;
    以下文本显示了示例查询。
    SELECT
        JSON_VALUE(h."VALUEJSON", '$.amount') AS quantity,
        JSON_VALUE(h."VALUEJSON", '$.blindingFactor') AS blinding_factor
    FROM "CentralBank_default_hist" h
    WHERE h."CHAINCODEID" = 'testChaincode$$_implicit_org_CentralBank'
      AND h."KEY" = 'otransaction~d5e08934fd520554162d694476bae8521803e4bf7272e8709fe34dd3eeecbfe4'
    ORDER BY h."BLOCKNO" DESC, h."TXNNO" DESC
    FETCH FIRST 1 ROW ONLY;
    以下文本显示了示例响应。
    quantity blinding_factor
    100 17721346708393996000
  3. 将先前定义的 generateCommitment 方法添加到位于 src 文件夹 (src/controller/<Chaincode_name>.controller.ts) 中的控制器文件。
  4. quantity(作为 value)和 blinding_factor(作为 blinding_factor)值从第二步传递到 generateCommitment 方法。
  5. 验证第一步中的 quantity_commitment 值是否与 generateCommitment 方法的输出匹配。

审计帐户余额

获取账户的当前实际 balance_commitmentbalance 值以及前面所述的致盲因子后,可以根据事务处理历史记录验证这些值。
  1. 使用 getAccountTransactionHistoryWithFiltersFromRichHistDB 方法检索帐户的所有事务。每个事务处理都有一个唯一的事务处理 ID 和相应的 quantity_commitment 条目(在状态数据库中),以及数量和致盲因子(在专用数据收集中)。
  2. 按照前面的步骤验证每个事务处理数量,并确保公共和专用数据同步。以下示例显示事务处理以及以前验证步骤中计算中使用的值。
    事务处理 1
    otransaction~d209ff46dc46f4adb42f0002377507fe995b32bc618ac919eba49141cf1b8008
    验证步骤中的值:
    quantity_commitment from step 1: 036a1d71b658b592a4261bc76d28b5a08b17cf553c67de2943d769741f8f23dd63
    quantity from step 2: 100
    blinding_factor from step 2: 17721346708393996000
     
    Now call the method generateCommitment("100", "17721346708393996000")
    Response: "036a1d71b658b592a4261bc76d28b5a08b17cf553c67de2943d769741f8f23dd63"
     
    quantity_commitment from step 1: 036a1d71b658b592a4261bc76d28b5a08b17cf553c67de2943d769741f8f23dd63
    Response From step 4: "036a1d71b658b592a4261bc76d28b5a08b17cf553c67de2943d769741f8f23dd63"
     
    balance_commitment from step 1 = Response From step 4
    LHS = RHS
     
    - This verifies that the Pedersen commitment is correct against the raw quantity and blindingFactor 
    事务处理 2
    otransaction~862aa9d9e877d3ea209b87299ab5b12c13ed5ce43d1cf1b934043c1dd02f58f6
    验证步骤中的值:
    quantity_commitment from step 1: dd63036a1d71b658b592a4261bc76d28b5a08b17cf553c67de2943d769741f8f23
    quantity from step 2: 50000
    blinding_factor from step 2: 6789721346708393996000
     
    Now call the method generateCommitment("50000", "6789721346708393996000")
    Response: "dd63036a1d71b658b592a4261bc76d28b5a08b17cf553c67de2943d769741f8f23"
     
    quantity_commitment from step 1: dd63036a1d71b658b592a4261bc76d28b5a08b17cf553c67de2943d769741f8f23
    Response From step 4: "dd63036a1d71b658b592a4261bc76d28b5a08b17cf553c67de2943d769741f8f23"
     
    balance_commitment from step 1 = Response From step 4
    LHS = RHS
     
    - This verifies that the Pedersen commitment is correct against the raw quantity and blindingFactor
    事务处理 3
    otransaction~5112f576c94c2d23c342479bfa37e34612414b3258a64b43cf51b920f4ff5868
    验证步骤中的值:
    quantity_commitment from step 1: d28b5a08889921d71b658b592a4261bc76b17cf553c67de2943d769741f8f23dd63
    quantity from step 2: 5000
    blinding_factor from step 2: 39317721346708996000
     
    Now call the method generateCommitment("5000", "39317721346708996000")
    Response: "d28b5a08889921d71b658b592a4261bc76b17cf553c67de2943d769741f8f23dd63"
     
    quantity_commitment from step 1: d28b5a08889921d71b658b592a4261bc76b17cf553c67de2943d769741f8f23dd63
    Response From step 4: "d28b5a08889921d71b658b592a4261bc76b17cf553c67de2943d769741f8f23dd63"
     
    balance_commitment from step 1 = Response From step 4
    LHS = RHS
     
    - This verifies that the Pedersen commitment is correct against the raw quantity and blindingFactor
  3. 按照事务处理的发生顺序迭代通过排序的事务处理列表,并计算每个属性的运行总计。对于每个事务处理,请完成以下步骤。
    1. 如果事务处理是贷项(加号),则使用 addCommitment 方法合并 quantity_commitment 属性。如果事务处理是借项(减),则使用 subCommitment 方法合并 quantity_commitment 属性。
    2. 如果交易是信用,则添加 quantity 属性。如果事务处理为借项,则减去 quantity 属性。
    3. 如果交易是信用,则添加 blinding_factor 属性。如果事务处理为借项,则减去 blinding_factor 属性。
    以下示例显示如何处理承诺、数量和致盲系数。
    处理承诺
    Starting balance_commitment: "2a4261d28b5a08889921d71b658b59bc76b17cf553c67de2943d769741f8f23dd63"
    
        For Transaction 1 Using method
        addCommitment(
        "2a4261d28b5a08889921d71b658b59bc76b17cf553c67de2943d769741f8f23dd63", 
        "036a1d71b658b592a4261bc76d28b5a08b17cf553c67de2943d769741f8f23dd63"
        ) = "a1d71b658036b592a4261bc76d28b5a08b17cf553c67de2943d769741f8f23dd63"
    
        current balance_commitment: "a1d71b658036b592a4261bc76d28b5a08b17cf553c67de2943d769741f8f23dd63"
        Transaction 2 Using method
        addCommitment(
        "a1d71b658036b592a4261bc76d28b5a08b17cf553c67de2943d769741f8f23dd63", 
        "dd63036a1d71b658b592a4261bc76d28b5a08b17cf553c67de2943d769741f8f23"
        ) = "b285a4261dd63036a1d71b658b592bc76da08b17cf553c67de2943d769741f8f23"
    
        current balance_commitment: "b285a4261dd63036a1d71b658b592bc76da08b17cf553c67de2943d769741f8f23"
        Transaction 3 Using method
        subCommitment(
        "b285a4261dd63036a1d71b658b592bc76da08b17cf553c67de2943d769741f8f23", 
        "d28b5a08889921d71b658b592a4261bc76b17cf553c67de2943d769741f8f23dd63"
        ) = "036a1d71b658b592a4261bc76d28b5a08b17cf553c67de2943d769741f8f23dd63"
    
    Final Commitment: "036a1d71b658b592a4261bc76d28b5a08b17cf553c67de2943d769741f8f23dd63"
    处理数量
    starting balance: 0
    
        For Transaction 1 
        current_balance = 0 + 100 = 100
        current_balance = 100
        For Transaction 2
        new current_balance = 100 + 5000 = 5100
        current_balance = 5100
        For Transaction 3
        new current_balance = 5100 - 500 = 4900
    
    Final_balance = 4900
    过程致盲因子
    starting blindingFactor: 67083177213493996000
    
        For Transaction 1 
        current_blindingFactor = 67083177213493996000 + 17721346708393996000 = 84804523921887992000
        current_balance = 84804523921887992000
        For Transaction 2
        new current_blindingFactor = 84804523921887992000 + 6789721346708393996000 = 6874525870630281988000
        current_balance = 6874525870630281988000
        For Transaction 3
        new current_blindingFactor = 6874525870630281988000 - 39317721346708996000 = 6835208149283572992000
    
    Final_balance = 6835208149283572992000
  4. 处理所有事务处理后,检查以下语句是否为真。
    • quantity_commitment 值与当前 Account.balance_commitment 值匹配
    • quantity 值与当前 Account.balance 值匹配
    • blinding_factor 值与当前 Account.blinding_factor 值匹配