Skip to content

Register a Kind

This guide walks you through writing a kind contract and registering it in the Kind Registry.

In this example, we'll build a kind contract for dice. Each dice object is modeled with a single element:

  • face: the number of dots representing its current value

The kind contract will implement two asset functions:

  • meta(): returns metadata in JSON format that describes the object token
  • picture(): generates an image of the dice

Before You Begin

Make sure you have:

  1. Bun installed (for scaffolding a project from the template repository)
  2. A wallet set up and funded with tokens

Write the Kind Contract

1. Initialize a project

Scaffold a kind contract project from the template:

bun create everytemplate/kind dice-kind

Build the project to verify it compiles:

cd dice-kind
bun run build

2. Implement contract logic

Edit assembly/index.ts to implement the asset functions. The final code looks like this (see dice-kind for the full repo):

@kind
class Dice {
  face!: Bytes32;
 
  meta(): Json {
    let data = json.create("{}");
    json.setString(data, "/name", `Dice #${object.id()}`);
    json.setString(data, "/description", "A dice");
    json.setString(data, "/image", object.assetUri2("picture"));
    return data;
  }
 
  picture(): Image {
    let canvas = image.create(800, 800, 2);
    const COLOR_WHITE = new PixelRgb8(255, 255, 255);
    const COLOR_BLACK = new PixelRgb8(0, 0, 0);
    const COLOR_RED = new PixelRgb8(255, 0, 0);
 
    image.drawFilledRectMut(canvas, new Rect(0, 0, 800, 800), COLOR_WHITE);
    image.drawHollowRectMut(canvas, new Rect(50, 50, 700, 700), COLOR_BLACK);
 
    let dots = (this.face.extractU8(31) % 6) + 1;
    switch (dots) {
      case 1:
        image.drawFilledCircleMut(canvas, new PointI32(400, 400), 50, COLOR_RED);
        break;
      case 2:
        image.drawFilledCircleMut(canvas, new PointI32(200, 200), 50, COLOR_BLACK);
        image.drawFilledCircleMut(canvas, new PointI32(600, 600), 50, COLOR_BLACK);
        break;
      case 3:
        image.drawFilledCircleMut(canvas, new PointI32(200, 200), 50, COLOR_BLACK);
        image.drawFilledCircleMut(canvas, new PointI32(400, 400), 50, COLOR_BLACK);
        image.drawFilledCircleMut(canvas, new PointI32(600, 600), 50, COLOR_BLACK);
        break;
      case 4:
        image.drawFilledCircleMut(canvas, new PointI32(200, 200), 50, COLOR_BLACK);
        image.drawFilledCircleMut(canvas, new PointI32(600, 200), 50, COLOR_BLACK);
        image.drawFilledCircleMut(canvas, new PointI32(200, 600), 50, COLOR_BLACK);
        image.drawFilledCircleMut(canvas, new PointI32(600, 600), 50, COLOR_BLACK);
        break;
      case 5:
        image.drawFilledCircleMut(canvas, new PointI32(200, 200), 50, COLOR_BLACK);
        image.drawFilledCircleMut(canvas, new PointI32(600, 200), 50, COLOR_BLACK);
        image.drawFilledCircleMut(canvas, new PointI32(400, 400), 50, COLOR_RED);
        image.drawFilledCircleMut(canvas, new PointI32(200, 600), 50, COLOR_BLACK);
        image.drawFilledCircleMut(canvas, new PointI32(600, 600), 50, COLOR_BLACK);
        break;
      case 6:
        image.drawFilledCircleMut(canvas, new PointI32(200, 200), 50, COLOR_BLACK);
        image.drawFilledCircleMut(canvas, new PointI32(200, 400), 50, COLOR_BLACK);
        image.drawFilledCircleMut(canvas, new PointI32(200, 600), 50, COLOR_BLACK);
        image.drawFilledCircleMut(canvas, new PointI32(600, 200), 50, COLOR_BLACK);
        image.drawFilledCircleMut(canvas, new PointI32(600, 400), 50, COLOR_BLACK);
        image.drawFilledCircleMut(canvas, new PointI32(600, 600), 50, COLOR_BLACK);
        break;
    }
    return canvas;
  }
}

Now build the contract. If successful, you will find index.wasm in the build directory:

bun run build

3. Meet kind-as and OVM

This code is written in AssemblyScript and can be compiled with kind-as.

  • See kind-as for the API reference.
  • See kasc for the CLI reference.

The code interprets the face value as the number of dots and draws them by calling image functions. The resulting contract is executed on the OVM (Object Virtual Machine) of the Every chain, which provides host functions for generating JSON and image assets verifiably.

Register the Kind

1. Register the code (as matter)

Register the wasm file as a matter:

every matter register build/index.wasm --account eve --network devnet

You’ll see output including the matter hash:

Register matter: form=1 mime=application/wasm blob=6876B build/index.wasm
Transaction submitted: 0xed68e949abedf05768384b912b01dee2198612e35b1215709903cd53173c2cde
MatterRegistered   ['...','0x1dea6f244d8636df267f8589beb433407d12b05b82432a83419254ad2754daa9']

2. Register the data (as matter)

Create a data file shared by all objects of this kind. For now, use an empty JSON file:

echo '{}' > data.json

Register it as matter:

every matter register data.json --account eve --network devnet

You’ll see output including its matter hash:

Register matter: form=1 mime=application/json blob=3B data.json
MatterRegistered   ['...','0x56c792cfe063dde75e9e6afb371542ea141c62c342820ce9b0394992c7f40d35']

3. Register the kind

With both code and data registered, register the kind:

every kind register \
  0x1dea6f244d8636df267f8589beb433407d12b05b82432a83419254ad2754daa9 \
  0x56c792cfe063dde75e9e6afb371542ea141c62c342820ce9b0394992c7f40d35 \
  '[1]' \
  '[]' \
  --foundry --account eve --universe sepolia

The four arguments are:

  • <code>: matter hash of the contract code
  • <data>: matter hash of the shared data
  • '[1]': element types array
  • '[]': supported relation IDs (empty for now)

Sample output:

Transaction sending...
Transaction sent: 0xd91f6effaee287da8f593461fe30e3fa121ae031f455b9e309bb3346d5017216
Waiting for confirmation...
Confirmed in: block 52991, hash 0xdf7addfd547e0360226188362e12252109958cd2677d024e691caa9e583291fe
KindRegistered {id:17n,desc:{traits:0,rev:1,kindRev:1,setRev:1,kindId:2n,setId:2n},code:'0x1dea6f244d8636df267f8589beb433407d12b05b82432a83419254ad2754daa9',data:'0x56c792cfe063dde75e9e6afb371542ea141c62c342820ce9b0394992c7f40d35',elemSpec:[1],rels:[],owner:'0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266'}

The KindRegistered event confirms that the kind has been successfully registered. In this example, the kind was assigned an ID of 17.

©2025 every