(Solidity) OpenZeppelin의 Context.sol 이해하기

오픈제플린이란?

OpenZeppelin은 Ethereum 스마트 계약 개발에 사용되는 오픈 소스 라이브러리입니다.

개발자가 안전하고 효율적인 스마트 계약을 구축할 수 있도록 보안이 검증된 계약 및 구성 요소를 제공합니다.

OpenZeppelin의 Context 계약은 이 라이브러리의 일부로 제공됩니다.

컨텍스트 계약이란 무엇입니까?

컨텍스트 계약은 현재 실행 컨텍스트에 대한 정보를 제공하는 추상 계약입니다.

트랜잭션의 발생자와 데이터를 처리하는데 사용되며 메타 트랜잭션과 같은 경우에도 정확한 정보를 처리할 수 있도록 도와줍니다.

GitHub – OpenZeppelin/openzeppelin-contracts: OpenZeppelin Contracts는 안전한 스마트 계약 개발을 위한 라이브러리입니다.

OpenZeppelin Contracts는 안전한 스마트 계약 개발을 위한 라이브러리입니다.

– GitHub – OpenZeppelin/openzeppelin-contracts: OpenZeppelin Contracts는 안전한 스마트 계약 개발을 위한 라이브러리입니다.

github.com

// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)

pragma solidity ^0.8.0;

/**
 * @dev Provides information about the current execution context, including the
 * sender of the transaction and its data. While these are generally available
 * via msg.sender and msg.data, they should not be accessed in such a direct
 * manner, since when dealing with meta-transactions the account sending and
 * paying for execution may not be the actual sender (as far as an application
 * is concerned).
 *
 * This contract is only required for intermediate, library-like contracts.
 */
abstract contract Context {
    function _msgSender() internal view virtual returns (address) {
        return msg.sender;
    }

    function _msgData() internal view virtual returns (bytes calldata) {
        return msg.data;
    }
}

댓글 섹션에 대한 설명은 다음과 같습니다.

@dev 현재 실행 컨텍스트에 대한 정보를 제공합니다.

여기에는 거래의 발신자와 데이터가 포함됩니다.

일반적으로 이 정보는 msg.sender 및 msg.data를 통해 사용할 수 있지만 메타 트랜잭션을 처리할 때 실행 비용을 지불하는 계정이 실제 발신자가 아닐 수 있으므로(응용 프로그램 관점에서) 이 방법으로 직접 액세스하십시오. 당신은해서는 안됩니다.

이 계약은 중간 및 라이브러리와 같은 계약에만 필요합니다.

주요 기능

컨텍스트 계약은 두 가지 주요 기능을 제공합니다.

_msgSender()

이 함수는 현재 트랜잭션의 보낸 사람을 반환합니다.

msg.sender를 직접 사용하는 대신 이 함수를 사용하여 발신자를 가져올 수 있습니다.

메타 트랜잭션과 같은 경우에도 보낸 사람 정보를 올바르게 처리하는 데 도움이 됩니다.

_msgData()

이 함수는 현재 트랜잭션의 데이터를 반환합니다.

msg.data를 직접 사용하는 대신 이 함수를 사용하여 데이터를 가져올 수 있습니다.

컨텍스트를 사용하는 이유는 무엇입니까?

컨텍스트 계약은 스마트 계약의 보안 및 간접성을 향상시킬 수 있습니다.

메타트랜잭션을 처리할 때 직접접속이 아닌 어플리케이션 관점에서 실제 발신자와 다를 수 있습니다.

_msgSender()그리고 _msgData()메타트랜잭션과 같은 특수한 상황도 고려하면서 발신자와 데이터를 안전하게 처리할 수 있는 기능을 사용하는 것이 바람직합니다.

또한 이러한 기능은 코드 재사용성과 유지 관리성을 향상시킵니다.

일반적인 트랜잭션 정보를 각각의 컨트랙트에 처리하는 로직을 중복해서 작성하는 대신 Context 컨트랙트를 상속받아 필요한 기능을 쉽게 임포트할 수 있습니다.

보안 강화?

Context 계약을 사용하여 보안을 강화한 이유는 주로 메타 트랜잭션과 관련이 있습니다.

메타트랜잭션은 트랜잭션의 발신자와 실행에 대한 비용을 지불하는 계정이 다를 수 있는 특별한 트랜잭션입니다.

이 경우 msg.sender를 직접 사용하면 실제로 트랜잭션을 보낸 계정이 아니라 실행에 대한 가스를 지불한 계정을 참조하게 됩니다.

이로 인해 발생할 수 있는 보안 문제나 오류를 방지하기 위해 Context 계약의 _msgSender() 함수를 사용하는 것이 좋습니다.

_msgSender() 함수를 사용하면 메타 트랜잭션의 경우에도 실제 트랜잭션을 시작한 계정을 올바르게 참조할 수 있습니다.

따라서 악의적인 사용자가 가스를 지불하는 계정을 변경하여 스마트 계약의 논리를 손상시키는 것을 방지할 수 있습니다.

또한 메타트랜잭션과 관련된 다양한 구현 방법이 있으므로 원하는 방법에 따라 _msgSender() 함수를 오버라이드하여 구현할 수 있습니다.

이러한 유연성은 스마트 계약의 보안을 강화합니다.

결론

OpenZeppelin의 Context는 이더리움 스마트 계약 개발에서 발신자와 데이터를 쉽고 안전하게 처리할 수 있는 도구를 제공합니다.

이를 활용하면 메타 트랜잭션과 같은 상황에서도 올바르게 작동하는 스마트 컨트랙트를 구축할 수 있고, 코드 재사용성과 유지보수성도 높일 수 있습니다.

따라서 스마트 계약 개발자는 OpenZeppelin 라이브러리 및 컨텍스트 계약을 활용하여 보다 강력한 애플리케이션을 구축하도록 권장됩니다.