// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
contract Vault {
bool public locked;
bytes32 private password;
constructor(bytes32 _password) {
locked = true;
password = _password;
}
function unlock(bytes32 _password) public {
if (password == _password) {
locked = false;
}
}
}
우리의 mission은 password를 풀어야 한다.
현재 locked는 true이다.
password는 private라서 접근을 못하는 데 어떻게 알 수 있을까??
이 문제을 풀기 위해선 Solidity의 저장영역의 구조를 알고 있으면 쉽다.
Solidity의 저장 영역은 총 4개이다.
- Storage
- memory
- calldata
- stack
이 중 영속적으로 저장을 하면서 변수나 함수가 저장되는 영역은 어디일까?? 바로 Storage이다.
Storage에는 변수와 함께 값도 같이 저장이 되어서 private이 걸려 있어도 접근할 수 있다. 왜냐하면 외부에서는 직접적으로 변수에는 접근을 할 수 없지만, 저장공간의 값에 접근을 하는 것이기 때문에 가능하다.
자 이제 문제로 들어와서 각 변수들은 Storage에 순차적으로 저장이 되는 데 slot하나당 32byte까지 저장할 수 있다.
만약 변수의 숫자가 32byte가 되지 않는다면 나머지는 0으로 채운다. 하지만 오른쪽과 같이 변수를 합쳐도 32byte가 안 넘으면 하나의 슬롯에 저장한다. 즉 a와 b는 slot2에 같이 저장돼있는 것을 확인할 수 있다.
다시 문제를 보면 현재 Contract에는 변수가 2개가 있다. locked와 password가 있기 때문에 slot0에는 locked가 slot1에는 password의 값이 있다.
그러면 Storage의 값을 보기 위해서는 getStorageAt(address _address, uint256 _index)함수를 써야 한다.
해당 _address의 _index에 들어있는 값을 확인할 수 있다.
slot1을 보면 password의 값을 볼 수 있다.
locked가 false가 뜨는 것을 확인할 수 있다.