컨트랙트를 배포하면 바이트코드 형태로 블록체인에 저장된다.
이렇게 저장된 컨트랙트를 인간의 언어로는 읽기 어렵다.
etherscan 에서는 컨트랙트 코드를 업로드하면 contract ABI, bytes code, constructor Argument 등을 띄워준다.
Etherscan uniswap token contract
위 링크는 이더스캔에서 확인할 수 있는 유니스왑 토큰 컨트랙트의 세부사항들이다.
contract ABI, bytes code, constructor Argument 등을 확인할 수 있다.
여기서, 배포할 때의 constructor 값을 확인할 수 있다.
account, minter 주소값이 설정되어있는데, 이 주소만이 유니스왑 토큰을 민팅할 수 있다. 언제? mintingAllowedAfter 만큼의 시간이 되었을 때.
하지만, constructor Argument 값을 제대로 확인하지 않고 코드만을 읽고 컨트랙트를 사용한다면 함정에 당할 수도 있다.
아래와 같은 예시 코드가 있다.
// SPDX-License-Identifier: MIT
pragma solidity 0.8.18;
contract Hi{
event log(string message);
function callEmit() external {
emit log("this is Hi contract.");
}
}
contract Hoo{
Hi hi;
constructor(Hi _hi){
hi = Hi(_hi);
}
function callHi() external {
hi.callEmit();
}
}
Hi 컨트랙트의 callEmit 함수는 "this is Hi contract."
라는 로그를 발생시킨다.
Hoo 컨트랙트는 Hi 컨트랙트를 인스턴스화 하여 CallEmit 함수를 불러낸다.
constructor 에도 (Hi _hi)
라는 인자를 받기에 당연히 Hi 컨트랙트를 생각하겠지만..
contract Others{
event log(string message);
function callEmit() external {
emit log("this is Others contract.");
}
}
위 처럼 Others 컨트랙트를 작성하고 이벤트 로그 부분만 "this is Others contract."
로 바꾸고 배포했다.
그리고 Others 컨트랙트 주소를 constructor 로 설정하고 Hoo 컨트랙트를 배포, callHi 를 실행하면..
Others 컨트랙트의 이벤트 로그가 기록된다.
Hoo 컨트랙트에 아래와 같이 Hi 컨트랙트를 인스턴스화 하는 것 처럼 보이게 만들었지만, 실제로는 아무 의미가 없다.
Hi hi;
constructor(Hi _hi){
hi = Hi(_hi);
}
외부 컨트랙트를 사용할 때, 올바른 주소인지 확인.
알 수 없는 주소인 경우, 이더스캔을 통해 컨트랙트 세부 데이터를 확인.
아래와 같이 특정 컨트랙트의 주소에 확인 마크가 있다면 안전.