솔리 디티 receive - solli diti receive


유튜브를 통해, 쉽고 간편하게 이해 해보아요!

https://youtu.be/bS4yIW4CHo8

솔리 디티 receive - solli diti receive

구독/좋아요 해주셔서 감사합니다 :) !!


안녕하세요

오늘은 fallback과 receive 함수에 대해서 알아 보도록 하겠습니다. 

fallback

이름 그대로 대비책 함수 입니다.  특징  1. 먼저 무기명 함수, 이름이 없는 함수입니다. 2. external 필수  3. payable 필수왜 쓰는가 ? 1. 스마트 컨트랙이 이더를 받을 수 있게 한다. 2. 이더 받고 난  후  어떠한 행동을 취하게 할 수 있다.  3. call함수로 없는 함수가 불려질때, 어떠한 행동을 취하게 할 수 있다.

먼저 0.6 이전 버전 전후 fallback 함수는 변화가 생깁니다.

0.6이전의 fallback

function() external payable {      }

자 그러면 0.6 이후로 어떻게 fallback 변했는지 보겠습니다. 

0.6 이후 fallback 

fallback은 recevie 와 fallback 으로 두가지 형태로 나뉘게 되었습니다.receive:  순수하게 이더만  받을때 작동 합니다.  fallback: 함수를 실행하면서 이더를 보낼때, 불려진 함수가 없을 때 작동합니다.

기본형 :  불려진 함수가 특정 스마트 컨트랙이 없을때 fallback 함수가 발동 합니다.  fallback() external {       } payable 적용시 : 이더를 받고 나서도 fallaback 함수가 발동합니다.  fallback() external payable {       } receive() external payable{      }

// SPDX-License-Identifier: GPL-3.0

pragma solidity >=0.5.0 < 0.9.0;


contract Bank{
    event JustFallback(address _from,string message);
    event RecevieFallback(address _from,uint256 _value ,string message);
    event JustFallbackWIthFunds(address _from,uint256 _value ,string message);
    //~0.6 
//   function() external payable {
//      emit JustFallbackWIthFunds(msg.sender, msg.value,"JustFallback is called");
//     }
    
    
    //0.6~
    // fallback() external {
    //   emit JustFallback(msg.sender,"JustFallback is called");
    // }
    // receive() external payable {
    //   emit RecevieFallback(msg.sender, msg.value,"RecevieFallback is called");
    // }
    
    //
    fallback() external payable {
     emit JustFallbackWIthFunds(msg.sender, msg.value,"JustFallbackWIthFunds is called");
    }
  
}

contract You{

    //receve() 
    function DepositWithSend(address payable _to) public payable{
         bool success = _to.send(msg.value);
         require(success, "Failled" );
    }
    
    function DepositWithTransfer(address payable _to) public payable{
        _to.transfer(msg.value);
    }
    
    function DepositWithCall(address payable _to) public payable{
        // ~ 0.7
        // (bool sent, ) = _to.call.value(msg.value)("");
        // require(sent,"Failed to send either");
        
        //0.7 ~
        (bool sent, ) = _to.call{value: msg.value}("");
        require(sent, "Failled" );
    }
    
    //fallback()
    function JustGiveMessage(address payable _to) public payable{
        (bool success, ) = _to.call("HI");
        require(success, "Failled" );
    }
    
    //To the fallback() with Funds
    function JustGiveMessageWithFunds(address payable _to) public payable{
        (bool success,) = _to.call{value:msg.value}("HI");
        require(success, "Failled" );
    }
    
}

Show

[NEW] 누구나 쉽게 따라하는 솔리디티 강의(솔리디티 버전 0.8.13)

1. Helloworld, 카운터컨트랙트, 데이터타입

2. 변수, 상수, 불변, 상태변수 읽고 쓰기

3. 이더 단위, 가스와 가스가격

4. 조건문, 반복문, 맵핑(mapping)

5. 배열, 열거형(enum), 구조체(calldata,memory) 

6. 데이터 저장공간, 함수(view,pure 속성)

7. 에러(error), 함수수정자(modifier)

8. 이벤트(events), 생성자(constructor), 상속

9. 상속, 섀도잉,super키워드 함수 속성들

10. 인터페이스(interface), payable, 이더전송,받기 관련

11. Fallback, Call, Delegate(솔리디티 업그레이드 기법)

12. 함수 선택자(function selector), 다른 컨트랙트 사용 및 생성기법

13. Try Catch, Import(임포트), Library(라이브러리)

14. ABI 디코드, hash 함수, 서명검증, 가스최적화

* 블록체인 전문가들도 놓치기 쉬운 비트코인, 이더리움의 핵심가치 강의

블록체인 전문가들도 놓치기 쉬운 비트코인, 이더리움의 핵심 가치 - 인프런 | 강의

블록체인 기획자,개발자,회사 대표라면 반드시 한번은 봐야 하는 강의입니다. 따로 공부할 시간이 없었다면, 이 요약본 강의를 통해서 비트코인,이더리움 백서의 핵심을 이해할 수 있습니다., -

www.inflearn.com

솔리 디티 receive - solli diti receive

1. Fallback

 - fallback은 함수이며, 어떤 arguments(전달인자)나 return값을 가지지 않는다.

 - 존재하지 않는 함수를 호출하거나(계약 내에  존재하지 않는 함수명을 사용하는 경우 폴백 함수 자동으로 호출)

 - 쉽게 설명해서, 호출된 함수와 이름이 일치하는 함수가 없을 때 폴백 함수가 호출됨

 - 이더가 컨트랙트로 바로 보내질때 호출됨 - receive() 함수가 없거나, msg.data가 없어야 함

 - fallback은 transfer, send가 호출될때 2,300 gas 제한이 있음

예제)

 - Fallback 함수는 external로 선언되어야 함.

 - fallback 함수에서 send,transfer는 2,300 gas 제한이 있음.

 - call의 경우 모든 가스를 사용하게 됨

 - 

솔리 디티 receive - solli diti receive

- transfer()와 call()을 사용하여 이더 전송.

솔리 디티 receive - solli diti receive

전체소스

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

contract Fallback {
    event Log(uint gas);

    // Fallback function must be declared as external.
    fallback() external payable {
        // send / transfer (forwards 2300 gas to this fallback function)
        // call (forwards all of the gas)
        emit Log(gasleft());
    }

    // Helper function to check the balance of this contract
    function getBalance() public view returns (uint) {
        return address(this).balance;
    }
}

contract SendToFallback {
    function transferToFallback(address payable _to) public payable {
        _to.transfer(msg.value);
    }

    function callFallback(address payable _to) public payable {
        (bool sent, ) = _to.call{value: msg.value}("");
        require(sent, "Failed to send Ether");
    }
}

2. Call

 - call은 다른 컨트랙트와 상호작용하는 저수준(low lever) 함수다.

 - fallback 함수 호출을 통해서 이더를 보낼경우에 이러한 방법을 추천한다.

 - 그러나 존재하는 함수를 호출하는 방법으로는 추천하지 않는다.

예제) Receiver 컨트랙트에 fallback() 선언 후 foo()함수 정의

솔리 디티 receive - solli diti receive

- Caller 컨트랙트는 call을 사용하여 Receiver 컨트랙트의 함수를 호출.

솔리 디티 receive - solli diti receive

소스파일

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

contract Receiver {
    event Received(address caller, uint amount, string message);

    fallback() external payable {
        emit Received(msg.sender, msg.value, "Fallback was called");
    }

    function foo(string memory _message, uint _x) public payable returns (uint) {
        emit Received(msg.sender, msg.value, _message);

        return _x + 1;
    }
}

contract Caller {
    event Response(bool success, bytes data);

    // Let's imagine that contract B does not have the source code for
    // contract A, but we do know the address of A and the function to call.
    function testCallFoo(address payable _addr) public payable {
        // You can send ether and specify a custom gas amount
        (bool success, bytes memory data) = _addr.call{value: msg.value, gas: 5000}(
            abi.encodeWithSignature("foo(string,uint256)", "call foo", 123)
        );

        emit Response(success, data);
    }

    // Calling a function that does not exist triggers the fallback function.
    function testCallDoesNotExist(address _addr) public {
        (bool success, bytes memory data) = _addr.call(
            abi.encodeWithSignature("doesNotExist()")
        );

        emit Response(success, data);
    }
}

3. DelegateCall

 -  DelegateCall은 call과 유사한 저수준(low lever) 함수다.

 - 컨트랙트 A가 delegatecall을 실행하여 컨트랙트 B를 실행할 수 있다.

 - 컨트랙트 B의 코드가 컨트랙트 A의 스토리지(storage), msg.sender, msg.value를 통해서 실행됨

 - 아래 예제에서 B를 먼저 실행후 A에서 delegatecall을 사용한다.

 - B의 코드를 실행하지만, A의 컨트랙트에 데이터가 저장된다.

솔리 디티 receive - solli diti receive

소스파일

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

// NOTE: Deploy this contract first
contract B {
    // NOTE: storage layout must be the same as contract A
    uint public num;
    address public sender;
    uint public value;

    function setVars(uint _num) public payable {
        num = _num;
        sender = msg.sender;
        value = msg.value;
    }
}

contract A {
    uint public num;
    address public sender;
    uint public value;

    function setVars(address _contract, uint _num) public payable {
        // A's storage is set, B is not modified.
        (bool success, bytes memory data) = _contract.delegatecall(
            abi.encodeWithSignature("setVars(uint256)", _num)
        );
    }
}

* DelegateCall

솔리 디티 receive - solli diti receive

 - 호출된 컨트래트의 코드가 호출한 컨트랙트의 Context에서 수행됨

 - msg.sender와 msg.value가 변하지 않음

 - 컨트랙트가 런타임에 서로 다른 주소의 컨트랙트를 호출 할 수 있음

 - 스토리지, 주소, 잔액은 여전히 호출 컨트랙트 참조

 - 코드만 호출 주소에서 가져옴

 - 라이브러리

 - 업그레이드 가능한 스마트컨트랙트의 기본개념임!!

소스출처 : https://solidity-by-example.org/

블록체인 교육 문의는 아래 링크 참고 바랍니다. 

https://kimsfamily.kr/414

블록체인 교육 커리큘럼 및 프로필

안녕하세요 제 프로필을 간략하게 정리하였습니다. 비즈니스 문의는 으로 연락주시기 바랍니다. 감사합니다. 프로필) 블록체인 강의 경력) 1. 블록체인 강의 (20년~현재) 2022년  -

kimsfamily.kr

솔리 디티 receive - solli diti receive