2019-11-08 03:19:27 +04:00
---
id: first-contract
title: First contract
---
2020-02-10 22:07:20 +04:00
So far so good, we have learned enough of the LIGO language, we are
confident enough to write out first smart contract.
2019-11-08 03:19:27 +04:00
2020-02-10 22:07:20 +04:00
We will be implementing a counter contract.
2019-11-08 03:19:27 +04:00
2020-02-10 22:07:20 +04:00
## Dry-running a Contract
2019-11-08 03:19:27 +04:00
2020-02-10 22:07:20 +04:00
Testing a contract can be quite easy if we utilize LIGO's built-in dry
run feature. Dry-run works by simulating the access function
execution, as if it were deployed on a real chain. You need to provide
the following:
2019-11-08 03:19:27 +04:00
- `file` - contract to run
- `entrypoint` - name of the function to execute
2020-02-10 22:07:20 +04:00
- `parameter` - parameter passed to the access function (in a theoretical invocation operation)
2019-11-08 03:19:27 +04:00
- `storage` - a mock storage value, as if it were stored on a real chain
2020-02-10 22:07:20 +04:00
Here is a full example:
2019-11-08 03:19:27 +04:00
<!-- DOCUSAURUS_CODE_TABS -->
<!-- Pascaligo -->
```
ligo dry-run src/basic.ligo main Unit Unit
// Outputs:
// tuple[ list[]
// Unit
// ]
```
<!-- END_DOCUSAURUS_CODE_TABS -->
2020-02-10 22:07:20 +04:00
Output of the `dry-run` is the return value of our access function, we
can see the operations emited - in our case an empty list, and the new
storage value being returned - which in our case is still `Unit` .
2019-11-08 03:19:27 +04:00
2020-02-10 22:07:20 +04:00
## A Counter Contract
2019-11-08 03:19:27 +04:00
2020-02-10 22:07:20 +04:00
Our counter contract will store a single `int` as it's storage, and
will accept an `action` variant in order to re-route our single `main`
access function to two entrypoints for `addition` and `subtraction` .
2019-11-08 03:19:27 +04:00
<!-- DOCUSAURUS_CODE_TABS -->
<!-- Pascaligo -->
```
type action is
2020-02-10 22:07:20 +04:00
Increment of int
2019-11-08 03:19:27 +04:00
| Decrement of int
function main (const p : action ; const s : int) : (list(operation) * int) is
2020-02-10 22:07:20 +04:00
((nil : list(operation)),
(case p of
2019-11-08 03:19:27 +04:00
| Increment (n) -> s + n
| Decrement (n) -> s - n
2020-02-10 22:07:20 +04:00
end))
2019-11-08 03:19:27 +04:00
```
2020-01-18 10:56:54 +04:00
<!-- CameLIGO -->
```cameligo
type action =
| Increment of int
| Decrement of int
let main (p, s: action * int) : operation list * int =
let result =
match p with
| Increment n -> s + n
| Decrement n -> s - n
in
(([]: operation list), result)
```
<!-- ReasonLIGO -->
```reasonligo
type action =
| Increment(int)
| Decrement(int);
let main = (p_s: (action, int)) : (list(operation), int) => {
let p, s = p_s;
let result =
switch (p) {
| Increment(n) => s + n
| Decrement(n) => s - n
};
(([]: list(operation)), result);
};
```
2019-11-08 03:19:27 +04:00
<!-- END_DOCUSAURUS_CODE_TABS -->
To dry-run the counter contract, we will use the `main` entrypoint, provide a variant parameter of `Increment(5)` and an initial storage value of `5` .
<!-- DOCUSAURUS_CODE_TABS -->
<!-- Pascaligo -->
```
ligo dry-run src/counter.ligo main "Increment(5)" 5
// tuple[ list[]
// 10
// ]
```
<!-- END_DOCUSAURUS_CODE_TABS -->
2020-02-10 22:07:20 +04:00
Our contract's storage has been successfuly incremented to `10` .
2019-11-08 03:19:27 +04:00
## Deploying and interacting with a contract on a live-chain
2020-02-10 22:07:20 +04:00
In order to deploy the counter contract to a real Tezos network, we'd
have to compile it first, this can be done with the help of the
`compile-contract` CLI command:
2019-11-08 03:19:27 +04:00
<!-- DOCUSAURUS_CODE_TABS -->
<!-- Pascaligo -->
```
ligo compile-contract src/counter.ligo main
```
<!-- END_DOCUSAURUS_CODE_TABS -->
Command above will output the following Michelson code:
<!-- DOCUSAURUS_CODE_TABS -->
<!-- Pascaligo -->
```
{ parameter (or (int %decrement) (int %increment)) ;
storage int ;
code { DUP ;
CAR ;
DIP { DUP } ;
SWAP ;
CDR ;
DIP { DUP } ;
SWAP ;
IF_LEFT
{ DUP ;
DIP 2 { DUP } ;
DIG 2 ;
DIP { DUP } ;
SUB ;
SWAP ;
DROP ;
SWAP ;
DROP }
{ DUP ;
DIP 2 { DUP } ;
DIG 2 ;
DIP { DUP } ;
ADD ;
SWAP ;
DROP ;
SWAP ;
DROP } ;
NIL operation ;
PAIR ;
SWAP ;
DROP ;
SWAP ;
DROP ;
SWAP ;
DROP } }
```
<!-- END_DOCUSAURUS_CODE_TABS -->
2020-02-10 22:07:20 +04:00
However in order to originate a Michelson contract on Tezos, we also
need to provide the initial storage value, we can use
`compile-storage` to compile the LIGO representation of the storage to
Michelson.
2019-11-08 03:19:27 +04:00
<!-- DOCUSAURUS_CODE_TABS -->
<!-- Pascaligo -->
```
ligo compile-storage src/counter.ligo main 5
// Outputs: 5
```
<!-- END_DOCUSAURUS_CODE_TABS -->
2020-01-22 19:16:08 +04:00
In our case the LIGO storage value maps 1:1 to its Michelson representation, however this will not be the case once the parameter is of a more complex data type, like a record.
2019-11-08 03:19:27 +04:00
## Invoking a LIGO contract
Same rules apply for parameters, as apply for translating LIGO storage values to Michelson. We will need to use `compile-parameter` to compile our `action` variant into Michelson, here's how:
<!-- DOCUSAURUS_CODE_TABS -->
<!-- Pascaligo -->
```
ligo compile-parameter src/counter.ligo main 'Increment(5)'
// Outputs: (Right 5)
```
<!-- END_DOCUSAURUS_CODE_TABS -->
2020-02-10 22:07:20 +04:00
Now we can use `(Right 5)` which is a Michelson value, to invoke our
contract - e.g. via `tezos-client`