Skip to content

Commit

Permalink
docs: draft initial docs version
Browse files Browse the repository at this point in the history
  • Loading branch information
scarmuega committed Apr 23, 2024
1 parent 1291e39 commit e2bb713
Show file tree
Hide file tree
Showing 18 changed files with 227 additions and 24 deletions.
9 changes: 2 additions & 7 deletions docs/components/hero.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,12 @@ export function Hero() {
<div className="flex justify-center">
<img src="/logo.png" alt="Asteria logo" className="mb-4" />
</div>
<h1 className="flex flex-col flex-wrap font-bold text-4xl md:text-6xl lg:text-7xl dark:text-gray-200">
The power of eUTxO model
</h1>
<h1 className="flex flex-col flex-wrap font-bold text-4xl md:text-6xl lg:text-7xl dark:text-gray-200">Asteria</h1>
</div>

<div className="mb-8 max-w-3xl text-center mx-auto">
<p className="md:text-lg text-gray-600 dark:text-gray-400">
Asteria is an open hackathon, a bot challenge that leverages the eUTxO model.
Players participate by moving a ship across a 2D grid and gathering resources. ADA rewards are available to players that reach the center of the gird.
All interactions from participants happen through on-chain transactions, forcing the developer to learn about the UTxO Model.
With ADA reward incentive and a compelling experience, we hope to attract developers from both inside and outside of the Cardano ecosystem
A Cardano bot challenge to showcase the capabilities of the eUTxO model. Players participate by moving a ship across a 2D grid and gathering resources. ADA rewards are available to players that reach the center of the gird. All interactions from participants happen through on-chain transactions, that leverage the UTxO Model.
</p>
</div>

Expand Down
4 changes: 3 additions & 1 deletion docs/pages/_meta.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,7 @@
"layout": "full"
}
},
"introduction": "Introduction"
"introduction": "Introduction",
"rules": "Rules",
"guides": "Guides"
}
3 changes: 3 additions & 0 deletions docs/pages/glossary.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# Glossary

- **Distance**: in the context of Asteria, the distance between two coordinates of a the grid is computed using [Manhattan distance](https://en.wikipedia.org/wiki/Taxicab_geometry).
4 changes: 4 additions & 0 deletions docs/pages/guides/_meta.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"creating_ship": "Creating a Ship",
"moving_ship": "Moving a Ship"
}
33 changes: 33 additions & 0 deletions docs/pages/guides/creating_ship.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@

# Creating a Ship

Creates a `ShipState` UTxO locking min ada and a `ShipToken` (minted in this tx), specifying in the datum the initial `pos_x` and `pos_y` coordinates of the ship, and setting `fuel` to an initial amount. Also adds to the `AsteriaUTxO` value the `SHIP_MINT_FEE` paid by the user.

![createShip diagram](/txs/createShip.png)

## Lucid Example

```ts
import { fromText } from "https://deno.land/x/[email protected]/mod.ts";
import { AssetClassT } from "../types.ts";
import { createShip } from "../transactions/create-ship.ts";

const admin_token: AssetClassT = {
policy: "0298aa99f95e2fe0a0132a6bb794261fb7e7b0d988215da2f2de2005",
name: fromText("tokenA"),
};
const ship_mint_lovelace_fee = 3000n;
const initial_fuel = 15n;
const pos_x = 20n;
const pos_y = -13n;

const txHash = await createShip(
admin_token,
ship_mint_lovelace_fee,
initial_fuel,
pos_x,
pos_y
);

console.log(txHash);
```
Empty file.
Empty file.
105 changes: 105 additions & 0 deletions docs/pages/guides/moving_ship.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@

# Moving a Ship

Updates the `pos_x`, `pos_y` and `fuel` datum fields of the `ShipState` UTxO by adding the `delta_x` and `delta_y` values specified in the redeemer, and subtracting the fuel amount needed for the displacement.

![moveShip diagram](/txs/moveShip.png)

```ts
import {
Data,
toUnit,
TxHash,
Constr,
UTxO,
} from "https://deno.land/x/[email protected]/mod.ts";
import { distance, lucidBase, required_fuel } from "../utils.ts";
import { ShipDatum, ShipDatumT } from "../types.ts";

// look up these values for the specific challenge you're particpating
const FUEL_PER_STEP = 5;

async function moveShip(
fuel_per_step: bigint,
delta_x: bigint,
delta_y: bigint,
ship_token_name: string,
pilot_token_name: string,
shipTxHash: TxHash
): Promise<TxHash> {
const lucid = await lucidBase();

const spacetimeRefTxHash: { txHash: string } = JSON.parse(
await Deno.readTextFile("./spacetime-ref.json")
);
const spacetimeRef = await lucid.utxosByOutRef([
{
txHash: spacetimeRefTxHash.txHash,
outputIndex: 0,
},
]);
const spacetimeValidator = spacetimeRef[0].scriptRef;
if (!spacetimeValidator) {
throw Error("Could not read spacetime validator from ref UTxO");
}
const spacetimeAddressBech32 =
lucid.utils.validatorToAddress(spacetimeValidator);

const shipyardPolicyId = lucid.utils.mintingPolicyToId(spacetimeValidator);
const shipTokenUnit = toUnit(shipyardPolicyId, ship_token_name);
const pilotTokenUnit = toUnit(shipyardPolicyId, pilot_token_name);

const ship: UTxO = (
await lucid.utxosByOutRef([
{
txHash: shipTxHash,
outputIndex: 0,
},
])
)[0];
if (!ship.datum) {
throw Error("Ship datum not found");
}
const shipAda = ship.assets.lovelace;

const shipInputDatum = Data.from<ShipDatumT>(
ship.datum as string,
ShipDatum as unknown as ShipDatumT
);

const moved_distance = distance(delta_x, delta_y);
const spent_fuel = required_fuel(moved_distance, fuel_per_step);
const shipInfo = {
fuel: shipInputDatum.fuel - spent_fuel,
pos_x: shipInputDatum.pos_x + delta_x,
pos_y: shipInputDatum.pos_y + delta_y,
ship_token_name: shipInputDatum.ship_token_name,
pilot_token_name: shipInputDatum.pilot_token_name,
};
const shipOutputDatum = Data.to<ShipDatumT>(
shipInfo,
ShipDatum as unknown as ShipDatumT
);

const moveShipRedeemer = Data.to(
new Constr(1, [new Constr(0, [delta_x, delta_y])])
);

const tx = await lucid
.newTx()
.collectFrom([ship], moveShipRedeemer)
.readFrom(spacetimeRef)
.payToContract(
spacetimeAddressBech32,
{ inline: shipOutputDatum },
{
[shipTokenUnit]: BigInt(1),
lovelace: shipAda,
}
)
.payToAddress(await lucid.wallet.address(), {
[pilotTokenUnit]: BigInt(1),
})
.complete();
}
```
30 changes: 14 additions & 16 deletions docs/pages/introduction.mdx
Original file line number Diff line number Diff line change
@@ -1,26 +1,24 @@

# Asteria
# Introduction

A Cardano bot challenge to showcase the capabilities of the eUTxO model.
Asteria is a Cardano bot challenge to showcase the capabilities of the eUTxO model. In particular, it's concurrency benefits.

## Mechanics
Developers participate by building their own bots (automated agents) that interact directly with the Cardano blockchain. Each bot can be defined as an off-chain process that controls particular UTxOs that are constrained by on-chain validators.

In this bot challenge you compete by moving a ship (your bot) through a 2D grid. The ship that reaches the center is allowed to collect the rewards.
Once the challenge has been layed out by the administrators, all following interactions and rewards are fully decentralized. There're no _admin keys_ to adjust any of the mechanics.

Ships are implemented as UTxOs with a datum holding a pair of (x, y) coordinates that represent their position in the 2D grid. To move a ship, a transaction must consume the UTxO and create a new one with holding the new position.
## Game Overview

![grid](/introduction1.svg)
- Your bot is in charge of controlling a (space) ship that moves in a 2D grid.
- The goal is to reach coordinates (0, 0) allowing the rewards of the challenge to be claimed.
- Your movement is constrained by a maximum speed and the availability of a fuel resource.
- Fuel is freely available at fixed coordinates in the grid, ships can gather the fuel if their coordinates overlap.

Movement of the ships is constrained by a _Space-Time_ on-chain script that limits their velocity. Strictly speaking, the max distance that a ship can move in any given transaction has a constant upper bound. Distances are defined using [Manhattan distance] to simplify the math.

![move tx](/introduction2.svg)
## Ongoing Challenges

Movement of the ships is also constrained by a _fuel_ token that is required for any change in position. An specifc amount of _fuel_ is required per distance unit. The lack of the required fuel amount will block the movement of the ship.
There might be any number of open challenges (games) ongoing at any point. Everything in Asteria is open-source, so you can even run your own challenge.

![gather tx](/introduction3.svg)

To accumulate fuel, ships must _gather_ these tokens which are distributed randomly across the same grid. To gather a fuel token, your ship needs to be in the same coordinates as the fuel.

To create a ship, a participant must mint the corresponding NFT from the valid policy id. A minimum amount of ADA will be requried for the mint. This ADA used to mint the ships will be increment the rewards locked for the winner. The initial position of the ship is decided by the player but is contrainted to the external boundary of the grid.

A unique UTxO will be place at the center of the grid to hold the rewards for the winner of the challenge. To claim rewards, a ship must be located at the center of the grid. Each claim is allowed to collect 1/2 of the total rewards.
|Name|Network|Shipyard Policy|
|--|--|--|
|alpha|`preview`|`000000`|
35 changes: 35 additions & 0 deletions docs/pages/rules/components.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
# Components

## Grid

- the grid is a virtual space in 2 dimensions (`x`, `y`).
- there's no on-chain representation of the grid
- coordinates on each dimension are discrete (integer values)
- the coordinates `(0, 0)` are considered the center of the grid

## Ship

- a ship is identified by a Cardano native asset token of a specific policy id. We call this class of token `ShipToken`.
- the UTxO that holds the `ShipToken` defines the state of the ship. We call this class of UTxOs `ShipState`.
- the datum of the `ShipState` UTxO contains information about current coordinates and available fuel.
- all `ShipState` UTxOs belong to a script address that constraints changes that can be applies to the state. We call this script `SpaceTimeScript`.

## Pilot

- the pilot is a Cardano native token from a particular policy id that is locked in an address managed by the participant. We call this class of token `PilotToken`.
- the goal of this token is to ensure that changes to the `ShipState` are triggered by the rightful owner of the ship.
- the pilot token needs to be present in any of the inputs of a transaction that progresses the state of the ship.

## Fuel Pellet

- a fuel pellet is freely available source of fuel tokens that are located at a fixed position in the grid.
- a fuel pellet is represented by a UTxO that contains any amount of `FuelToken` and is locked at a specific script address. We call this class of UTxO `PelletState`
- the datum of a `PelletState` defines the position of the pellet within the _grid_.
- the amount of fuel tokens in the `PelletState` represents the available fuel.

## Asteria

- Asteria is an asteroid located at the center of the grid that represents the end goal of the challenge.
- Asteria is represented by an UTxO that called `AsteriaUtxo`.
- This UTxO will hold the aggregated rewards of the challenge.
- This UTxO holds a datum with a counter that controls a sequence used to enforce ship uniqueness.
28 changes: 28 additions & 0 deletions docs/pages/rules/gameplay.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# Gameplay

## Building a ship

- to create a ship, the participant has to mint a new `ShipToken` and matching `PilotToken` through a mint validator called `ShipyardPolicy`.
- each Pilot / Ship token pair will be unique. The validator will ensure uniqueness by incrementing a "counter" datum locked in the `AsteriaUtxo`.
- the asset name of the `ShipToken` and `PilotToken` will contain the counter value as a suffix. Eg: `SHIP23` and `PILOT23`.
- the `ShipToken` needs to be locked in the `SpaceTimeScript` and the `PilotToken` needs to go to an address controlled by the participant.
- the mint process will require locking an ADA payment adding to the reward pot. The amount of this payment is defined by our constant `SHIP_MINT_FEE`.

## Moving your ship

- movement of a ship through the grid is achieved by a transaction the consumes the `ShipState` UTxO and outputs a new one with the updated state.
- the maximum _distance_ that can be achieved in a single transaction is constrained by the constant `MAX_SHIP_MOVEMENT_PER_TX`.
- moving the ship will consume a quantity of fuel proportional to the distance. The ratio of fuel required per distance unit is defined by the constant `FUEL_PER_DISTANCE_UNIT`.

## Gathering fuel

- gathering fuel is achieved by a transaction that consumes the `ShipUtxo` and a `PelletUtxo` and outputs a new `ShipUtxo` with increased fuel value.
- to consume a fuel pellet, the position of the ship must overlap with the position of the pellet.
- the total amount of fuel that ship has can't exceed the `MAX_SHIP_FUEL` parameter.
- if the fuel pellet isn't totally consumed, a new `PelletUtxo` needs to be generated with the remaining of the fuel and maintaining the same location in the grid.

## Mining Asteria

- this action is achieved by a transaction that consumes the `ShipUtxo` and `AsteriaUtxo` and outputs a new one that extracts assets from the `AsteriaUtxo` into a wallet defined by the participant.
- the amount of assets that can be extracted from the `AsteriaUtxo` must not exceed a percentage of the total available defined by the `MAX_ASTERIA_MINING`.
- to execute this action, the `ShipUtxo` must be present at coordinates `(0, 0)`.
Binary file added docs/public/txs/createAsteria.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/public/txs/createPellet.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/public/txs/createShip.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/public/txs/gatherFuel.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/public/txs/mineAsteria.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/public/txs/moveShip.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/public/txs/quit.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit e2bb713

Please sign in to comment.