Guys I need to store and retrieve a struct encoded as a bytes32, data fits precisely in a bytes32 and for the encoding I can do a simple (bytes32(abi.encodePacked(...))
To go from bytes32 to struct what would be the most convenient way?
I was thinking of using assembly to copy the bytes32 into the struct but I don't know if there are better approaches or if it's possible to do that in assembly

Jul 15, 2022, 11:20 AM
if i understand you clearly, this might help
Jul 15, 2022, 11:25 AM
nice snippet, thx
Jul 15, 2022, 11:27 AM
Not really unfortunately
Jul 15, 2022, 11:30 AM
if data fits into same struct i think you can retrieve the bytes directly with the snippet into struct.
Jul 15, 2022, 11:33 AM
Can you make that a bit less pseudocode to understand what you mean?
Jul 15, 2022, 11:34 AM
to be more explicit
NOTE: read from memory should be view
using assembly might require you to use some logic, unable to lay hand on a material that can help at the moment.
Jul 15, 2022, 11:41 AM
Did you test this?
It's not working on my side
Jul 15, 2022, 11:45 AM
i have once use it and it worked.
what i did was to return the value from the bytes then i passed the value into a struct, instead of return a struct directly, i breakdown the bytes to get the data first.
Jul 15, 2022, 11:49 AM
// SPDX-License-Identifier: MIT

pragma solidity >=0.7.0 <0.9.0;

contract Storage {

struct c{
uint128 a;
uint128 b;
}

function encode(uint128 a, uint128 b) public pure returns(uint256) {

return (uint256) ((bytes32)(abi.encodePacked(a,b)));
}

function decode(uint256 data) public pure returns(c memory f) {
return abi.decode(abi.encodePacked(data),(c));
}
}
a reproducible example to test on remix
Jul 15, 2022, 11:50 AM
That only works for single variable encoding
Use bytes to encode struct data instead of bytes32
Jul 15, 2022, 12:25 PM
Yeah I turn that back into bytes before the decode
Jul 15, 2022, 12:28 PM
Nah it doesn't work like that. You turned it back to bytes by doing abi.encodePacked right?
Jul 15, 2022, 12:34 PM
Yes
Here is a snippet
Jul 15, 2022, 12:36 PM
Yeah it won't work as intended
Jul 15, 2022, 1:00 PM
Ok then how should it work?
Wtf wow basically everyone but me is becoming an admin it seems ahahah
Just noticed gg
Jul 15, 2022, 1:01 PM
Keep it as bytes? Or maybe you'll need some assembly magic
Jul 15, 2022, 1:01 PM
just a minute
Jul 15, 2022, 1:03 PM
I need to store that as bytes32 and so I will have a bytes32 when I go to read it, but if I take that and abi.encodePacked a bytes32 I get a bytes(32) so I don't understand where would be the issue
Jul 15, 2022, 1:03 PM
The thing is abi decode only works on unpacked data, not packed ones
Jul 15, 2022, 1:22 PM
If I think at a low level what I would like to do should be pretty simple: like get the storage slot or memory location of where the struct is stored and write there the 32 bytes but I don't know solidity's assembly enough😅
I know, I made that like that following @Encryption01 's suggestion as he said he made it work like that once but I also wouldn't have expected it to work
@grimreaper619 do you know of a way to do this in assembly?
I could always reconstruct the struct through operations on bytes but it seems a bit overkill and a pain in the ass to maintain if I then decide to change the struct's members
Jul 15, 2022, 1:32 PM
Nope. Not much of an assembly guy myself
Maybe you could write a function which converts packed bytes32 to unpacked bytes
Jul 15, 2022, 1:43 PM
i made that worked when i packed all the value into a struct and then decode using that method, that why i shared it.
Jul 15, 2022, 1:48 PM
I just made a comparison

1)

0x0000000000000000000000000000000a00000000000000000000000000000064

2)

0x000000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000064
1 is packed encoding and other is unpacked. Shouldn't be hard to convert
Only 2 works with abi.decode
Jul 15, 2022, 1:50 PM
Yeah but I would have liked to keep it more general to support also other structs that fit into 32 bytes, not having to deal with masks etc. If it was avoidable
No worries, can you check if maybe the data was abi.encoded instead of encodePacked?
Oh seems like he's not anymore, good choice
Jul 15, 2022, 1:54 PM
Why not use a single getter which returns all the struct data? It should only take one SLOAD I assume
Jul 15, 2022, 1:59 PM
But also inside the contract I need to parse the bytes into a struct to read some fields
Jul 15, 2022, 2:01 PM
this was what i had , then encode the struct params with web3
Jul 15, 2022, 2:03 PM
And the format of the data as input is not Packed right? In this case it takes 64 bytes as input right?
Jul 15, 2022, 2:05 PM
i tested with this just now.
0x0000000000000000000000007e73cb86a05f1c326035dcb985ccb3f5197e257c000000000000000000000000000000000000000000000001158e460913d00000
Jul 15, 2022, 2:05 PM
// bytes20
let token := shr(96, calldataload(0x00))
// bytes20
let pair := shr(96, calldataload(0x14))
// uint128
let amountIn := shr(128, calldataload(0x28))
// uint128
let amountOut := shr(128, calldataload(0x38))
// uint8
let tokenOutNo := shr(248, calldataload(0x48))

This is how calldata parsing looks like in assembly. Maybe experiment with it and you'll get what you want :)
Jul 15, 2022, 2:06 PM
Yeah that's 64 bytes
Jul 15, 2022, 2:07 PM
packed.
and 64
Jul 15, 2022, 2:07 PM
Uhh that's not what packing means
Its not packed, simply encoded
Jul 15, 2022, 2:08 PM
It's not a result of a packed encoding, otherwise it would have taken 20+32=52 bytes
Jul 15, 2022, 2:08 PM
going through this again to check if i actually get what you are saying right made me ran a simple test here.
Jul 15, 2022, 2:19 PM
you are not packing them, it works but uses 64 bytes
Jul 15, 2022, 2:26 PM

© 2024 Draquery.com All rights reserved.