2026년 상식닷컴 선정 식당 & 카페 리스트
최근에 오픈한 호텔을 찾는다면 살펴보세요

솔리디티에서 'send'와 'transfer'의 차이는 무엇인가요?

_____
Q: 솔리디티에서 `send`와 `transfer`의 차이는 무엇인가요?

A: `send`와 `transfer`는 이더(ETH)를 다른 주소로 보내기 위해 솔리디티에서 사용하는 저수준 함수이지만 동작 방식과 에러 처리에서 차이가 있습니다.

---

1. 동작 원리

- `transfer`
- 문법: `recipient.transfer(amount);`
- 지정된 주소로 `amount`만큼의 이더를 보내며, 전송 실패 시 자동으로 트랜잭션을 revert(롤백)합니다.
- 내부적으로 고정 가스(2300 gas)를 수신자에게 제공하여, 복잡한 코드를 실행하지 못하도록 제한합니다.

- `send`
- 문법: `bool success = recipient.send(amount);`
- 이더를 보내고 성공 여부를 `bool` 값으로 반환합니다.
- 전송 실패 시 revert하지 않고 `false`를 반환하므로, 호출하는 쪽에서 실패 처리(예: revert 또는 다른 로직)를 직접 구현해야 합니다.
- 또한 2300 gas만 수신자에게 제공됩니다.

---

2. 에러 처리

- `transfer`: 전송 실패 시 즉시 트랜잭션 전체를 revert함 → 코드가 간결해지고 오류 처리 간단
- `send`: 전송 실패 시 `false` 반환, 호출자가 직접 실패 처리 필요 → 더 세밀한 오류 제어 가능

---

3. 가스 제한

두 함수 모두 수신자에게 2300 gas만 전달하는데, 이는 단순 이벤트 로그 기록이나 상태 변수 수정 등 최소한 작업만 가능하게 하여 재진입 공격 방지에 도움을 줍니다.
---

4. 사용 권장 사항

- 간단히 이더를 보내고 예외 발생 시 자동으로 롤백하길 원한다면 `transfer`가 적합
- 전송 실패 상황을 커스터마이징하여 처리해야 하거나, 실패 시에도 별도의 로직을 돌리려면 `send` 사용 가능

---

5. 참고: 2300 gas 제한 문제

최근 네트워크 환경이나 수신자의 fallback 함수 복잡성 때문에 2300 gas 제한이 모자랄 수 있어 `send`와 `transfer` 사용에 제한이 있을 수 있습니다. 따라서, 복잡한 송금 로직에는 `call` 사용이 권장됩니다.

예:
```solidity
(bool success, ) = recipient.call{value: amount}("");
require(success, "Transfer failed.");
```

---

요약
| 기능 | transfer | send |
|-------------|-------------------------------|-------------------------------|
| 반환 값 | 없음 (예외 발생 시 revert) | bool (성공 여부 반환) |
| 에러 처리 | 자동 revert | 직접 처리 필요 |
| 가스 제한 | 2300 gas 고정 | 2300 gas 고정 |
| 사용 편의성 | 간편 | 세밀한 제어 가능 |

---

따라서, 이더 전송 시 단순 호출과 예외 처리를 원하면 `transfer`를, 실패 후 처리가 필요하면 `send`를 사용하세요. 다만 복잡한 상황에서는 `call`을 고려하는 것이 더 안전합니다.
Solidity에서 `send`와 `transfer`는 이더(ETH)를 전송하는 데 사용되는 두 가지 메서드입니다.

이 두 메서드는 비슷한 목적을 가지고 있지만, 몇 가지 중요한 차이점이 있습니다.

이 글에서는 이 두 메서드의 차이점, 사용 방법, 그리고 각각의 장단점에 대해 자세히 설명하겠습니다.

1. 기본 개념 - send : `send` 메서드는 이더를 전송하는 데 사용되며, 전송이 성공하면 `true`를 반환하고 실패하면 `false`를 반환합니다.

이 메서드는 전송이 실패할 경우 예외를 발생시키지 않기 때문에, 호출자는 반환 값을 확인하여 전송 성공 여부를 판단해야 합니다.

- transfer : `transfer` 메서드는 이더를 전송하는 데 사용되며, 전송이 성공하면 아무런 값을 반환하지 않습니다.

만약 전송이 실패하면 예외를 발생시킵니다.

이 메서드는 항상 2300 가스만을 사용하여 호출되며, 이는 상대적으로 적은 양입니다.



2. 가스 사용량 - send : `send`는 호출 시 가스 사용량이 유동적입니다.

전송이 실패할 경우, 호출자는 가스 사용량을 고려하여 적절한 가스를 설정해야 합니다.

- transfer : `transfer`는 항상 2300 가스를 사용합니다.

이 가스 양은 수신자가 `fallback` 함수를 호출할 때 필요한 최소한의 가스 양입니다.

따라서, 수신자가 복잡한 로직을 포함한 함수를 호출할 경우, `transfer`는 실패할 수 있습니다.



3. 예외 처리 - send : `send`는 실패할 경우 `false`를 반환하므로, 호출자는 이 값을 확인하여 적절한 조치를 취해야 합니다.

예를 들어, 전송이 실패했을 때 재시도하거나 사용자에게 알릴 수 있습니다.

- transfer : `transfer`는 실패할 경우 예외를 발생시키므로, 호출자는 try-catch 블록을 사용하여 예외를 처리해야 합니다.

이로 인해 코드가 더 간결해질 수 있지만, 예외 처리 로직을 추가해야 합니다.



4. 사용 예시 ```solidity // send 사용 예시 function sendEther(address payable recipient, uint amount) public returns (bool) { bool sent = recipient.send(amount); require(sent, "Failed to send Ether"); return sent; } // transfer 사용 예시 function transferEther(address payable recipient, uint amount) public { recipient.transfer(amount); } ```

5. 보안 고려사항 - send : `send`는 실패할 경우 `false`를 반환하므로, 호출자가 이 값을 확인하지 않으면 이더가 손실될 수 있습니다.

따라서, `send`를 사용할 때는 항상 반환 값을 체크해야 합니다.

- transfer : `transfer`는 예외를 발생시키므로, 호출자가 예외를 처리하지 않으면 트랜잭션이 실패하게 됩니다.

이는 코드의 안전성을 높이는 데 도움이 됩니다.



6. `send`와 `transfer`는 이더를 전송하는 데 사용되는 두 가지 메서드로, 각각의 장단점이 있습니다.

`send`는 실패 시 `false`를 반환하므로 호출자가 반환 값을 확인해야 하며, `transfer`는 예외를 발생시켜 코드의 안전성을 높입니다.

그러나 `transfer`는 항상 2300 가스를 사용하므로, 수신자가 복잡한 로직을 포함한 함수를 호출할 경우 실패할 수 있습니다.

따라서, 이더 전송 시 어떤 메서드를 사용할지는 상황에 따라 다르며, 개발자는 각 메서드의 특성을 이해하고 적절한 방법을 선택해야 합니다.

작성자: 이지수 [비회원] | 작성일자: 1년 전 2024-11-22 19:32:11
조회수: 212 | 댓글: 0 | 좋아요: 0 | 싫어요: 0
내용이 부정확하다면 싫어요를 클릭해주세요.