NEWTON
Asked
5 months ago
108
views
0
Are you able to nest mappings in Cairo like you can in Solidity?
e.g. in Solidity you can do
mapping(address => mapping(uint256 => bool));
is this doable in Cairo? I want to do something similar to
func mappingA(value: felt) -> func mappingB(value: felt) -> (value: felt){ }
mapping(x, y) -> (z) is not gonna work, here is some context:
I'm working through the sample ERC721_Metadata.cairo and ERC721_Metadata_Base contract shown here https://github.com/starknet-edu/starknet-erc721/tree/main/contracts/token/ERC721
It looks like from what I can tell the tokenUri is set for each domain, and even though calling the @view function does take in a tokenId, calling to set the tokenUri does not and it's not clear to me how that mapping could exist otherwise. So I wanted to modify the contract to have a token_id -> token_uri mapping. Because of the way those mappings exist though, you need to provide both the token_uri_len: felt and token_uri: felt* when writing them. This means it can only be done once, otherwise you'd need a specific @storage_var for every token that's minted, just to hold it's tokenuri. I was hoping to do something like
// Represents a tokenUri struct TokenUri { // The length of the token bytes token_uri_len: felt, // The pointer to the beginning of the token uri bytes token_uri: felt*, } @storage_var func token_uris(token_id: felt) -> (token_uri: TokenUri) { }
But because of the token_url: felt* pointer in that struct, it can't be used as a storage variable return type. It gives an error when I try to compile showing
starknet_contracts/ERC721_Metadata.cairo:29:36: The return type of storage variables must be a felts-only type (cannot contain pointers). func token_uris(token_id: felt) -> (token_uri: TokenUri) {
This question was originally posted on StarkNet Discord
Newton
asked
5 months ago
0
Accepted answer
Ugh yeah, it looks like the way this is done there has to be two storage variables per token. One holds the length of the token_uri, and the other holds the index -> value mapping for each byte of the token uri
@storage_var func ERC721_base_token_uri(index: felt) -> (res: felt) { } @storage var func ERC721_base_token uri len() -> (res: felt) { }
func ERC721_Metadata_setBaseTokenURIf { syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range check ptr }(token uri _len: felt, token uri: felt*, token uri suffix: felt) { _ERC721 Metadata_setBaseTokenURI (token_uri_len, token uri); ERC721_base_token_uri_len.write(token_uri_len); return (); } func _ERC721_Metadata_setBaseTokenURI{ syscall _ptr: felt*, pedersen ptr: HashBuiltin*, range check ptr }(token uri len: felt, token uri: felt*) { if (token_uri_len == 0) { return (); } ERC721_base_token_uri.write(index=token uri len, value=[token uril); ERC721 Metadata setBaseTokenURI(token_uri_len=token_uri_len- 1, token_uri=token_uri + 1); return (); }
This answer was originally posted on StarkNet Discord
Newton
answered
5 months ago
storage for array
How to use get_fp_and_pc in Cairo Lang?
How to submit a StarkNet contract?
Cairo Lang / StarkNet: What are Revoked references? What is alloc_locals?
What is SHARP in Cairo Language?
A switch statement in Cairo lang to set two distinct values
a pointer with a hint, without doing a memory allocation
How to use Access Control in Cairo language securely?
Hey, is there anyway to debug Cairo contracts in hardhat environment? Something like hardhat console in solidity
Searching for Cairo Questions
Cairo: How can i approve erc20 and transfer in the same transaction?
Cairo/Nile: Testing the proxy upgrade feature, but my tests fail with the error message TypeError: int() can't convert non-string with explicit base.
ApeWorX: How do I fund newly created accounts from the ape console?
Does Kakarot zkEVM have a token?