The ultimate end-to-end EOS dApp development tutorial — Part 2

Infinite X
Infinite X
Published in
11 min readJun 15, 2018

--

Are you ready for some serious work to do?

Let’s summarize what we have learned so far in the previous two tutorials. We know how to setup and build EOSIO, starting a local testnet node with nodeos, creating an account and using it to deploy our own contract. And the most important we have learned how to write EOS smart contracts or at least the basics. We did a lot of new things, but we’re about to do even more with the second part today.

If you’re just starting with the series check the previous two tutorials:

  1. First steps in EOS Blockchain Development
  2. The ultimate end-to-end EOS dApp development tutorial — Part 1

In part 1, we have started developing our Oasis dApp. We created a simple structure of the project and implemented partly our Players smart contract. There is a lot of work to do so let begin.

Keep a note that the EOSIO is still in development and some of the steps might change in the future. However, our team will try to keep the tutorial always up to date.

You can find all the source code for this part in GitHub

Last update — 29 July, 2018 — The tutorial was updated with the latest version of EOSIO — v1.1.1

As I said the last time we created a simple project structure. However, when you developing an EOS dApp in a real-world situation the things are not so simple. We want everything we do to be automatic and to generate the files we need in order to develop our dApp the best way we can, right? Well, this is why our team created a tutorial on “How to setup VS Code and/or CLion for EOS dApp Development“.

We decided it’s much better for you if the setup tutorial is separate from this one. So before you continue, go and set up your IDE the way we need it.

Project Update

Did you set up your IDE? Yes? Cool, let’s continue.

You have now the basic skeleton for developing your dApp. Move the folders from the old project structure inside the new one. More precisely Players, Marketplace, Games & Oasis inside contracts folder. When you do this it’s time to build.

Take a note that each of your contracts should have the .abi file generated before the build. If you’re using VS Code with our custom commands then run the ⌘+I command which we have set as a shortcut while you’re in Players folder. This will generate Players.abi.

Now run ⌘+R to start the build process. Since this is our first build it will take time to build everything.

When the building process finishes you’ll see that it has generated some files for you.

Most importantly it has the files we need for our Players smart contract. You can find them inside build / contracts / Players:

Some of the files like Players.abi and Players.wast should be familiar to you. The last time we used them to deploy our smart contract to the blockchain. The others will be used for our unit tests.

Update and Extend Players contract

1. Update

If you remember in the previous tutorial we have created two files — Players.hpp & Players.cpp, which are our header(.hpp) and implementation(.cpp) files. Almost all of the code we have written was inside the Players.cpp and only a few imports in the Players.hpp. We’re going to make small changes on that for two reasons.

  1. First, the header file is responsible for the declaration of all variables, constants, and actions referenced by the .cpp file. It’s pretty much like an interface. On the other hand, the implementation files hold the implementation of all actions.
  2. The second reason to update our contract it’s based on C++ and programming conventions. When you want to use one contract in another you should import it. However, the best way to do that is to import the .hpp file as the contract who will use it doesn’t need to know what the implementation is or in other words we shouldn’t import the .cpp file. It’s a bad practice.

So update the two files as follow:

Players.hpp

Players.cpp

Let’s see what we have changed.

The Players.hpp now contains the Players class declaration. Inside the class we have the player structure and our actions — add, update & getplayer but this time only its signature. The implementation of the actions is inside Players.cpp as it should be. The structure of the implementation file is a bit different. Our actions are inside the namespace and they are referenced from the Players class with the Player::{action_name} template. We’ve also moved the EOSIO_ABI macros inside the Players.hpp.

You’re probably wondering what is happening behind the scenes? Let’s summarize!

Header files (.hpp) allow you to make the interface (in this case, the class Players) visible to other .cpp files, while keeping the implementation (in this case, Players’ action bodies) in its own .cpp file. The #include statement is basically like a copy/paste operation. The compiler will “replace” the #include line with the actual contents of the file you’re including when it compiles the file.

Let’s check now that we have not broken anything. While you’re still in Players.cpp run ⌘+I to generate the Player.abi file then runs ⌘+R to rebuild the Players contract. When it’s done go to terminal and deploy the contract to the blockchain. You remember how to do it, right?

Here is a hint! Your current folder should be “build“:

If you haven’t used the oasis wallet in a while you’ll probably get an error “Error 3120003: Locked wallet“. To unlock it run the command below. Note that you need your wallet password. You save it the last time when we created the oasis wallet, right? Yeah, we need exactly that password.

If you didn’t save it there are 3 options:

  1. Delete the current oasis wallet and create it again. Don’t forget to save the password and the keys this time.
  2. Create another wallet
  3. Start with a fresh new blockchain node

The option number 1 and 3 are probably the best as all demos are using the oasis wallet and you can make a mistake if you use another name.

Try again to deploy the contract. This time everything should be ok and Players will be deployed. Let’s add a new player. Note that you’ll need to create another account as the rule is one player per account. Create a new pair of keys for it which you will import again in the oasis wallet. Name the account “wade” and create the new player — parzival:

We’ll use the player later in our tutorial series. Now we’ll continue with extending the Players contract.

2. Extend

Once you have updated the Players contract we’re going to add even more things to it. Currently, each player has a username, level, health_points & energy_points. As a next step, we’re going to add a collection to keep all abilities and inventory which will contain all his purchased items from the Marketplace. Finally, we’ll create the currency for our dApp. If we’re going to purchase items from the store we’re going to need some coins to do it.

IMPORTANT NOTE: With the latest version EOSIO there is a very unpleasant problem — once you deploy your table (in our case the struct player) you won’t be able to add new properties. You will probably get the following error: eosio_assert_message assertion failure. This will be fixed in the future by EOSIO, but for now, we have to deal with it. One way to ignore the problem is to rename your struct (GitHub issue 3825). However, for our tutorial, we decided it will be much more clear to do the following steps:

  1. Restart the node — when you restart the node with –delete-all-blocks it will clear everything. This is what we’re trying to accomplish
  2. Create new oasis wallet — delete your old one and create your new oasis wallet as we did it in part 1
  3. Create the anorak account
  4. Build and the deploy Players smart contract — once you have added the 2 new properties from the below code (abilities & inventory) you should build and deploy the contract
  5. Create the players — create again the player art3mis & wade
  6. Test — once you have done all that you’ll be able to test your new properties

This is a temporary solution. We will update the tutorial as soon as EOSIO fix it!

Abilities

Go to the player struct in Players.hpp and add new abilities container like this:

The vectors in C++ are sequence containers representing arrays that can change in size. This is exactly what we need as we don’t know how many abilities a player could have. As you see our vector will contain only string elements — the abilities. Don’t forget to add abilities property to the EOSLIB_SERIALIZE.

In Players.hpp we’ll do one more thing. In order to work properly the added vector, we should remove the private modifier. In other words, we’ll make the struct public. So before continue go and delete it.

We have added our new property but we still don’t have an action which will add an ability to a player. Here is what we’ll do

When we want a player to get a new ability we’ll execute the addability action.

Before testing the new action let’s make some changes in the getplayer action. Remove the old print and add this code:

Let’s test now. Do you remember what you need to do? ⌘+I, ⌘+R and then deploy the contract. Are you ready? Cool, let’s add “shapeshifting” ability for player art3mis:

Awesome, we just added an ability for our player. Try to add another one yourself.

Inventory

The inventory is another important property of our player. It keeps all items purchased from the Marketplace.

For this purpose, we will need another vector container to keep the items. We’ll also need to create an item object. And, of course, last but not least an action to add the items inside the container.

Let’s start with adding the new item object inside Players.hpp. Each object of this type will have item_id, name, how much power and health it will give to its owner. Does it come with a new ability and/or level_up?

Add the new property inventory inside the player struct — it’s going to be a vector of items. Now, create and implement the action which will save the items inside the inventory:

We’ll stop here as we need the Marketplace smart contract which we haven’t created yet.

Marketplace Smart Contract

We’re going to create now our Marketplace smart contract. This is where each player can buy items.

Our contract will have the following actions:

  • add — it will add new products in the Marketplace
  • update — it will update the quantity of each product by product Id
  • remove — it will remove a product from the Marketplace
  • getbyid — using only the product Id we’ll be able to get an information about the product
  • buy — when a user wants to buy his new item he’ll be using this action

You know how the basic skeleton of an EOS smart contract looks like. Before continue, try to create Marketplace.hpp & Marketplace.cpp yourself. If you’re not sure then check the Players smart contract. Don’t forget to add add_subdirectory(Marketplace) inside the CMakeLists.txt in the contracts folder.

Once you have the contract ready add all actions and don’t forget to add them in the EOSIO_ABI macro at the end. Also, take a note here that in order to keep all the products we’re going to need a multi-index container — productIndex and object template — product. Our add action uses the product struct as a parameter, this means that the declaration of the struct must be before the action. If we don’t do this the action simply won’t know about it and it won’t work.

Now, let’s implement our actions. You should know how to as we have done it in Players smart contract already — some of them are exactly the same as add, update, getbyid. However here is the implementation of all actions.

We’ll take a close look at the first action — buy. There is two inline action

  • Inline Transfer — transfer tokens from the buyer to the contract
  • Inline Action — call an action from another contract

In order to receive his item, the player should pay for it. This is why we’re using an inline transfer which facilitates the process for us. Then the second inline action is executed which add the item to players’ inventory.

Before testing the whole logic we need first to create our currency. This is where eosio.token contract comes handy. The contract is not in our project but we know where it is. Go to the folder of eosio repo and find eosio.token.wast & eosio.token.abi files in the build directory. We’ll use them to deploy the contract with our anorak account:

Deploy the eosio.token

Create our currency with symbol OAS

Issue some tokens to wade & anorak accounts

We have now our currency for the Oasis dApp and we can use it in the Marketplace. Let’s return to it. We’re going to create a new account which will operate with the Marketplace smart contract and will deploy it. Create it and named it market.

Deploy the Marketplace contract and don’t forget to do ⌘+I, ⌘+R before that. Now, it’s time to test it.

Awesome items. Let’s buy one. Parzival decided that he has need of elf’s potion, so he bought it:

Before checking our player, update the getplayer action and add this code snippet at the end of the action:

Check now the player:

You passed it! This is the end of Part 2. Our advice is to take your time to understand everything we did and try to do it by yourself. In Part 3 we’re going to create some games which our players could play and win new OAS.

Are you developing Blockchain? Or perhaps you really see the benefits of finding the right use of the technology for you, but are not sure how to start? We wrote an article aimed at those who seek continuous progress or wish to successfully implement the technology in their venture. Short and to the point. — Click here

We hope you enjoyed this article! The authored worked hard to make sure of that. Remember. Sharing is caring. Especially when it comes to articles. We have already started Part 3, make sure to follow us on LinkedIn, Facebook and Twitter if you want to be the first to know when.

Scan the QR | Subscribe for our monthly Newsletter

--

--

Infinite X
Infinite X

evolve your business. | Enterprise Blockchain Solutions