Smart Contract Development in Michelson (Tezos)

We design and develop full-cycle blockchain solutions: from smart contract architecture to launching DeFi protocols, NFT marketplaces and crypto exchanges. Security audits, tokenomics, integration with existing infrastructure.
Showing 1 of 1 servicesAll 1306 services
Smart Contract Development in Michelson (Tezos)
Complex
~3-5 business days
FAQ
Blockchain Development Services
Blockchain Development Stages
Latest works
  • image_web-applications_feedme_466_0.webp
    Development of a web application for FEEDME
    1161
  • image_ecommerce_furnoro_435_0.webp
    Development of an online store for the company FURNORO
    1051
  • image_logo-advance_0.png
    B2B Advance company logo design
    561
  • image_crm_enviok_479_0.webp
    Development of a web application for Enviok
    827
  • image_logo-aider_0.jpg
    AIDER company logo development
    762
  • image_crm_chasseurs_493_0.webp
    CRM development for Chasseurs
    850

Smart Contract Development in Michelson (Tezos)

Tezos is one of the few platforms where smart contracts compile to Michelson stack bytecode, not EVM opcodes. This is a fundamental difference: if you come with Solidity experience, first encounter with Michelson feels like something between respect and cultural shock. Stack machine, formal verification as first class, on-chain storage typified down to details. Meanwhile, the ecosystem is significantly smaller than Ethereum — fewer ready libraries, fewer auditors, fewer patterns. Mistakes here are more expensive.

Why Michelson Is Not Just "Another Language"

Most developers write in high-level dialects: SmartPy (Python syntax), LIGO (dialects CameLIGO, JsLIGO, PascaLIGO), or Archetype (for formal verification). But Michelson is the intermediate layer everything compiles to, and understanding it is necessary.

Consider a specific situation: contract in SmartPy compiles without errors, deploys to Ghostnet testnet, but on calling via Taquito, transaction fails with FAILED: script_rejected. Without reading Michelson code, impossible to understand at what exact point the stack ended up in incorrect state. Decompiler octez-client gives raw Michelson — and here real debugging begins.

Typical Mistakes When Transitioning from EVM

Storage layout doesn't match expectations. In Solidity storage is slots. In Tezos storage is big_map and map, nested records (record), option types. Developers used to Solidity mappings sometimes incorrectly model nested structures in LIGO. Result: get from big_map returns None where Some(value) was expected, because key was constructed incorrectly.

Entrypoint routing. In Tezos contract can have multiple entrypoints, which in Michelson are implemented via OR tree. SmartPy and LIGO generate this tree automatically, but if client (Taquito) calls entrypoint by name and name in ABI doesn't match name in code, transaction is rejected. Problem particularly tricky during contract update — ABI in frontend may remain from old version.

Gas estimation on FA2. Standard FA2 (analogue of ERC-1155 in Tezos) assumes batch operations. On large batch Taquito sometimes underestimates gas limit, and transaction fails already on-chain. Correct solution — explicitly set storageLimit and gasLimit or use estimate() from Taquito with 10-15% buffer.

Stack and Tools

Development Languages

Language Syntax Best for
SmartPy Python-like Quick prototype, on-chain tests
CameLIGO OCaml-like Type safety, large projects
JsLIGO JavaScript-like Teams with JS background
Archetype Declarative Formal verification via Why3
Michelson Stack Audit, optimization, debugging

For production we use CameLIGO as main language. Static typing in OCaml style eliminates whole class of errors at compilation stage. SmartPy we apply for quick experiments and internal tests.

Infrastructure

  • octez-client — CLI for node interaction, deploy, entrypoint calls, storage view
  • Ligo CLI — compilation, dry-run, Michelson generation
  • Taquito — JavaScript library for frontend integration (analogue of ethers.js)
  • Better Call Dev — block explorer with convenient storage view and calls
  • SmartPy IDE — for quick testing in browser
  • Ghostnet — main testnet

Formal Verification via Archetype

Archetype allows writing contracts with formal specifications then verified via Why3 and Alt-Ergo. This is not abstract possibility — we applied this to escrow contract where required to mathematically prove funds can never be locked under any call sequence. Verification revealed one edge case: with certain combination of refund and claim in one block, contract could enter state from which impossible to withdraw funds. Neither unit tests nor fuzzing found this.

FA2 — Standard You Need to Know

FA2 (TZIP-12) is main token standard in Tezos. Analogue of ERC-1155, but with stricter specification on operators and permissions. FA2 implementation includes:

  • transfer — batch transfer with operator checks
  • update_operators — adding/removing operators for address
  • balance_of — balance request (callback pattern, not view function)

Callback pattern in balance_of is classic stumbling block. Unlike Solidity where view function returns value synchronously, in Tezos balance request is separate transaction with callback contract. Frontend must either read storage directly via RPC, or implement on-chain callback. Taquito provides fa2.getBalance() on top of direct storage read.

Operators vs. Allowances

FA2 has no concept of allowance like ERC-20. Instead — operators: addresses allowed to manage tokens on behalf of owner. This is more powerful (operator manages all tokens at once), but also riskier: if don't implement proper check in transfer, operator can transfer anything. TZIP-12 specifies check order clearly, and we follow it strictly.

Development Process

Requirement analysis. Determine: do we need FA1.2 (analogue of ERC-20) or FA2, are there batch operations, is multi-sig logic needed (analogue of Gnosis Safe — Multi-sig from Tezos Foundation).

Storage design. Storage in Tezos is contract state stored on-chain and billed separately from gas. big_map is lazy structure, doesn't load to memory wholly, pay only for specific key access. map loads fully. For large collections always big_map.

CameLIGO development. Local compilation via Ligo CLI, dry-run to check logic without deploy.

Testing. Unit tests via SmartPy test runner or Ligo test framework. Integration tests via Taquito on Ghostnet.

Deploy and verification. Deploy via octez-client originate. Source verification on Better Call Dev and tzkt.io — Etherscan analogue for Tezos.

Timeline

Medium complexity contract (FA2 with custom logic, no formal verification) — from 3 to 5 working days. Contracts with formal verification via Archetype/Why3 — from 2 weeks. DeFi protocol on Tezos (DEX, lending) — from a month.

Cost is calculated after requirements analysis.

What to Look for in Tezos Contract Audits

Reentrancy via TRANSFER_TOKENS. Tezos is not protected from reentrancy automatically. If contract calls external address via TRANSFER_TOKENS then modifies storage, reentrancy attack possible. Protection pattern — checks-effects-interactions (change storage first, then external call). In Tezos this is especially important because contract calls execute asynchronously in operation queue.

Check amount in payable entrypoints. In Tezos any entrypoint can receive tez. If don't check Tezos.get_amount() = 0tez in entrypoints that shouldn't receive funds, user accidentally locks tez in contract.

Storage fees. Writing new data to storage costs tez. If contract allows unlimited entries to map without payment, this is DoS vector: attacker adds thousands of entries, exhausts contract balance on storage fees, contract stops working.