
Show HN: /r/place backed by the Bitcoin blockchain - mess110
https://mess110.github.io/blog/cryptoplace/
======
scientaster
Would have been much easier with an ethereum smart contract. No gimmicky
address list, it's a crowdsourced picture in the blockchain.

    
    
      contract Place {
        struct Pixel {
          bytes3 color;
          uint lastPayment;
        }
    
        Pixel[10000][10000] board;
    
        modifier onBoard(uint x, uint y) {
          if (x > 10000 || y > 10000) {
            throw;
          } 
          _;
        }
    
        // Accepts funds, if the funds sent are greater than funds for that pixel last, change the color.
        function colorPixel(uint x, uint y, bytes3 color) payable onBoard(x, y) { 
          Pixel p = board[x][y];
          if (msg.value > p.lastPayment) {
            msg.sender.send(p.lastPayment); // refund previous price of pixel
            p.color = color;                // set the color
            p.lastPayment = msg.value;      // set new cost to whatever the person sent in
          } else {
            throw;
          }
        }
      }
    

May contain an error or two, but that's the general gist of it.

~~~
splintercell
> msg.sender.send(p.lastPayment); // refund previous price of pixel

This code suffers from Recursive calling vulnerability (same bug which caused
the DAO to be hacked).

You're sending the money BEFORE you're updating the balances.

There is a better way to write the payment code (and also wouldn't take you
more than 5 minutes to write).

Here is one way to do it:

    
    
        function colorPixel(uint x, uint y, bytes3 color) payable onBoard(x, y) { 
          Pixel p = board[x][y];
          lastPayment = p.lastPayment;
          p.lastPayment = msg.value;
          if (msg.value > lastPayment) {
            if(!msg.sender.send(lastPayment)) throw; // refund previous price of pixel
            p.color = color;                // set the color
          } else {
            throw;
          }
        }
    

Another shorter way:

    
    
        function colorPixel(uint x, uint y, bytes3 color) payable onBoard(x, y) { 
          Pixel p = board[x][y];
          require(msg.value > p.lastPayment);
          if(!msg.sender.send(p.lastPayment)) throw; // refund previous price of pixel
          p.color = color;                // set the color
          p.lastPayment = msg.value;      // set new cost to whatever the person sent in
        }

~~~
scientaster
Good analysis of the code, and nice correction. Agreed that you should always
check your sends' return values, too! In this example you have to send more
than the last guy, so I think a recursive call would still put in more ether
than would be withdrawn. Still undesired though.

If it were fleshed out more it should probably return the ether to the last
depositor instead of the purchaser.

Thanks for the feedback!; I'm tempted to turn this into an example Dapp later
today.

------
pavel_lishin
A fun way to get people to donate money to wallets you control. Kind of like
Million Dollar Homepage, but without any pesky guarantees.

~~~
i_cant_speel
Agreed. I think it could be a great way to raise money for some kind of cause
though.

~~~
pavel_lishin
> _I think it could be a great way to raise money for some kind of cause
> though._

I'd like to see some proof that the charity-runner isn't going to abscond with
the money once it was done, either due to maliciousness, or even something
like getting stressed out over success (like some Kickstarters have done.)

(And yeah, I know - it's not like it's a Bitcoin/blockchain only problem - but
at least with "real" money, there's typically a system in place where you can
at least start trying to get the money back.)

~~~
notwhoyouthink
Another user suggested using Ethereum smart contracts for this. I'm not
terribly familiar with Ethereum, but I wonder if the contract could be
designed to automatically forward to a Charity-held wallet, or even the wallet
of a reputable intermediary like Watsi.

~~~
pavel_lishin
I'd be incredibly wary of using Ethereum contracts for this. The DAO has shown
that writing software is apparently difficult.

~~~
splintercell
What do you think about Tezos Smart Contracts then?

~~~
pavel_lishin
I've done no research, I don't really know much about the whole...
ledgersphere?

Seems like it just puts in a mechanism for changing the protocol without
forking the chain, but I'm not sure why people couldn't continue running the
old protocol, effectively forking it anyway (other than a "look, we all agreed
to no forks, you're explicitly a dick if you fork it, not just someone with a
disagreement" angle.)

~~~
splintercell
Oh well I was pointing out to the part where their whole codebase is formally
prove, plus their Smart Contract language Michelson is functional and can be
used very easily to be formally proven (there by leading to writing more
secure smart contracts), since you're earlier concern was security.

~~~
pavel_lishin
I don't see that anywhere, although I only googled very briefly. The closest I
saw was this:

> _Updates to the protocol can be required to carry formal proofs indicating
> that they respect agreed core principles agreed upon by the stakeholders._

Which doesn't really make sense; how do you write a formal proof that
something align with someone's core principles?

------
josephg
It'd be fun to make a free version using the same concept by rolling your own
proof of work system. You could do something like requiring a unique proof of
work to be submitted for each pixel change. To change a pixel you need to
generate a random number which hashes to a lower value (when interpreted as a
bignum) than the existing holder of the pixel.

The UI for something like that would be great - your client could just
constantly generate random hashes and buffer a list of the best values its has
come up with. Then the screen could highlight all pixels you can edit. As you
wait longer (and generate better and better hashes), you can edit more
'valuable' pixels.

(Of course, that would only work if each hash could only be used once. You
could embed the pixel value into the hash's input, but then you'd need to
decide which pixels you want to edit before you start generating hashes. And
that would be way less fun.)

------
gus_massa
It's not obvious enough how to see the image. It's linked from the image at
the top and there is a link at the bottom, but you should add something more
obvious like "look at the current image!!!"

Also, it would be nice that the image at the top is live, something like a gif
autogenerated once a minute.

------
libeclipse
The niche aspect is something everyone is overlooking. Combining this with the
"auctioning" each pixel seems like it would be pretty slow moving.

Also, how would you protect against faked transactions? Certainly waiting for
confirmations is out of the question.

~~~
mess110
The image is updated once every 10 minutes, mostly due to my slow server. It
takes about 7 minutes to query the data and write it to disk.

This is not as dynamic as Reddit Place, the code is waiting for 1 confirmation
before the pixel is colored.

------
root_axis
I tend to be pretty skeptical of all things crypto, but this seems pretty
cool. It's not very useful, but it seems like a fun concept.

~~~
iplaw
And generate some modest revenue for a side project. It looks like he's made
around $1500 so far.

~~~
btzll
He didn't make that much money, he pre-filled almost all colored pixels

