Last weekend we participated in the First Eastern European Tezos Hackathon as mentors, and now we want to tell you how we prepared for it, what happened and what conclusions we drew.
We decided to go through all the steps from setting up the environment to calling the smart contract and record everything. We used four tools for local development and debugging of smart contracts in Tezos:
- Granary — All-in-one toolkit for smart contract development;
- LIGO — High-level smart-contract language that compiles down to Michelson;
- PyTezos — Python SDK for Tezos;
- Better Call Dev — Michelson contract explorer.
All sources are available in our repository https://github.com/baking-bad/tezos-nft-sample.
# Setting up sandbox
Before we go we need to ensure all necessary system libraries are installed and also proper versions of node.js, python, and docker.
# Sudoless docker
A typical issue, when you cannot run any docker command without sudo
. Explained in the official docs: https://docs.docker.com/install/linux/linux-postinstall/
# Python environment
Common problems with python: multiple versions on the same machine, missing ssl or zlib modules. The best workaround is using pyenv
, start from this page: https://github.com/pyenv/pyenv/wiki/Common-build-problems
# PyTezos dependencies
In order to work with elliptic curve cryptography (ed25519, secp256k1, NIST256) you need to install system libraries first, follow the instructions: https://baking-bad.github.io/pytezos/#requirements
We are good to go now, let’s start from cloning our starter kit and installing dependencies.
$ git clone https://github.com/baking-bad/tezos-nft-sample$ cd tezos-nft-sample$ npm i$ pip install -r requirements.txt
After that, we can run the local Tezos node (a single node blockchain) and activate a protocol (in our case it’s Athens).
$ npm run init$ npm run start$ npm run activate-alpha
This is what Granary basically provides, a sandboxed Tezos chain of a single node, and a set of useful scripts to interact with it. We can then shut down the node with npm run stop
or reset to the initial state with sudo npm run clean
# Compiling sources and testing
We have a sample contract written in LIGO in the src/nft.ligo
file (this is a demo source, pls do not use it for any other purpose). Next thing we want to do is compile it down to Michelson. Luckily Granary is shipped with a dockerized LIGO compiler and a convenient alias.
$ npm run compile
If everything goes well we will get a result in a .tz file, otherwise, there will be an error message (atm stdout and stderr are not separated, but this to be fixed soon).
Great! Time for tests 😃 We will write unit tests using standard unittest
python package and a little PyTezos magic. Note that you can use all the power of Python e.g. interactive debugger.
Alternatively, you can just run tests from the command line (using pytest
under the hood).
$ npm run test
Our smart contract seems to work as expected so we can move on to the next step.
# Deploying and calling a contract
In this section, we will use a custom PyTezos client written specifically for this contract. You can use the standard tezos-client
as well.
PyTezos client has several useful features, first automatic generation of the initial storage, and secondly implied interface annotations. This means that even if your code is not annotated if it implements a well-known interface, the necessary annotations will be added to it (this is optional of course).
$ python -m client originate$ npm run bake
What we did is first injected an origination with our contract and default storage (empty), and then baked a block including this operation.
You can spot a link in the terminal output containing originated {contract_id}
. It will be used in the following calls since there is no ability to make contract aliases atm. The link leads to a page in the Michelson contract explorer (BCD), where you can inspect all the operations, script, and state.
$ python -m client mint --contract-id={contract_id} --token-id=42$ npm run bake$ python -m client burn --contract-id={contract_id} --token-id=42$ npm run bake
That’s it, we’ve managed to interact with our smart contract and see how its state changes depending on the input.
# What did we learn, Palmer?
We definitely should do it again 😄
Speaking of PyTezos there were a few problems with the installation due to a lack of detailed documentation, which will be fixed. Better Call Dev performed well, we even added a self-hosted feature during the hackathon for one of the teams.
The biggest revelation was that with our toolset you can do some things extremely quickly. If you are working with alphanet you don’t even need to set up a local environment, just use online Jupyter notebooks at Google Colab.
# Initial storage
It’s often difficult for newcomers to understand Michelson expressions. LIGO toolset offers a way to generate storage or parameter, but what can be done with PyTezos is even simpler.
GITHUB BLOCK HERE
First of all, you can try to generate a default (empty) storage, and in many cases, PyTezos will be able to do it by itself. Anyway, you can make it yourself but using an ordinary JSON format! PyTezos will provide a docstring explaining the type scheme.
# Transaction parameters
The same trick can be used for generating parameters.
GITHUB BLOCK HERE
# Faucet account activation and reveal
This is something you need first when dealing with alphanet. Not mentioning that there is a predefined demo account in PyTezos for instant work, you can make your own in a minute: https://baking-bad.github.io/pytezos/#activate-account
We’re still under the impression of the event hosted by Everstake and Bake’n’rolls, which was absolutely fantastic. Lot’s of feedback gathered and we will do our best to provide a reliable basis for the further hackathons.
If you have read to the end — you are awesome 😃
Follow us on Twitter and join our cozy Telegram chat where you can ask any question about our products and services.
See you at the next Tezos event!