Last active
December 14, 2023 09:21
-
-
Save reaperes/737319ca04dc39696852d804e1a99e7e to your computer and use it in GitHub Desktop.
solidity assembly mload, add real-world example
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
pragma solidity ^0.8.9; | |
contract Simple { | |
function example() public pure { | |
address remote = 0x1111111111111111111111111111111111111111; | |
address local = 0x2222222222222222222222222222222222222222; | |
bytes memory path = abi.encodePacked(remote, local); | |
assembly { | |
return(0x00, x) // What number is suitable for x? | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Answer is 200.
=====
다음은 example 함수를 실행시켰을때 메모리에 저장되는 데이터 입니다.
0x0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c80000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002811111111111111111111111111111111111111112222222222222222222222222222222222222222
0x 를 제외한 모든 글자는 400 자 입니다. 1 byte 를 16진수로 표기할 경우 2글자가 필요합니다. 따라서, 위의 글자들은 총 200 bytes 를 16 진수로 표기한 것으로 볼 수 있습니다.
위 데이터를 분해하면 다음과 같이 나누어질 수 있습니다.
[section 1 - solidity reserved space]
1-1: scratch space for hashing methods
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
1-2: currently allocated memory size (aka. free memory pointer)
00000000000000000000000000000000000000000000000000000000000000c8
1-3: reserved space (zero slot)
0000000000000000000000000000000000000000000000000000000000000000
[section 2 - user memory space]
2-1: abi-encoded data
0000000000000000000000000000000000000000000000000000000000000028 (encoded 된 총 데이터 길이)
1111111111111111111111111111111111111111 (remote address)
2222222222222222222222222222222222222222 (local address)
만일 remote address 를 얻고 싶으면 assembly 코드를 다음과 같이 작성하면 됩니다.
위 코드의 의미는 path 의 변수값이 저장된 메모리의 offset + 32 위치에서 20 bytes 만큼의 데이터를 리턴하라는 의미 입니다.
32는 데이터 길이를 나타내는 데이터 크기가 uint256(32 bytes)를 가지기 때문에 설정한 값이며,
20은 address 길이가 20 bytes (hex 의 경우 40 글자) 이기 때문에 설정되었습니다.
=====
예시의 개념은 실제 서비스 되는 코드들에서 사용되는 개념입니다. LayerZero contract 의 코드를 보면서 좀 더 이해의 폭을 넓힐 수 있습니다.
https://github.com/LayerZero-Labs/LayerZero/blob/main/contracts/UltraLightNodeV2.sol#L131
=====
references
[1] https://docs.soliditylang.org/en/latest/internals/layout_in_memory.html
[2] https://docs.soliditylang.org/en/develop/abi-spec.html