Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions dynamic_records/gold_token/.env
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
NETWORK=testnet
PRIVATE_KEY=APrivateKey1zkp8CZNn3yeCseEtxuVPbDCwSyhGW6yZKUYKfgXmcpoGPWH
ENDPOINT=http://localhost:3030
180 changes: 180 additions & 0 deletions dynamic_records/gold_token/build/abi.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,180 @@
{
"program": "gold_token.aleo",
"structs": [],
"records": [
{
"path": [
"Token"
],
"fields": [
{
"name": "owner",
"ty": {
"Primitive": "Address"
},
"mode": "None"
},
{
"name": "amount",
"ty": {
"Primitive": {
"UInt": "U64"
}
},
"mode": "None"
},
{
"name": "purity",
"ty": {
"Primitive": {
"UInt": "U64"
}
},
"mode": "None"
}
]
}
],
"mappings": [],
"storage_variables": [],
"functions": [
{
"name": "mint",
"is_final": false,
"inputs": [
{
"name": "owner",
"ty": {
"Plaintext": {
"Primitive": "Address"
}
},
"mode": "None"
},
{
"name": "amount",
"ty": {
"Plaintext": {
"Primitive": {
"UInt": "U64"
}
}
},
"mode": "None"
}
],
"outputs": [
{
"ty": {
"Record": {
"path": [
"Token"
],
"program": "gold_token.aleo"
}
},
"mode": "None"
}
]
},
{
"name": "mint_custom",
"is_final": false,
"inputs": [
{
"name": "owner",
"ty": {
"Plaintext": {
"Primitive": "Address"
}
},
"mode": "None"
},
{
"name": "amount",
"ty": {
"Plaintext": {
"Primitive": {
"UInt": "U64"
}
}
},
"mode": "None"
},
{
"name": "purity",
"ty": {
"Plaintext": {
"Primitive": {
"UInt": "U64"
}
}
},
"mode": "None"
}
],
"outputs": [
{
"ty": {
"Record": {
"path": [
"Token"
],
"program": "gold_token.aleo"
}
},
"mode": "None"
}
]
},
{
"name": "transfer",
"is_final": false,
"inputs": [
{
"name": "token",
"ty": "DynamicRecord",
"mode": "None"
},
{
"name": "to",
"ty": {
"Plaintext": {
"Primitive": "Address"
}
},
"mode": "None"
}
],
"outputs": [
{
"ty": "DynamicRecord",
"mode": "None"
}
]
},
{
"name": "balance_of",
"is_final": false,
"inputs": [
{
"name": "token",
"ty": "DynamicRecord",
"mode": "None"
}
],
"outputs": [
{
"ty": {
"Plaintext": {
"Primitive": {
"UInt": "U64"
}
}
},
"mode": "None"
}
]
}
]
}
40 changes: 40 additions & 0 deletions dynamic_records/gold_token/build/main.aleo
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
program gold_token.aleo;

record Token:
owner as address.private;
amount as u64.private;
purity as u64.private;

function mint:
input r0 as address.private;
input r1 as u64.private;
cast r0 r1 24u64 into r2 as Token.record;
output r2 as Token.record;

function mint_custom:
input r0 as address.private;
input r1 as u64.private;
input r2 as u64.private;
gte r2 1u64 into r3;
lte r2 24u64 into r4;
and r3 r4 into r5;
assert.eq r5 true;
cast r0 r1 r2 into r6 as Token.record;
output r6 as Token.record;

function transfer:
input r0 as dynamic.record;
input r1 as address.private;
get.record.dynamic r0.amount into r2 as u64;
get.record.dynamic r0.purity into r3 as u64;
cast r1 r2 r3 into r4 as Token.record;
cast r4 into r5 as dynamic.record;
output r5 as dynamic.record;

function balance_of:
input r0 as dynamic.record;
get.record.dynamic r0.amount into r1 as u64;
output r1 as u64.private;

constructor:
assert.eq edition 0u16;
9 changes: 9 additions & 0 deletions dynamic_records/gold_token/build/program.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"program": "gold_token.aleo",
"version": "0.1.0",
"description": "",
"license": "",
"leo": "3.5.0",
"dependencies": null,
"dev_dependencies": null
}
6 changes: 6 additions & 0 deletions dynamic_records/gold_token/program.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"program": "gold_token.aleo",
"version": "0.1.0",
"description": "Gold token implementing the TokenStandard interface. Carries a purity field beyond the interface minimum.",
"license": "MIT"
}
61 changes: 61 additions & 0 deletions dynamic_records/gold_token/src/main.leo
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
// gold_token.aleo — private gold token implementing the TokenStandard interface.
//
// The Token record carries an extra `purity` field (karat value, 1–24) beyond
// the minimum fields required by TokenStandard. When gold_token.aleo is
// called via dynamic dispatch, the caller receives the token as `dyn record`
// and never needs to know about `purity` at compile time.
interface TokenStandard {
record Token {
owner: address,
amount: u64,
.. // implementors may add extra fields beyond these
}
fn mint(owner: address, amount: u64) -> Token;
fn transfer(token: dyn record, to: address) -> dyn record;
fn balance_of(token: dyn record) -> u64;
}

program gold_token.aleo : TokenStandard {
// Token carries purity (karat value) alongside the standard fields.
// This extra field is invisible to the router at compile time but remains
// accessible via `dyn record` field access inside this program.
record Token {
owner: address,
amount: u64, // milligrams
purity: u64, // karat value: 1 (lowest) to 24 (pure gold)
}

// Creates a Token at maximum purity (24-karat).
// This satisfies the interface's `mint` requirement with a sensible default.
fn mint(owner: address, amount: u64) -> Token {
return Token { owner, amount, purity: 24u64 };
}

// Creates a Token with a custom purity level.
// This is a program-specific function — not required by the interface.
fn mint_custom(owner: address, amount: u64, purity: u64) -> Token {
assert(purity >= 1u64 && purity <= 24u64);
return Token { owner, amount, purity };
}

// Transfers the token to a new owner.
//
// `token` arrives as `dyn record` because dynamic calls always erase the
// concrete type. We read the fields we care about — including the
// program-specific `purity` field — rebuild the record under the new
// owner, then cast back to `dyn record` for the return value.
fn transfer(token: dyn record, to: address) -> dyn record {
let amount: u64 = token.amount;
let purity: u64 = token.purity; // dyn record field access — fails at runtime if missing
let new_token: Token = Token { owner: to, amount, purity };
return new_token as dyn record; // explicit cast: static record → dyn record
}

// Returns the token's amount without needing to know its full structure.
fn balance_of(token: dyn record) -> u64 {
return token.amount;
}

@noupgrade
constructor() {}
}
Loading