Who is calling: abi.caller and ownership

Without knowing the caller, every function is public to everyone. This is how access control works.

abi.caller() returns the address that invoked this call, as bytes. It is how a contract tells its owner from a stranger.

from stdlib import abi, storage

K_OWNER = b"demo:owner"

def init(owner: bytes) -> None:
    storage.set(K_OWNER, bytes(owner))

def _only_owner() -> None:
    abi.require(abi.caller() == storage.get(K_OWNER, b""), b"not_owner")

The context also gives you:

callwhat it is
abi.caller()who called *this* contract (may be another contract)
abi.tx_origin()the account that signed the transaction
abi.self_address()this contract's own address
abi.block_height()the height this call is executing at
abi.block_timestamp()the block's timestamp
abi.chain_id()1 on Animica mainnet

Use caller(), not tx_origin(), for authorisation. If contract B calls your contract, caller() is B while tx_origin() is still the human who started the chain of calls. Authorising on tx_origin means any contract a user touches can act as that user — the classic phishing hole. tx_origin is for telemetry, not permissions.

Your turn

Build an owned counter. init(owner) records the owner. bump() may only be called by the owner and increments; anyone else gets b"not_owner". owner() returns the stored owner.

Hints

Stuck? Ask

Answered by Animica's own free inference network. It is donated GPU capacity, so give it 20-30 seconds.