robinmonjo / coincoin

Blockchain based cryptocurrency proof-of-concept in Elixir. Feedback welcome
402 stars 54 forks source link

Better polymorphism #12

Closed robinmonjo closed 6 years ago

robinmonjo commented 6 years ago

Fix https://github.com/robinmonjo/coincoin/issues/11

Goal of this PR is explained in the linked issue.

I managed to do it with a minimum impact on the existing code (no API change 😊). This is pretty cool because data stored in the blockchain are completely independents and the blockchain can store anything (for example 2 differents tokens could run simultaneously on the same blockchain).

Here is how it works:

Let's say someone want to do:

defmodule Person do
     defstruct [:name, :age]
end

person = %Person{name: "roger", age: 34}
Blockchain.add(person)

We want other peers to see in the block data that the data is a Person (and not a Map). So everything happens at the P2P protocol layer:

The JSON sent to peers will look like:

{ data: {"type": "Elixir.Person", data: { name: "roger", age: 34 } } }

So initial data is stored in a struct that embeds the type and the data. So when decoding, we just have to read the type, and, if there is any, data is converted to the struct type. Of course it works also with "scalar" types.

This also simplify a lot the token app that doesn't have to switch from Map to Token.Transaction. Block contents are just pattern matched and that's it.

yordis commented 6 years ago

@robinmonjo what about sending the AST instead? What way your not limited on what you could save there pretty much. You can safe executable code I guess.

Just random thoughts, thinking on smart contracts

robinmonjo commented 6 years ago

hey @yordis you are thinking ahead 😁. I have some ideas about smart contracts and let people write smart contract in Elixir. But this won't be stored at this level. It will not be part of the blockchain, it will be part of a protocol implemented on top of it. In this PR I ensure people can store any structs in blocks without conflicts. So later we can imagine storing a struct with a field containing AST that would be ran to unlock an output for example.