I'm curious about how one might replicate the functionality of http://whatbitcointhinks.com/ using bitcoin script. The functionality is that there's a sort of crowdfunding competition between two charities. There's a time limit on the competition so that by the end, the charity that has raised the most funds wins all the funds.

Here's a screenshot of the concept:

whatbitcointhinks.com screen shot

The question of how this might be implemented as a smart contract came up on r/bitcoin, and I suggested a scheme that would use three p2sh addresses. But a reply asks whether the loser might get around the restriction by claiming the funds before the winner:

Maybe side A is one p2sh address, side B is another p2sh address, and both scripts specify as outputs a third p2sh address that's a sort of 1-of-2 multi-sig address where each charity holds one of the two privkeys. Its not multi-sig exactly, because the additional restrictions are nLockTime, and for charity A to claim the funds, the inputs to the side A p2sh need to be greater than the inputs to side B p2sh.

Suppose for concreteness that A gets 10 1BTC donations and B gets 9. What stops B from broadcasting a transaction using all 9 B donations and 8 of the 10 A donations?

Is there a way to implement this as a crowdfunding-like contract in bitcoin script?

  • In addition to the answer below indicating that this isn't possible with Bitcoin, note that it's also foolish even as a third-party implementation. The charities or other parties who are receiving the funds can easily rig the vote by "donating" to themselves. (Lighthouse crowd funding has the same weakness: the receiving party can fund themselves to capture the other donors' money.) – David A. Harding Feb 26 '15 at 17:38
  • Yeah, but that's a meta-issue with all crowdfunding systems (bitcoin or otherwise). – Martin Brown Feb 27 '15 at 13:11

It can't be done with today's infrastructure. We can imagine two solutions.

First solution: Bitcoin upgrades

Script gets progressively more powerful with new opcodes. In this case I think there would actually have to be a new UTXO set index (which nodes don't currently even calculate) so the script could find all the payments to a particular address/with a particular marker and reflect upon them. You could then have people put money into outputs with scripts that say in pseudo-code:

  • If it's past a certain time
  • Do the UTXO lookup to find all outputs tagged as being for party A
  • Do the same lookup for party B
  • Parse and sum them to figure out which one won. The existing instruction set might or might not be quite good enough for this, but re-enabling the opcodes that were panic disabled a long time ago doesn't seem impossible: just needs good unit tests.
  • Then using the result of that calculation, require a signature originated by the winning address

So the script architecture could do this, with an extension and a few of the disabled opcodes being re-enabled. But the real question is - should it?

The primary downside of allowing this sort of thing is that calculating the needed database indexes is computationally intensive and will slow nodes down, thus making them more expensive to run and hurting Bitcoin scaling.

The upside is that this construction would be audited and verified by every network participant, which is the best security you can have in Bitcoin.

For this particular use case, I'd probably feel the costs outweighed the benefits. The construction is IMO rather odd and uncompelling. It's possible though, that someone comes up with a use case for an OP_LOOKUP_OUTPUTS that actually is compelling, and we have been talking forever about making nodes calculate more indexes over the UTXO set. If we end up doing that for other reasons anyway, at that point exposing it via Script doesn't seem like such a big leap and making this construct as a "pure" smart contract would become possible (easy, even).

Second solution: oracle network

Since Bitcoin began there has been a debate about the balance between simplicity and power in scripting contracts. Bitcoin has a fairly restrictive scripting language, partly because in the early days it was found to be insufficiently well tested and open to security exploits, and reducing unused power was a quick way to stabilise the core.

Ethereum is the exact opposite, it gives scripts enormous power and access to lots of expensive capabilities, like data storage slots. How secure it is, how resistant to DoS attacks and so on is currently an unresolved question, but we know from bitter experience with Bitcoin, Java, Flash, HTML/JS etc that sandboxing mobile code is extremely hard. They're gonna have their work cut out for them. All mobile code sandboxes I know about have been found to have holes in them at some point, so nobody has ever managed to do what Ethereum wants to do without recurring exploits. This is why the Bitcoin community is so conservative with increasing Script's power.

It would be ideal if we could somehow create two scripting systems, one simple/trivial one that manages the movement of money in the core network and a more powerful one in which security breaches only impact the people using those features instead of everyone.

There's a couple of ways we can do this in Bitcoin.

One is to have an independent p2p network of oracles:


In this case each oracle has an identity and people pay to a threshold signature of pre-selected oracles. Each oracle runs the program independently and then signs with their private key if the program succeeds.

The problem here is that you don't have much agility. Oracles can't come and go in the same way miners do.

Another is to use a side chain, when such technology becomes available. In this case the side chain does not contain any coins and two-way pegging is not necessary. Rather the side chain "transactions" just assert that a program was run and was satisfied. Oracles then "mine" the side chain thus proving that a hashpower majority ran the script and got the expected output.

A final way is to use SNARKs, when such technology becomes available.

The appeal of sandboxing things this way is that if, for example, a sandbox escape exploit is found in the dominant oracle implementation, it would result in oracle-locked outputs becoming stealable but not any other Bitcoin outputs, so the risk is contained.

The Ethereum design in contrast binds things together more tightly. An exploit in the Ethereum contracts engine could result in the entire system breaking.


There's no capability in the Bitcoin scripting language to access blockchain related data that isn't included either in the transaction or the output script that the transaction is trying to spend. This basically means that you won't be able to calculate and compare total address balance in the script.

You'll need a third party intermediary who can assess which party has more bitcoins in their account.

  • Thanks. I was wondering if the amounts could be compared as done in a kickstarter contract, but looking more closely the comparison there is total input value to a hard-coded output value (the "goal" amount). – Martin Brown Feb 27 '15 at 13:06

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.