Tezos is one of the oldest smart contract blockchains, with Ethereum being the very first.
While Ethereum is a popular choice among developers for developing and deploying smart contracts, its applications are not very scalable due to high fees and slow transactions. In contrast, Tezos applications are very efficient and inexpensive to set up.
In this guide, you will learn how to develop and deploy smart contracts in Tezos with SmartPy CLI. We will cover:
tezos-client
You can get the final project’s code in this GitHub repo.
To follow along with this article, you need to be familiar with the Tezos blockchain. Your knowledge doesn’t have to be in-depth.
Knowledge of the Ethereum blockchain is not required, but it helps a lot.
Tezos is a blockchain network and a smart contract platform that is built to be adaptive through its governance model and self-upgrading ability.
While Tezos and Ethereum are similar blockchains that support smart contracts and DApp development, they are different in several ways. The Tezos vs. Ethereum table below shows some of the differences between the two networks.
Tezos | Ethereum |
Developers make proposals to upgrade the blockchain protocol on the network | Developers use a hardfork to upgrade the blockchain protocol |
Stakeholders control upgrades to the blockchain protocol by voting to accept or decline proposals | The creators of the blockchain network govern upgrades to the blockchain protocol |
Uses formal verification for executing smart contracts | Uses EVM to store and execute smart contracts on the network |
Participants (nodes) have the option to provide computing resources or delegate their tokens to participate in validating transactions | All participants (nodes) must provide computing resources and stake their coins to participate in validating transactions |
Gas fees are low, which makes it very scalable | Gas fees are really high, which makes it unscalable |
SmartPy is a tool that allows you to build smart contracts easily on the Tezos blockchain.
You write contracts in SmartPy using Python. If you’re already familiar with Python, you don’t have to learn a new smart contract programming language.
SmartPy comes in two other variants that use other syntaxes: SmartTS, which uses TypeScript, and SmartML, which uses OCaml.
SmartPy compiles Python scripts to Michelson. Michelson is a low-level programming language for smart contracts in Tezos. SmartTS and SmartML can also be compiled using the SmartPy tool.
Smart contracts are programs that you can build, deploy, and execute on a blockchain network. You don’t need to own a node on the network before deploying your smart contract.
With smart contracts, you can build applications accessible to all devices without owning or maintaining a server. These fully decentralised applications require little or no maintenance.
Smart contracts use the full potential of blockchains, allowing you to execute programs on the chain as well as to interact with the chain itself. You can hold or transfer tokens and access specialised functionality on the blockchain with a smart contract.
To install SmartPy CLI, run the command below:
$ bash <(curl -s https://smartpy.io/cli/install.sh)
This command creates a smartpy-cli
directory in home
with this tree structure:
smartpy-cli ├── browser.py ├── node_modules/ ├── originator.js ├── package.json ├── package-lock.json ├── __pycache__/ ├── smart.css ├── smart.js ├── smartpyc.js ├── smartpyc.py ├── smartpyio.py ├── smartpy.py ├── SmartPy.sh ├── smarttop/ ├── smart-ts-cli.js ├── templates/ ├── theme.js └── typography.css
To confirm the installation, run the following:
$ ~/smartpy-cli/SmartPy.sh --version
As an extra step to make SmartPy.sh
easily accessible, create an alias by copying the below into your .bashrc
file or related profile file:
$ alias smartpy="$HOME/smartpy-cli/SmartPy.sh"
Now you can use:
$ smartpy --version
Instead of:
$ ~/smartpy-cli/SmartPy.sh --version
tezos-client
This guide uses tezos-client
to interact with a deployed smart contract. To install tezos-client,
run one of the commands below, depending on whether you are using a Mac or Linux operating system:
# Mac $ brew tap serokell/tezos-packaging-stable https://github.com/serokell/tezos-packaging-stable.git $ brew install tezos-client # Linux $ wget https://github.com/serokell/tezos-packaging/releases/latest/download/tezos-client $ chmod +x tezos-client $ mkdir -p $HOME/.local/bin $ mv tezos-client $HOME/.local/bin $ echo 'export PATH="$HOME/.local/bin:$PATH"' >> $HOME/.bashrc $ source $HOME/.bashrc
Note that if you are using Windows, you need to install a Linux distro with wsl and run the Linux installation.
After installing tezos-client
, you need to set it up. Start by running the command below:
$ tezos-client --endpoint https://jakartanet.ecadinfra.com config update
This guide uses the Jarkatanet testnet to deploy and interact with a smart contract. The above command connects tezos-client
to the Jakartanet testnet through the node https://jakartanet.ecadinfra.com
on the network.
Before you perform any operation with tezos-client
, you need to connect an account. Tezos provides Faucet accounts that allow you to interact with the network for free.
You need to visit the Jakartanet Faucet website and download the Faucet file. After doing that, open the download folder in your terminal and run this command:
$ tezos-client activate account faucet with ./jakartanet.json
The command activates the Faucet account in your tezos-client
and gives it an alias faucet
. To check the balance for this account, open the jakartanet.json
file, copy the value of pkh
, then run this command:
$ tezos-client get balance for <address>
Replace <address>
with the pkh
value that you copied.
Note that Tezos Faucet accounts are publicly available to everyone and have a limited amount of Tez tokens, so you have to regulate your usage.
To begin creating our example smart contract, create a new store_text.py
file and copy the below into it:
import smartpy as sp class StoreText(sp.Contract): def __init__(self, value): self.init(text = value) @sp.entry_point def replace(self, params): self.data.text = params.text @sp.entry_point # Note: the spaces before "@" def append(self, params): self.data.text += params.text
Here’s how the above contract works, piece by piece:
First, we imported the smartpy
library:
import smartpy as sp
Then, we defined a class that extends sp.Contract
:
class StoreText(sp.Contract):
Lastly, we defined a few items within the smart contract; first, a constructor to initialise text
:
def __init__(self, value): # Note: the spaces before "def" self.init(text = value)
Second, an entry point to replace the value of text
:
@sp.entry_point # Note: the spaces before "@" def replace(self, params): self.data.text = params.text
Third, an entry point to append a string to text
:
@sp.entry_point # Note: the spaces before "@" def append(self, params): self.data.text += params.text
Next, let’s take a look at how to test the smart contract.
Smart contracts that are deployed to Tezos cannot be changed or removed. This can be a problem because there could be errors in the contract, and errors could lead to costly mistakes and the loss of funds.
SmartPy gives you the ability to easily test your contract before deploying. Testing the contract doesn’t require any tokens or a wallet account to run. All you need to do is open the store_text.py
file and copy the below below it:
@sp.add_test(name = "StoreText") def test(): scenario = sp.test_scenario() contract = StoreText("Hello") scenario += contract scenario.verify(contract.data.text == "Hello") contract.replace(text = "Hi") contract.append(text = ", there!") scenario.verify(contract.data.text == "Hi, there!")
Here’s how the snippet works. First, we registered a the test
function as a test script:
@sp.add_test(name = "StoreText")
Then, we defined the test
function:
def test():
In the remaining lines, we created a test scenario:
scenario = sp.test_scenario()
Initialized the contract with "Hello"
:
contract = StoreText("Hello")
Added the contract instance to the scenario:
scenario += contract
Verified that the contract’s text
value is "Hello"
:
scenario.verify(contract.data.text == "Hello")
Called the replace
and append
entry points:
contract.replace(text = "Hi") contract.append(text = ", there!")
And finally, verified that the contract’s text
value is now "Hi, there"
:
scenario.verify(contract.data.text == "Hi, there!")
After adding the test, save the file and run this command:
$ ~/smartpy-cli/SmartPy.sh test store_text.py ./test-output
If the test is successful, the compiler won’t throw an error message.
Before you deploy your smart contract, you need to compile it to Michelson. As mentioned earlier, Michelson is a low-level programming language used for smart contracts on the Tezos blockchain.
To compile store_text.py
, run the following:
$ ~/smartpy-cli/SmartPy.sh compile message.py ./output
If it compiled successfully, you should see an output
folder like the one below:
output/ ├── scenario.json ├── script_init.py ├── script_pure.py └── storeMessage/ ├── log.txt ├── step_000_cont_0_contract.json ├── step_000_cont_0_contract.py ├── step_000_cont_0_contract.tz ├── step_000_cont_0_sizes.csv ├── step_000_cont_0_storage.json ├── step_000_cont_0_storage.py ├── step_000_cont_0_storage.tz └── step_000_cont_0_types.py
The output
directory contains all the files necessary to deploy the smart contract.
To deploy store_text.py
, open the output/storeMessage
folder in the terminal and run the command below:
$ ~/smartpy-cli/SmartPy.sh originate-contract --code step_000_cont_0_contract.json --storage step_000_cont_0_storage.json --rpc https://jakartanet.ecadinfra.com [INFO] - Using RPC https://jakartanet.ecadinfra.com/... [INFO] - Contract KT1………………CAjjW originated!!!
Here’s is how the command works:
originate-contract
tells tezos-client
to deploy (“originate”) a contract--code step_000_cont_0_contract.json
points to the compiled contract file--storage step_000_cont_0_storage.json
points to the compiled storage file--rpc https://jakartanet.ecadinfra.com
points to an RPC node on the network you are deploying toTezos smart contracts usually involve two components: the storage and the contract. The storage holds the data that the contract stores, and the contract holds the logic of the smart contract.
Note that you can deploy the contract with any of the contract or storage compilations. They just have to be the same file extension when you are using the command.
By default, if you’re deploying on a testnet, the compiler will use a Faucet account. If you are deploying to the mainnet or you want to use your wallet account, add the --private-key
flag followed by the account’s private key.
Before interacting with the deployed smart contract, you need to know how the contract currently looks. To do that, open the SmartPy Explorer in your browser and follow these steps:
mainnet
to jakartanet
https://jakartanet.ecadinfra.com
to the text boxWhen the contract data has appeared, the text storage should display as “Hello, There!”
Now that you know the contract’s text, you can change it to “Hi, There!” by calling the replace
entrypoint with this command:
$ tezos-client transfer 0 from faucet to <contract-address> --entrypoint replace --arg '"Hi, There!"'
If the command was successful, when you refresh the explorer, the storage should now display “Hi, There!”
Note that you must replace <contract-address>
with the address of the deployed contract before running the command.
This article covers the process of building smart contracts on Tezos with SmartPy. Building smart contracts allows you to take full advantage of the blockchain network to build decentralised applications and organisations.
I hope this article helped you understand the process of building smart contracts on Tezos. If you’d like to read more about smart contracts, check out this article about smart contract mistakes to avoid.
Thanks for reading! And have a nice day.Developing and deploying Tezos smart contracts
LogRocket is like a DVR for web and mobile apps, recording everything that happens in your web app or site. Instead of guessing why problems happen, you can aggregate and report on key frontend performance metrics, replay user sessions along with application state, log network requests, and automatically surface all errors.
Modernize how you debug web and mobile apps — Start monitoring for free.
Would you be interested in joining LogRocket's developer community?
Join LogRocket’s Content Advisory Board. You’ll help inform the type of content we create and get access to exclusive meetups, social accreditation, and swag.
Sign up nowLearn how to implement one-way and two-way data binding in Vue.js, using v-model and advanced techniques like defineModel for better apps.
Compare Prisma and Drizzle ORMs to learn their differences, strengths, and weaknesses for data access and migrations.
It’s easy for devs to default to JavaScript to fix every problem. Let’s use the RoLP to find simpler alternatives with HTML and CSS.
Learn how to manage memory leaks in Rust, avoid unsafe behavior, and use tools like weak references to ensure efficient programs.