Skip to main content
Version: Next

Contracts

Smart contracts are programs that run on a blockchain. For an overview of how smart contracts work on Tezos, see An introduction to smart contracts on docs.tezos.com. For an example LIGO contract, see Quickstart or load one of the templates in the Online IDE.

For the data type that represents a contract, see Contracts.

Components of a contract

A smart contract has three main elements:

  • Its address: a contract is a kind of account, and can receive and send tez
  • Its storage: data that is dedicated to and can be read and written only by the contract
  • Its code: one or more entrypoints, which are a kind of function that can be called either from outside the chain or from other contracts

Account and address

Originated (deployed) smart contracts are assigned an account address. Just like user accounts, the smart contract can accept tez sent to its account and store it. Its code can send the tez to other accounts. Contracts can also delegate their tez to other accounts just like user accounts can.

In most cases, contracts have addresses that start with KT1. However, they can also be tied to an implicit account and have an address that starts with kt1, kt2 or kt3, depending on the hashing function.

Getting a contract's address

The function Tezos.get_self_address returns the address of the currently running contract.

This function can be misleading because it returns the address of the contract executing the code, which in rare cases can be different from the address of the contract in which the code is written. For example, it's possible for one contract to run a lambda that is contained in another contract; in this case, the function returns the address of the contract that is running the lambda, not the contract that contains the lambda.

const current_addr: address = Tezos.get_self_address();

To get the address of the contract that contains the currently running code, use the function Tezos.self(entrypoint). This function returns the address of the contract that contains the code even if another contract is currently executing that code.

The string entrypoint is the name of a valid entrypoint such that entrypoint is not "%default", or the empty string denoting the "%default" entrypoint (which is the root of the smart contract parameter if no "%default" entrypoint is explicitly defined). If the contract does not have the specified entrypoint, the call results in an type checking error.

Naming convention: if you are using entrypoints, use "%bar" to denote the constructor "Bar" of the parameter, in turn corresponding to the entrypoint function bar. If you are not using entrypoints: use "%default".

const check = () => Tezos.self("%default");

Storage

Smart contracts have persistent storage. The originator of the contract sets the initial value of the storage. After it is originated, only the contract itself can change the storage.

Contract storage is publicly readable by users outside the chain. However, a contract can see only its own storage, not the storage of any other contracts.

Metadata

Contracts often store metadata that provides descriptive information about them to wallets, explorers, dApps, and other off-chain applications. Contract metadata is stored off-chain and therefore on-chain applications including smart contracts cannot access it. To store data off-chain in a decentralized way, many Tezos developers use IPFS.

The primary Tezos standard for metadata is TZIP-016 (Tezos Metadata Standard).

For more information about metadata, see Adding package metadata.

Code

The code of a contract is publicly viewable and cannot be changed after the contract is originated (deployed). A contract's code can include these elements:

  • Entrypoints, which are the ways that the contract can be called, similar to a method or function in many programming languages or an endpoint in an API.

  • Views, which are a way for contracts to expose information to other contracts and to off-chain consumers.

  • Internal functions, which allow you to organize and reuse code.

For clarity, LIGO developers often store the code of a contract in a single namespace. However, LIGO does not require that contract code is in a namespace, that a namespace contains a contract, or that only one contract is in a namespace.