NEWTON
Asked
10 months ago
117
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
10 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
10 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
Can you explain Cairo v0.10 usage functions as expressions?
StarknetPy Error in get_balance_sync (StarknetErrorCode.ENTRY_POINT_NOT_FOUND_IN_CONTRACT)
How do I connect my wallet to my Pathfinder node?
ApeWorX: Why do I need to fund a Starknet account before deploying it?
Error when deploying Cairo: [WARNING] alpha-goerli is a legacy network name parameter and it won't be supported in future versions
How to install Nethermind's Solidity to Cairo transpiler without an error "command not found: warp"?
Are transpiled contracts only interactable with the warp cli?