Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Understanding UTXO Model Challenges: Multi-Item Transactions and Transaction Conditions" #169

Open
NadigerAmit opened this issue Feb 9, 2024 · 1 comment

Comments

@NadigerAmit
Copy link
Contributor

NadigerAmit commented Feb 9, 2024

I have some questions about handling UTXO inputs and outputs, specifically their relationship and how they ensure transaction security.
Here's what I'm interested in:

Question 1: Allocating Funds in UTXO Transactions
When a buyer is purchasing multiple items (e.g., kitties) from different sellers,
how can we ensure that the buyer sends the correct amount to each seller?
For example, suppose there are sellers A and B with Kitty-A priced at 20 and Kitty-B priced at 30. How can we prevent the buyer from mistakenly sending the wrong total amount to one seller without specifying the amounts for each item?
Example of a problematic situation: If the user/wallet sends 30 to user A and 20 to User B, it is not correct. How to check this as we don't have info on the intended recipient info in the output constraint checker?

pub trait SimpleConstraintChecker: Debug + Encode + Decode + Clone {
/// The error type that this constraint checker may return
type Error: Debug;
/// The actual check validation logic
fn check(
&self,
input_data: &[DynamicallyTypedData],
peek_data: &[DynamicallyTypedData],
output_data: &[DynamicallyTypedData],
) -> Result<TransactionPriority, Self::Error>;

One potential issue is that the transaction validation in the constraint checker primarily focuses on the total sum of inputs covering the total sum of outputs. While this ensures that the buyer sends enough funds to cover the overall cost, it doesn't inherently enforce the correct allocation of funds to individual sellers in a multi-item transaction. For example, if the user mistakenly sends 30 units to User A and 20 units to User B, there isn't a built-in mechanism to verify the intended recipient for each output.

How can we address this challenge within the UTXO model to guarantee that the buyer allocates the correct amounts to specific sellers when making a multi-item purchase?

Question 2: Transaction Conditions in UTXO Model
In the UTXO model, how can we implement checks for specific transaction conditions,
like preventing transfers to oneself ("TransferToSelf") and
verifying that the buyer is the rightful owner of the kitty being purchased ("BuyerIsKittyOwner")?
Are these checks possible in the UTXO model, and if so, what's the recommended approach to effectively implement them?

Ownership Verification:
We can ensure that each input is properly signed by its owner (buyer) using the redeemers.
We can verify that each output has the correct verifier to ensure ownership of the newly created UTXOs.

However, one challenge is that constraint checkers, which are responsible for transaction validation, do not have direct access to information about redeemers and output verifiers.

To address this, one potential solution could be introducing an additional constraint checker, for example, an "AdvancedConstraintChecker," which holds information about the owners of both inputs and outputs.
This way, we can perform checks related to "TransferToSelf" and "BuyerIsKittyOwner" effectively.

Questions 3 :How can we facilitate the purchase of a asset when the buyer and seller operate from different wallets?

The challenge lies in the need for the buyer to sign the money input and the seller to sign the asset, requiring signatures from different wallets. This scenario becomes complex as both private keys are unlikely to be stored in the same wallet in real-world situations.

Current Limitation:
Buying an asset (for example Kitty) between two users with different wallets is currently not supported. The constraint arises from the inability to sign transactions with private keys from separate wallets simultaneously.

In the current CLI wallet, which supports multiple key pairs, it is possible to facilitate trade between two users using the same wallet

Potential Solutions:

Atomic Swaps: Utilize time-locked transactions to ensure that either both parties receive their assets or neither does, providing a secure and fair exchange.
Time-Locked Smart Contracts: Although UTXO blockchains traditionally lack smart contracts, explore the use of time-locked smart contracts to enable secure exchanges between users with different wallets.
Order Book System: Implement an order book system that matches buyers and sellers through centralized or decentralized listings, streamlining the process of connecting users for kitty transactions.

I know we are yet to support the atomic swaps, smart contracts, and Dex(order book). But please let me know if there is some way we can support the buying operation by some other means in the current implementation.

@JoshOrndorff
Copy link
Contributor

JoshOrndorff commented Feb 12, 2024

Problem

Two users have assets that they would like to exchange. As a concrete example let's say Alice owns an NFT in a single utxo. Bob owns 10 coins spread across several UTXOs. Alice and Bob have a "double coincidence of wants" and would be willing to trade the NFT for a total of 9 coins. They want the sale to be atomic so neither of them leaves with both the kitty and the coins; they either swap or they leave with what they came with.

Solution 1: Single Transaction

The simplest way is to construct a single transaction that consumes all the relevant input state and creates all the desired output state.

The complication here is that this transaction consumes inputs owned by both Alice and Bob. That means it requires a signature from both Alice and Bob. So some out-of-band coordination must happen. The same is true of the current MultiSignature verifier, and indeed such coordination is sometimes required. Frontends can help solve this problem by creating the transaction and giving a file or QR code to pass to the counterparty, or even passing it through some centralized matching service. This is all totally viable.

There is no risk that the coins will go to someone other than Alice. Although the constraint checker is not able to enforce that the coins go to Alice, the transaction requires a signature from Alice. If Bob proposed a transaction that sends the coins somewhere else, Alice would never sign it.

Solution 2: Intermediate State

If you prefer for users to be able to post sales on-chain and accept sales on-chain from their own wallet with no out-of-band communication, you can implement an on-chain invoicing system.

When Alice lists her Kitty for sale she gets back an invoice. When Bob buys the Kitty he creates a payment. Later Alice can claim the payment in a third transaction which consumes both the payment and the invoice. Only Alice can do this redemption because she owns the invoice.

image

This scheme has the advantage that the users do not need to coordinate offchain or even know each before the sale is listed. It has the disadvantage that it requires three separate transactions.

Of course you would also need a transaction type to allow Alice to cancel her sale and get her privately-owned kitty back if there are no buyers. So a more complete picture would look like this

image

Solution 3: HTLC Swaps

A final option is hash time lock contract swaps a la #168. These have both disadvantage. They require off-chain coordination as well as multiple transactions. However, they offer the advantage that the assets do not even need to live on the same chain.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants