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

Allow conversion from bytes to bytesNN #9170

Closed
ekpyron opened this issue Jun 10, 2020 · 4 comments · Fixed by #11047
Closed

Allow conversion from bytes to bytesNN #9170

ekpyron opened this issue Jun 10, 2020 · 4 comments · Fixed by #11047
Assignees
Labels
language design :rage4: Any changes to the language, e.g. new features

Comments

@ekpyron
Copy link
Member

ekpyron commented Jun 10, 2020

Allow conversions from the dynamic bytes type to the fixed bytes bytesNN types.

Probably best to start with calldata to support e.g. bytes4 sig = bytes4(msg.data[:4]); (resp. bytes4 sig = bytes4(bytes(msg.data[:4]));, i.e. for proper calldata arrays first and then directly on calldata slices).

But this also makes sense for memory and storage.

There may very well be an existing issue for that, but I didn't find any on a quick search.

@ekpyron
Copy link
Member Author

ekpyron commented Jun 10, 2020

Among the main reasons for this: #9167

@chriseth
Copy link
Contributor

invalid opcode if the byte array is too short?

@cameel cameel added feature language design :rage4: Any changes to the language, e.g. new features labels Nov 22, 2020
@mijovic mijovic self-assigned this Mar 4, 2021
@ekpyron
Copy link
Member Author

ekpyron commented Apr 13, 2021

I'm wondering if we shouldn't just allow conversions from too long (truncating) as well as from too short (padding) bytes arrays.
Wouldn't that be more consistent with how explicit conversions work right now for any other types?
Is the fact we might change other types in a future version a good reason for introducing inconsistencies now?

EDIT: (I'm for example not yet sure if I won't argue against checks on conversions in 0.9 and for a notion of explicit safe_convert or something like that instead... - on the other hand maybe not, since explicit masking is maybe also not too bad for other types, but then we'd need to sort memory slicing for this here...)

@axic
Copy link
Member

axic commented Apr 21, 2021

We discussed new casting/conversion syntax here and here:

We could consider C++ism cast<byte[]>(cast<byte[32]>(cast<uint256>(1234))) to make it worse (or use convert<>)
And add copyof on top of it: cast<byte[]>(copyof cast<byte[32]>(cast<uint256>(1234)))
uint256(1234).as<byte[32]>().as<byte[]>() may be a bit more readable :)

I thought we had an issue proposing a syntax something like cast<toType>(val) instead of explicit conversions. I guess it is just more verbose so people would dislike it?
But at least would probably be easier to read cast<address payable>(..) than address payable(..).
If we do have cast<> as an unchecked casting, then we could later consider adding convert<> which does checks.
I wonder if we could use the cast syntax for multiple-step casting, i.e. cast<uint128,int128,int16>(..uint256 input..) or cast<uint128 -> int128 -> int16>(..uin256 input..) (similar to the mapping syntax)
But the other option we briefly discussed is explicit casting works like static_cast/reinterpret_cast and we could introduce truncation/conversion helper on the types, i.e. bytes32.truncateFrom(<dynamic bytes>).
Instead of the multiple step casting I suppose there could be nicer helpers in the stdlib doing that?

On the meeting we also mentioned perhaps we should not name them cast, but rather truncate and extend, etc.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
language design :rage4: Any changes to the language, e.g. new features
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants