블록체인 학습
0 XP

msg.value

함수가 호출될 때 그 호출과 함께 보내진 Ether 의 양은 전역 변수 msg.value 로 읽을 수 있습니다. 단위는 항상 Wei 이며 타입은 uint256 입니다. "이번 호출에 돈이 얼마나 딸려 왔는가"를 알려 주는 값입니다. 결제, 입금, 기부 같은 모든 자금 관련 로직이 이 변수에서 출발합니다.

msg.value 와 payable 의 관계

msg.value 가 0보다 큰 값을 가지려면, 호출되는 함수가 반드시 payable 이어야 합니다. payable 이 아닌 함수에 Ether 를 실어 보내면 msg.value 를 읽기도 전에 트랜잭션 자체가 실패(revert)하고, 그런 함수 안에서 msg.value 는 항상 0입니다.

payable 이 돈을 받을 문을 여는 쪽이라면, msg.value 는 그 문으로 들어온 액수를 읽는 쪽입니다.

보낸 금액 검증하기

require 와 msg.value 를 함께 쓰면 "정확히 얼마를 보내야 한다" 또는 "최소 얼마 이상이어야 한다" 같은 결제 조건을 강제할 수 있습니다. 조건을 만족하지 못하면 트랜잭션이 되돌려지고, 보낸 Ether 도 함께 호출자에게 되돌아갑니다.

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
 
contract PaymentGate {
    uint256 public lastPaid;
 
    // 보낸 금액(msg.value)을 그대로 기록합니다.
    function pay() public payable {
        lastPaid = msg.value;
    }
 
    // 정확히 1 ether 를 보내야만 통과합니다.
    function payExactlyOneEther() public payable {
        require(msg.value == 1 ether, "must send exactly 1 ether"); // 정확히 1 ether
    }
 
    // 최소 0.1 ether 이상이어야 통과합니다.
    function payAtLeast() public payable {
        require(msg.value >= 0.1 ether, "min 0.1 ether"); // 0.1 ether 이상
    }
}

msg.sender 는 "누가 호출했는가"(주소), msg.value 는 "얼마를 함께 보냈는가"(금액)를 알려 줍니다. 결제 로직에서는 이 두 값을 함께 읽어 누가 얼마를 냈는지 처리합니다.

msg.value 의 단위는 항상 Wei 이므로, 비교할 때도 1 ether 같은 단위 접미사를 함께 써 주면 사람이 의도한 금액과 정확히 일치하는지 안전하게 검증할 수 있습니다.

Code Editor
에디터를 불러오는 중...
실행 결과

Run 버튼을 눌러 코드를 실행하세요.