Skip to content

Latest commit

 

History

History
130 lines (89 loc) · 4.8 KB

getting-started.mdx

File metadata and controls

130 lines (89 loc) · 4.8 KB
title Installation and first contract
description Install the Lithe compiler, write a contract, compile it, and deploy it to a local chain.

Installation and first contract

:::warning Lithe is in early development and experimental. The language, standard library, and compiler output can change without notice, and neither the compiler nor the standard library has been audited. :::

Install the compiler

Install the latest release with the install script:

curl -fsSL https://lithe-lang.org/install.sh | sh

It downloads the compiler for your platform, Linux or macOS on x86-64 or ARM64, checks it against the release's checksums, and installs it to ~/.lithe/bin/lithe, or $LITHE_HOME/bin/lithe when LITHE_HOME is set. If that directory isn't on your PATH, it adds it in your shell's profile (~/.zshrc, ~/.bashrc, ~/.bash_profile on macOS, fish's config.fish, or ~/.profile); set LITHE_NO_MODIFY_PATH=1 to have it print the line instead. Run it again to update. To install a given version, pass it after -s --:

curl -fsSL https://lithe-lang.org/install.sh | sh -s -- 0.5.1

Or build a release with Cargo, which installs it to ~/.cargo/bin and needs the same tools as building from source, below:

cargo install --git https://github.com/celestiaorg/lithe --tag v0.5.1 --locked

To build from source, run this from the repository root with a recent stable Rust toolchain, CMake, Python 3, and a C++ compiler (brew install cmake on macOS, sudo apt install cmake python3 g++ on Debian and Ubuntu). The first build also compiles the Z3 solver that lithe prove runs, which takes a few minutes:

cargo build --release
export PATH="$PWD/target/release:$PATH"

Check the install with lithe --version. Contracts you deploy should be built with a released compiler, so that they can be verified.

Run with no arguments, lithe prints its commands. See Command line for the full list, and Editors to set up VS Code, Cursor, or Recur.

Write a contract

A Lithe file is a contract. Create counter.lithe:

(* Comments are written like this, and they nest. *)

storage is record {
  count : uint;
}

external view function get() : uint is
  storage.count

external function inc() is {
  storage.count += 1;
}

external function dec() is {
  storage.count -= 1;
}

A few things to notice:

  • storage is record declares the contract's persistent state. Every contract has one, and every access is qualified as storage.count.
  • uint is an unsigned 256-bit integer. 1 is a uint literal. Arithmetic is checked, so dec on zero reverts with Panic(0x11), the same panic Solidity uses.
  • external puts a function in the ABI. external view promises the function never writes, and the compiler checks the promise.
  • := assigns, and += adds to what is there. = compares.
  • A function body is a block { ... } or a single expression.

Compile

lithe compile counter.lithe

This prints the contract's creation bytecode as hex. Generate its ABI with:

lithe abi counter.lithe

To build every .lithe file in a directory into Foundry-style artifacts under ./out, pass the directory:

lithe compile src

Deploy and call

The output of lithe compile is creation code, so any deployment tool can use it. With Foundry and a local anvil:

anvil &

KEY=0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80
cast send --private-key $KEY --create $(lithe compile counter.lithe)
# contractAddress 0x5FbDB2315678afecb367f032d93F642f64180aa3

cast send --private-key $KEY 0x5FbDB2315678afecb367f032d93F642f64180aa3 "inc()"
cast call 0x5FbDB2315678afecb367f032d93F642f64180aa3 "get()(uint256)"
# 1

Calling dec() twice from here reverts with panic: arithmetic underflow or overflow (0x11). To test a contract with Foundry or Hardhat, see Testing. To deploy one with a deploy, or with delegated modules, see Deploying.

See what the compiler knows

Because effects are explicit, the compiler can summarize each entrypoint:

lithe footprint counter.lithe
inc   writes: count            during defers: callable
dec   writes: count            during defers: callable
get   reads: count             during defers: callable

Inspecting contracts covers footprint, abi-tree, analysis, errors, and storage.

Next steps