Created
March 13, 2023 01:03
-
-
Save swkim109/a2ddcbc1ff1cb9d798b1fd0f9f12ad93 to your computer and use it in GitHub Desktop.
mapping storage
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
mapping 타입의 스토리지 해시 | |
저장되는 슬롯 번호 = keccak256(key || slot No.) | |
(예) | |
mapping(address => uint256) public m; | |
m[0x5B38Da6a701c568545dCfcB03FcB875f56beddC4] = 100; | |
슬롯번호는 | |
ethers.utils.keccak256("0x0000000000000000000000005B38Da6a701c568545dCfcB03FcB875f56beddC40000000000000000000000000000000000000000000000000000000000000000") | |
= 0x58f8e73c330daffe64653449eb9a999c1162911d5129dd8193c7233d46ade2d5 | |
슬롯에 해당하는 스토리지 해시 | |
= 0x2f4efd012f30b85c3b205250c3dad4cd9208919ba8889723a8325ec6826f69e1 | |
구조체일때 | |
struct UserInfo { | |
uint256 id; | |
uint256 age; | |
} | |
mapping(address => UserInfo) public m; | |
m[0x5B38Da6a701c568545dCfcB03FcB875f56beddC4] = UserInfo({id: 100, age: 50}); | |
구조체의 각 필드의 위치는 처음 슬롯번호부터 차례로 +1, +2... | |
id의 슬롯번호 | |
ethers.utils.keccak256("0x0000000000000000000000005B38Da6a701c568545dCfcB03FcB875f56beddC40000000000000000000000000000000000000000000000000000000000000000") | |
= 0x58f8e73c330daffe64653449eb9a999c1162911d5129dd8193c7233d46ade2d5 | |
age의 슬롯번호 | |
0x58f8e73c330daffe64653449eb9a999c1162911d5129dd8193c7233d46ade2d5 + 1 | |
= 0x58f8e73c330daffe64653449eb9a999c1162911d5129dd8193c7233d46ade2d6 | |
in Remix
{
"0x8f098fdec8d49f366ac3ab21b3c2455b0a419f443611b0573a9a9744054b4412": {
"key": "0x58710dca1e2a45afe5496e8d02017d2788e01040086e5de4c6d09b2c1a60473d",
"value": "0x64"
}
}
{
"id": 0,
"jsonrpc": "2.0",
"method": "eth_getStorageAt",
"params": [
"0x054AfC9C126105526F5Dc27FFf27F9E00d5fCBD9",
"0x58710dca1e2a45afe5496e8d02017d2788e01040086e5de4c6d09b2c1a60473d",
"latest"
]
}
{
"jsonrpc": "2.0",
"id": 0,
"result": "0x0000000000000000000000000000000000000000000000000000000000000064"
}
MPT의 구조는?
{
"id": 0,
"jsonrpc": "2.0",
"method": "eth_getProof",
"params": [
"0x054AfC9C126105526F5Dc27FFf27F9E00d5fCBD9",
["0x58710dca1e2a45afe5496e8d02017d2788e01040086e5de4c6d09b2c1a60473d"],
"latest"
]
}
스토리지 트리의 노드는 leaf 노드 하나 밖에 없다.
"storageHash": "0x9c3c7f5b29952928a22cb71982914b3a0677794eddfa4e00cc038ff1ca48e4b0",
"storageProof": [
{
"key": "0x58710dca1e2a45afe5496e8d02017d2788e01040086e5de4c6d09b2c1a60473d",
"value": "0x64",
"proof": [
"0xe3a1208f098fdec8d49f366ac3ab21b3c2455b0a419f443611b0573a9a9744054b441264"
]
}
]
proof는 leaf 노드의 RLP 인코딩이다. leaf 노드는 [key, value]
구조이고 key는 슬롯번호의 해시이다. leaf 노드만 있고 경로의 길이가 32바이트 짝수이므로 hex prefix 인코딩 규칙에 따라 key에 0x20
이 추가된 것이다.
const node = ethers.utils.RLP.encode(["0x208f098fdec8d49f366ac3ab21b3c2455b0a419f443611b0573a9a9744054b4412", "0x64"]);
// 0xe3a1208f098fdec8d49f366ac3ab21b3c2455b0a419f443611b0573a9a9744054b441264
storageHash는 RLP 인코딩 결과의 해시가 된다.
ethers.utils.keccak256("0xe3a1208f098fdec8d49f366ac3ab21b3c2455b0a419f443611b0573a9a9744054b441264")
// 0x9c3c7f5b29952928a22cb71982914b3a0677794eddfa4e00cc038ff1ca48e4b0
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
key 가
string
타입일 경우슬롯번호 s = ethers.utils.keccak256(v) =
0x58710dca1e2a45afe5496e8d02017d2788e01040086e5de4c6d09b2c1a60473d
슬롯해시 = ethers.utils.keccak256(s) =
0x8f098fdec8d49f366ac3ab21b3c2455b0a419f443611b0573a9a9744054b4412