Smart Contracts (thanks to Michael Bacina) |
A CryptoKitty |
You can even take this a little bit further. As shown with the CryptoKitty the smart contract does not need to have anything to do with transferring money from a to b or writing some sort of financial contract. In theory you could use the smart contract to do anything you might be able to use asynchronous computing power for.
- First of all it's quite easy to run a test EOS node on your own machine which allows you as a developer to play with it and understand it in a sandbox type environment.
- EOS aims to provide much higher transaction rates than the current major block chains can provide. It promises up to 50000 transactions per second which all of a sudden is big enough to handle amounts of payments similar to major credit card companies like Visa and Mastercard.
- Smart contracts on EOS can be written in C/C++ which is really nice, as you don't need to learn a new programming language for it.
So let's take a look at how I got my example EOS contract deployed to my own test EOS node.
First, clone the EOS code
~$ git clone https://github.com/eosio/eos ~/eos
~$ cd eos
Build the EOS code
I tried this on Ubuntu 16.04. Compile the EOS code base:First, clone the EOS code
~$ git clone https://github.com/eosio/eos ~/eos
~$ cd eos
Then build the whole lot:
~/eos$ ./build.sh ubuntu full
This takes a while but once it's finished you should be able to run your EOS node:
~/eos/build/programs/eosiod$ ./eosiod
It now exits with an error. You need to set up data-dir/config.ini as described in the EOS docs: https://github.com/EOSIO/eos
At this point your EOS node should be happily up and running. Which is really neat. You've got a EOS block chain node running for development purposes on your local machine!
~/eos/build/programs/eosiod $ ./eosiod
Before you can use your EOS node you need to create a wallet and an account. Since our smart contract will be computing the Fibonacci sequence, I'm going to call the account fibonacci. The following commands do that for you. They use a demo account inita that is created in the config.ini file when its set up as above.
Here we use the eosioc program which is a client to the EOS network:
~/eos/build/programs/eosioc $ ./eosioc wallet create
~/eos/build/programs/eosioc $ ./eosioc wallet open
Import the inita demo key:
~/eos/build/programs/eosioc $ ./eosioc wallet import 5KQwrPbwdL6PhXujxW37FSSQZ1JiwsST4cqQzDeyXtP79zkvFD3
This takes a while but once it's finished you should be able to run your EOS node:
~/eos/build/programs/eosiod$ ./eosiod
It now exits with an error. You need to set up data-dir/config.ini as described in the EOS docs: https://github.com/EOSIO/eos
At this point your EOS node should be happily up and running. Which is really neat. You've got a EOS block chain node running for development purposes on your local machine!
~/eos/build/programs/eosiod $ ./eosiod
Before you can use your EOS node you need to create a wallet and an account. Since our smart contract will be computing the Fibonacci sequence, I'm going to call the account fibonacci. The following commands do that for you. They use a demo account inita that is created in the config.ini file when its set up as above.
Here we use the eosioc program which is a client to the EOS network:
~/eos/build/programs/eosioc $ ./eosioc wallet create
~/eos/build/programs/eosioc $ ./eosioc wallet open
Import the inita demo key:
~/eos/build/programs/eosioc $ ./eosioc wallet import 5KQwrPbwdL6PhXujxW37FSSQZ1JiwsST4cqQzDeyXtP79zkvFD3
Create two private keys for the fibonacci account:
Create the fibonacci account:
~/eos/build/programs/eosioc $ ./eosioc create account inita fibonacci {private key1} {private key2}
The code can be found in github here: https://github.com/coderthoughts/fibonacci
It exists of two components: an external contract, in the fibonacci.abi file which defines how the application communicates with the outside world. The actual communication typically happens in JSON:
~/eos/build/programs/eosioc $ ./eosioc create key
Private key:###
Public key: ###
~/eos/build/programs/eosioc $ ./eosioc create key
Private key:###
Public key: ###
~/eos/build/programs/eosioc $ ./eosioc create account inita fibonacci {private key1} {private key2}
Create the smart contract
I created a little testproject called fibonacci which computes the fibonacci sequence to a certain iteration in the EOS smart contract and stores the result in the EOS database.The code can be found in github here: https://github.com/coderthoughts/fibonacci
It exists of two components: an external contract, in the fibonacci.abi file which defines how the application communicates with the outside world. The actual communication typically happens in JSON:
{
"structs": [{
"name": "compute",
"base": "",
"fields": {
"iterations": "uint64"
}
},{
"name": "result",
"base": "",
"fields": {
"id": "name",
"value": "uint64"
}
}],
"actions": [{
"action_name": "compute",
"type": "compute"
}],
"tables": [{
"table_name": "results",
"type": "result",
"index_type": "i64",
"key_names": ["id"],
"key_types": ["name"]
}]
}
And there is the fibonacci.cpp file that contains the source code in C++ of the contract. The main bit of the C++ contract is just the apply() method that gets invoked when the EOS Smart Contract receives a message:
uint64_t fibonacci(uint64_t iterations) {
uint64_t first = 0;
uint64_t second = 1;
if (iterations == 0)
return 0;
eosio::print("1 ");
for (uint64_t i=1; i < iterations; i++) {
uint64_t res = first + second;
first = second;
second = res;
eosio::print(res, " ");
}
return second;
}
/// The apply method implements the dispatch of events to this contract
void apply(uint64_t code, uint64_t action) {
if (action == N(compute)) {
auto message = eosio::current_message<compute>();
eosio::print("Calling fibonacci\n");
uint64_t num = fibonacci(message.iterations);
result res(eosio::name(code), num);
Results::store(res, res.id);
eosio::print("Stored result in database\n");
}
}
There are also specific EOS libraries available, the documentation is here: https://eosio.github.io/eos/group__contractdev.html
Deploy your own smart contract
An interesting part of the EOS smart contract development lifecycle is that these contract don't get compiled in regular machine language, what C++ compilers normally do, but it gets compiles into a WebAssembly .wast file. This file is some sort of assembler language but then platform independent and this is what EOS uses at runtime.Once deployed, you can execute your contract by sending a message to it. The contract executes and can write its output to a database location for later retrieval by a client.
The easiest way to compile the fibonacci source is to put the files with the other example smart contracts in the EOS codebase, in the contracts directory. Then you've got everything in the path as the compiler expects it:
Compile the project:
~/eos/contracts$ ../build/tools/eoscpp -o fibonacci/fibonacci.wast fibonacci/fibonacci.cpp
Upload the fibonacci smart contract to the EOS node:
~/eos/contracts$ eosioc set contract fibonacci fibonacci/fibonacci.wast fibonacci/fibonacci.abi
Now we can start executing it. Lets run the fibonacci compute for 8 iterations and store the result:
~/eos/contracts$ eosioc push message fibonacci compute '{"iterations":8}' -S fibonacci
On the EOS demon console you can see some debug output from the smart contract
> Calling fibonacci
> 1 1 2 3 5 8 13 21 Stored result
However a real user will obviously never be able to see this. So to obtain the result of the computation, we'll look it up in the EOS database:
/build/programs/eosioc$ ./eosioc get table fibonacci fibonacci results
{
"rows": [{
"id": "fibonacci",
"value": 21
}
],
"more": false
}
So the result is 21. We've executed our smart contract and obtained the result on the EOS blockchain!