Tezos Installation and Address Generation

The Tezos community grows quite rapidly and, often, the documentation that can be found no longer reflects the actual state of things. My task was to deploy a smart contract in the main Tezos network, and this was not a trivial task.

First, a brief introduction. The current version of the code can be found at this link, and the documentation is here. In this part, we will analyze the installation of the current version of Tezos and account generation.

Tezos Installation

We will work in Mainnet, but install Babylon, since it will be necessary to generate the private key in unencrypted form, and this is only possible in a test network:



wget

sudo cp opam-2.0.3-x86_64-linux /usr/local/bin/opam

sudo chmod a+x /usr/local/bin/opam

git clone

cd tezos

git checkout babylonnet

opam init --bare

make build-deps

eval $(opam env)

make sudo apt install -y rsync git m4 build-essential patch unzip bubblewrap wget pkg-config libgmp-dev libev-dev libhidapi-dev whichwget https://github.com/ocaml/opam/releases/download/2.0.3/opam-2.0.3-x86_64-linux sudo cp opam-2.0.3-x86_64-linux /usr/local/bin/opamsudo chmod a+x /usr/local/bin/opamgit clone https://gitlab.com/tezos/tezos.git cd tezosgit checkout babylonnetopam init --baremake build-depseval $(opam env)make

More details here. To build Tezos with Mainnet pre-sets, you need to replace git checkout babylonnet with git checkout mainnet

We need the tezos-node and tezos-client executables. In one terminal window, run:

./tezos-node run --rpc-addr localhost

In another one:

./tezos-client gen keys my_tezos_address

cat ~/.tezos-client/secret_keys

And you should see something similar to:

[ { “name”: “my_tezos_address”,

“value”:

“unencrypted:SECRET_KEY” } ]

Under any circumstances do not spread it anywhere and do not show SECRET_KEY to anyone.

Perhaps there is an easier way to generate the key in unencrypted form or a way to decrypt the existing one. Leave your comments below.

Smart Contract Deployment in Tezos Mainnet

In the previous section, we learned how to build and run a Tezos node and generate an address. Now let’s compile the smart contract and deploy it to the Tezos main network.

Smart Contract Compilation

The first problem: the smart contract was written in Liquidity and there was a convenient on-line editor that stopped working with the Tezos network, but there is still a compiler that can translate source code to Michelson. The last one is the official language of Tezos, but very low-level. Recommended languages for writing contracts for Tezos:

Ligo — Pascal-like language

SmartPy — Python-like language

Morley — a library for Haskell

In general, I advise you to read the Tezos Developer Portal if you are interested in developing for Tezos. Unfortunately, there is not a word about the main network, although there are differences.

In order not to rewrite the contract, but to take advantage of what is, we install the Liquidity compiler:



git clone

cd liquidity

eval `opam env --switch liquidity`

make clone-dune-network

make build-deps

make opam switch create liquidity 4.06.1git clone https://github.com/OCamlPro/liquidity cd liquidityeval `opam env --switch liquidity`make clone-dune-networkmake build-depsmake

For details, see the official documentation. During the assembly, everything stopped several times because there were missing dependencies. See the error message and manually install the necessary libraries.

Finally, compiling is as simple as possible:

./liquidity contract.liq

The output is a contract.tz file that we need. Liquidity produces slightly optimized code. If you write, for example, in Ligo, you can get fewer operations and, accordingly, deployment will be cheaper.

Deployment of Smart Contract

Another problem was the inconsistency of the documentation with reality. If you are looking for how to deploy a contract on the Tezos network, you will surely find the following instructions:

tezos-client originate my_contract transferring 0 from my_account running my_contract.tz

but it didn’t work for me, I got Unrecognized command error. Looking at the tezos-client documentation I didn’t find originate command at all. There are no convenient tools with a graphical interface so our only option is command line interface.

Fortunately, I found a great tool for working with Tezos — pytezos. Please note that this is a fork, it comes with a pytezos script. Installation:

virtualenv -p python3 venv

source venv/bin/activate

pip install git+https://github.com/baking-bad/pytezos

pytezos

If after executing the last command you saw help messages, then everything went well.

Before deploying the contract, you need to reveal an account on the node. pytezos uses the public site https://rpc.tzkt.io/mainnet/. We do the following:

pytezos activate --network mainnet SECRET_KEY

where SECRET_KEY is your private key generated earlier. Now move on to deploying the contract:

pytezos deploy --network mainnet --key SECRET_KEY contract.tz --dry-run

where contract.tz is the compiled smart contract; --dry-run — this option allows you to check the correctness of all data. If everything went well, remove --dry-run and run again.

Interaction with Smart Contract

In general, you can work with a contract as follows. Open the python console:

from pytezos import pytezos

mnet = pytezos.using(key=SECRET_KEY, shell=”mainnet”)

ci = mnet.contract(CONTRACT_ADDRESS)

ci

CONTRACT_ADDRESS — the address of the contract, which can be obtained after pytezos deploy is executed or look, for example, at Tezos.ID transactions in your account.

The last line will show the available methods for the contract, as well as the address of your account, public node and contract.

To call a method, execute:

ci.CONTRACT_FUNCTION().operation_group.sign().inject()

CONTRACT_FUNCTION — the name of the method that we are going to call; in brackets we pass the arguments according to the description of the method; .operation_group.sign().inject() — signs the transaction and sends it to the network. After execution, you will see transaction information that looks like:

{

'chain_id':'NetXdQprcVkpaWU',

'hash':'HASH',

'protocol':'PsBabyM1eUXZseaJdmXFApDSBqj8YBfwELoxZHHW77EMcAbbwAS',

'branch':'BLEprQFdYU5KkqbLs8jhNZtAogLnP6Jc8iJVhzTbsUaTB7M8hoe',

'contents':[

{

'kind':'transaction',

'source':'PUBLIC_ADDRESS',

'fee':'40298',

'counter':'2333835',

'gas_limit':'400000',

'storage_limit':'60000',

'amount':'0',

'destination':'CONTRACT_ADDRESS',

'parameters':{

'entrypoint':'CONTRACT_FUNCTION',

'value':{

'prim':'Pair',

'args':[

...

]

}

}

}

],

'signature':'sigetA79oZqn2Rworst4Cpn59wEHc1aTvrRCh7iH4hQhTjAuA6t9RshZie8BEXjp2GJCocPFqV3d3iZrhe5Zw8bfNTbPK2Xz'

}

You can use HASH to search for a transaction in the blockchain and check its status:

op = mnet.shell.blocks[-20:].find_operation(HASH)

op['contents'][0]['metadata']['operation_result']['status']

If you receive an exception after the first line, then the transaction has not been included into the blockchain yet and you need to wait.