[CODEOS] Essential knowledge in EOS contract development

Hello, We’re EOSeoul, a technical Block Producer candidate based in Korea.
Today, we’re pleased to announce ‘CODEOS’, EOSeoul Development Course, where you can learn all about EOS development. We’ve spent the past couple of months building education material from the ground up with the ultimate goal of ensuring that we’re giving community the best possible foundation.

CODEOS is to develop the global blockchain ecosystem by riding the EOS knowledge gap and supporting EOS developer. Today we’re going to cover essential knowledge in EOS contract development. This article is a summary of basic concepts, and we will cover each concept in more detail in the following articles.

Nowadays, Security is very important and has to be given a highest priority. Blockchain is becoming a very interesting and it seems to be very easy to adapt by any person. The open source of blockchain programming is making everyone to learn and also many are getting more interested in peeping into other projects and hack them.

Since it is very important to learn the issues and to know the situations where we need to be more secure, we thought of writing an article about permissions, authorizations, responsibilities as an owner of an account and issues you might need to be concern with while using tokens.
Hope this article will help you understand these topics.

account

Account is generally,

  • without smart contract
  • with smart contract

Account without contract are the normal EOS account to use Dapp service like playing games, betting tokens, and transferring tokens etc.

Account with smart contracts : To provide Dapp services, you need to make account with smart contract. eosio.token account has eosio.token action to manage tokens. So token contract provides users the facility of creating tokens, token issuing and token transfering.

While performing these actions, users or contract holder’s might face security issues. So contract developers need to give high importance in understanding the cases and handling the issues. These issues could be related to accounts, contracts, tokens or RAM.

1account : 1contract

Every EOSIO smart contract is set to a single EOSIO account. A contract is basically an object that other accounts can interact with. An account cannot have more than 1 contract.

Create account

Format of creating an account in cleos

$ cleos create account eosio NEW_ACCOUNT OWNER_KEY ACTIVE_KEY
This command is basically for private testnet. This command is used as practise purpose only and is not linked with real blockchain. But when developers work with real blockchain, public testnet or public mainnet is been used. To create account in the public testnet or mainnet, the command is as below.

$cleos system newaccount [OPTIONS] creator name OwnerKey [ActiveKey]

creator: The name of the account creating the new account (required)
name : The name of the new account (required)
OwnerKey: The owner public key for the new account (required)
ActiveKey: The active public key for the new account
[Options] are more about staking, buying ram, permissions, max net usage, delay time etc.

This explains that the account is secured with both owner key and active key. We always need to save the keys in a separate personal document for later usage. As a beginner it is advised to use the active key for all the actions we make till you completely understand the concepts.

EOS Actions

There are two types of calling EOS action: External and inline actions.

1) External actions

: External actions happen when the user calls action directly from the outside.

2) Inline Actions

  • Type 1 : Inline actions happen when an action calls to another action in same contract.
  • Type 2 : Inline actions happen when an action calls to another action in external contract.

Here we used the example of addressbook and abcounter in eosio developer portal in the section 2.6 and 2.7

Let’s take a look at each type of Inline actions.

Type 1 Inline action permissions:

In this, when implementing the “push action” , there came an error!
$cleos push action addressbook upsert '["sriaccount11", "Marc","Albert", "flat 603 city apt", "small city", "USA"]' -p sriaccount11@active

Error 3090003: Provided keys, permissions, and delays do not satisfy declared authorizations
Ensure that you have the related private keys inside your wallet and your wallet is unlocked.

Type 2 Inline Actions to external contract

This type 1 error happens in the case of type 2 action too. Inline actions can only be executed by eosio.code permission, so to recover this error, eosio.code permission is required.
If you want to know how to check inline actions authorization, click here!

eosio.code

eosio.code is a virtual code authority which enhances the security and enable contracts to execute inline actions.
In order to get permissions, eosio.code has to be added in its own contract’s account. Below is the image explaining what happens after adding eosio.code.

So, to accomplish this, it is necessary to run the following code:
$cleos set account permission addressbook active '{"threshold": 1,"keys": [{"key": "YOUR_PUBLIC_KEY","weight": 1}], "accounts": [{"permission":{"actor":"addressbook","permission":"eosio.code"},"weight":1}]}' -p addressbook@owner

In order for the inline actions to interact with in the contract or with an external contract the inline actions require permissions and authorizations of its owner contract’s account.

To learn in more detailed or to learn more other possibilities of permissions we can see in this following link in the Eos developer page.
https://developers.eos.io/eosio-cleos/reference#cleos-set-account

This issue makes us to realize that the permissions and authorisations take a very important part of the interactions between accounts,contracts, and actions.

Permission

Permissions are basically consist of Owner key or Active key. There are three types of weights : Keys, Accounts and Waits.

For account management, using account name is easier and more intuitive than using public keys which are difficult to memorize. As we already mentioned about eosio.code, you should use type of account weights in this case.

Format of Permissions

In the above example we also can observe that there are 2 permissions in accounts which means that one account can permit to one or more accounts. This concept is Multisig.

Multi signature account

In this another small example we will explain how a multisignature wallet works, and how to set one up yourself.

Taken from the EOSIO Wiki

In this example ,The owner permission has a threshold of 2, and has 2 keys, both with a weight of 1. This means that the signature of both keys is needed to perform any action that requires the owner permission.
The active permission has a threshold of 1, and has 2 keys, both with a weight of 1. This means that only 1 signature of any of of the 2 keys is required to perform any action that requires the active permission.

Waits : waits allows user to ensure that a transaction may not be executed without a required
delay. To specify a wait in EOS, you must provide a wait_sec and weight of the delay.

Permissions are very important part of the interactions.

  • They improve Security
  • Scheduling the transactions can also be managed with the help of weights and thresholds.

Notification

When using inline action, you need to add permission ‘contract@eosio.code’, to user’s account. However, it’s not easy to apply to service because most of users are reluctant to add it to their own account. So notification function is used mainly in service instead of adding permission.

A notification is a function to deliver success action to designated user once the action is successfully completed.
When actions are made within contracts or using external contracts, there is very helpful way of checking if its properly done or not is by getting notification. eosio.token is a good instance to understand how a transfer actions are made and how the notification is made.

Here,

require_auth( account name )
This action explains that the transfer function requires the authorization of the account holder from where the tokens are transferred.

require_recipient( account name )

This action helps in getting notification to the account. This explains that the current action to be delivered to the account name.

Action Handlers

‘EOSIO_DISPATCH macro’ and ‘apply function’:
There are also some very important issues which are needed to keep in mind.

Every smart contract must provide an apply action handler, or “dispatcher”. The dispatcher is a function that listens to all incoming actions and performs the desired behavior. These dispatchers are designed as small macros.

Our contract’s first line of security begins at your dispatcher. It is very crucial to limit the exposure of how the dispatchers are handled inside the logic of actions. This is highly depended on the code developer or programmer. Always take great caution when writing a custom dispatcher, and be aware of the security implications of each individual implementation method. It can be simplified the work by making a header file of all possible dispatchers and action handlers, but you need to make your own EOSIO_DISPATCH macro for real service.

#define EOSIO_DISPATCH( eosio::bios, (setpriv)(setalimits)(setglimits)(setprods)(reqauth) )

#define EOSIO_DISPATCH( TYPE, MEMBERS ) extern "C" { void apply( uint64_t receiver, uint64_t code, uint64_t action ) { if( code == receiver ) { switch( action ) { EOSIO_DISPATCH_HELPER( TYPE, MEMBERS ) } // does not allow destructor of thiscontract to run: eosio_exit(0); } } }

In order to respond to a particular action, code is required to identify and respond to specific actions requests. apply uses the receiver, code, and action input parameters as filters to map to the desired functions that implement particular actions.

Sometimes the code could be “itself” or the “receiver” depending on the necessity. We can also make a custom macro that can consider our needs uniquely. these are completely again depending on the type of account transaction (inline or deferred).

The apply function can filter on the code parameter using something like the following.

In order to respond to a particular action, code is required to identify and respond to specific actions requests. apply uses the receiver, code, and action input parameters as filters to map to the desired functions that implement particular actions.

Sometimes the code could be “itself” or the “receiver” depending on the necessity. We can also make a custom macro that can consider our needs uniquely.
The apply function can filter on the code parameter using something like the following
if (code == name("contract_name").value) { // your handler to respond to particular code }

The apply function can filter on the action parameter using something like the following
if (action == name("action_name").value) { // your handler to respond to particular action }
The apply function can filter on the action parameter using something like the following

if (code==self) { // can make some upserts, updates, erase, notify to its own actions. }

The apply function can filter on the action parameter using something like the following
if (code==receiver) { switch(action) { // does not allow the dispatcher of this contract to run: eosio_exit(0); } }

The next article will cover action handlers in more detail.

Past hacked issues:

The hacking was also possible due to the conditions they applied for the apply code. Few examples are:

Tokens 24 is says that September 9th , DEOS Game user called “runningsnail” receiving $1,000 payments repeatedly after depositing 10 EOS and winning jackpot only seconds later. 10th september they confirmed that this was a hack.

EOS BET TRANSFER HACK STATEMENT written by EOS Bet Casino,September 15th, a smart contract was hacked and had a significant loss of funds occured.The fault was in ABI forwarder. It allows the contract to accept every in-come of eosio token and every possibility of action with the smart contract.

Similarly this happens to EOS Knights. Eos knights has also published on september 14th that they experienced a similar hack. But fortunately, before the attacker hacked, their prospectors.io reported the issue and evacuated their EOS to safe account.

Conclusion:

EOS is safe, but if contract developer make flaw in the contract, security issues could happen. So it is very important for the developer to completely understand the concepts of

Authorities
Permissions
eosio.code
Notification
require_auth
require_recipient
Dispatchers

Thank you.

Team EOSeoul.