Implementing a Hypothetical Currency Application on EOS

in eos •  last year

Today we are excited to share with you the first sneak peak of how EOS works and how developers build applications.

High Level Introduction

EOS is structured like a group of people and/or scripts (bots) that are exchanging messages between them. It could be thought of as an email system where every user or bot has an account.

Like email, messages have a sender, receiver, and potentially a couple of accounts that are copied on the message. Also like email, messages are not guaranteed to be delivered just because they were sent. Delivering a message implies that the receiver accepted the message and processed it according to the receivers code.

Unlike e-mail, the recipient and any accounts copied on the message have the ability to reject the message in which case the message will not be delivered to them.

The EOS blockchain is a transparent and permanent log of all messages that were successfully delivered to all addressed accounts, but may also include outgoing messages generated by a bot.

Publish Code not Binary

When we describe "bots" we are referring to self-executing source code published on the blockchain. An account (aka application or smart contract) is a set of message handlers that can read/store state and/or generate new messages that are dispatched asynchronously to other accounts. Messages can be processed by different accounts in parallel because every account's state is private and inaccessible from other accounts.

Structure of an Application

Every account (aka application) has its own private database in which it can define any number of tables with a number of sorted indices per table. These database tables are used to store the state of your application. This state is described by a schema which makes it possible for general purpose block explorers to represent the state of all contracts in a meaningful way.

Every account can define any number of types, aka structs. These structs define the binary serialization of messages and enable anyone to convert the binary representations to and from canonical human readable JSON representations. This keeps the blockchain transparent for all while having efficient binary encodings.

Lastly every account can define what actions it wants to take when it is copied on a message delivered to any other account. For example, an exchange needs to process deposits when a Transfer message is delivered to a currency application and the exchange application is the recipient.

Example Currency Application

One of the simplest applications is a currency. This example will walk through how a currency application could be structured on EOS.

Disclaimer

The following example code is for conceptual purposes only and final implementation details will certainly be different.

Basic Currency Contract

When writing an application you start by asking yourself what actions are taken by the actors (aka accounts), then you define the database schema which stores and indexes data derived from these actions. After you have defined these things you specify the logic that transforms database state based upon an incoming action. Lastly, you (optionally) group message handlers into permission groups.

Let's look at a simple high-level application that implements a currency. A currency can be represented as a table mapping the owner to their balance. It allows the owner of the balance to transfer funds to another account and will create a new balance entry for that account if one does not exist. It must prohibit sending money to yourself and require that the amount transferred is greater than 0. Initially all the money is owned by the contracts own account. Any time a balance reaches 0, the account's balance record should be deleted.

struct Transfer
  to      AccountName
  from    AccountName
  amount  UInt64

struct Init

table Balance
  owner   AccountName
  balance UInt64

on Init action
   precondition:
     eos.requireAuthority( eos.thisAccount() )
     eos.require( !Balance.find( eos.thisAccount() ) ) /// only call once

   apply:
     self         = Balance.new()
     self.owner   = eos.thisAccount()
     self.balance = 100000  /// maximum currency supply
     Balance.save(self)


on Transfer action
   validate:
     // static validation, verifies action is internally consistent
     // no access to database tables
     eos.require( action.amount > 0 ) 
     eos.require( action.to != action.from ) 
     eos.requireNotify( action.to ) 

   precondition:
     // identify possible precondition check that can 
     // be executed with readonly access
     eos.require( Balance[action.from].balance >= action.amount )
     eos.requireAuthority( action.from )

   apply:
     // assuming all prior steps pass, perform the state transition
     // that updates balances and/or creates a new account for receiver
     var from = Balance[message.from]
     var to   = Balance.find( action.to )

     if( !to ) {
        to         = Balance.new()
        to.owner   = action.to
     }

     from.balance = from.balance - action.amount
     to.balance   = to.balance   + action.amount

    Balance.save(to)

    if( from.balance > 0 )
        Balance.save(from)
    else if( from != eos.thisAccount() ) 
        Balance.delete(from)

Things to Notice

Event handlers are divided into three sections: validate, precondition, and apply. These different sections separate out processing into distinctly different phases which enables performance optimizations and parallelism. The validate, and precondition checks are all read-only which means they can be processed in parallel.

The apply step is the only part that needs to be performed to regenerate the current database state from the history of pre-verified actions. This is critical because it is much cheaper to process calculations in validate and precondition than it is in apply. Once a block is deemed irreversible validate and precondition never have to execute again whereas apply must be executed to generate the deterministic state every time the blockchain is synchronized.

Stay Tuned

Stay tuned for more information on how decentralized applications communicate on EOS. Also, don't forget to signup to our mailing list at http://eos.io.

Authors get paid when people like you upvote their post.
If you enjoyed what you read here, create your account today and start earning FREE STEEM!
Sort Order:  

What I like about this code, is that it looks like a "template" that is easily modified by amateur coders.

Many people started learning programming languages by taking existing code that someone else wrote... making a few changes, and personalizing it to do what they wanted instead.

Instead of API's which explain commands, and you have to write your own code to talk to the API...

Having modular code that already does basic tasks, and inviting anyone to plug and play with this code, changing only certain parameters makes it even easier to onboard a lot of people.

Remember the original LOGO programming language?

It was so easy to use. Kids were drawing boxes and lines on the screen with real basic commands. It gave you a sense of empowerment and encouraged you to learn more.

If we do away with API's, and instead give pre-made, basic scripts that already do basic functions, this will help make widespread adoption easier.

Think of basic perl cgi scripts for websites. Once you looked at how some worked, you could modify the source code and build your own version. The key was finding existing scripts written by someone else and making your own tweaks, modifications, and edits.

·

Yes, totally. As a beginner learning to code with JavaScript, React, and Redux, these are very familiar concepts to me.

Great to see example of practical use cases! Hope there will be more of these... :)

Every account (aka application) has its own private database

Where these db is stored?

·

In the implied blockchain state on every node. Aka, the same place your STEEM posts, balances, and votes are stored.

This would use chainbase behind the scenes so would be fast and stored in shared memory.

·
·

Thanks, it makes sense!

Apply basically will have limited 3 seconds of execution time ?

·
·
·
·
·
·
·

Did... I read this correctly? One thousandth of a second...?

Wow.

·
·
·
·

This means the processing of the transaction on a node could happen quickly, but we're still bound by network lag time to transmit this data to other nodes, correct?

Oh wait. This means the state change can happen in 1 ms. The only lag would be the time it would take to send / receive communication through the internet to obtain the current state?

Ahh, we need more info. :)

·
·
·

Your transaction should not require 3 seconds to execute. If your transaction is so complex it takes 3 seconds to execute, the chain should reject it as a denial of service attack. :P

Apply will need a short period of time during which it can make its changes, but those changes should be very fast (updating some database entries). If you're doing crazy complex, multi-millisecond computations in your smart contracts, you're probably doing it wrong, but in any event you'll need to break it up over multiple transactions because the block producers won't let you hog all the CPU time and starve out all the other users.

·
·
·
·

Yeah, that's max limit to execution! I remember when DAO was hacked there was counter measures (intentional spamming) that caused delays on contract execution... looking forward to learn more

I am flabbergasted by the fact that you can include a fully functional private database in each contract. It means that you could write accounting and business solutions in a revolutionary new way (no more double entry archaic methods). For the first time, as a former business application developer, I can relate to the blockchain technology and figure how massively disruptive it will be. Is this feature exclusive to EOS Blockchain (contract private database)?

More awesomeness. Shared with @Steemtrail.

Hello @eosio .. what a great week for y'all, and ... for us all as well! This post has been featured in the latest issue of STEEMINT - The STEEM Intelligence Journal .... the Special EOS Edition!

Hi. I am a regular Joe, and I don't understand most of what is in this post. I have gathered that EOS is a competitor to Ethereum and that your goal is to make it more effective in terms of transactions per sec. I have never participated in an ICO, but I did sign up for the mailing list, hoping to participate in this one. If you read this comment and you are tech savvy, could you please try to explain what EOS is capable of in layman terms? And how it works? This would be greatly appreciated.

·

I think that was @dantheman's attempt to explain this to pseudo-average joe types. I thought the email / messages analogy was pretty good. All blockchain projects are very complex, and no analogy will be perfect. It truly depends on what level of understanding you are seeking. How easily can you explain the way a computer works? Your understanding will only be limited by your own curiosity and willingness to learn. Give yourself time to absorb the info. I've been a geek / techno wizard type for my entire life and there are things that are beyond my understanding, but only b/c I have not chosen to invest the time to dig deeper.

Anytime you simplify a topic accuracy and details are lost. How accurate do you want your explanation to be?

·
·

I think his point is from a user perspective, what benefits are there to such a system in real world scenarios.

Basically what Dan did is similar to explaining how SMTP, POP3, MTA, and MX works for email. Now ask most people how each component works for email, and they'll tell you:

Uh, I don't know. In the TO line, I put my mother's email address. In the subject line I put "hi mom" and then I type what I want to send.

What could EOS do better, than existing technologies out there (from a USER perspective only). That's going to be the key thing to explain.

·
·

Thank you for the reply. I want the explanation to be so simple that it only highlights the differences between EOS and Ethereum from a user perspective like Intelliguy says. He is spot on with his e-mail analogy.

If any of you have seen the tv show Silicon Valley it highlights this potential problem perfectly. Their software "Pied Piper" is really nice and useful, but no one understands it and the dev. team is not able to explain what they have made to the general public.

It may be completely obvious to the devs that their product is good and that it could revolutionize the world, but remember that the general public know nothing of how anything works with programming. It is all magic to them. You press W on your keyboard and your character moves forward in the video game.... You flick the switch and the light comes on.... You press this sequence of numbered buttons and the phone rings....

·

Remember, this is software that hasn't even been officially and formally announced yet. Keep watching and the picture will become more clear. :)

Very cool. I was searching for more info on EOS and here it is. Crypto-currencies are evolving before our very eyes.

This sounds really interesting. I almost want to think up some real world problems just to see if I could build their solutions within EOS. :)

Will there be a testnet for people who want to play around with this?

Once a block is deemed irreversible validate and precondition never have to execute again whereas apply must be executed to generate the deterministic state every time the blockchain is synchronized.

I really like that. Seems like an efficient way to go if much of the code to validate things has already been run before it was applied and won't need to be run again.

·

Yes there will be a public test net.

·
·

Niiiiice. I wish I could be at Consensus. I hope it's one hell of a party. :)

im hyped on this project ;)

Great to see your recent work on the language. Very clean. You said it would change so here goes..

It would be very cool to get rid of this: Balance.save(to) and this Balance.save(from). The contract would need to be transactional to some extent so a failed assertion or error would roll all the changes.

This is motivating me to add your text format in a struct serialization parser. Using text in addition to json is a very easy enhancement.

Excellent. Definitely looking forward for the testnet

We need to off block chain contacts too, like Aeternity is implementing. Private contacts that only ever need to touch the chain if there is a dispute

Messages, will be checked / earmarked as 'processed' by the chain software? In the end one of the validators is processing the message and executes the code right to store it in the db. What happens if a physical server in the middle of the execution quits because of power failure?

Will messages get a lifetime? Doubles(p)ent messages :) will there be unexecuted messages floating around on chain? Are you the messenger?

Lastly, are you know working on hypothetical apps and building the source afterwards or is the source, specifically for the eos part, already ready?

See you in nyc!

·

Messages are like Steem and BitShares transactions. A power failure would simply require replaying from the last good snapshot of the state.

l like
how can l join this? ico or pos?

Sweeeeeeet! Please keep writing like this!!!

Indeed.. very detail. Thanks. I ve been looking information like this..

·

::DD give it here :)

i like your post

When writing an application you start by asking yourself what actions are taken by the actors (aka accounts)... After you have defined these things you specify the logic that transforms database state based upon an incoming action.

So this looks similar to redux in the react world with actions that triggers reducers to perform some changes on state. Is this accurate?

Very interesting read!

I have a lot to read then :) This seems like just a flake of everything possible

Was that graph made with yEd Graph Editor?

What database are you referring to in the "Structure of an Application" section. Is it levelDB ? If levelDB how are you achieving the concept of indices in the NoSQL database, and are you achieving the O(logN) efficiency ? Can you please explain ?

Great article for newbies. I would like to see real world use case scenarios with more complex data structures and scope management.
Thanks,