DIP-20 transfer msg.caller

This is the transfer function for dip20 tokens standard

  public shared(msg) func transfer(to: Principal, value: Nat) : async TxReceipt {
        if (_balanceOf(msg.caller) < value + fee) { return #Err(#InsufficientBalance); };
        _chargeFee(msg.caller, fee);
        _transfer(msg.caller, to, value);
        ignore addRecord(
            msg.caller, "transfer",
                ("to", #Principal(to)),
                ("value", #U64(u64(value))),
                ("fee", #U64(u64(fee)))
        txcounter += 1;
        return #Ok(txcounter - 1);
  • When a canister call this function what will be the msg.caller?
  • Is it user Principal id or canister Principal id?

From the spec:

  • ic0.msg_caller_size : () → i32 and ic0.msg_caller_copy : (dst : i32, offset: i32, size : i32) → ()
    The identity of the caller, which may be a canister id or a user id. During canister installation or upgrade, this is the id of the user or canister requesting the installation or upgrade. During a system task (heartbeat or global timer), this is the id of the management canister.

So if user U calls canister A which then in turn calls your dip20 token canister B then msg.caller will be A. There is no way for the token canister to figure out the identity of U (or if there even is a user U behind the call).

1 Like

It will be the cnaister Id of the caller canister.
So imagine you have a canister and you’re calling the transfer func of a dip20 ledger from your canister, then in that case msg.caller will be your principal id of your canister(Canister ID)