Basic Contract
Here is a basic contract definition. Place example.cpp
and CMakeLists.txt
in an empty folder.
example.cpp
#include <eosio/asset.hpp>
#include <eosio/eosio.hpp>
// The contract class must be in a namespace
namespace example
{
// The contract
struct example_contract : public eosio::contract
{
// Use the base class constructors
using eosio::contract::contract;
// Action: user buys a dog
void buydog(eosio::name user, eosio::name dog, const eosio::asset& price)
{
// TODO: buy a dog
}
};
// First part of the dispatcher
EOSIO_ACTIONS(example_contract, //
"example"_n, //
action(buydog, user, dog, price))
} // namespace example
// Final part of the dispatcher
EOSIO_ACTION_DISPATCHER(example::actions)
// ABI generation
EOSIO_ABIGEN(actions(example::actions))
CMakeLists.txt
# All cmake projects need these
cmake_minimum_required(VERSION 3.16)
project(example)
# clsdk requires C++20
set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
# Libraries for building contracts and tests
find_package(clsdk REQUIRED)
# Build example.wasm contract
add_executable(example example.cpp)
target_link_libraries(example eosio-contract-simple-malloc)
# Generate example.abi
# This is a 2-step process:
# * Build example.abi.wasm. This must link to eosio-contract-abigen.
# * Run the wasm to generate the abi
add_executable(example-abigen example.cpp)
target_link_libraries(example-abigen eosio-contract-abigen)
add_custom_command(TARGET example-abigen POST_BUILD
COMMAND cltester example-abigen.wasm >example.abi
)
# These symlinks help vscode
execute_process(COMMAND ln -sf ${clsdk_DIR} ${CMAKE_CURRENT_BINARY_DIR}/clsdk)
execute_process(COMMAND ln -sf ${WASI_SDK_PREFIX} ${CMAKE_CURRENT_BINARY_DIR}/wasi-sdk)
# Generate compile_commands.json to aid vscode and other editors
set(CMAKE_EXPORT_COMPILE_COMMANDS on)
Building
This will create example.wasm
and example.abi
:
mkdir build
cd build
cmake `clsdk-cmake-args` ..
make -j $(nproc)
Trying the contract
clsdk comes with nodeos, cleos, and keosd. The following will execute the contract:
# Start keosd on an empty directory
killall keosd
rm -rf testing-wallet testing-wallet-password
mkdir testing-wallet
keosd --wallet-dir `pwd`/testing-wallet --unlock-timeout 99999999 >keosd.log 2>&1 &
# Create a default wallet. This saves the password in testing-wallet-password
cleos wallet create -f testing-wallet-password
# Add the default development key
cleos wallet import --private-key 5KQwrPbwdL6PhXujxW37FSSQZ1JiwsST4cqQzDeyXtP79zkvFD3
# Start up a fresh chain
killall nodeos
rm -rf data config
nodeos -d data --config-dir config --plugin eosio::chain_api_plugin --plugin eosio::producer_api_plugin -e -p eosio >nodeos.log 2>&1 &
# Install the contract
cleos create account eosio example EOS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV
cleos set abi example example.abi
cleos set code example example.wasm
# Try out the contract (does nothing)
cleos push action example buydog '["eosio", "fido", "100.0000 EOS"]' -p eosio
vscode support
The following files configure vscode:
Code completion and symbol lookup does not work until the project is built (above).