-
Notifications
You must be signed in to change notification settings - Fork 764
🐺 Cairo wishlist 🦀 #1714
-
Hey Cairo builders 🐺, let's discuss about what you would like to see for Cairo.
It can be:
- new features in Cairo
- quality of life improvements
Ultimately we would need to create issues for feature requests, but for the moment we don't have a clear process on how to handle external demands. So let's discuss those here and we will try to review / filter the requests and see if we can integrate some of them in the roadmap.
We appreciate your feedback and we will try to do our best to fit your needs!
Abdel__StarkWare_a_wolf_wearing_Santa_Clauss_hat_in_Santas_slei_311ca34c-dc44-4a47-8ba1-076cf2a4feab
Beta Was this translation helpful? Give feedback.
All reactions
-
❤️ 12
Replies: 57 comments 66 replies
-
Add is_some and is_none to Option type.
Description
The is_some and is_none methods return true if the Option is Some or None, respectively.
See https://doc.rust-lang.org/std/option/#querying-the-variant for the description of those functions.
Proposition
Proposed signature for is_some():
fn is_some() -> bool
Proposed signature for is_none():
fn is_none() -> bool
Beta Was this translation helpful? Give feedback.
All reactions
-
these are now supported - you currently need to add use option::OptionTrait; and use option::OptionTraitImpl;
similarly for Result.
Beta Was this translation helpful? Give feedback.
All reactions
-
Less verbose/cheaper struct storage updates
Description
To read single attribute full struct needs to be read into memory, to update single struct attribute full struct needs to be rewritten. It is both more verbose than necessary and probably (depending on implementation) inefficient. More in depth problem description is here: https://hackmd.io/@RoboTeddy/BJZFu56wF#Concisely-update-large-structs.
Beta Was this translation helpful? Give feedback.
All reactions
-
+1, compiler level struct packing would be great too
Beta Was this translation helpful? Give feedback.
All reactions
-
This would be so sweet!
Beta Was this translation helpful? Give feedback.
All reactions
-
Automaticaly generate trivial view functions for storage variables
Description
Trivial storage related view functions take a lot of space and make contracts diffucult to read and understand. It should be possible to mark storage variables as public (similar to Solidity public modifier). As a result a view function should be generated.
Proposition
Instead of:
struct Storage {
value: felt,
}
#[view]
fn value() -> felt {
value::read()
}
use public 'modifier':
struct Storage {
#[public]
value: felt,
}
Beta Was this translation helpful? Give feedback.
All reactions
-
bytes32 equivalent
Description
When working on cross chain apps, Cairo short strings are very inconvenient. Felt based short strings and their solidity counterpart bytes32 are of diffrent lenght(251 vs 256) and of different encoding (left vs right padding). There is no easy conversion between the two.
Proposition
There should be a bytes32 equivalent type available in Cairo. The usual operations: comparison, bit operators, shift operators, index access should be available.
See: https://docs.soliditylang.org/en/v0.8.17/types.html#fixed-size-byte-arrays
Beta Was this translation helpful? Give feedback.
All reactions
-
I would love to have /* */ multi-line commenting as I often need to add large blocks of text to contextualize the code I write.
Beta Was this translation helpful? Give feedback.
All reactions
-
❤️ 3
-
Support structs as l1_handler parameters
Description
Currently when, for example Uint256 is send from l1 to l2 it needs to be manually converted to the desired type:
@l1_handler
func handle_deposit{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr}(
from_address: felt,
amount_low: felt,
amount_high: felt,
sender_address: felt,
) {
let amount = Uint256(low=amount_low, high=amount_high);
When there are more than one struct the code gets noisy.
Proposition
When structs are supported as l1_handler parameters, above would be more readble:
@l1_handler
func handle_deposit{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr}(
from_address: felt,
amount: Uint256,
sender_address: felt,
) {
Beta Was this translation helpful? Give feedback.
All reactions
-
❤️ 2
-
It would be nice if we can have a float type. I know it's not as easy as people think to create but it would help a lot programmers 🚀
Beta Was this translation helpful? Give feedback.
All reactions
-
Do you mean an IEEE-754 float type, or do you mean a fixed point decimal type?
If its the first then I think it should be a library rather than a language built-in.
Beta Was this translation helpful? Give feedback.
All reactions
-
It's functionality can be improve
Beta Was this translation helpful? Give feedback.
All reactions
-
It would be awesome to have a cairo plugin for Intellij.
Beta Was this translation helpful? Give feedback.
All reactions
-
@software-mansion team plans to work on this 😃
Beta Was this translation helpful? Give feedback.
All reactions
-
StarkNet Cairo should allow function overloading. To make this possible, we will need to modify the function selector calculation to include the input types and the function name.
This change will affect type-checking and remote contract calls from the language perspective. However, resolving these is easy because we can statically determine which instance of the function is being used.
Since we can statically resolve function overloading, it doesn't introduce any performance overhead.
Beta Was this translation helpful? Give feedback.
All reactions
-
Adding an is_empty() fn on Array Trait could be very handy
(I know I could do arr.len() == 0_usize, but isn't arr.is_empty() way more readable?)
Beta Was this translation helpful? Give feedback.
All reactions
-
❤️ 1
-
added it to the trait now - available at main or at next release :)
Beta Was this translation helpful? Give feedback.
All reactions
-
❤️ 2
-
add address type
Description
Currently felt type is used to represent contract addreses, e.g.:
fn transfer_from(sender: felt, recipient: felt, amount: u256)
Proposition
There should be an address type to represent contract addresses:
fn transfer_from(sender: address, recipient: address, amount: u256)
Beta Was this translation helpful? Give feedback.
All reactions
-
will this also be reflected in the ABI?
Beta Was this translation helpful? Give feedback.
All reactions
-
Does that mean this type can only be used on contract addresses? I mean the ContractAddress type?
Beta Was this translation helpful? Give feedback.
All reactions
-
-
if the address is the type of the inputs - it'd be reflected in the ABI, of course a different abi can decide different strategies.
-
you'd be able to construct it from
felts i guess - but its meaning is a contract-address.
Beta Was this translation helpful? Give feedback.
All reactions
-
we already have such a type
ContractAddress- will change ERC20 impl to use it. would also consider adding an aliastype address = ContractAddress;
address would be more in line with felt, u256. On the other hand, having to many conventions (CamelCase, short types?) is not sth we want.
Beta Was this translation helpful? Give feedback.
All reactions
-
The alias type address = ContractAddress is very handy, I'm for including it in the lang.
Beta Was this translation helpful? Give feedback.
All reactions
-
👍 2
-
Optimize usage of storage
Let's assume I have a struct:
struct { some_field1: u8, some_field2: u32, some_field3: u64 }
It should underneath be all contained in one felt rather than 3 separate felts to use the less possible storage on L1.
Beta Was this translation helpful? Give feedback.
All reactions
-
I think this should be opt-in behaviour, like Rust's #[repr(...)], because as far as I remember, this involves doing extra operations while reading/writing compressed fields?
Beta Was this translation helpful? Give feedback.
All reactions
-
I think it does indeed (lot of masks and bitwise operations), so depending on how optimized the costs for those is, it may or may not be more gas efficient...
Beta Was this translation helpful? Give feedback.
All reactions
-
IMO if when creating a struct, you can somehow specify the masks that need to be used to only perform the bitwise related operation it can already help.
But then it creates some burdens on the developper as he can make a mistake and not define a correct mask.
Beta Was this translation helpful? Give feedback.
All reactions
-
That brings unsafety issues. I think this should be entirely automated and hidden from the programmer, so that a) we will have space to investigate various optimization patterns throughout time because there won't be any internal stability guarantees, and b) users won't be able to mess up things.
I think following would do the job:
#[repr(packed)] struct Foo { some_field1: u8, some_field2: u32, some_field3: u64 }
or perhaps introduce versioning, because people will store this on the chain so there must be a possibility for backward and perhaps forward compatibility:
#[repr(packed, version = 1)] struct Foo { some_field1: u8, some_field2: u32, some_field3: u64 }
Beta Was this translation helpful? Give feedback.
All reactions
-
👍 3
-
This is handled by the StorageAccess trait, which will allow packing to be finely controlled. For example, here is how we store a custom struct in Dojo:
It could be extended to handle packing / unpacking and we can introduce procmacros to generate the logic
impl StorageAccessPosition of starknet::StorageAccess::<Position> {
fn read(
address_domain: felt, base: starknet::StorageBaseAddress
) -> starknet::SyscallResult::<Position> {
Result::Ok(
Position {
x: starknet::storage_read_syscall(
address_domain, starknet::storage_address_from_base_and_offset(base, 0_u8)
)?,
y: starknet::storage_read_syscall(
address_domain, starknet::storage_address_from_base_and_offset(base, 1_u8)
)?,
}
)
}
fn write(
address_domain: felt, base: starknet::StorageBaseAddress, value: Position
) -> starknet::SyscallResult::<()> {
starknet::storage_write_syscall(
address_domain, starknet::storage_address_from_base_and_offset(base, 0_u8), value.x
)?;
starknet::storage_write_syscall(
address_domain, starknet::storage_address_from_base_and_offset(base, 1_u8), value.y
)
}
}
Beta Was this translation helpful? Give feedback.
All reactions
-
❤️ 5
-
What do you think about providing access the contract context inside of starknets StorageAccess trait? I'm not sure exactly how that would look. Perhaps it is easier once we have the new contract syntax.
It would allow us to add access control directly at the storage level, which seems much more robust and less error prone.
One approach could be a Ownable<T> struct that wraps values but that would duplicate the owner state for each variable.
Beta Was this translation helpful? Give feedback.
All reactions
-
I think Ownable is a wonderful idea, and with some clever type engineering we can avoid the extra state.
Let me try,:
struct AdminToken{} fn getAdminToken()->Option<AdminToken>{...} #[storage] struct MyContract{ sensitive: LockedWith<felt, AdminToken> } fn get_sensitive(self: MyContract) -> Option<felt> { Some(self.sensitive.read().unlock(getAdminToken()?)) }
Beta Was this translation helpful? Give feedback.
All reactions
-
❤️ 2
-
Support for get_blockhash
Beta Was this translation helpful? Give feedback.
All reactions
-
This and / or a get_random potentially associated with the need for leader election randomness would be wonderful and a huge boost to games.
Beta Was this translation helpful? Give feedback.
All reactions
-
👍 1
-
Arrays can be defined in the constant pool and support initialization data.
Description
We are using Cairo to rewrite a Solidity ERC721 contract. This contract defines five arrays, each containing 30 to 60 different short strings. In the contract functions, a random string from each array is selected and concatenated to form a complete name. In Cairo, we cannot define and initialize arrays directly in the contract. Currently, we are manually writing indexes using LegacyMap to achieve this.
21693301815_ pic
31693301850_ pic
41693301884_ pic
Proposition
We want to directly define string array data in the contract.
Beta Was this translation helpful? Give feedback.
All reactions
-
I want a map-like data structure (Array or Dict) that supports multiple levels of nesting, random write and can be used in memory, without relying on LegacyMap structures in storage.
Beta Was this translation helpful? Give feedback.
All reactions
-
map-like data structure (Array or Dict)
So an array or a dict?
Do you want to manipulate data only in memory or should it support contract storage?
Beta Was this translation helpful? Give feedback.
All reactions
-
Beta Was this translation helpful? Give feedback.
All reactions
-
I want '<<' and '>>' Operators. They provide left shift and right shift features with less gas cost.
Beta Was this translation helpful? Give feedback.
All reactions
-
In solidity contract, we can user block.number to get current block number, but i do not know how to get block number in cairo contract.
Beta Was this translation helpful? Give feedback.
All reactions
-
You can use starknet::info::get_block_number() (see corelib).
Beta Was this translation helpful? Give feedback.
All reactions
-
👍 1
-
I know i can use get_caller_address() to get like msg.sender. but how can i get msg.value in cairo?
Beta Was this translation helpful? Give feedback.
All reactions
-
And in solidity, type(unit).max if i am not wrong that can get the max number for this type. Are there some function like that in cairo?
Beta Was this translation helpful? Give feedback.
All reactions
-
There is no msg.value in Starknet. All value transfers are ERC20 transfers.
Beta Was this translation helpful? Give feedback.
All reactions
-
👍 1
-
ok
Beta Was this translation helpful? Give feedback.
All reactions
-
how can i remove a element in Array by index? I can not find this method.
Beta Was this translation helpful? Give feedback.
All reactions
-
if we write legacyMap use the same key, whether will replace the value??
Beta Was this translation helpful? Give feedback.
All reactions
-
Proof verification within a cairo program would be a massive step forward in building fully decentralized state machines!
Beta Was this translation helpful? Give feedback.
All reactions
-
I want Base64 utils that could support type like Array<felt252>
Beta Was this translation helpful? Give feedback.
All reactions
-
i wanna deploy contract on remix easily
Beta Was this translation helpful? Give feedback.
All reactions
-
Make it possible to store functions inside variables.
This will make it possible to, among other things, support more functional programming paradigms:
- Pass functions as parameters to other functions - e.g. will allow to define
map,filter,reduceetc. on Arrays. Will allow iterator-related methods. - Return functions as results from other functions
- Define scoped (local) functions inside other functions
Beta Was this translation helpful? Give feedback.
All reactions
-
Big DEV QOL improvement would be the possibility to make mutation testing.
You'd run the tool, it would make some tweak in the code (for example changing a <= to a <) and expect a test to fail.
This could be a big improvement for checking some edge cases that are not correctly tested or detect a big if the tests are correct.
Existing tools are:
Beta Was this translation helpful? Give feedback.
All reactions
-
Beta Was this translation helpful? Give feedback.
All reactions
-
Hey guys! Does the VSCode extension works on Windows? I'm struggling to make it work on Windows but it doesn't work. Someone use it on Windows?
Beta Was this translation helpful? Give feedback.
All reactions
-
Hey! I don't think why it shouldn't work. But I can't help you if you don't tell me what's happening 😛
Try running the Troubleshooting guide from extension's readme
Beta Was this translation helpful? Give feedback.
All reactions
-
Oh, ok! Let me try to explain. When I open the project in VSCode with WSL in remote mode, the extension works normally. In WSL I have the scarb installed through the asdf manager. So when I open the project through the WSL, the extension is able to communicate with the cairo-language-server.
On other hand, when I open the project directly through the Windows, where I have the scarb installed manualy, cause asdf doesn't work in the Windows, the extension isn't able to communicate with the cairo-language-server.
If any moment you're want to make a video conference through Discord or any other platform I'm available.
Beta Was this translation helpful? Give feedback.
All reactions
-
The extension is unable to find scarb.exe automatically on your Windows machine.
- Do you have
scarb.exesearchable fromPATHenvironment variable? In other words: does runningscarbwork from PowerShell/Batch? - You can always manually put path to
scarbin your VSCode configuration. Look up in preferences GUI.
When the extension gets to a valid Scarb installation, it should automatically find the scarb-cairo-language-server.exe binary which ships the LS.
Beta Was this translation helpful? Give feedback.
All reactions
-
-
Yep, my scarb is running in PowerShell.
image -
I changed manually the path to scarb in my VSCode configuration:
This notification appeared on the screen:
image
In the output this is the error message:
image
Beta Was this translation helpful? Give feedback.
All reactions
-
Hey! you have to specify path with binary C:\Program Files\scarb\bin\scarb.exe (same for LS).
Beta Was this translation helpful? Give feedback.
All reactions
-
❤️ 1
-
@Draggu hey man! Thank you very much, it worked! I need to produce a tutorial for this.
Beta Was this translation helpful? Give feedback.