Mappings: many values, one namespace

There is no dict in storage. You build one by composing keys — and the prefix you choose is a security boundary.

Storage is flat: bytes to bytes. A mapping is just a key-building function:

def _k_bal(addr: bytes) -> bytes:
    return b"anm20:bal:" + addr

def _k_allow(owner: bytes, spender: bytes) -> bytes:
    return b"anm20:allow:" + owner + b":" + spender

That is exactly how the Animica token standard does it. Every key is prefixed with the contract's own namespace so two different mappings can never collide.

Composite keys need a separator you control. prefix + a + b is unsafe if a can vary in length: for two-byte pieces, a=b"xy", b=b"z" and a=b"x", b=b"yz" both build prefix + b"xyz" — one user's allowance becomes another's. Animica addresses are fixed 32-byte values so concatenation is safe *there*, but the moment a key part is variable-length you need a separator or a length prefix. The token standard uses b":" between parts for exactly this reason.

Your turn

Implement a two-level mapping: set_score(game, player, points) and score(game, player). Different games must keep separate scores for the same player.

Hints

Stuck? Ask

Answered by Animica's own free inference network. It is donated GPU capacity, so give it 20-30 seconds.