ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 나만보는 Blockchain 개념 (4) 솔리디티로 이더 송금하기
    BlockChain/Technology 2021. 7. 27. 15:19

    오늘의 주제

    1. 컨트랙트에서 이더 송금하기

    2. fallback() 함수

    3. selfdestruct() 함수

     


    1. 컨트랙트에서 이더 송금하기

     

    Solidity 프로그래밍을 위해 remix.ethereum에 들어갑니다.

    새로 파일을 하나 만들고, 아래 코드를 작성하고 컴파일을 합니다.

     

    pragma solidity 0.8.6;
    
    contract Test1 {
        
        uint nonce;
        
        constructor(uint _nonce) payable {
            nonce = _nonce;   
        }
        
        function getNonce() public view returns (uint) {
            return nonce;
        }
        
        function withdraw(uint _nonce) public {
            require(nonce == _nonce);
            payable(msg.sender).transfer(address(this).balance);
        }
        
    }

     

    ↔ 실행결과

     

    이 코드를 실행하면 getNonce로 컨트랙트의 잔액을 확인하고 withdraw로 잔액을 호출한 사람의 주소로 인출합니다.

     

     

    ++코드 설명

    unint nonce 

    unint : 부호가 없는 정수형 타입

    nonce 변수를 선언하였습니다.

     

    constructor(unit _nonce) payable

    생성자 함수로 이 코드가 처음 배포될 때 실행된다. nonce에는 배포할 때 입력한 값이 담깁니다.

    payable 솔리디티의 특별한 키워드로 payable이 붙은 함수는 이더리움을 전송 받을 수 있게 됩니다.

    function getNonce() 

    컨트랙트에 있는 nonce값을 조회합니다. 그래서 view가 적혀있습니다.

     

    function withdraw()

    컨트랙트 계좌에 있는 잔액을 인출한다. msg.sender(함수를 호출한 사람)에게 this(컨트랙트)의 잔액을 보내줍니다.

    <address>.transfer(uint256 amount):
    주어진 양만큼의 이더를 Address 로 전송합니다.

     


    2. fallback() 함수

     

    fallback 함수는 이름이 없는 함수입니다. 어떤 계약이든 단 하나의 fallback 함수를 가질 수 있습니다. 매칭되는 함수가 존재하지 않거나 data없이 호출되었을 때 fallback 함수가 호출이 됩니다. 대비책 함수라고도 불립니다.

    fallback () external [payable]function
    키워드도 없고 이름도 없습니다. external 가시성을 갖고 payable을 선택적으로 가질 수 있습니다.이더를 받아야 한다면 payable을 명시합니다.

     

    아래 코드를 작성하고 실행해봅니다.

    pragma solidity 0.8.6;
    
    contract Test4 {
        
        uint balance;
        
        constructor() payable {
            balance = msg.value;
        }
        
        fallback() external payable {
            require(msg.value >= balance);
            payable(msg.sender).transfer(address(this).balance);   
        }
        
    }

     

    ↔ 실행결과

     

    생성자 함수가 있어 balance에는 배포했을 때의 msg.value 값이 담깁니다. 

    함수를 호출했을 때 컨트랙트에 함수가 없으므로 fallback 함수가 실행이 되서 

    msg.value가 balance보다 크다면 (require), 컨트랙트의 이더 잔액이 호출한 사람의 주소로 전송됩니다.

     

    ++코드 설명

    fallback() external payable

    fallback()에 external을 가지게 해서 외부 호출로 실행되게 합니다. payable이 붙었기 때문에 함수가 실행될 때 이더를 전송할 수 있습니다.

    : 함수의 가시성
    external / public / internal / private
        - private : contract 내부에서만 접근 가능합니다.
                     또한 이름을 명명할때 _를 많이 붙입니다.
        - internal : contract 내부와 상속된 contract에서 접근이 가능합니다.
                     외부에서는 접근할 수 없기 때문에 this 로 접근도 불가능합니다.
        - public : 모든 방법으로 접근할 수 있습니다. 외부 contract에서도 접근할 수 있습니다.
        - external : 다른 contract와 transaction으로만 호출 될 수 있습니다. 내부호출은 불가능합니다

     

    require(msg.value >= balance)은 호출한 사람의 value가 컨트랙트의 balance보다 커야 fallback함수가 실행되게 조건을 붙입니다.

     


    3. selfdestruct() 함수

     

    selfdestruct 함수는 말그대로 자체파괴하는 특징을 가졌습니다. 실행이 되면 이전의 기록들은 확인이 가능하지만 실행된 시점 이후의 컨트랙트 함수들은 실행되지 않습니다. 만약 컨트랙트에 대량의 이더가 담겨 있는데 해커의 공격으로 인해 컨트랙트에 이더가 묶이게 될 경우 안에 들어있는 이더를 다른 계정이나 컨트랙트로 전송할 수 있습니다. 컨트랙트가 배포된 상태로 존재하기 때문에 여러 위험으로부터 안전장치 역할을 수행합니다. 그렇기 때문에 실무에서는 이 함수를 사용할 수 있는 권한이 누구에게 있는지 반드시 확인해야 합니다.

     

    아래 코드는 파괴될 경우 msg.sender로 컨트랙트의 잔액이 이동하게 됩니다. 다른 컨트랙트로 보내는 방법은 이렇습니다. selfdestruct가 실행될 때  test7로 잔액을 보내고 싶다면 selfdestruct(test7)이라고 입력하면 파괴 후에 잔액이 이동하게 됩니다. test7에 payable이라는 속성이 없어도, test6의 남은 잔액을 이어받을 수 있습니다.

     

    pragma solidity 0.8.6;
    
    contract Test6 {
        
        constructor() payable {
            
        }
        
        function destroy() public {
            selfdestruct(payable(msg.sender));
        }
        
    }

     

     

     

    댓글

Designed by Tistory.