Skip to content

Commit

Permalink
pages on creating, testing and deploying smart contract (#152)
Browse files Browse the repository at this point in the history
* pages on creating, testing and deploying smart contract

* fixed file location & language style, recovered package.json and package-lock.json

* Eliminate bold formatting in lists

* updated creating smart contracts

* testing updated

* updated creating and testing

* updated deploying

* New format for dates based on #154

* updated pages

* fix indent

* Update docs/smart-contracts/creating.md

Co-authored-by: Tim McMackin <[email protected]>

* Update docs/smart-contracts/deploying.md

Co-authored-by: Tim McMackin <[email protected]>

* Update docs/smart-contracts/testing.md

Co-authored-by: Tim McMackin <[email protected]>

* Update docs/smart-contracts/testing.md

Co-authored-by: Tim McMackin <[email protected]>

* Update docs/smart-contracts/deploying.md

Co-authored-by: Tim McMackin <[email protected]>

* Interacting with the contract

---------

Co-authored-by: Tim McMackin <[email protected]>
Co-authored-by: Tim McMackin <[email protected]>
  • Loading branch information
3 people authored Nov 16, 2023
1 parent cfc2d36 commit c747d1b
Show file tree
Hide file tree
Showing 5 changed files with 207 additions and 27 deletions.
62 changes: 62 additions & 0 deletions docs/smart-contracts/creating.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
---
title: Creating smart contracts
author: 'Yuxin Li'
last_update:
date: 6 November 2023
---
## Introduction
This documentation provides step-by-step instructions for creating smart contracts on Tezos. After creating the contract, you can find the resources on [testing](testing.md) and [deploying](deploying.md).

## Choosing your smart contract language
Tezos supports a variety of smart contract [languages](./languages): Michelson, SmartPy, LIGO, Archetype.

You can select a language based on your familarity with programming paragims, the complexity of the contract you want to deploy, and the specific features you require. Here's a more detailed table for each language:

| | **Michelson** | **SmartPy** | **LIGO** | **Archetype** |
|:----------------:|:----------------------------------------------------------:|:-----------------------------------------------------:|:-------------------------------------------------------------------------------------:|:---------------------------------------------------------------------------------:|
| **Complexity** | High (stack-based, low-level) | Low (Python-like, high-level) | Moderate (various high-level syntaxes) | Moderate (includes formal specification features) |
| **Capabilities** | Full control over contract, optimal for gas efficiency | Easy to write, automatically manages stack operations | Statically-typed, strong error checking | Specialized for formal verification and correctness |
| **Use Cases** | Optimized contracts, developers with blockchain experience | Python developers, rapid prototyping | Developers familiar with static typing, variety of mainstream programming backgrounds | High-security contracts, developers looking for formal proof of contract behavior |

For beginners, we recommand **SmartPy** or **LIGO** for their higher-level more abstracted approach.


## Making a strategic choice
Before writing your code, take some time to consider whether your project is suitable for starting with a pre-existing template or if it would be better to start from scratch. Essentially, this depends on the type of contract you are building. For example:
- FA2 contract: it’s better to use a template to start.
- Others: build it from scratch.

## Coding your contract
Before coding, you should clearly outline the purpose of your smart contract, define the problem it addresses, detail the functions it will perform, and specify any external interactions or transactions it will manage.

### Starting with online IDE
The online editor is the quickest and easiest way to get started.

For example:
- For smartpy user, we recommend to use the [SmartPy online IDE](https://smartpy.io/)
- For Ligo user, we recommend to use the [Ligo online IDE](https://ligolang.org/?lang=jsligo)


### Defining contract storage
Contract storage holds the persistent state of your smart contract. It’s important to carefully design your storage since storage is expensive on-chain. You should avoid storing any data that the contract will not use.

- SmartPy: Use Pythonic classes and types to represent storage. SmartPy provides a straightforward way to map these into Michelson storage requirements.
- LIGO: Choose the most suitable syntax flavor and use the type definitions to lay out the storage structure.

In Tezos, big maps are a storage optimization feature for large sets of data, , especially when handling large datasets that don't need to be fully loaded into memory at once. Big maps are ideal for ledger applications with numerous accounts, as they load data lazily, fetching only necessary parts on demand. In contrast to regular maps, suitable for smaller collections, and lists, which order data, big maps save costs when the dataset is large.

In SmartPy, you can define a big map using `sp.big_map`, and in LIGO, you use `big_map` keyword for the type declaration.

### Defining entrypoints
Entrypoints serve as methods to receive external communication in Tezos.

- SmartPy: Entrypoints are defined as methods within a Python class that extends `sp.Contract`. They use decorators like `@sp.entry_point` to denote entrypoints
- LIGO: Entrypoints in LIGO are defined as functions that manipulate storage. The `function` keyword is used, and each entrypoint function must be explicitly marked for export in the contract interface

You should clearly define the parameters and storage interaction for both languages.

- Each entrypoint's **parameters** must be well-specified, with types that match the expected inputs. For example, if an entrypoint is supposed to accept an integer and a string, the parameter list should reflect this.
- The contract **storage** is usually passed as an argument to the entrypoints. In SmartPy, the storage is accessed through the self.data attribute inside the entrypoint methods. In LIGO, storage is a parameter of the function, and it's often the last parameter by convention.



90 changes: 90 additions & 0 deletions docs/smart-contracts/deploying.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
---
title: Deploying smart contracts
author: 'Yuxin Li'
last_update:
date: 6 November 2023
---
## Introduction
In Tezos, deploying a smart contract is often referred to as “origination”. This process essentially creates a new account that holds the smart contract's script. Contracts originated in this manner have addresses that start with `KT1` (known as originated accounts), which distinguishes them from the implicit accounts with addresses beginning with `tz1`, `tz2`, or `tz3`.

## Prerequisites
- Compile your contract and its initial storage
- Set up an wallet account on Tezos with some tez to pay the fees
- Ensure that you have obtained the [Tezos client](../developing/octez-client/installing)

## Deploying a smart contract
Generally, there are two methods for deploying your smart contracts: either using the command line in your terminal or deploying through an online IDE.

### Deploying via terminal
The first one is to deploy through your terminal. Here is the syntax for the Tezos command line to deploy a smart contract:
```bash
octez-client originate contract CONTRACT_NAME transferring AMOUNT_TEZ from FROM_USER \
running MICHELSON_FILE \
--init 'INITIAL_STORAGE' --burn-cap GAZ_FEE
```
where:
- `CONTRACT_NAME` is the name given to the contract.
- `MICHELSON_FILE` is the path for the Michelson smart contract code (.tz file).
- `AMOUNT_TEZ` is the quantity of Tez being transferred to the newly deployed contract. If a contract balance reaches 0 then it is deactivated.
- `FROM_USER` account from which the Tez are taken (and transferred to the new contract).
- `INITIAL_STORAGE` is a Michelson expression. The --init parameter is used to specify the initial state of the storage.
- `GAZ_FEE` is a specified maximal fee the user is willing to pay for this operation (using the --burn-cap parameter).

### Deploying via online IDE
As for deploying through your online IDE, if you are using Ligo or SmartPy programming languages, you can simply deploy your smart contracts through their respective online IDEs.
- [SmartPy online IDE](https://smartpy.io/)
- [Ligo online IDE](https://ligolang.org/?lang=jsligo)

## Interacting with the contract
Once you have successfully originated the smart contract and it is included in a baked block, there are two ways to interact with it: through command lines or through a block explorer.

### Interacting through command lines
The first method involves interacting with the contract's entry points using command lines.

For example, suppose you have a smart contract with an entrypoint called `update_data`, which takes an integer as an argument to update some data in its storage. Here's how you might invoke this entrypoint:

```bash
octez-client call CONTRACT_NAME from YOUR_ACCOUNT_ADDRESS \
--arg 'New_Integer_Value' \
--entrypoint update_data \
--burn-cap FEE_LIMIT
```
Where:

- `CONTRACT_NAME`: Identifier or the address of the contract that you want to interact with.
- `YOUR_ACCOUNT_ADDRESS` Your own account address that will initiate the transaction.
- `--arg`: Argument that you're passing to the entrypoint, in this case, an integer value. You need to format this according to the expected input in the contract's Michelson code.
- `--entrypoint`: Method in the smart contract that you're calling.
- `--burn-cap`: The maximum fee you are willing to spend for this transaction to be included in the blockchain.

Here's an example with hypothetical values filled in:

```bash
octez-client call KT1Vsw5kh4P1Vn... from tz1VSUr8wwNhLAzempoch5d6hLRiTh8Cjcjb \
--arg '42' \
--entrypoint update_data \
--burn-cap 0.05
```
Where:

- `KT1Vsw5kh4P1Vn...`: Contract address.
- `tz1VSUr8wwNhLAzempoch5d6hLRiTh8Cjcjb`: User's account address.
- `'42'`: New integer value you wish to pass to the update_data entrypoint.
- `0.05`: Maximum amount of Tez you're willing to pay in fees.

:::note
Always ensure that you check the documentation specific to the smart contract you are interacting with, as the expected arguments (`--arg`) and the name of the entrypoint (`--entrypoint`) can vary widely depending on the contract's design and purpose.
:::

### Interacting via blockchain explorers

A blockchain explorer is an efficient and user-friendly tool that enables you to interact with deployed contracts. In the Tezos ecosystem, there are two main blockchain explorers:

- [Better Call Dev](https://better-call.dev/)
- [TzKT](https://tzkt.io/)

To interact with a contract, simply copy its address into one of these blockchain explorers. Below is the user interface for interacting with a contract through Better Call Dev:

![UI for Better Call Dev](/img/tutorials/better-call.png)


77 changes: 51 additions & 26 deletions docs/smart-contracts/testing.md
Original file line number Diff line number Diff line change
@@ -1,33 +1,56 @@
---
title: Testing
authors: 'Mathias Hiron (Nomadic Labs), Sasha Aldrick (TriliTech), Tim McMackin (TriliTech)'
title: Testing smart contracts
author: 'Yuxin Li'
last_update:
date: 5 October 2023
date: 6 November 2023
---

The hardest part of writing smart contracts is avoiding bugs.
Even though most contracts are small compared to regular software applications, they run in an adversarial environment with high financial stakes.
Therefore, the potential for bugs with dramatic consequences is high.

- Due to the public nature of the blockchain, malicious users can exploit bugs for their own profit at the expense of legitimate users.
- Due to the immutable nature of contracts (even with upgradeability), you must test your smart contracts extensively before production deployment.
## Introduction
Tezos blockchain smart contracts are immutable after deployment, so you must rigorously test to ensure functionality, prevent errors, and avoid potential financial losses. Importantly, contract testing doesn't require any tokens or a wallet account to execute.

High-level languages come with tools to help write tests, and some testing tools can be used independently of the language used to write the smart contract.
For example, [SmartPy](https://smartpy.io/manual/scenarios/overview) includes syntax dedicated to testing.

## Structure of a test scenario

A test scenario usually consists of the following:

- Instructions to deploy the contract with a given initial storage and balance.
- Valid calls to entrypoints, with different parameters and context information such as:
- the address of the `caller`
- the amount of `tez` sent
- the `timestamp` of the block (value of `now` during the call)
- the `level` of the block
- Verification of the value of the storage or `balance`, after each execution of an entrypoint.
- Invalid calls to entrypoints, with the indication that they are expected to fail.
- Verification of the error caused by these invalid calls.
For example, [SmartPy](https://smartpy.io/manual/scenarios/overview) includes syntax dedicated to testing.

The following SmartPy test code snippet is for a Tezos smart contract that acts like a calculator. The code defines a series of tests to check the functionality of the calculator contract.

```bash
if "templates" not in __name__:

@sp.add_test(name="Calculator")
def test():
c1 = main.Calculator()
scenario = sp.test_scenario(main)
scenario.h1("Calculator")
scenario += c1
c1.multiply(x=2, y=5)
c1.add(x=2, y=5)
c1.add(x=2, y=5)
c1.square(12)
c1.squareRoot(0)
c1.squareRoot(1234)
c1.factorial(100)
c1.log2(c1.data.result)
scenario.verify(c1.data.result == 524)
```
The test scenario runs these operations sequentially and would check if all operations execute as expected and if the final result matches the expected value.
## Prerequisites
- Set up an wallet account on Tezos with some tez to pay the fees
- Ensure that you have obtained the [Tezos client](../developing/octez-client/installing)
# Structure of a test scenario
A test scenario usually consists of the following steps:
1. Decide the smart contract's initial storage and `balance`
1. Valid calls to entrypoints, with different parameters and context information such as:
- the address of the `caller`
- the amount of `tez` sent
- the `timestamp` of the block (value of `now` during the call)
- the `level` of the block
1. Verify the contract's storage or `balance` changed the way you expected.
1. Invalid calls to entrypoints, and they are expected to fail.
1. Verification of the error caused by these invalid calls, making sure the error messages are the ones you thought would come up.
When executed, the test scenario is successful if all verifications are correct, and all invalid calls fail with the expected errors.
Expand All @@ -52,9 +75,9 @@ Here are some tips to follow when getting started:
- If possible, have another developer write the test to avoid testing semantic errors incorrectly.
- Make sure to cover every possible execution path, whether it's valid or invalid.
- Create many small tests, each checking something very specific, rather than a long test that tries to do many things at once.
- Test around the limits.
- Test around the limits
For example, if a value should be always above 10, include a call with the value 10 that should fail and a call with the value 11 that should succeed.
- Test the extremes.
- Test extremes
For more information about avoiding flaws in contracts, see [Avoiding flaws](https://opentezos.com/smart-contracts/avoiding-flaws/) on opentezos.com.
Expand All @@ -64,3 +87,5 @@ For more information about avoiding flaws in contracts, see [Avoiding flaws](htt
- Archetype: [Completium test scenario](https://completium.com/docs/contract/test-scenario)
- SmartPy: [Tests and scenarios](https://smartpy.io/manual/scenarios/overview)
- LIGO: [Testing LIGO](https://ligolang.org/docs/advanced/testing)
Upon test successful, you can deploy your smart contract!
5 changes: 4 additions & 1 deletion sidebars.js
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,9 @@ const sidebars = {
'smart-contracts/logic/errors',
],
},
'smart-contracts/creating',
'smart-contracts/testing',
'smart-contracts/deploying',
'smart-contracts/entrypoints',
'smart-contracts/storage',
'smart-contracts/special-values',
Expand All @@ -170,7 +173,7 @@ const sidebars = {
'smart-contracts/delegation',
// 'smart-contracts/multisig-specialized',
// 'smart-contracts/multisig-usage',
'smart-contracts/testing',

// 'smart-contracts/deploying',
],
},
Expand Down
Binary file added static/img/tutorials/better-call.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit c747d1b

Please sign in to comment.