---
title: "Solidity의 selfdestruct란?"
description: "정의, 작동 방식, 시작 방법"
---

# Solidity의 selfdestruct란?

**업데이트**: Selfdestruct는 [EIP-6049](https://eips.ethereum.org/EIPS/eip-6049)에 명시된 대로 Shanghai Ethereum 업그레이드 과정에서 폐기되었습니다. 이 글은 이제 오래된 정보이며, 해당 기능이 이전에 어떻게 작동했는지만 다룹니다.

_Selfdestruct_는 개발자가 컨트랙트를 종료하고자 할 때 사용하던 [Solidity](https://www.alchemy.com/overviews/solidity)의 키워드입니다. 2021년 연구 논문 "Why Do Smart Contracts Self-Destruct? Investigating the Selfdestruct Function on Ethereum"에 따르면 약 800개의 컨트랙트가 _selfdestruct_ 키워드를 포함하고 있어, [Solidity를 공부하면서](https://www.alchemy.com/overviews/learn-solidity) 알아둘 만한 중요한 개념입니다.

이 글에서는 _selfdestruct_가 무엇이었는지 정의하고, 그 목적을 설명하며, [Solidity](https://www.alchemy.com/dapps/solidity) 스마트 컨트랙트에서 _selfdestruct_를 구현하는 예제를 제공합니다.

## **Selfdestruct란 무엇인가?**

Selfdestruct는 컨트랙트를 종료하고, Ethereum 블록체인에서 바이트코드를 제거하며, 컨트랙트에 남아 있던 자금을 지정된 주소로 전송하는 데 사용되던 키워드입니다.

_Selfdestruct_는 2016년, Ethereum 블록체인과 탈중앙화 조직\([DAO](https://www.alchemy.com/dapps/top/daos)\)이 초기 단계에 있던 시기에 등장했습니다. 초기 DAO 중 하나가 해킹으로 360만 ETH를 잃었습니다. Solidity 컨트랙트의 불변성 때문에 이 공격은 며칠간 지속되었습니다. 당시에는 컨트랙트를 파기할 방법이 없었기 때문에, 초기 DAO 개발자들은 추가 악용을 막기 위해 블록체인 전체를 포크했습니다.

이런 이유로 _selfdestruct_는 보안 위협이 발생했을 때 대피구 역할을 하도록 만들어졌습니다. 처음에는 "suicide function"이라 불렸지만, **Solidity v0.5.0**부터 _selfdestruct_로 이름이 바뀌었습니다.

### 개발자들은 왜 selfdestruct 함수를 사용했는가?

개발자들은 주로 스마트 컨트랙트 코드의 보안을 개선하고, 사용하지 않는 컨트랙트를 정리하고, Ethereum 자산을 빠르게 이전하기 위해 selfdestruct 함수를 사용했습니다.

_Selfdestruct_는 개발자가 스마트 컨트랙트를 업그레이드해야 할 때 유용했습니다. 예를 들어 [ERC-20 프레임워크](https://www.alchemy.com/overviews/erc20-solidity)는 상호운용성을 위해 Ethereum상의 모든 대체 가능 토큰(fungible token)에 대한 표준 구현체입니다. ERC-20 표준과 인터페이스하지 않는 토큰은 다른 컨트랙트와 상호작용하는 데 어려움을 겪게 됩니다.

이런 경우 개발자들은 현재 컨트랙트를 업그레이드하는 대신 새로운 컨트랙트로 전환합니다. 따라서 _selfdestruct_ 함수를 사용해 현재 컨트랙트에서 자금을 인출하고, 필요한 기능을 갖춘 새 컨트랙트를 만들 수 있었습니다.

개발자들은 또한 잠재적 보안 위협에 대비하기 위해 _selfdestruct_ 함수를 사용했습니다. 같은 [2021년 selfdestruct 스마트 컨트랙트 보고서](https://arxiv.org/pdf/2005.07908.pdf#:~:text=On%20the%20one%20hand%2C%20using,an%20attack%20vector%20for%20attackers)에 따르면, 개발자가 자신의 컨트랙트에서 보안 결함을 발견했을 때 _selfdestruct_ 함수는 결함이 있는 컨트랙트를 즉시 종료하고 안전한 컨트랙트로 교체하는 데 도움이 되었습니다.

### Selfdestruct 사용의 단점은 무엇인가?

Selfdestruct 함수의 단점은 ERC-20 토큰을 복구할 수 없다는 점과, 자기 파괴 이후 토큰을 다른 곳으로 재전송할 수 없다는 점입니다.

일반적으로 _selfdestruct_ 함수는 컨트랙트 종료를 제때 알리지 않은 개발자들에 의해 호출됩니다. 팀이 업데이트를 공지하더라도 충분히 빠르게 퍼지지 않을 수 있습니다. 그 결과 일부 사람들은 컨트랙트가 여전히 활성화되어 있다고 생각하고 파기된 컨트랙트로 자금을 보내게 될 수 있습니다. 이 경우 해당 자금은 손실됩니다.

_selfdestruct_ 사용의 두 번째 단점은 이 함수가 Ether\(ETH\)만 전송할 수 있고, 알트코인이나 ERC-721 토큰 표준을 따르는 NFT와 같은 다른 ERC-20 토큰은 전송할 수 없다는 점입니다. _selfdestruct_가 호출되면 이러한 자산은 결코 복구할 수 없습니다.

#### 일부는 왜 selfdestruct 함수를 위험하다고 여겼는가?

Selfdestruct 함수는 악의적인 개발자가 러그풀(rug pull)을 실행하기 더 쉽게 만들었습니다.

이 함수를 통해 개발자는 _selfdestruct_를 호출하고 자금을 자신의 개인 지갑으로 보낼 수 있었습니다. 이런 이유로 일부 프로토콜 사용자와 개발자들은 _selfdestruct_ 함수 사용에 대해 엇갈린 반응을 보였습니다.

## Selfdestruct는 어떻게 작동하는가?

Selfdestruct는 체인에서 컨트랙트 바이트코드를 지우고, 남아 있는 유동성을 지정된 주소로 전송한 다음, 개발자에게 가스 수수료 일부를 환급하는 방식으로 작동합니다.

컨트랙트는 상태(state)와 함수(function)라는 두 가지 요소로 구성됩니다. 이 요소들이 컨트랙트의 동작과 [호출 가능한 함수](https://www.alchemy.com/overviews/solidity-functions)를 정의합니다. 바이트코드를 제거한다는 것은 컨트랙트를 정의하는 요소가 없어진다는 뜻이며, 이로 인해 컨트랙트를 더 이상 호출할 수 없게 됩니다.

_selfdestruct_ 함수에는 파기 후 컨트랙트 자금이 어디로 가야 하는지를 나타내는 필수 파라미터가 있었습니다.

### **네거티브 가스(negative gas)란 무엇이며 왜 중요한가?**

네거티브 가스는 개발자가 selfdestruct 함수를 사용할 때마다 Ethereum 체인이 환급해 주는 트랜잭션 수수료의 일부를 가리킵니다.

Ethereum은 블록체인에서 데이터를 제거함으로써 발생하는 가스 절감분을 호출자에게 보상함으로써 _selfdestruct_ 함수 사용을 장려했습니다. 컨트랙트가 _selfdestruct_ 함수를 호출하면, 트랜잭션에 사용된 총 가스의 절반이 호출자에게 환급되었습니다.

### Selfdestruct는 Ethereum 블록체인상의 컨트랙트 이력을 제거하는가?

아니요, selfdestruct 함수는 Ethereum 체인에서 컨트랙트의 이력을 제거하지 않습니다 — 이 함수는 컨트랙트의 바이트코드만 제거합니다.

Ethereum은 상호 연결된 노드 네트워크가 항상 블록체인 상태의 사본을 보관하는 퍼블릭 원장, 즉 블록체인입니다. 따라서 _selfdestruct_ 함수를 호출하기 전에 이루어진 모든 데이터와 트랜잭션은 온체인에 영구적으로 기록되며 변경할 수 없습니다.

### Selfdestruct 함수를 호출한 후 자금은 영구적으로 사라지는가?

**아니오이면서 예입니다. 기존 ETH는 함수 호출자가 지정한 다른 주소로 전송되지만, ERC-20 토큰은 손실됩니다.**

또한 누군가 selfdestruct된(즉, 종료된) 컨트랙트로 자금을 보내면, 그 자금은 재전송되지 않고 손실됩니다.

## Selfdestruct 함수 예제

이 프로그램의 목표는 컨트랙트 내 ETH가 특정 금액에 도달할 때까지 NFT 민팅을 허용하는 것입니다. 해당 금액에 도달하면 프로그램은 보너스로 모든 Ether를 마지막 민터의 지갑으로 전송합니다. 각 사용자는 1 Ether로 여러 개의 NFT를 민팅할 수 있지만 한 번에 하나씩만 가능합니다. **이 컨트랙트는 프로덕션 환경에서 사용하기 위한 것이 아니라 예제 목적으로만 작성되었습니다.**

이 민트 컨트랙트의 주요 문제는 "_this.balance_"를 사용해 종료 조건을 트리거할 만큼 컨트랙트에 충분한 자금이 있는지를 확인한다는 점입니다. 따라서 공격자는 지정된 한도를 넘기도록 손쉽게 금액을 보낸 다음, _selfdestruct_ 키워드를 사용해 자금을 자신이 선언한 생성자(constructor) 주소로 리다이렉트할 수 있습니다.

따라서 _selfdestruct_를 사용할 때 개발자는 특정 조건을 만족시키기 위해 사용하는 변수에 주의해야 합니다. 컨트랙트 주소나 컨트랙트 내 자금에 대한 참조는 인위적으로 조작될 수 있으므로 사용을 피해야 합니다.

## **Selfdestruct 함수 사용 방법**

Selfdestruct 함수를 초기화하는 것은 간단합니다. 함수 내에서 selfdestruct 키워드를 사용하고, selfdestruct 함수 호출 후 컨트랙트 자금을 받을 수 있는 payable 주소를 지정하면 됩니다.

다음은 Solidity 강좌에서 일반적으로 가르치는 _selfdestruct_ 함수의 예입니다:

이 코드가 하는 일은 다음과 같습니다:

- 함수의 이름은 *destroy*입니다
- 파라미터는 *apocalypse*라는 이름으로 주소를 지정합니다
- destroy 함수가 호출되면 apocalypse 변수를 통해 주소가 지정됩니다
- [함수 가시성(visibility)은 public으로 선언되어](https://www.alchemy.com/overviews/solidity-function-visibility) 다른 컨트랙트도 이를 호출할 수 있습니다
- 그런 다음 _selfdestruct_ 키워드를 사용하고, apocalypse 변수를 payable로 선언한 뒤 전달합니다

이 함수는 public이기 때문에 잠재적인 보안 결함을 안고 있습니다. 이를 방지하려면 _onlyOwner_ modifier를 추가하거나, [require 구문](https://www.alchemy.com/overviews/solidity-require)을 사용해 오직 소유자만 destroy 함수를 호출할 수 있도록 확인하는 것을 고려할 수 있습니다.

### Alchemy의 Solidity 개발자 과정으로 Solidity와 selfdestruct 함수 배우기

*Selfdestruct*는 보안 침해가 발생했을 때, 개발자가 컨트랙트를 업그레이드하고자 할 때, 또는 오래된 컨트랙트를 제거하고자 할 때 컨트랙트를 종료하는 안전장치 역할을 합니다. _selfdestruct_의 사용 여부는 Solidity 개발자 커뮤니티에서 여전히 논쟁의 대상이지만, 이 함수의 도입은 많은 잠재적 해킹을 막는 데 도움이 되었습니다.

_selfdestruct_와 같은 중요한 함수에 대해 더 알아보고 [더 나은 Solidity 개발자가 되고](https://www.alchemy.com/overviews/how-to-become-a-solidity-developer) 싶다면 Alchemy University의 [무료 7주 Ethereum Bootcamp](https://university.alchemy.com/?a=d1bd288312)에 등록해 보세요. 개발 자체가 처음인 분이라면, Ethereum bootcamp를 시작하기 전 사전 과정으로 Alchemy의 **3주 JavaScript 속성 과정**을 추천합니다.
