Awesome! The Flipstarter was announced and I can't wait to see it working.
Like I said before, we were doing our own "funding" site section before we learned about the fact that @im_uname and @emergent_reasons were working on Flipstarter, at which point we scrapped the project.
I'm intrigued by their "assurance contract" implementation - we don't have that much experience with contracts, so our way was much simpler.
Just for fun, I'll explain our approach.
We took the "blind escrow" contract as the base.
It has four methods ("ways for money to leave the contract"):
"pay the seller, signed by the buyer"
"refund, signed by the seller"
"pay the seller, signed by the arbitrator"
"refund, signed by the arbitrator"
The money enters the contract and can leave it one of two ways: to the seller or to the buyer, and one of three "signers" can sign this transaction (the buyer, the seller or the arbitrator, if the buyer and the seller can't agree).
We kept only the last two methods.
So, imagine the person who wants to donate is the "buyer" and the guy who wants some funding is the "seller". We are the "arbitrator".
If somebody wants to pledge $100 - he/she sends it to this simplified "blind escrow" contract (it looks like sending to a regular cash address) and we immediately sign the "refund" transaction and give the signed transaction back to the person who wants to donate - he/she is free to broadcast it at any time to cancel the pledge.
As soon as the server detects that the total amount has been pledged (i.e. all of the pledges add up to some amount that needs to be collected) - our server just broadcasts all of the "pay the seller, signed by the arbitrator" transactions, thereby completing the funding (completely non-custodial, since we can only forward money to the seller or return to the buyer).
We could have also selected to use "pay the seller, signed by the buyer" (instead of signed by us), but it was a bit harder to implement, so a bit more error-prone. Since we're amateurs in this, we've decided to do it the simpler way ("signed by us").
Here's the full contract for anyone curious (in CashScript, hat tip to @rosco) - uses the new Global covenant variables from 0.3.x:
pragma cashscript ^0.3.1;
contract FundingContract(bytes20 recipientPkh, bytes20 funderPkh,
bytes20 arbiterPkh, string nonce) {
function donate(string nonce2, int fee, pubkey arbiterPk, sig s) {
require(int(tx.version) >= 2);
require(nonce == nonce2);
require(hash160(arbiterPk) == arbiterPkh);
require(checkSig(s, arbiterPk));
int amount1 = int(bytes(tx.value)) - fee;
bytes34 out1 = new OutputP2PKH(bytes8(amount1), recipientPkh);
require(hash256(out1) == tx.hashOutputs);
}
function refund(string nonce2, int fee, pubkey arbiterPk, sig s) {
require(int(tx.version) >= 2);
require(nonce == nonce2);
require(hash160(arbiterPk) == arbiterPkh);
require(checkSig(s, arbiterPk));
int amount1 = int(bytes(tx.value)) - fee;
bytes34 out1 = new OutputP2PKH(bytes8(amount1), funderPkh);
require(hash256(out1) == tx.hashOutputs);
}
}
Warning! This is an unaudited Bitcoin Cash contract. We've tested it and it works, but we can't guarantee it's bug-free.
nonce
is just some random bytes to generate a new address each time to avoid replay attacks. (Otherwise if the "buyer" sends another amount next month to this same address - somebody could just replay the "donate" call)
donate
can only send the full amount minus the transaction fee (see the amount1
check) to the recipientPkh
(pubkey hash), whereas refund
can only send the full amount back.
pk
= public key, pkh
= public key hash, funder
= the buyer, recipient
= the seller
Small note to @rosco: we need a way to spend only a single UTXO in CashScript library, otherwise if somebody sends two times to the same address - the covenant check of the full amount doesn't work. (Imagine somebody sends 1 BCH and 2 BCH, the covenant sees the output as 3 BCH minus the fee, whereas the input is really 1 BCH for one UTXO and 2 BCH for the other, so the contract can't run correctly. We've implemented it by badly editing the CashScript library source, but I'm sure you could find the better way)
Wonderful project. (Great explanation of the ESCROW too. I had visions of a world class ERC-20 ESCROW platform in my someday-maybe list.)