secret을 private하게 선언해줬다.
이렇게 선언하면 외부에선 못 읽는 거 아니었어?????
엄... 아니었다.
EVM에는 2^256개의 slot이 있고 이 slot에 데이터를 보관한다.
한 slot은 32byte의 데이터를 저장할 수 있다.
아래에 예를 보자.
bytes32가 한 슬롯을, uint가 또 한 슬롯을
그리고 address가 20byte를 차지하고 남는 공간에 bool이 1byte를 차지한다.
그렇기 때문에 web3.eth.getStorageAt(addr, slot, console.log)
를 통해 storage에 직접 접근해 해당 slot의 데이터를 출력할 수 있다.
private으로 데이터를 선언해도 storage에 저장되는 것은 마찬가지이기때문에 읽어올 수 있다.
말로만 들어선 믿기지 않는다. 그럼 내가 여태 private이라고 생각했던 건 뭐란 말인가.
한번 해보자. 아래 코드를 사용해 실습할거다.
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.17;
contract Contract {
string private secret;
constructor(string memory _secret) {
secret = _secret;
}
}
보이는 것 처럼 secret을 privateValue로 설정해서 Goerli에 배포해보자.
기다렸다가 배포된 contract address를 복사해가자
3.truffle을 사용해 goerli에 접속하고 배포된 주소로 web3.eth.getStorageAt(addr, 0, console.log)
을 실행해보면 값이 뜬다.
0x7072697661746556616c7565
를 string으로 디코딩해보면 privateValue
라는 값을 확인할 수 있다.이럴수가... private하다고 믿은 내 값이.. private하지 않았다. evm에는 절대 민감한 정보를 어떤 식으로든 저장해놓지 말자....
여담
사실 별다른 조치없이 배포해서 ether scan에서 확인하면 inputdata에서 privateValue라는 값을 확인할 수 있기는 하다.
어쨋든 이와는 별개로 내부적으로 정해진 값이라도 evm에 저장된 정보는 외부에서 열람가능하단 사실을 잊지 말자.
https://www.youtube.com/watch?v=Gg6nt3YW74o&list=PLO5VPQH6OWdWsCgXJT9UuzgbC8SPvTRi5&index=4