Confidential Payments Overview
Oracle Blockchain Platform Digital Assets Edition uses Pedersen commitments to keep data secure.
Zero-Knowledge Proofs
Zero-knowledge proofs (ZKPs) are cryptographic protocols that let an honest prover demonstrate a statement's truth to a verifier without revealing any additional information. A dishonest prover cannot convince a verifier that a false statement is true. ZKPs ensure that no sensitive data is revealed beyond the validity of the claim. ZKPs make it possible to prove specific properties of a secret value, such as confirming that it falls within a range or is the result of a specific computation, without revealing the value itself.
Pedersen Commitments
Zero-knowledge proofs depend on commitment schemes, where someone can commit to a certain value while keeping it hidden from others. Oracle Blockchain Platform Digital Assets Edition uses Pedersen commitments. Pedersen commitments use random values known as blinding factors along with elliptic-curve cryptography to ensure both secrecy and immutability. Pedersen commitments are homomorphic; in other words, they support performing mathematical operations such as addition and subtraction on commitments while preserving the relationships between the underlying values. Pedersen commitments are used in private transaction protocols, secure multiparty computation, and anonymous credential systems.
Working with Confidential Payments
You use the Confidential-Transaction
header in a
transaction request to enable the confidential payments feature.
When you send the Confidential-Transaction
header set to
true in a request, the REST proxy in Oracle Blockchain
Platform generates a unique random number (the blinding factor required for a Pedersen
commitment) and passes it in the transient map. This is used by the chaincode to process
the input and to store the sensitive information in a private data collection rather
than the state database.
Transaction Information
All token operations (account creation, minting, transfer, burning, and so on) generate a transaction record so that transaction history can be tracked. Transaction data is stored in two place: the public ledger (state database) and a private data collection. With confidential payments, the sensitive data is stored in clear text only in the private data collections of the organizations involved in the transaction. The following table shows where transaction values are stored for any given transaction ID.
Public Ledger (State Database) | Private Data Collection |
---|---|
|
|
Token Account Information
Similarly, information about token accounts is stored in the public ledger and a private data collection. The following table shows where transaction values are stored for any given token account ID.
Public Ledger (State Database) | Private Data Collection |
---|---|
|
|
- The
account_id
key, which is unique for every user in the system. Typicall it is the SHA-256 hash of theorgId
(MSP ID) anduserId
(user name or email) combined with other prefixes or suffixes. - The public ledgers stores all of the account keys of any user. Users can have multiple fungible token accounts, one for each token.
- Token details are stored in the
token_type
,token_id
andtoken_name
fields. - The
balance
andonhold_balance
fields hold the Pedersen commitment hash that represents the actual text value of balance that is stored in the private data collection.
- The
account_id
key, described previously. - The
balance
andonhold_balance
fields hold the actual text value of those balances. - The
balance_blinding_factor
andon_hold_balance_blinding_factor
fields store the random key used for creating thebalance
andonhold_balance
commitments stored in the public ledger. - Daily transaction details are stored in the
max_daily_amount
,daily_amount
,max_daily_transactions
,daily_transactions
, andcurrent_date
fields.
Typical Operations with Confidential Payments
The workflow when you mint, transfer, hold, or burn tokens while using confidential payments includes additional steps to ensure data integrity.
Minting Tokens
issueTokens
API.
- In the confidential payments case, the
issueTokens
method takes thetoken_id
value as input, and also requires a blinding factor, which is sent from the REST proxy along with the token quantity passed in the transient map. - After verification, the Pedersen commitment is generated from the blinding factor and the quantity of tokens to mint.
- The overall quantity is then updated in both the public ledger and the private data collection. In the public ledger, the Pedersen commitment that represents the existing balance is increased with the Pederson commitment that represents the quantity of tokens minted (issued). The actual value of the balance stored in the private data collection is increased accordingly.
- The blinding factor is also updated, so that at any time the balance and blinding factor in the private data collection can be used to verify the corresponding commitment stored in the public ledger.
Transferring Tokens Within an Organization
transferTokens
API.
- In the confidential payments case, the
transferTokens
method takes thetoken_id
and optional parameters as input, and also requires a blinding factor, which is sent from the REST proxy along with theuserId
andorgId
values for the receiver and the token quantity passed in the transient map. - After verification, the Pedersen commitment is generated from the blinding factor and the quantity of tokens to transfer.
- The quantity of tokens in the sender's account is decreased and the quantity in the receiver's account is increased, in both the public ledger and the private data collection. In the public ledger, the Pedersen commitment that represents the sender's existing balance is decreased by the Pedersen commitment that represents the quantity of tokens transferrerd. For the receiver, the balance is increased in the same way. The actual values of the sender's balance and the receiver's balance are updated in the private data collection.
- The blinding factor is also updated, so that at any time the balance and blinding factor in the private data collection can be used to verify the corresponding commitment stored in the public ledger.
Transferring Tokens Between Organizations
holdTokens
API to extract the transfer amount and place it on hold.
- In the confidential payments case, the
holdTokens
method takes thetoken_id
,operation_id
, andexpiration_time
values as input, and also requires a blinding factor, which is sent from the REST proxy along with thenotary_user_id
,notary_org_id
,to_user_id
, andto_org_id
values and the token quantity passed in the transient map. - After verification, the Pedersen commitment is generated from the blinding factor and the quantity of tokens to hold.
- A hold object and a sender object are created.
- The balance commitments, actual balances, and transaction objects are saved to the public ledger and to the private data collections for both organizations, which updates all of the balances accordingly.
Holding Tokens
As mentioned previously, hold operations are used to transfer tokens between organizations. Hold operations use hold, sender, and receiver objects, similar to the transaction and token account objects that store data in both the public ledger and the private data collection. Hold operations can also be used for transfers in the same organization, in which case sender and receiver objects are not created and the transfer occurs as a regular Token Taxonomy Framework operation using Pedersen commitments. The following table shows where transaction values are stored for any given hold transaction ID.
In confidential mode, transfers between organizations involve two private data collections. Instead of modifying the account key/value pair, for debits a sender object is created during the hold operation and for credits a receiver object is created (when the executeHoldReceiver
API runs). The balance is placed in the sender object. The credited amount is placed in the receiver object, which is assigned to the recipient. When the debit operation is complete, the sender object is no longer in use and can be deleted. Similarly, after the balance moves from the receiver object to the recipient's account, the receiver object can be deleted.
Public Ledger (State Database) | Private Data Collection |
---|---|
|
|
The following table shows the information for the sender object that is created for inter-organizational transfers and holds.
Public Ledger (State Database) | Private Data Collection |
---|---|
|
|
The following table shows the information for the receiver object that is created for inter-organizational transfers and holds.
Public Ledger (State Database) | Private Data Collection |
---|---|
|
|
- In the confidential payments case, the
holdTokens
method takes thetoken_id
and optional parameters as input, and also requires a blinding factor, which is sent from the REST proxy along with theuserId
andorgId
values for the receiver and the token quantity passed in the transient map. - The hold operation must be approved or rejected by a notary user.
- If the notary user approves the hold operation, the quantity is debited from the sender and hold objects and a transaction object is created. A receiver object is created as well and the quantity is credited to the receiver object.
- If the notary user rejects the hold, the held quantity is credited back to the sender's account and a transaction object is created.
- The balance commitments, actual balances, and transaction objects are saved to the public ledger and to the private data collection, which updates all of the balances accordingly.
Burning Tokens
burnTokens
API.
- In the confidential payments case, the
burnTokens
method takes thetoken_id
value as input, and also requires a blinding factor, which is sent from the REST proxy along with the token quantity passed in the transient map. - After verification, the Pedersen commitment is generated from the blinding factor and the quantity of tokens to burn.
- The overall quantity is then updated in both the public ledger and the private data collection. In the public ledger, the Pedersen commitment that represents the existing balance is decreased with the Pederson commitment that represents the quantity of tokens burned. The actual value of the balance stored in the private data collection is decreased accordingly.
- The blinding factor is also updated, so that at any time the balance and blinding factor in the private data collection can be used to verify the corresponding commitment stored in the public ledger.