Hello World Contract

Create a new directory called "hello" in the contracts directory you previously created, or through your system GUI or with cli and enter the directory.

cd CONTRACTS_DIR
mkdir hello
cd hello

Create a new file, "hello.cpp" and open it in your favourite editor.

touch hello.cpp

Below the eosio.hpp header file is included. The eosio.hpp file includes a few classes required to write a smart contract.

#include <eosio/eosio.hpp>

Using the eosio namespace will reduce clutter in your code. For example, by setting using namespace eosio;, eosio::print("foo") can be written print("foo")

using namespace eosio;

Create a standard C++11 class. The contract class needs to extend eosio::contract class which is included earlier from the eosio.hpp header

#include <eosio/eosio.hpp>

using namespace eosio;

class [[eosio::contract]] hello : public contract {};

An empty contract doesn't do much good. Add a public access specifier and a using-declaration. The using declaration will allow us to write more concise code.

#include <eosio/eosio.hpp>

using namespace eosio;

class [[eosio::contract]] hello : public contract {
  public:
       using contract::contract;
};

This contract needs to do something. In the spirit of hello world write an action that accepts a "name" parameter, and then prints that parameter out.

Actions implement the behaviour of a contract

The above action accepts a parameter called user that's a name type. EOSIO comes with a number of typedefs, one of the most common typedefs you'll encounter is name. Using the eosio::print library previously included, concatenate a string and print the user parameter. Use the braced initialization of name{user} to make the user parameter printable.

As is, the ABI <> generator in eosio.cdt won't know about the hi() action without an attribute. Add a C++11 style attribute above the action, this way the abi generator can produce more reliable output.

Everything together, here's the completed hello world contract

The ABI Generator in infrablockchain.cdt supports several different style of attributes. You can compile your code to web assembly (.wasm) as follows:

When a contract is deployed, it is deployed to an account, and the account becomes the interface for the contract. As mentioned earlier these tutorials use the same public key for all of the accounts to keep things simple.

Create an account for the contract using infra-cli create account, with the command provided below.

Deploy the compiled wasm to the blockchain with infra-cli set contract.

Get an error? Check if your wallet needs to be unlocked.

In previous steps you should have created a `contracts` directory and obtained the absolute path and then saved it into a cookie. Replace "CONTRACTS_DIR" in the command below with the absolute path to your `contracts` directory.

Great! Now the contract is set, push an action to it.

As written, the contract will allow any account to say hi to any user

As expected, the console output is "Hello, bob"

In this case "alice" is the one who authorized it and user is just an argument. Modify the contract so that the authorizing user, "alice" in this case, must be the same as the user the contract is responding "hi" to. Use the require_auth method. This method takes a name as a parameter, and will check if the user executing the action matches the provided parameter.

Recompile the contract

And then update it

Try to execute the action again, but this time with mismatched authorization.

As expected, require_auth halted the transaction and threw an error.

Now, with our change, the contract verifies the provided name user is the same as the authorising user. Try it again, but this time, with the authority of the "alice" account.

What's Next?

Last updated