Study/Blockchain & Solidity

[Solidity 깨부수기] 상속 & 이벤트 (2)

veriperi 2024. 6. 5. 03:04
728x90

01 Event - 정의

▶ 솔리디티에는 print 대신 event를 활용하여 값을 출력할 수 있다. → 즉, 이벤트로 값을 출력할 때 그 값들은 블록 안에 저장이 된다. 이렇게 블록 안에 저장된 값을 언제든 꺼내서 쓸 수 있다.

 

📌 Event 정의 방법→  event '이벤트의 이름' ('쓰고자 하는 타입' '이름');

// SPDX-License-Identifier: MIT

pragma solidity >=0.8.0 <0.9.0;

contract lec13 {
   
    event info(string name, uint256 money);

}

현재 info라는 이벤트를 생성하여 string name과 uint256 money 이렇게 두 개의 값들을 출력하고자 예제를 작성하였다.

 

이 이벤트를 출력하기 위해서 sendMoney 함수를 생성할 수 있다.

만약, sendMoney 함수를 사용 시, 누가 보냈는지에 대한 기록이 필요하므로 info 값에 보내는 사람의 이름과 얼마를 보내는지에 대한 값을 출력할 수 있다. 이 값들이 출력될 경우 블록체인 안에 있는 블록에 저장된다.

 

블록이 저장되면 해당 블록은 불변하기에 언제든 꺼내서 쓸 수 있다.

이후 실행되면 log의 info 부분에 출력된 것을 확인할 수 있다.

 

 

02 Event - indexed

▶ 이벤트 내에서만 사용할 수 있는 event의 키워드로, 특정한 이벤트의 값들을 들고 올 때 사용된다.

 

// SPDX-License-Identifier: MIT

pragma solidity >=0.8.0 <0.9.0;

contract Lec14 {
    event numberTracker(uint256 num, string str);
    event numberTracker2(uint256 indexed num, string str);

    uint256 num =0;
    function PushEvent(string memory _str) public {
        emit numberTracker(num,_str);
        emit numberTracker2(num,_str);
        num ++;
    }
}

현재 작성된 2개의 이벤트에 대해 확인할 수 있다.여기서 numberTracker2는 indexed가 추가되어 num을 통해 특정 이벤트 값들을 갖고 올 수 있다. 예를 들어 numberTraker2가 10개의 이벤트가 있다고 가정했을 때 1부터 10까지가 있다. 이후 5라는 num만 필요하다고 가정했을 때 5만 입력하여 numberTraker2의 이벤트를 가져올 수 있다.

 

반대로 numberTraker는 동일한 상황에서 5라는 num만 필요하다고 가정했을 때 5만 적힌 이벤트를 갖고 올 수 없다. 즉, 인덱스를 통해 원하는 이벤트 값들을 필터링하여 갖고올 수 있음을 알 수 있다.

 

이를 확인해보기 위해 위와 같이 .js 코드를 작성해줄 수 있다. 추가로 생략된 부분이 있어 실습은 진행하지 못하였다.getPastEvents 함수를 사용하고 있고, num을 통해 필터링을 진행해줄 수 있다. num은 2나 1일 때인 이벤트를 갖고올 수 있다. fromBlock과 toBlock은 범위를 말고 있다.

 

이후 출력 결과를 확인해보니 events 즉, numberTracker2는 두 번째와 첫 번째 이벤트만 출력되고, events2는 numberTracker의 모든 이벤트 값들이 출력이 될 수 있다.

 

 

03 상속 - super

▶ 함수를 오버라이딩 할 때 사용하는 것으로, super을 통해 원래의 함수들을 갖고 올 수 있다.

 

// SPDX-License-Identifier:GPL-30
pragma solidity >= 0.7.0 < 0.9.0;

contract Father {
    event FatherName(string name);
    function who() public virtual{
        emit FatherName("KimDaeho");
    }
}

contract Son is Father{
    event sonName(string name);
    function who() public override{
        emit FatherName("KimDaeho");
        emit sonName("KimJin");
    }
}

현재 father과 son이라는 부자관계의 스마트 컨트랙이 있다. 

father 안에는 event fatherName 그리고 이 function who를 사용하면 이 fatherName이 출력된다. son이라는 스마트 컨트랙도 마찬가지로 이 sonName son의 이름을 나타내는 이벤트 값이 있고 이 who라는 function을 아버지 컨트랙으로부터 상속받고 오버라이딩 하고 있음을 확인할 수 있다.

 

하지만, who라는 function 자체가 엄청 길다고 가정했을 때 하나하나 작성해줄 수 없으므로 super을 사용하여 작성해줄 수 있다.

// SPDX-License-Identifier:GPL-30
pragma solidity >= 0.7.0 < 0.9.0;

contract Father {
    event FatherName(string name);
    function who() public virtual{
        emit FatherName("KimDaeho");
    }
}

contract Mother {
    event MotherName(string name);
    function who() public virtual{
        emit MotherName("leeSol");
    }
}

contract Son is Father{
    event sonName(string name);
    function who() public override{
        super.who();
        emit sonName("KimJin");
    }
}

즉, 위와 같이 코드를 수정하여 super을 활용해 작성해줄 수 있다.

 

 

04 상속의 순서

▶ 상속의 순서를 통해 super가 어떻게 작동하는지 알아보자

// SPDX-License-Identifier:GPL-30
pragma solidity >= 0.7.0 < 0.9.0;

contract Father {
    event FatherName(string name);
    function who() public virtual{
        emit FatherName("KimDaeho");
    }
}

contract Mother {
    event MotherName(string name);
    function who() public virtual{
        emit MotherName("leeSol");
    }
}

contract Son is Father, Mother{
    
    function who() public override(Father,Mother){
        super.who();
    }
}

위 코드에서는 가족 관계의 스마트 컨트랙이 있다. father, mother 그리고 son이 있다. son은 father와 mother를 상속받고 있다. father과 mother은 who라는 function이 있다. 이 두 function에서 son은 who를 오버라이딩하고 있다.

 

여기서 2개의 who 중 mother name을 갖고 온 것을 알 수 있다. 그 이유를 조금 더 살펴보자면 Son is Father, Mother이므로 즉, Mother 두번째로 상속받은 가장 최신의 것이기 때문이다.

 

이를 배포 후 실행시켜보면 위와 같은 결과를 확인할 수 있다.

 

 

 

출처 : https://inf.run/qNVC
728x90