이더리움/솔리디티

[솔리디티] 12. Payable, Transfer, Send, Call

라이튼 2023. 8. 2. 22:51

이전글

 

[솔리디티] 11. 에러 처리

이전글 [솔리디티] 10. 이벤트 이전글 [솔리디티] 9. 조건문, 반복문 이전글 [솔리디티] 8. 매핑, 구조체, 열거형 이전글 [솔리디티] 7. view 함수, pure 함수, 모디파이어, 오버로딩 이전글 [솔리디티] 6.

kwjdnjs.tistory.com

 

Payable, Transfer, Send, Call

 이번 글에서는 payable, transfer, send, call에 대해 알아보겠습니다.

 

1. Payable

 payable이란 생성자나 함수에 붙일 수 있는 키워드입니다. 생성자에 payable을 붙일 경우 컨트랙트 배포 과정에서 컨트랙트 계정(CA)으로 이더를 보낼 수 있으며, 함수에 payable을 붙일 경우 함수 호출 과정에서 CA로 이더를 보낼 수 있습니다.

 

 다음과 같이 생성자에 payable을 붙이면 컨트랙트 배포 과정에 이더를 CA로 보낼 수 있습니다.

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

contract Payable {
    constructor() payable {

    }
}

 

 배포 과정에서 이더를 전송하기 위해서는 다음과 같이 전송할 이더의 양과 단위를 선택한 후 deploy 버튼을 눌러야 합니다.

 

 

 컨트랙트 배포가 정상적으로 이뤄졌다면 EOA의 이더 잔고가 줄어들고 CA의 이더 잔고가 증가하게 됩니다. 컨트랙트 계정 잔고 갱신에는 조금 시간이 필요할 수 있습니다.

 

 

 이번에는 함수에 payable 키워드를 붙여보겠습니다.

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

contract Payable {
    function func() public payable {

    }
}

 

 함수 호출과정에서 이더를 전송하려면 이전과 동일하게 전송할 금액을 단위와 함께 작성해야 합니다. 적절한 이더의 양을 적은 후에 deploy 버튼이 아닌 함수 버튼을 눌러 함수를 호출합니다. 함수가 정상적으로 호출되면 CA의 이더 잔고가 증가하게 됩니다.

 

 

2. transfer, send, call

 이번에는 CA의 이더를 EOA에게 전송하는 방법에 대해 알아보겠습니다.

 

 CA에서 EOA로 이더를 전송하기 위해서는 transfer, send, call 함수를 사용해야 합니다. 각각의 함수를 하나씩 살펴보겠습니다.

 

 먼저 transfer 함수는 payable 키워드가 붙은 address 뒤에 transfer()을 붙이는 형식으로 사용할 수 있습니다. transfer함수의 괄호 안에는 전송할 이더의 양을 wei 단위로 넣습니다. 만약 전송과정에서 오류가 발생할 경우 트랜잭션은 취소됩니다.

 

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

contract Payable {
    constructor() payable {}

    function transfer(address payable addr, uint value) public {
        addr.transfer(value);
    }
}

 

 컨트랙트 생성 과정에서 CA로 일정량의 이더를 보내준 뒤, transfer 함수를 EOA 주소와 전송할 이더의 양과 함께 호출합니다.

 

 참고로 계정 항목에서 주소를 누르면 컨트랙트를 배포한 EOA 외에 다른 EOA도 선택할 수 있습니다. 적절한 주소를 선택한 뒤에 옆의 복사버튼을 눌러 주소를 복사할 수 있습니다.

 

 

  이더 전송이 정상적으로 이뤄지면 EOA의 이더 잔고가 증가하고, CA의 이더 잔고가 줄어들게 됩니다.

 

 

 

 다음으로 send 함수에 대해 알아보겠습니다. send 함수는 transfer 함수처럼 payable이 붙은 address의 뒤에 send()를 붙여 사용할 수 있습니다. transfer 함수는 전송 결과를 반환하지 않는 반면, send 함수는 전송 결과를 bool 타입으로 반환합니다. 일반적으로 send 함수는 전송 결과가 반환된다는 성질을 이용하여 require 함수와 함께 사용합니다.

 

 참고로 변수 선언 과정에서 payable이 붙지 않은 address를 send나 transfer 함수와 함께 사용해야 할 경우 다음과 같이 payable(address) 형태로 사용할 수 있습니다.

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

contract Payable {
    constructor() payable {}

    function send(address addr, uint value) public {
        bool result = payable(addr).send(value);
        require(result, "Failed to send Ether");
    }
}

 

 마지막으로 call 함수에 대해 알아보겠습니다. call 함수는 send 함수와 비슷하게 이더 전송 결과를 bool 타입으로 반환하지만, payable이 적용되지 않은 address에도 사용할 수 있는 함수입니다. call 함수는 다음과 같이 사용할 수 있습니다.

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

contract Payable {
    constructor() payable {}

    function call(address addr, uint value) public {
        (bool result, ) = addr.call{value: value}("");
        require(result, "Failed to send Ether");
    }
}

 

 지금까지 payable, transfer, send, call에 대해 알아봤습니다. 다음 글에서는 CA에서 다른 CA로 이더를 전송하는 방법에 대해 알아보겠습니다. 감사합니다.

 

 

다음글

 

[솔리디티] 13. receive, fallback, delegatecall

이전글 [솔리디티] 12. Payable, Transfer, Send, Call 이전글 [솔리디티] 11. 에러 처리 이전글 [솔리디티] 10. 이벤트 이전글 [솔리디티] 9. 조건문, 반복문 이전글 [솔리디티] 8. 매핑, 구조체, 열거형 이전글

kwjdnjs.tistory.com