Open carlaKC opened 3 years ago
Welcome @carlaKC !
Some thoughts:
Neat use case :) I like it
TLDR; This can definitely be solved using DLC oracles! Not all too much has to be done (on paper anyway, in terms of building server code there is a non-trivial amount of work involved but nothing too crazy). PTLCs using DLC oracles might be a better solution compared to DLCs, noting that both can be supported simultaneously if that would be beneficial.
I think there are two ways this could work:
Funders enter into a single-funded DLC with the (potential) receiver with a Contract Execution Transaction (CET) for the two cases goal_met
paying exclusively to the receiver, and goal_not_met
paying exclusively to the funder. (There is also a refund transaction as usual). The benefit for this way of doing it is that you don't have to worry about registration separate from the DLC (although the receiver will still have to publish information about it somewhere publicly for you), and that you can release funds on goal_not_met
instead of relying on a timeout. The cost of doing it this way is that DLC-protocol-level interaction is required between the funder and receiver and the receiver has to have a DLC-enabled wallet. The interaction consists of 1.5 round trips. The main down-side of requiring this interaction is that new contracts cannot be put on-chain if the receiver's server goes down, whereas the next way of doing this would still allow new contracts to be added to the funding pool without relying on the receiver's servers (assuming that the registration isn't happening on these servers that have gone down, at least not exclusively)
Without requiring any interaction with the receiver, the funder could unilaterally setup a Point Time Lock Contract (PTLC) corresponding to the signature of the message goal_met
. If that signature is released, then the receiver can claim the funds in the PTLC via the point-lock. If the signature is not released by some predetermined block, then the funder can reclaim the funds in the PTLC via the time-lock. The benefit for this way of doing it is that you don't have to have any interaction with the receiver in order to broadcast the contract on-chain, but you probably still need to register your PTLC someplace publicly so that it can be audited and added to the count. This approach is also, technically speaking, much much simpler: A couple other friends and I implemented PTLC functionality from scratch over a weekend for a hack-day back in April (https://youtu.be/w9o4v7Idjno), and that included all of the new cryptography in the library secp256k1, which can now be re-used without doing that work again.
It just so happens that these two approaches are fully compatible! That means that assuming some sane registry of relevant PTLCs and DLCs, the receiver could support both kinds and have oracles count funds from both. The resulting signature from the oracle could then be used to unlock both kinds of contracts.
From a general privacy perspective DLCs have a lighter on-chain footprint than PTLCs but for this use case, contracts must be publicly revealed in order to be counted towards the total so I don't think it is a significant consideration.
As I mentioned, in either way of this being done, the oracle signing goal_met
or goal_not_met
must only commit to a 32-byte R value and then later sign (after auditing the funding contract registry) and broadcast this signature and nothing else is required from them. What is better, it is encouraged that there be multiple trustworthy auditor oracles (preferably not all controlled by the receiver :P) which do this signing, and in this case, some EC point math can be done to make the DLCs/PTLCs in to 2-of-3 oracles claim goal_met
or 3-of-5 or etc.
So long as 3 or 5 or whatever number of truly trustworthy oracles exist this vastly reduces the chances that you were accidentally wrong in trusting an oracle and that they've been bribed or compromised.
In either approach, using a threshold of multiple oracles (chosen by the user, different funders can use different oracles according to their preferences) maximizes trust-minimization (i.e. minimizes trust the most that can be done on BTC) and all trust is placed solely in the threshold set of oracles (of each funders choosing) with no trust resting on the funder or receiver.
To the best of my knowledge, there is no easy way to hide much at all about individual funders' contracts from the oracle. With ZKPs it is possible to prove that some amount has been met in some set of blocks but not only does this require a lot of extra work on the receiver's end but it also trusts the receiver not to reveal this information, and worst of all the complexity of such a ZKP is super duper HUGE. Probably not worth it, at least in the current state of the crypto libraries I'm familiar with. Might be a fun project for some PhD student someday though haha
In terms of practically implementing software to support this use case, I believe the following is what is required:
A registry server (preferably open-source so that it can be easily used by anyone who wants to raise funds). This would need to be able to take as input a transaction, funding amount, and some public keys as well as proof the tx was included in a block, and as a result add to its publicly query-able database of funding contracts (after validating the transaction is included in a known valid block). I am having trouble ball-parking how much work this is. It is not trivial but not overly complicated either. I will note that this will take longer to implement for the DLC approach than the PTLC approach because there's more stuff that needs to be validated in the latter, but not by a large margin. My best guess is that this could be hacked together pretty quickly but might take a bit longer to do in a nice maintainable way.
Auditor Oracles. Most of this functionality is already done in multiple implementations as it is not very different from a normal DLC oracle. The only new thing is that the data on the registry would need to be validated against the chain, unless the oracle maintains the registry and has already done this validation.
If the DLC approach is taken:
If the PTLC approach is taken:
Welcome to the spec @carlaKC :)
Crowdfunding is a really interesting use-case for the Bitcoin ecosystem and AFAIK it hasn't been solved yet, at least in a scalable, cheap, privacy-preserving way.
Let's discuss more the problem before to examine potential solutions.
Let's say you have Alice, Bob and Caroll making the pledge between them to pay Dave 0.1 BTC, at the blocking condition that every other funder respect its commitment. At the difference of other MPSP payment schemes like a group of friends splitting a bill, we can't assume social trust between Alice, Bob and Caroll, it's really likely they're complete strangers for each other.
Thus, we're aiming for this trustless property, each payment to Dave isn't only atomic on its own but also atomic as a whole, you're looking to establish circular dependencies between each funder's payment. As of today, you have different logics to achieve such circular dependency : economic incentives (e.g Barrier Escrow, third-party external observer (e.g an oracle), onchain scripting (e.g malleability flags).
We're also aiming to make this crowdfunding application scalable. Let's examine BitcoinACKs as an onchain example, pledges are in the 10 000 - 100 000 order of magnitude. If you assume onchain fees in the 1000 - 10000 sat range (i.e current sat/byte level), and a funders set size of 10 to achieve crowdfunding target, it means they will spend almost as much in fees than in crowdfunding reward. Further, you will also have a cost for the payee to spend O(n) onchain outputs where n is the number of onchain transaction gathered to reach the target. If you aim for massive, scalable crowdfunding with thousands of participants involved, I would say onchain might not be the best direction...
Lastly, about privacy, you have different viewpoints to consider. Funders would like to hide their identity and amounts given from any other protocol participant. Funder would lile to hide their identity and likely amounts collected from any other protocol participants, including oracle if involved. Also, you may want to hide the existence of the crowdfundign contract from the transaction log itself, which is the DLC OG privacy assumption. You might have to consider side privacy leaks like a public website advertising the crowdfunding with a well-known blockheight...
There is a old-known solution to enable crowdfunding, which is relying on SIGHASH_ANYONECANPAY permissivemalleability to interactively build a onchain crowdfunding transaction among multiple participants.
It's nicely trustless, as the transaction will be valid only if the fundee gathered enough inputs to reach the output target as committed by SIGHASH_ALL participant signatures. Though it doesn't scale and fundee will learn the set of utxos involved in the crowdfunding, even assuming you blind them a la CoinShuffle to break the input ordering announced by the fundee to each funder. And the only way to securely exit a non-successful crowdfunding for a funder is to double-spend the pledged input ("costly timeout").
In fact, some folks tried to build a bitcoin crowdfunding platform few years ago but it never reached momentum.
MPP are cool and at the protocol-level, there is no requirement that all the chunk are coming from
the same payer, if chunks are tagged with the same payment_secret
. MPP can be leveraged as a
interactive crowdfunding scheme :
I think this scheme is correct but it comes at least with 2 strong weaknesses, a) the fundee has to display its channel funding utxo and commitment transaction (and likely to prove the valid commitment tx in a zero-knowledge way to avoid verifiers closing channels they're not involved with...) and b) funder have a strong liveliness requirement to update their PTLC with point of participants entering in the crowdfunding after them...
The whole interactivity and public provability of the crowdfunding state can be removed by relying on a DLC oracle to achieve these functions. Involved oracles are named Arbiter (as arbiter resolving disputes outside the courts, contrary to the onchain blockchain-as-a-judge model).
Let's sketch such protocol.
I think this protocol is quite nice because it's scalable and quite good about privacy, funder identities aren't disclosed. You might also keep privacy for the funder if the proofs towards the oracle are privacy-preserving. The fundee can add crowdfunding amount noise by sending dumb PTLCs to itself. Funder-interactivity is limited at sending a PTLC, no action is required for settlement. The protocol is trust-minimized in the bounds of the DLC security model, the oracles can't steal the stakes, even with collusion of the whole set of funders. They can only halt the crowdfunding.
W.r.t to the proof systems requirement, AFAICT, you don't need general statement ZKPs. Those ones are effectively complex, what you're looking is a zero-knowledge set membership system. And it turns out there is already a post-taproot PoC candidate. The balance state proof can be cooperatively built with your channel counterparty, built as a proof-of-reserve to avoid state onchain usage by the verifier.
Hopefully, this would help you to clarify the crowdfunding properties you're aiming for before to hack an application. Bear in mind low-value crowdfunding when deciding for onchain or offchain. My intuition, the bitcoin primitives to build a really cool crowdfunding protocol still need to mature a bit (beginning with taproot/schnorr to activate)
Lastly, if you understand off-chain you understand onchain too, we're using the same transactions :p
Hi dlc-spec!
I've been thinking about another form of DLC that could have some interesting applications - a single funded DLC used specifically for crowdsourcing funding in a trustless manner. This is a very rough idea, and may not work at all, but I just wanted to put it out there for discussion.
Problem
Crowd-funding with Bitcoin (so far) requires trust. Gross. Typically this would take two forms:
Idea
A simplified, single-funded DLC could be used to setup trust-minimized crowdsourcing for projects, depending only on an oracle that signs the outcome of the conditions for funding. I'm not a script-wizard, but the paths for the contract could be as follows:
Examples
Traditional Crowd Funding
goal_met
orgoal_not_met
by examining all registered txns to calculate total committed amt at the decided upon blockh/t to BitcoinACKs PR pledges, which gave me this idea.
Motivation
There are likely some trust issues with the oracle knowing the amount pledged, perhaps there is some zero knowledge magic that one could do, but even without that I think this takes a step in the direction of less trusted funding models?