📢 Beta: Test thoroughly in development. Feedback appreciated!
Learn to build a DeFi-style token in DAL: services, maps, and chain integration.
Time: 30 minutes
Difficulty: Beginner
Prerequisites: Basic programming knowledge
A token service that:
@trust, @chain,
fn, let, literalsmkdir defi-token && cd defi-token
touch DefiToken.dalDAL uses services (not contract). Use
@trust for the service trust model; add @chain
when the service interacts with a blockchain.
// DefiToken.dal
@trust("hybrid")
@chain("ethereum")
service DefiToken {
name: string = "DeFi Token";
symbol: string = "DFT";
total_supply: int = 0;
balances: map<string, int> = {};
current_price: int = 0;
}
Use fn,
if (condition) (parentheses required), and
semicolons after statements.
@trust("hybrid")
@chain("ethereum")
service DefiToken {
name: string = "DeFi Token";
symbol: string = "DFT";
total_supply: int = 0;
balances: map<string, int> = {};
current_price: int = 0;
fn balance_of(account: string) -> int {
if (self.balances.contains_key(account)) {
return self.balances[account];
}
return 0;
}
fn transfer(to: string, amount: int) -> bool {
let from = auth::session("user", ["holder"]).user_id;
if (self.balances[from] < amount) {
log::info("token", "Insufficient balance");
return false;
}
self.balances[from] = self.balances[from] - amount;
self.balances[to] = self.balances[to] + amount;
log::info("token", "Transfer done");
return true;
}
fn initialize(owner: string, initial_supply: int) {
self.balances[owner] = initial_supply;
self.total_supply = initial_supply;
log::info("token", "Token initialized");
}
}
Use oracle::fetch (or similar stdlib)
and literals for data. Literals use
key: value with a colon.
fn update_price() {
let price_response = oracle::fetch("DFT/USD", { source: "chainlink" });
self.current_price = price_response;
log::info("token", "Price updated");
}
fn get_price() -> int {
return self.current_price;
}
Use if (condition) and
return with semicolons.
fn mint(to: string, amount: int) {
self.total_supply = self.total_supply + amount;
self.balances[to] = self.balances[to] + amount;
log::info("token", "Minted");
}
fn burn(amount: int) -> bool {
let from = auth::session("user", ["holder"]).user_id;
if (self.balances[from] < amount) {
log::info("token", "Insufficient balance to burn");
return false;
}
self.total_supply = self.total_supply - amount;
self.balances[from] = self.balances[from] - amount;
log::info("token", "Burned");
return true;
}
if (condition) { }.{ key: value }.let,
return, and expression statements.log::info("tag", message)
or log::audit("tag", message) (no log::error
in current engine).# Parse/compile (project-specific)
cargo run -- DefiToken.dal
# Run tests if you have a test runner
cargo testDeployment is environment-specific. Use your chain tooling; the
service can be instantiated with
DefiToken::new() or
service::new("DefiToken") in DAL.
You used:
@trust("hybrid") and
@chain("ethereum") on a servicebalances: map<string, int> = {}fn with parameters and
-> return_typeif (condition) with parentheseslog::info("tag", message){ key: value } for data