Skip to content

Commit

Permalink
70 add fuel tokens (#71)
Browse files Browse the repository at this point in the history
* updated design document.

* onchain with fuel tokens.

* fixed shipyard unit tests.

* offchain for creating ship with fuel tokens.

* moving ship with fuel tokens.

* gathering fuel tokens.

* burning remaining fuel tokens when mining asteria.

* burning remaining fuel tokens when quitting.

* creating pellets with fuel tokens.

* removed burn of fuel check when admin consumes pellets.

* consuming pellets with fuel tokens.

* refactored unit tests.

* WIP: fuel policy tests

* removed vscode settings file.

* fuel policy tests

* fixed name

* updated plutus.json

* updated script refs

* fixed typo.

* minting no tokens check on GatherFuel redeemer.

* updated spacetime script ref.
  • Loading branch information
franciscojoray authored Jul 8, 2024
1 parent 523823b commit 07d712f
Show file tree
Hide file tree
Showing 47 changed files with 3,157 additions and 2,389 deletions.
2 changes: 1 addition & 1 deletion offchain/script-refs/asteria-ref.json
Original file line number Diff line number Diff line change
@@ -1 +1 @@
{"txHash":"8734a7c57080e71f04618fa59cc94f5216eecda8a3ff2229947087838074aa8d"}
{"txHash":"999eb94c9fa1df83e7a18d074f4da5963c5945ed4410fa9fd402435d35a3991c"}
2 changes: 1 addition & 1 deletion offchain/script-refs/pellet-ref.json
Original file line number Diff line number Diff line change
@@ -1 +1 @@
{"txHash":"7c215f620bdb549479eefec6bc8b97aed6f4b8d48bc99775d5560190475f0b45"}
{"txHash":"bfc7523659c6e649d72f1931e3d8bfe200bb51d3634b36249b68f96172de0b3b"}
2 changes: 1 addition & 1 deletion offchain/script-refs/spacetime-ref.json
Original file line number Diff line number Diff line change
@@ -1 +1 @@
{"txHash":"669b5cc55b7c93c1728cb0413a69ad319d87cdfdf650cbef162792554bca328f"}
{"txHash":"7853afe4445954b0b09262bfee4031d3100e7d976b0125fb9fea8130d36b1157"}
20 changes: 18 additions & 2 deletions offchain/transactions/admin/pellets/consume-pellets.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ import {
TxHash,
Constr,
UTxO,
Script,
fromText,
} from "https://deno.land/x/lucid@0.10.7/mod.ts";
import { fetchReferenceScript, lucidBase } from "../../../utils.ts";
import { AssetClassT } from "../../../types.ts";
Expand All @@ -24,25 +26,39 @@ async function consumePellets(
await Deno.readTextFile("./script-refs/pellet-ref.json")
);
const pelletRef = await fetchReferenceScript(lucid, pelletRefTxHash.txHash);
const pelletValidator = pelletRef.scriptRef as Script;
const fuelPolicyId = lucid.utils.mintingPolicyToId(pelletValidator);
const fuelTokenUnit = toUnit(fuelPolicyId, fromText("FUEL"));

const pellets: UTxO[] = await lucid.utxosByOutRef(
pellets_tx_indexes.map((i) => ({
txHash: pellets_tx_hash,
outputIndex: i,
}))
);
const totalFuel = pellets.reduce(
(sum, pellet) => sum + pellet.assets[fuelTokenUnit],
0n
);

const adminTokenUnit = toUnit(admin_token.policy, admin_token.name);
const adminUTxO: UTxO = await lucid.wallet
.getUtxos()
.then((us) => us.filter((u) => u.assets[adminTokenUnit] >= 1n))
.then((us) => us[0]);

const consumeRedeemer = Data.to(new Constr(1, []));
const consumePelletRedeemer = Data.to(new Constr(1, [new Constr(1, [])]));
const burnFuelRedeemer = Data.to(new Constr(1, []));
const tx = await lucid
.newTx()
.mintAssets(
{
[fuelTokenUnit]: -totalFuel,
},
burnFuelRedeemer
)
.readFrom([pelletRef])
.collectFrom(pellets, consumeRedeemer)
.collectFrom(pellets, consumePelletRedeemer)
.collectFrom([adminUTxO])
.complete();

Expand Down
31 changes: 22 additions & 9 deletions offchain/transactions/admin/pellets/create-pellets.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import {
Assets,
Constr,
Data,
fromText,
Script,
toUnit,
TxHash,
Expand All @@ -26,6 +28,7 @@ async function createPellets(
const pelletRef = await fetchReferenceScript(lucid, pelletRefTxHash.txHash);
const pelletValidator = pelletRef.scriptRef as Script;
const pelletAddressBech32 = lucid.utils.validatorToAddress(pelletValidator);
const fuelPolicyId = lucid.utils.mintingPolicyToId(pelletValidator);

const spacetimeRefTxHash: { txHash: string } = JSON.parse(
await Deno.readTextFile("./script-refs/spacetime-ref.json")
Expand All @@ -37,12 +40,13 @@ async function createPellets(
const spacetimeValidator = spacetimeRef.scriptRef as Script;
const shipyardPolicyId = lucid.utils.mintingPolicyToId(spacetimeValidator);

const fuelTokenUnit = toUnit(fuelPolicyId, fromText("FUEL"));
const adminTokenUnit = toUnit(admin_token.policy, admin_token.name);
const mintFuelRedeemer = Data.to(new Constr(0, []));
let tx = await lucid.newTx();

for (const pellet of params) {
const pelletInfo = {
fuel: pellet.fuel,
pos_x: pellet.pos_x,
pos_y: pellet.pos_y,
shipyard_policy: shipyardPolicyId,
Expand All @@ -52,14 +56,23 @@ async function createPellets(
PelletDatum as unknown as PelletDatumT
);

tx = tx.payToContract(
pelletAddressBech32,
{ inline: pelletDatum },
{
[adminTokenUnit]: BigInt(1),
...prize_tokens,
}
);
tx = tx
.readFrom([pelletRef])
.mintAssets(
{
[fuelTokenUnit]: pellet.fuel,
},
mintFuelRedeemer
)
.payToContract(
pelletAddressBech32,
{ inline: pelletDatum },
{
[fuelTokenUnit]: pellet.fuel,
[adminTokenUnit]: BigInt(1),
...prize_tokens,
}
);
}
const completeTx = await tx.complete();
const signedTx = await completeTx.sign().complete();
Expand Down
24 changes: 20 additions & 4 deletions offchain/transactions/user/create-ship.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,13 @@ async function createShip(
const spacetimeAddressBech32 =
lucid.utils.validatorToAddress(spacetimeValidator);

const pelletRefTxHash: { txHash: string } = JSON.parse(
await Deno.readTextFile("./script-refs/pellet-ref.json")
);
const pelletRef = await fetchReferenceScript(lucid, pelletRefTxHash.txHash);
const pelletValidator = pelletRef.scriptRef as Script;
const fuelPolicyId = lucid.utils.mintingPolicyToId(pelletValidator);

const asterias: UTxO[] = await lucid.utxosAt(asteriaAddressBech32);
if (asterias.length != 1) {
throw Error(
Expand All @@ -76,10 +83,10 @@ async function createShip(
AsteriaDatum as unknown as AsteriaDatumT
);

const fuelTokenName = fromText("FUEL");
const shipTokenName = fromText("SHIP" + asteriaInputDatum.ship_counter);
const pilotTokenName = fromText("PILOT" + asteriaInputDatum.ship_counter);
const shipInfo = {
fuel: initial_fuel,
pos_x: pos_x,
pos_y: pos_y,
ship_token_name: shipTokenName,
Expand All @@ -92,28 +99,37 @@ async function createShip(
);

const adminTokenUnit = toUnit(admin_token.policy, admin_token.name);
const fuelTokenUnit = toUnit(fuelPolicyId, fuelTokenName);
const shipTokenUnit = toUnit(shipyardPolicyId, shipTokenName);
const pilotTokenUnit = toUnit(shipyardPolicyId, pilotTokenName);

const addNewShipRedeemer = Data.to(new Constr(0, []));
const mintRedeemer = Data.to(new Constr(0, []));
const mintFuelRedeemer = Data.to(new Constr(0, []));
const mintShipRedeemer = Data.to(new Constr(0, []));
const tx = await lucid
.newTx()
.validTo(Number(tx_latest_posix_time))
.readFrom([asteriaRef, spacetimeRef])
.readFrom([asteriaRef, spacetimeRef, pelletRef])
.mintAssets(
{
[shipTokenUnit]: BigInt(1),
[pilotTokenUnit]: BigInt(1),
},
mintRedeemer
mintShipRedeemer
)
.mintAssets(
{
[fuelTokenUnit]: initial_fuel,
},
mintFuelRedeemer
)
.collectFrom([asteria], addNewShipRedeemer)
.payToContract(
spacetimeAddressBech32,
{ inline: shipDatum },
{
[shipTokenUnit]: BigInt(1),
[fuelTokenUnit]: initial_fuel,
}
)
.payToContract(
Expand Down
18 changes: 13 additions & 5 deletions offchain/transactions/user/gather-fuel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import {
Constr,
UTxO,
Script,
fromText,
} from "https://deno.land/x/lucid@0.10.7/mod.ts";
import { fetchReferenceScript, lucidBase } from "../../utils.ts";
import {
Expand Down Expand Up @@ -48,6 +49,7 @@ async function gatherFuel(
const pelletRef = await fetchReferenceScript(lucid, pelletRefTxHash.txHash);
const pelletValidator = pelletRef.scriptRef as Script;
const pelletAddressBech32 = lucid.utils.validatorToAddress(pelletValidator);
const fuelPolicyId = lucid.utils.mintingPolicyToId(pelletValidator);

const ship: UTxO = (
await lucid.utxosByOutRef([
Expand All @@ -70,8 +72,8 @@ async function gatherFuel(
},
])
)[0];
if (!ship.datum) {
throw Error("Ship datum not found");
if (!pellet.datum) {
throw Error("Pellet datum not found");
}
const pelletAda = pellet.assets.lovelace;

Expand All @@ -80,7 +82,6 @@ async function gatherFuel(
ShipDatum as unknown as ShipDatumT
);
const shipInfo = {
fuel: shipInputDatum.fuel + gather_amount,
pos_x: shipInputDatum.pos_x,
pos_y: shipInputDatum.pos_y,
ship_token_name: shipInputDatum.ship_token_name,
Expand All @@ -97,7 +98,6 @@ async function gatherFuel(
PelletDatum as unknown as PelletDatumT
);
const pelletInfo = {
fuel: pelletInputDatum.fuel - gather_amount,
pos_x: pelletInputDatum.pos_x,
pos_y: pelletInputDatum.pos_y,
shipyard_policy: shipyardPolicyId,
Expand All @@ -117,8 +117,14 @@ async function gatherFuel(
);
const adminTokenUnit = toUnit(admin_token.policy, admin_token.name);

const fuelTokenUnit = toUnit(fuelPolicyId, fromText("FUEL"));
const shipFuel = ship.assets[fuelTokenUnit];
const pelletFuel = pellet.assets[fuelTokenUnit];

const shipRedeemer = Data.to(new Constr(1, [new Constr(1, [gather_amount])]));
const pelletRedeemer = Data.to(new Constr(0, [gather_amount]));
const pelletRedeemer = Data.to(
new Constr(1, [new Constr(0, [gather_amount])])
);
const tx = await lucid
.newTx()
.validFrom(Number(tx_earliest_posix_time))
Expand All @@ -130,6 +136,7 @@ async function gatherFuel(
{ inline: shipOutputDatum },
{
[shipTokenUnit]: BigInt(1),
[fuelTokenUnit]: shipFuel + gather_amount,
lovelace: shipAda,
}
)
Expand All @@ -138,6 +145,7 @@ async function gatherFuel(
{ inline: pelletOutputDatum },
{
[adminTokenUnit]: BigInt(1),
[fuelTokenUnit]: pelletFuel - gather_amount,
lovelace: pelletAda,
}
)
Expand Down
27 changes: 22 additions & 5 deletions offchain/transactions/user/mine-asteria.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import {
Constr,
UTxO,
Script,
fromText,
} from "https://deno.land/x/lucid@0.10.7/mod.ts";
import { fetchReferenceScript, lucidBase } from "../../utils.ts";
import {
Expand Down Expand Up @@ -36,6 +37,15 @@ async function mineAsteria(
spacetimeRefTxHash.txHash
);
const spacetimeValidator = spacetimeRef.scriptRef as Script;
const shipyardPolicyId = lucid.utils.mintingPolicyToId(spacetimeValidator);

const pelletRefTxHash: { txHash: string } = JSON.parse(
await Deno.readTextFile("./script-refs/pellet-ref.json")
);
const pelletRef = await fetchReferenceScript(lucid, pelletRefTxHash.txHash);
const pelletValidator = pelletRef.scriptRef as Script;
const fuelPolicyId = lucid.utils.mintingPolicyToId(pelletValidator);
const fuelTokenUnit = toUnit(fuelPolicyId, fromText("FUEL"));

const asteriaRefTxHash: { txHash: string } = JSON.parse(
await Deno.readTextFile("./script-refs/asteria-ref.json")
Expand All @@ -44,8 +54,6 @@ async function mineAsteria(
const asteriaValidator = asteriaRef.scriptRef as Script;
const asteriaAddressBech32 = lucid.utils.validatorToAddress(asteriaValidator);

const shipyardPolicyId = lucid.utils.mintingPolicyToId(spacetimeValidator);

const ship: UTxO = (
await lucid.utxosByOutRef([
{
Expand All @@ -61,6 +69,7 @@ async function mineAsteria(
ship.datum as string,
ShipDatum as unknown as ShipDatumT
);
const shipFuel = ship.assets[fuelTokenUnit];

const asterias: UTxO[] = await lucid.utxosAt(asteriaAddressBech32);
if (asterias.length != 1) {
Expand Down Expand Up @@ -91,6 +100,7 @@ async function mineAsteria(
);

const adminTokenUnit = toUnit(admin_token.policy, admin_token.name);

const shipTokenUnit = toUnit(
shipyardPolicyId,
shipInputDatum.ship_token_name
Expand All @@ -102,19 +112,26 @@ async function mineAsteria(

const shipRedeemer = Data.to(new Constr(1, [new Constr(2, [])]));
const asteriaRedeemer = Data.to(new Constr(1, []));
const burnRedeemer = Data.to(new Constr(1, []));
const burnShipRedeemer = Data.to(new Constr(1, []));
const burnFuelRedeemer = Data.to(new Constr(1, []));
const tx = await lucid
.newTx()
.validFrom(Number(tx_earliest_posix_time))
.mintAssets(
{
[shipTokenUnit]: BigInt(-1),
},
burnRedeemer
burnShipRedeemer
)
.mintAssets(
{
[fuelTokenUnit]: -shipFuel,
},
burnFuelRedeemer
)
.collectFrom([ship], shipRedeemer)
.collectFrom([asteria], asteriaRedeemer)
.readFrom([spacetimeRef, asteriaRef])
.readFrom([spacetimeRef, asteriaRef, pelletRef])
.payToContract(
asteriaAddressBech32,
{ inline: asteriaOutputDatum },
Expand Down
Loading

0 comments on commit 07d712f

Please sign in to comment.