Hello!
I am creating a test simple DEX with reference to the defi in the dfinity example, but while reading the code, I had a question on the following part.
[type.mo]
module {
public type Token = Principal;
public type DIPInterface = actor {
transfer : (Principal,Nat) -> async TxReceipt;
transferFrom : (Principal,Principal,Nat) -> async TxReceipt;
allowance : (owner: Principal, spender: Principal) -> async Nat;
getMetadata: () -> async Metadata;
};
};
[main.mo]
import T "types";
actor class Dex() = this {
public shared(msg) func deposit(token: T.Token): async T.DepositReceipt {
Debug.print("Depositing Token: " # Principal.toText(token) # " LEDGER: " # Principal.toText(ledger));
if (token == ledger) {
await depositIcp(msg.caller)
} else {
await depositDip(msg.caller, token)
}
};
// After user approves tokens to the DEX
private func depositDip(caller: Principal, token: T.Token): async T.DepositReceipt {
// cast token to actor
let dip20 = actor (Principal.toText(token)) : T.DIPInterface;
// get DIP fee
let dip_fee = await fetch_dip_fee(token);
// Check DIP20 allowance for DEX
let balance : Nat = (await dip20.allowance(caller, Principal.fromActor(this)));
// Transfer to account.
let token_reciept = if (balance > dip_fee) {
await dip20.transferFrom(caller, Principal.fromActor(this),balance - dip_fee);
} else {
return #Err(#BalanceLow);
};
switch token_reciept {
case (#Err e) {
return #Err(#TransferFailure);
};
case _ {};
};
let available = balance - dip_fee;
// add transferred amount to user balance
book.addTokens(caller,token,available);
// Return result
#Ok(available)
};
};
The example deploys two original tokens using the DIP20 token standard.
I understand that I have two original tokens and I want to define an interface to call the token canister’s method, but why can I just specify the principal and it will be cast to the appropriate token actor?
I would like to know what is actually happening on in the casting (or rather creation of the entity?)
[motoko.mo : depositDip()]
// cast token to actor
let dip20 = actor (Principal.toText(token)) : T.DIPInterface;
Does the program call the appropriate token canister actor by reference to the interface and canister ID (principal) defined in Candid?
Thank you in advance for your response.