How canister get the `message.caller`?

I’m learning the account model of canister.
I run whoami example,and read Principals and caller identification.

My question is how canister get the message.caller when I run dfx canister call whoami whoami. In other blockchain system, the message.caller is getted by the signature. For different callers have different signature, the blockchain system can get the different caller.

Is there any other information about this?

1 Like

There’s a brief overview of it here, along with another example of its usage: Add access control with identities :: Internet Computer


I init the actor with the initializer

shared({ caller = initializer }) actor class TestCaller() {
    private stable let owner_ : Principal = initializer;

    public query func owner() : async Principal {
    	return owner_;
    public shared({ caller }) func callerPrincipal() : async Principal {
        return caller;

In dfx v0.6.23, the owner_ will be the my default account’s Principal.

and I upgrade dfx to v0.6.24 today, and in dfx v0.6.24, the owner_ will be the wallet canister’s id, for detail: 0.6.24 release note.

This is the demo:

$ dfx canister  create testcaller
Creating canister "testcaller"...
Creating the canister using the wallet canister...
Creating a wallet canister on the local network.
The wallet canister on the "local" network for user "default" is "rwlgt-iiaaa-aaaaa-aaaaa-cai"
"testcaller" canister created with canister id: "rrkah-fqaaa-aaaaa-aaaaq-cai"

$ dfx canister call testcaller owner
(principal "rwlgt-iiaaa-aaaaa-aaaaa-cai")

$ dfx canister call testcaller callerPrincipal
(principal "l73xb-uaoom-uk6vy-yjmwy-ffdjj-tfbbn-wlsve-xxy7i-5d27t-6yh3t-fqe")

So how to get the default account’s Principal when init the constructor, except input as a argument?

1 Like

You can get the owner by passing it as an installation argument. I’ve updated the whoami example to reflect this. You probably want something like this:

actor class TestCaller(arg : Principal) {
    public query func owner() : async Principal {
    	return arg;

and then install with

dfx canister install --argument='(principal "...")'

Yes, passing it as an installation argument can solve it.