Solidity에서 assembly("memory-safe") {} 문법 설명
1. 개요
Solidity 0.8.20부터 assembly 블록을 사용할 때 메모리 안전성을 보장하기 위해 assembly("memory-safe") {} 문법이 도입되었습니다.
이 기능은 내부적으로 메모리 할당을 안전하게 처리하는 코드만 허용하며, 메모리 충돌을 방지하여 보안성을 높입니다.
2. 기존 assembly 블록과의 차이점
Solidity에서는 Yul 어셈블리 (assembly {} 블록)를 통해 저수준 연산을 직접 수행할 수 있습니다.
하지만, 일반적인 assembly {} 블록은 메모리 충돌(memory corruption) 위험이 존재합니다.
이를 해결하기 위해 “memory-safe” 모드가 추가되었습니다.
📌 기존 assembly {} 예제 (메모리 안전성 보장 없음)
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
contract UnsafeAssembly {
function getFreeMemoryPointer() public pure returns (uint256 ptr) {
assembly {
ptr := mload(0x40) // 메모리 프리 포인터 로드
}
}
}
✅ mload(0x40)을 사용하여 현재 **사용 가능한 메모리 주소(프리 포인터)**를 가져올 수 있습니다.
❌ 하지만 memory-safe 모드가 없으면 메모리 충돌이 발생할 가능성이 있습니다.
3. assembly("memory-safe") {} 사용 방법
assembly("memory-safe") {}를 사용하면 메모리 안전성이 보장되는 범위 내에서만 어셈블리 코드 실행이 가능합니다.
📌 assembly("memory-safe") {} 적용 예제
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
contract SafeAssembly {
function getFreeMemoryPointer() public pure returns (uint256 ptr) {
assembly ("memory-safe") {
ptr := mload(0x40) // 안전하게 메모리 포인터 로드
}
}
}
✅ "memory-safe"를 선언하면 Solidity 컴파일러가 메모리 안전성을 보장하도록 강제합니다.
4. memory-safe 모드의 주요 특징
✅ 1) 허용되는 연산
• mload(0x40), mstore(0x40, ptr) 등 프리 메모리 포인터 관련 연산 허용.
• calldatacopy(), codecopy() 등 데이터 복사 연산 사용 가능.
• return() 및 revert() 같은 정상적인 컨트롤 플로우 지원.
❌ 2) 금지되는 연산
• 메모리 충돌을 유발할 수 있는 연산은 사용할 수 없음.
• 직접적인 메모리 할당 (malloc-like behavior) 금지.
• 메모리 바운더리를 벗어난 직접 접근은 제한됨.
5. 기존 assembly {}와의 비교
구분기존 assembly {}assembly("memory-safe") {}
| 메모리 충돌 방지 | ❌ 불가능 | ✅ 가능 |
| 직접적인 메모리 조작 가능 | ✅ 가능 | ❌ 제한됨 |
| 컴파일러 검증 여부 | ❌ 없음 | ✅ 검증 수행 |
| 추천 사용 사례 | 메모리 직접 조작 필요 시 | 보안이 중요한 코드 |
6. memory-safe 모드가 중요한 이유
1. 메모리 오버플로우 및 데이터 오염 방지
• assembly 블록에서 잘못된 메모리 조작을 수행하면 중요한 데이터가 손상될 수 있습니다.
• "memory-safe" 모드를 사용하면 Solidity 컴파일러가 자동으로 이러한 문제를 방지합니다.
2. 컨트랙트의 보안 강화
• assembly {}를 사용하면 가스 비용이 절약되지만, 잘못된 메모리 접근이 발생할 위험이 있음.
• assembly("memory-safe") {}는 제한된 범위 내에서만 안전한 연산 수행을 허용하여 해킹 위험을 줄입니다.
3. Solidity 코드 유지보수 용이
• "memory-safe"를 선언하면, 향후 Solidity 버전이 업데이트될 때 더 적은 변경 사항으로 코드를 유지할 수 있습니다.
7. 결론
🔹 Solidity 0.8.20부터 도입된 "memory-safe" 모드는 메모리 안전성을 보장하면서도 어셈블리 코드의 장점을 활용할 수 있도록 합니다.
🔹 기본적으로 assembly("memory-safe") {}를 사용하는 것이 추천되며, 정말 필요한 경우에만 기존 assembly {}를 활용해야 합니다.
🔹 앞으로 Solidity에서는 "memory-safe" 모드를 기본으로 설정하는 방향으로 발전할 가능성이 높습니다. 🚀
'Solidity' 카테고리의 다른 글
| Solidity 에서 메모리 읽기 - mload() 와 add() (0) | 2025.02.20 |
|---|---|
| 저수준 호출(low-level call) 문법 - call, staticCall, delegateCall (0) | 2025.02.20 |
| Solidity 개발 시, 가스비 절감을 위한 최적화 기법 (1) | 2025.01.03 |
| Ethereum 에서 사용할 수 있는 주요 오라클 서비스 (2) | 2025.01.03 |
| 외부 오라클을 사용한 난수 생성 방법 (5) | 2025.01.03 |