Meet **Pedro**, our *artisan taco chef* who has decided to open a Taco shop on the Tezos blockchain, using a smart-contract. He sells two different kinds of tacos, the **el clásico** and the **especial del chef**.
To help Pedro open his dream taco shop, we'll implement a smart-contract, that will manage supply, pricing & sales of his tacos to the consumers.
<divstyle="opacity: 0.7; text-align: center; font-size: 10px;">Made by <ahref="https://www.flaticon.com/authors/smashicons"title="Smashicons">Smashicons</a> from <ahref="https://www.flaticon.com/"title="Flaticon">www.flaticon.com</a> is licensed by <ahref="http://creativecommons.org/licenses/by/3.0/"title="Creative Commons BY 3.0"target="_blank">CC 3.0 BY</a></div>
In this tutorial, we'll use LIGO's dockerized version for the sake of simplicity. You can find the installation instructions [here](setup/installation.md#dockerized-installation-recommended).
<divstyle="opacity: 0.7; text-align: center; font-size: 12px; margin-top:-24px;">Installing the <b>next</b> version of LIGO's CLI</div>
## Implementing our first entry point
> From now on we'll get a bit more technical. If you run into something we have not covered yet - please try checking out the [LIGO cheat sheet](language-basics/cheat-sheet.md) for some extra tips & tricks.
To begin implementing our smart contract, we need an entry point. We'll call it `main` and it'll specify our contract's storage (`int`) and input parameter (`int`). Of course this is not the final storage/parameter of our contract, but it's something to get us started and test our LIGO installation as well.
- **`(nil : list(operation))`** - a `nil` value annotated as a list of operations, because that's required by our return type specified above
- **`contractStorage + parameter`** - a new storage value for our contract, sum of previous storage and a transaction parameter
### Running LIGO for the first time
To test that we've installed LIGO correctly, and that `taco-shop.ligo` is a valid contract, we'll dry-run it.
> Dry-running is a simulated execution of the smart contract, based on a mock storage value and a parameter.
Our contract has a storage of `int` and accepts a parameter that is also an `int`.
The `dry-run` command requires a few parameters:
- **contract** *(file path)*
- **entrypoint** *(name of the entrypoint function in the contract)*
- **parameter** *(parameter to execute our contract with)*
- **storage** *(starting storage before our contract's code is executed)*
And outputs what's returned from our entrypoint - in our case a touple containing an empty list (of operations to apply) and the new storage value - which in our case is the sum of the previous storage and the parameter we've used.
```zsh
# Contract: taco-shop.ligo
# Entry point: main
# Parameter: 4
# Storage: 3
ligo dry-run taco-shop.ligo --syntax pascaligo main 4 3
<divstyle="opacity: 0.7; text-align: center; font-size: 12px; margin-top:-24px;">Simulating contract execution with the CLI</div>
<br/>
*`3 + 4 = 7` yay! Our CLI & contract work as expected, we can move onto fulfilling Pedro's on-chain dream.*
---
## Designing Taco shop's contract storage
We know that Pedro's Taco Shop serves two kinds of tacos, so we'll need to manage stock individually, per kind. Let's define a type, that will keep the `stock`&`max_price` per kind - in a record with two fields. Additionally, we'll want to combine our `taco_supply` type into a map, consisting of the entire offer of Pedro's shop.
Next step is to update the `main` entry point to include `taco_shop_storage` as its storage - while doing that let's set the `parameter` to `unit` as well to clear things up.
function main (const parameter: unit ; const taco_shop_storage : taco_shop_storage) : (list(operation) * taco_shop_storage) is
block {skip} with ((nil : list(operation)), taco_shop_storage)
```
### Populating our storage in a dry-run
When dry-running a contract, it's crucial to provide a correct initial storage value - in our case the storage is type-checked as `taco_shop_storage`. Reflecting [Pedro's daily offer](tutorials/get-started/tezos-taco-shop-smart-contract.md#daily-offer), our storage's value will be defined as following:
**Storage value**
```zsh
map
1n -> record
current_stock = 50n;
max_price = 50000000mtz;
end;
2n -> record
current_stock = 20n;
max_price = 75000000mtz;
end;
end
```
> Storage value is a map, with two items in it, both items are records identified by natural numbers `1n` & `2n`.
**Dry run command with a multi-line storage value**
```zsh
ligo dry-run taco-shop.ligo --syntax pascaligo main unit "map
*If everything went as expected, the `dry-run` command will return an empty list of operations and the contract's current storage, which is the map of products we've defined based on the daily offer of Pedro's taco shop.*
Now that we have our stock well defined in form of storage, we can move on to the actual sales. We'll replace the `main` entrypoint with `buy_taco`, that takes an `id` - effectively a key from our `taco_shop_storage` map. This will allow us to calculate pricing, and if the sale is successful - then we can reduce our stock - because we have sold a taco!
### Selling the tacos for free
Let's start by customizing our contract a bit, we will:
- rename the entrypoint from `main` to `buy_taco`
- rename `parameter` to `taco_kind_index`
- change `taco_shop_storage` to a `var` instead of a `const`, because we'll want to modify it
<divstyle="opacity: 0.7; text-align: center; font-size: 12px; margin-top:-24px;">Stock decreases after selling a taco</div>
<br/>
### Making sure we get paid for our tacos
In order to make Pedro's taco shop profitable, he needs to stop giving away tacos for free. When a contract is invoked via a transaction, an amount of tezzies to be sent can be specified as well. This amount is accessible within LIGO as `amount`.
To make sure we get paid, we will:
- calculate a `current_purchase_price` based on the [equation specified earlier](tutorials/get-started/tezos-taco-shop-smart-contract.md#calculating-the-current-purchase-price)
- check if the sent `amount` matches the `current_purchase_price`
- if not, then our contract will `fail` and stop executing
- if yes, stock for the given `taco_kind` will be decreased and the payment accepted
<divstyle="opacity: 0.7; text-align: center; font-size: 12px; margin-top:-24px;">Stock decreases after selling a taco, if the right amount of tezzies is provided</div>
<divstyle="opacity: 0.7; text-align: center; font-size: 12px; margin-top:-24px;">Stock does not decrease after a purchase attempt with a lower than required amount.</div>
<br/>
**That's it - Pedro can now sell tacos on-chain, thanks to Tezos & LIGO.**
---
## 💰 Bonus: *Accepting tips above the taco purchase price*
If you'd like to accept tips in your contract as well, simply change the following line, depending on which behavior do you prefer.