블록체인: EVM 명령어

독수리박박·2024년 5월 20일
0

EVM 명령어


1. 스택 명령어

  • PUSHn: 스택에 n바이트 값을 푸시합니다.
    • 예: PUSH1 0x60 (값 0x60을 스택에 푸시)
  • POP: 스택에서 값을 하나 팝합니다.
  • DUPn: 스택의 n번째 값을 복사하여 스택 맨 위에 푸시합니다.
    • 예: DUP1 (스택 맨 위의 값을 복사)
  • SWAPn: 스택 맨 위의 값과 n번째 값을 교환합니다.
    • 예: SWAP1 (스택 맨 위의 값과 두 번째 값을 교환)

2. 메모리 및 저장소 명령어

  • MLOAD: 메모리에서 값을 로드합니다.
  • MSTORE: 메모리에 값을 저장합니다.
  • SLOAD: 계약 저장소에서 값을 로드합니다.
  • SSTORE: 계약 저장소에 값을 저장합니다.

3. 산술 및 논리 명령어

  • ADD: 스택의 두 값을 더합니다.
  • SUB: 스택의 두 값을 뺍니다.
  • MUL: 스택의 두 값을 곱합니다.
  • DIV: 스택의 두 값을 나눕니다.
  • AND: 스택의 두 값을 AND 연산합니다.
  • OR: 스택의 두 값을 OR 연산합니다.
  • XOR: 스택의 두 값을 XOR 연산합니다.
  • NOT: 스택의 맨 위 값을 NOT 연산합니다.

4. 제어 흐름 명령어

  • JUMP: 스택 맨 위의 주소로 무조건 점프합니다.
  • JUMPI: 스택 맨 위의 주소로 조건부 점프합니다.
  • PC: 현재 명령어의 프로그램 카운터를 푸시합니다.
  • JUMPDEST: 점프할 수 있는 유효한 목적지 주소를 표시합니다.

5. 환경 명령어

  • CALLER: 호출자의 주소를 푸시합니다.
  • CALLVALUE: 트랜잭션의 값을 푸시합니다.
  • CALLDATALOAD: 트랜잭션의 데이터 페이로드를 로드합니다.
  • CALLDATASIZE: 트랜잭션 데이터의 크기를 푸시합니다.
  • CALLDATACOPY: 트랜잭션 데이터를 메모리로 복사합니다.
  • CODESIZE: 현재 코드의 크기를 푸시합니다.
  • CODECOPY: 현재 코드를 메모리로 복사합니다.

6. 로그 명령어

  • LOGn: 로그 항목을 기록합니다. n은 추가되는 토픽의 수를 나타냅니다.
    • 예: LOG1 (하나의 토픽을 포함한 로그를 기록)

7. 시스템 명령어

  • CREATE: 새 계약을 생성합니다.
  • CALL: 다른 계약을 호출합니다.
  • CALLCODE: 다른 계약의 코드를 현재 계약의 컨텍스트에서 호출합니다.
  • DELEGATECALL: 다른 계약의 코드를 호출자의 컨텍스트에서 실행합니다.
  • SELFDESTRUCT: 계약을 파괴하고 잔액을 지정된 주소로 보냅니다.

EVM 명령어를 활용한 인라인 어셈블리 활용 예시

  1. ADD
pragma solidity ^0.8.0;

contract InlineAssembly {
    function add(uint256 a, uint256 b) public pure returns (uint256 result) {
        assembly {
            // 스택에 'a'와 'b'를 푸시
            let x := a
            let y := b
            // ADD 명령어를 사용하여 두 값을 더함
            result := add(x, y)
        }
    }
}
  1. 조건부 점프 JUMPI
pragma solidity ^0.8.0;

contract InlineAssembly {
    function conditionalJump(uint256 value) public pure returns (uint256) {
        assembly {
            let result
            switch value
            case 0 {
                // value가 0일 경우
                result := 0
            }
            default {
                // value가 0이 아닐 경우
                result := 1
            }
            mstore(0x80, result) // 메모리에 결과를 저장
            return(0x80, 32)     // 결과 반환
        }
    }
}
  1. 스택 조작: PUSH, POP, DUP, SWAP 명령어
pragma solidity ^0.8.0;

contract InlineAssembly {
    function stackManipulation() public pure returns (uint256) {
        assembly {
            // 스택에 값을 푸시
            let a := 1
            let b := 2
            let c := 3
            
            // DUP 명령어를 사용하여 스택의 맨 위 값을 복사
            dup1
            
            // SWAP 명령어를 사용하여 스택의 두 값을 교환
            swap1
            
            // 스택에서 값을 팝
            pop
            
            // 결과값을 반환
            mstore(0x80, a) // 메모리에 값을 저장
            return(0x80, 32) // 결과 반환
        }
    }
}

솔리디티에서 인라인 어셈블리를 사용하는 것은 고급 기능으로, 보안과 최적화를 위해 주의해서 사용해야 합니다. 인라인 어셈블리는 주로 성능 최적화나 복잡한 저수준 작업을 수행할 때 사용됩니다.

0개의 댓글