상세 컨텐츠

본문 제목

Solidity - Sending Ether (transfer, send, call)

카테고리 없음

by Yongari 2023. 1. 12. 22:47

본문

Sending Ether (transfer, send, call)
이더 송금하기 (전송, 보내기, 호출)

How to send Ether?
이더를 어떻게 보내냐?

You can send Ether to other contracts by
너는 이더를 다른 계약(스마트 컨트랙트)로 보낼 수 있다. 

  • transfer (2300 gas, throws error) - 전송(2300 가스, 오류 발생)
  • send (2300 gas, returns bool) - 전송(2300 가스, bool 값 리턴 {true, false} )
  • call (forward all gas or set gas, returns bool) - 호출(모든 가스 또는 설정한 가스, bool 값을 리턴하는 것을 포함 )

How to receive Ether?
이더는 어떻게 받나요?

A contract receiving Ether must have at least one of the functions below

Ether를 받는 스마트 컨트랙트에는 아래 기능 중 하나 이상이 있어야 합니다

  • receive() external payable 
  • fallback() external payable

receive() is called if msg.data is empty, otherwise fallback() is called.
msg.data가 비어 있으면 receive()를 호출하고, 그렇지 않으면 fallback()을 호출합니다.


Which method should you use?
어떤 방법을 사용해야 합니까?

call in combination with re-entrancy guard is the recommended method to use after December 2019.
2019년 12월 이후에 재-진입(re-entrancy) 가드와 결합된 콜을 사용하는 것이 권장된다. 

Guard against re-entrancy by
다음과 같은 방법으로 재-진입(re-entrancy)을 방지합니다

  • making all state changes before calling other contracts - 다른 계약을 호출하기 전에 모든 상태 변경
  • using re-entrancy guard modifier - 재-진입 가드 한정자 사용

 

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.17;

contract ReceiveEther {
    /* 
    Which function is called, fallback() or receive()?
    //fallback() 또는 receive() 중 어떤 함수를 호출합니까?

           send Ether
               |
         msg.data is empty?
              / \
            yes  no
            /     \
receive() exists?  fallback()
         /   \
        yes   no
        /      \
    receive()   fallback()
    */

    // Function to receive Ether. msg.data must be empty
	// 이더를 받는 함수, msg.data가 비어있어야 합니다.
    receive() external payable {}

    // Fallback function is called when msg.data is not empty
    // // Fallback 함수, msg.data가 비어있지 않아야 합니다.
    fallback() external payable {}

    function getBalance() public view returns (uint) {
        return address(this).balance;
    }
}

contract SendEther {
    function sendViaTransfer(address payable _to) public payable {
        // This function is no longer recommended for sending Ether.
        // 이 함수는 Ether를 보내는 데 더 이상 권장되지 않습니다.
        _to.transfer(msg.value);
    }

    function sendViaSend(address payable _to) public payable {
        // Send returns a boolean value indicating success or failure.
        // This function is not recommended for sending Ether.
        // 보내기는 성공 또는 실패를 나타내는 bool 값을 반환합니다.
        // Ether 전송에는 이 함수를 사용하지 않는 것이 좋습니다.
        bool sent = _to.send(msg.value);
        require(sent, "Failed to send Ether");
    }

    function sendViaCall(address payable _to) public payable {
        // Call returns a boolean value indicating success or failure.
        // This is the current recommended method to use.
        // 호출은 성공 또는 실패를 나타내는 bool 값을 반환합니다.
        // 현재 권장되는 사용 방법입니다.
        (bool sent, bytes memory data) = _to.call{value: msg.value}("");
        require(sent, "Failed to send Ether");
    }
}

Try on Remix

 

Remix - Ethereum IDE

 

remix.ethereum.org