top | item 14236945

Show HN: /r/place backed by the Bitcoin blockchain

30 points| mess110 | 8 years ago |mess110.github.io

27 comments

order
[+] scientaster|8 years ago|reply
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|8 years ago|reply
> 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
    }
[+] gus_massa|8 years ago|reply
Is this code equivalent to the current code?

IUUC the current code accumulate the payment to each pixel and whatever color has more accumulated money is chosen.

IIUC your code only consider the last payment and to replace the old color you have to outbid it, without any consideration of the previous payments.

Another strategies:

Penny auction: Whatever color received the last payment is the chosen one. This is more similar to /r/place

Generals.io: If someone adds money to the current color, then increase the accumulated money in that color. If someone adds money to another color the amount is discounted. Unless the result is negative and the color changes.

[+] mess110|8 years ago|reply
Guess I know what I am playing with soon :)
[+] pavel_lishin|8 years ago|reply
A fun way to get people to donate money to wallets you control. Kind of like Million Dollar Homepage, but without any pesky guarantees.
[+] iplaw|8 years ago|reply
Yea, with a 0.001 BTC (~$1.42) minimum, this 100x100 pixel pilot could generate $14,200 if all pixels are colored and no pixels are contested. If it scales, in both pixels and interest, a decent amount of donations could be generated.

That said, cryptocurrency is much more niche than, say, an open-access canvas requiring only a Reddit account.

[+] i_cant_speel|8 years ago|reply
Agreed. I think it could be a great way to raise money for some kind of cause though.
[+] josephg|8 years ago|reply
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|8 years ago|reply
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|8 years ago|reply
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|8 years ago|reply
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|8 years ago|reply
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|8 years ago|reply
And generate some modest revenue for a side project. It looks like he's made around $1500 so far.