Olive oil traceability, step by step

5. Modelling the lot

Goal: Write the minimal structure of a lot in Solidity: data, phases and one token per lot.

From here on we build a small version you can write in an afternoon. You need Node.js, Hardhat and the OpenZeppelin libraries. The language is called Solidity.

A smart contract is like a vending machine: the rules are inside the machine, and everyone who uses it finds the same rules.

Three ideas

Struct: a card with several fields (code, cultivar, number of bottles, recalled). Enum: a list of possible values, here the phases. ERC-721: the standard for "unique" tokens, where each number identifies exactly one object; we use one token per lot, so the lot has an owner and a number.

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.24;

import {ERC721} from "@openzeppelin/contracts/token/ERC721/ERC721.sol";

contract LottoMinimo is ERC721 {
    enum Fase { Raccolta, Molitura, Analisi, Imbottigliamento }

    struct Lotto {
        string codice;
        string cultivar;
        uint32 nBottiglie;
        bool richiamato;
    }

    uint256 private _ultimoId;
    mapping(uint256 => Lotto) private _lotti;

    constructor() ERC721("Lotto minimo", "LTT") {}

    function creaLotto(string calldata codice, string calldata cultivar) external returns (uint256 id) {
        id = ++_ultimoId;
        _lotti[id] = Lotto(codice, cultivar, 0, false);
        _mint(msg.sender, id);
    }
}

Line by line

  1. import: takes the ERC-721 base from the OpenZeppelin library (installed with npm i @openzeppelin/contracts).
  2. enum Fase: the four phases in order; internally they are 0, 1, 2, 3.
  3. struct Lotto: a lot's card. nBottiglie starts at 0 and is set at bottling.
  4. _ultimoId counts lots; _lotti links each token number to its card.
  5. The constructor gives the token a name and a symbol.
  6. creaLotto: raises the counter, saves the card and, with _mint, creates the token owned by the caller (msg.sender).

In the full Pietre di Vita contract the card also has area, harvest date, kilos of olives and recall reason, and the lot code is checked for uniqueness. The basic logic is this one.

Try it yourself

Create a folder, run npx hardhat init (choose a JavaScript project), then npm i @openzeppelin/contracts. Copy the code into contracts/LottoMinimo.sol and run npx hardhat compile. If you see "Compiled ... Solidity files successfully" it works.

What you learned

To go deeper