Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

bug: get_caller_address() returns 0x0 when called inside an external view function #6959

Open
elton-cs opened this issue Dec 30, 2024 · 3 comments
Labels
bug Something isn't working

Comments

@elton-cs
Copy link

Bug Report

Cairo version:

v2.8.4

Current behavior:

Calling get_caller_address() within an external view function returns the 0x0 contract address. This was discovered when using starket.js within a svelte application and additionally reproduced in both sozo call and starkli call within dojo contracts and cairo contracts respectively.

Oddly enough, calling the same view function from within another external write function (aka a function that takes ContractState by reference and can modify state) does not have this issue and retrieves the correct contract address for use within the function (example provided below).

Expected behavior:

Calling get_caller_address() should return the caller's contract address (which should never be 0x0)

Steps to reproduce:

  • create new cairo project: scarb new <some_project>
  • create an external view function that takes as input @ContractState and returns ContractAddress.
  • body of function only calls and returns get_caller_address()
  • declare, deploy, and call function

Related code:

use starknet::ContractAddress;

#[starknet::interface]
trait ISimpleContract<T> {
    fn view_caller_address(self: @T) -> ContractAddress;
    fn get_stored_address(self: @T) -> ContractAddress;
    fn set_caller_address_from_view_function(ref self: T);
}

#[starknet::contract]
mod simple_contract {
    use super::ISimpleContract;
    use starknet::{ContractAddress, get_caller_address};
    use core::starknet::storage::{StoragePointerReadAccess, StoragePointerWriteAccess};

    #[storage]
    struct Storage {
        caller_address: ContractAddress,
    }

    #[abi(embed_v0)]
    impl ISimpleContractImpl of ISimpleContract<ContractState> {
        fn view_caller_address(self: @ContractState) -> ContractAddress {
            get_caller_address()
        }

        fn set_caller_address_from_view_function(ref self: ContractState) {
            self.caller_address.write(self.view_caller_address());
        }

        fn get_stored_address(self: @ContractState) -> ContractAddress {
            self.caller_address.read()
        }
    }
}

Other information:

In the code snippet above,

  • view_caller_function() incorrectly returns the 0x0 contract address when called inside a call transaction, whether it be from starknet.js, sozo, or starkli inside either a dojo or vanilla cairo contract.
  • set_caller_address_from_view_function does not have this problem when called inside an invoke transaction, as it correctly reads the user's contract address and modifies the caller_address field in the contract's storage, even though it also calls view_caller_function() within itself.
@elton-cs elton-cs added the bug Something isn't working label Dec 30, 2024
@elton-cs
Copy link
Author

elton-cs commented Dec 30, 2024

I should note I'm using cairo v2.8.4 because that's the current supported cairo version by dojo at the time of writing, maybe this is fixed in newer releases but I didn't get a chance to check and didn't see any issues reported prior so I'm assuming it may still be a bug.

I suspect it may have something to do with snapshots and how they interact with get_caller_address(), specifically in the context of performing a call transaction... looking very edge casey haha.

@elton-cs elton-cs changed the title bug: get_caller_address() returns 0x0 when called inside an external view function bug: get_caller_address() returns 0x0 when called inside an external view function Dec 30, 2024
@enitrat
Copy link
Contributor

enitrat commented Dec 30, 2024

view_caller_function() incorrectly returns the 0x0 contract address when called inside a call transaction, whether it be from starknet.js, sozo, or starkli inside either a dojo or vanilla cairo contract.

There's no such thing as a "call transaction" - either it's a transaction (or invoke transaction) or an RPC call.

If you're talking about an RPC call, the result is expected to be 0. The RPC call is not made from an address. I think in EVM worlds the RPC lets you set who the msg.sender is when doing an eth_call but this option does not exist on Starknet

@elton-cs
Copy link
Author

There's no such thing as a "call transaction" - either it's a transaction (or invoke transaction) or an RPC call.

Makes sense, thanks for the clarification!

If you're talking about an RPC call, the result is expected to be 0. The RPC call is not made from an address. I think in EVM worlds the RPC lets you set who the msg.sender is when doing an eth_call but this option does not exist on Starknet

In this case, my only concern/confusion would be if there's anything else that's not set in the sequencer when doing such calls, as opposed to transactions? Because it just seems inconsistent that the same function will work correctly when invoked within a contract, but not when done from outside (with a call). Also, if I understand correctly, invoke transactions cannot return values when called externally?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants