Hello!

I just spent the past 2 weeks as an intern for Dogami. This intership was a mandatory part of my curriculum as a 10th grader (“Seconde”) at my school.

I decided to log what I’ve done every day during my intership.

Day 1

I was introduced to everyone and I got to see how the frontend developpers worked. At the end of the day I was given an assignment: build a UI library for unifying all of the reusable UI components on their frontend.

Day 2

I worked on this assignment pretty much all day.

Day 3

I finished the UI library mid afternoon:

I was given something new to do. I was introduced to PyMich. PyMich is a Python to Michelson compiler that lets you write smart contracts in Python (Michelson is pretty hard to work with). I was told to write a smart contract to see how it works.

Day 4

So I did:

from dataclasses import dataclass
from pymich.michelson_types import *


class FA12(BaseContract):
    voting_data: BigMap[String, Nat]
    addresses_that_have_already_voted: BigMap[Address, Nat]
    voter_whitelist: Set[Address]
    total_votes: Nat
    is_open: bool
    owner: Address

    def vote(self, votingFor: String):
        if not self.is_open:
            raise Exception("This election is closed!")
        if not (Tezos.sender in self.voter_whitelist):
            raise Exception("You are not part of the whitelist.")
        if Tezos.sender in self.addresses_that_have_already_voted:
            raise Exception("You can't vote more than once.")
        self.voting_data[votingFor] = self.voting_data.get(
            votingFor, Nat(0)) + Nat(1)
        self.total_votes = self.total_votes + Nat(1)
        self.addresses_that_have_already_voted[Tezos.sender] = Nat(1)

    def open(self):
        if Tezos.sender != self.owner:
            raise Exception("You must be the contract owner to open the election!")
        if self.is_open:
            raise Exception("This election is already open!")
        self.is_open = True

    def close(self):
        if Tezos.sender != self.owner:
            raise Exception("You must be the contract owner to close the election!")
        if not self.is_open:
            raise Exception("This election is already closed!")
        self.is_open = False

    def getResults(self, candidate: String) -> Nat:
        return self.voting_data.get(candidate, Nat(0))

This is a pretty simple contract that lets an entity organise a vote by having a whitelist with the addresses of their electors and having them interact with the smart contract to vote. The entity can also open and close the vote.

This Python code gets compiled to michelson.

Originating the contract was pretty easy using pytezos:

from pytezos import pytezos, ContractInterface
from pytezos.contract.result import OperationResult

pytezos = pytezos.using(
    "ithacanet", key='ithacanet2.json')

contract = ContractInterface.from_file('./main.tz')

ci = contract.using("ithacanet",
                    key='ithacanet2.json')

storage = {
    "voting_data": {},
    "addresses_that_have_already_voted": {},
    "voter_whitelist": {
        "tz1QLkUi8mrQf3p34u4g98Gb1J7LKwjUpdtA",
        "tz1TMdknT1LKFngc2M9NTYNRiqfE21APPd2z",
        "tz1N7Cz2zVqmxhv7ejJJZ9u1z8uSJshVY9Mi",
        "tz1fyvvULDnujY9ZwWdECZQRZxZ3dvtpSKuJ",
    },
    "total_votes": 0,
    "is_open": False,
    "owner": "tz1fyvvULDnujY9ZwWdECZQRZxZ3dvtpSKuJ",
}
opg = ci.originate(initial_storage=storage).send(min_confirmations=1)

contract_addr = OperationResult.from_operation_group(
    opg.opg_result)[0].originated_contracts[0]
contract = pytezos.using("ithacanet",
                         key='ithacanet2.json').contract(contract_addr)

print(contract.address)

You can see the final contract here.

Next, I coded a small indexer for my contract using DipDup. Following this documentation:

Day 5

Today I worked on making a git submodule for unifying logic components for Dogami’s frontend. I made quite a few changes on the first version! Thank god for VSCode’s automatic imports updating. Git log

Day 6

Today is Monday, the first day of my second and final week at Dogami. Today I cleaned up the example reference app for the Dogami UI library: example reference app for the Dogami UI library

I then opened a pull request for my code to be merged to the main branch.

Day 7

The Alpha 2 reveal date is tomorrow, everyone is super busy!

I worked on making a pagination system for the website and opened a pull request.

Day 8

Today is the day of the reveal! Everyone around the office revealed their dogs and it was an overall exciting experience. Today I learnt how the probabilities work for the reveals and built visualisations.

Since there is a set number of dogs that the smart contract picks from, the starting probabilities for each trait are set at the start. Once people start revealing we might get, by pure chance, a higher number of one type of dog, the probability for that type of dog will eventually go down compared to the others. When everyone is done revealing, the probabilities will have balanced out and, for example, there will be exactly 800 dogs of each breed in Alpha 1.

Gen 1 Breed Reveal Probabilities (Real, as of June 22nd 2022) Gen 1 Breed Reveal Probabilities

Gen 1 Rarity Reveal Probabilities (Real, as of June 22nd 2022) Gen 1 Rarity Reveal Probabilities

Day 9

Today I worked on optimising the reveal videos… They used to be 40MB for a 24s long clip. That’s way too high… They used the H.264 codec. So I came up with this bash script.

mkdir compressed
for f in ./*.mp4 ; \
do ffmpeg -i "$f" -deadline good -cpu-used 0 -c:v libvpx-vp9 -crf 38 -b:v 0 -pass 1 -an -f null /dev/null \
&& ffmpeg -i "$f" -deadline good -cpu-used 0 -c:v libvpx-vp9 -crf 38 -b:v 0 -pass 2 -c:a copy "./compressed/$f.webm" ; \
done

Let’s break it down:

  • First I create a folder named compressed in the current working directory.
  • I then loop two consecutive ffmpeg commands for each .mp4 file f in the current working directory.
  • I do a first pass with the following settings
    • Input footage: "$f"
    • Encoding speed: -deadline good -cpu-used 0
      • These are VP9 settings
    • Video encoder settings: -c:v libvpx-vp9 -crf 38 -b:v 0 -pass 1
      • VP9 Codec
      • CRF (Constant Rate Factor) of 38 (the higher it is the worse the output footage will look)
      • Video bitrate should be set to 0 for CRF to work
      • This is a first pass
    • No audio : -an
    • I don’t output any video, just a log : -f null /dev/null
  • I do a second pass with the following settings
    • Input footage: "$f"
    • Encoding speed: -deadline good -cpu-used 0
      • These are VP9 settings
    • Video encoder settings: -c:v libvpx-vp9 -crf 38 -b:v 0 -pass 2
      • VP9 Codec
      • CRF (Constant Rate Factor) of 38 (the higher it is the worse the output footage will look)
      • Video bitrate should be set to 0 for CRF to work
      • This is the second pass
    • I don’t reencode the audio I just copy it : -c:a copy
    • I output the footage to ./compressed: "./compressed/$f.webm"

With these settings I’m able to go from 40MB to 4.7MB with negligeable loss of quality.

I also improved the pagination I wrote a few days ago for the marketplace and rewrote the whole filtering system for the marketplace so that the filtering is done on the graphql requests themselves. This fixes a bug where there were empty pages because I could not request more than 100 swaps at a time (before I added pagination there wre results that just weren’t shown, so pagination helped mitigate the issue but not solve it).

But now the requests take like 8s. I suspected a lack of indexing tables on the indexer so I talked to the guy responsible and got a build working on my machine. When I added indexing tables the requests now took 20ms. Nice! I opened a pull request with my modifications with the branch name indexing-the-indexer-whoa-indexception.

Day 10

There are only two days left to my internship: today and next Monday. Today I worked on ironing out the code for the pagination and filtering system I wrote. My indexing-the-indexer-whoa-indexception branch also got merged.

I was the last to leave the office today. They have a white board with paper that folds up (like in the movies) for presentations in the office. With no one was looking, I had to draw a few doodles on it…

  • Demon dog

Demon dog sketch

  • Chihuahua

Chihuahua sketch