일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
- 알고리즘
- DEFI
- 재진입공격
- POS
- 블록체인
- 블록체인 기술
- .dsym
- reentrancy
- 프로그래머스
- pow
- view 이동
- DPOS
- solidity
- 암호화폐
- 백준
- Report
- PBFT
- 비트코인
- dsYM
- Crash
- 이더리움
- Mining
- Xcode
- External Call
- ios
- ethereum
- 분산원장
- viewcontroller
- Blockchain
- Algorithm
- Today
- Total
개발하기좋은날
스마트 컨트랙트 시큐리티 패턴 본문
이전 포스팅에서
Checks Effects Interaction, Mutex Pattern
알아보고 재진입 공격에 대해서 포스팅을 하였습니다
이번엔 그밖에 다양한 시큐리티 패턴에 대해 알아보고자 합니다
1. Emergency Stop Pattern
- 블록체인에 배포된 스마트컨트랙트는 수정이 불가능합니다
그래서 예기치 못한 버그로 인해서 큰 피해를 줄 수 있는데 Emergency Stop Pattern은 특정 함수들이 실행되지 않도록 제어할 수 있도록 프로그래밍하는 패턴입니다. 쉽습니다
contract EmergencyStop is Owned {
bool public contractStopped = false;
modifier haltInEmergency {
require(contractStopped)
_;
}
modifier enableInEmergency {
require(!contractStopped)
_;
}
function toggleContractStopped() public onlyOwner {
contractStopped = !contractStopped;
}
function deposit() public payable haltInEmergency {
// some code
}
function withdraw() public view enableInEmergency {
// some code
}
}
컨트랙트의 Owner만이 function의 제어권을 조절할수있습니다.
haltInEmergency로 함수를 제어합니다 Owner만이 contractStopped의 변수값을 수정할 수 있습니다.
2. Speed Bump Pattern
- 과속 방지턱 패턴은 이름에서 알 수 있듯이 보행자를 보호하기 위한 안전장치입니다
Speed Bump Pattern은 특정 함수를 실행하기 위해서 의도적으로 시간을 지연시키거나 한 번에 인출할 수 있는
금액에 제한을 두는 패턴입니다.
이렇게 하는 이유는 특정 함수를 다수의 사용자가 무제한적으로 호출함으로 컨트랙트에 이상이 생기는 것을 방지하기 위함입니다.
contract SpeedBump {
struct Withdrawal {
uint amount;
uint requestedAt;
}
mapping (address => uint) private balances;
mapping (address => Withdrawal) private withdrawals;
uint constant WAIT_PERIOD = 7 days;
function deposit() public payable {
if(!(withdrawals[msg.sender].amount > 0)) {
balances[msg.sender] += msg.value;
}
}
function requestWithdrawal() public {
if (balances[msg.sender] > 0) {
uint amountToWithdraw = balances[msg.sender];
balances[msg.sender] = 0;
withdrawals[msg.sender] = Withdrawal({ amount: amountToWithdraw, requestedAt: now });
}
}
function withdraw() public {
if(withdrawals[msg.sender].amount > 0 && now > withdrawals[msg.sender].requestedAt + WAIT_PERIOD) {
uint amount = withdrawals[msg.sender].amount;
withdrawals[msg.sender].amount = 0;
msg.sender.transfer(amount);
}
}
}
deposit을 통해 입금한 Balances를 인출하기 위해서는 withdraw() 수행이 가능합니다
인출하기위해서는 두 가지 조건이 필요합니다
requestWithdrawal() 호출을 통해서 예약을 하고, WAIT_PERIOD의 인출시간이 지나야지만 최종적으로 인출이 가능합니다.
3. Rate Limit Pattern
- 위 패턴은 함수를 호출할 수 있는 빈도를 제한하는 패턴입니다.
아래의 코드는 함수 F가 한번 실행이 되면 1분이 지나야 만 다시 실행할 수 있도록 구현되어 있습니다.
contract RateLimit {
uint enabledAt = now;
modifier enabledEvery(uint t) {
if (now >= enabledAt) {
enabledAt = now + t;
_;
}
}
function f() public enabledEvery(1 minutes) {
// some code
}
}
4. Balance Limit Pattern
- 스마트 컨트랙트 내의 잔액의 최댓값을 설정하여, 최대값 이상으로 컨트랙트로 금액이 보내지는 것을 막는 패턴입니다.
contract LimitBalance {
uint256 public limit;
function LimitBalance(uint256 value) public {
limit = value;
}
modifier limitedPayable() {
require(this.balance <= limit);
_;
}
function deposit() public payable limitedPayable {
// some code
}
}
위 코드는 LimitBalance 함수를 통해 컨트랙트에서 보유할 수 있는 최대 잔액을 설정한 후, 보유한 잔액이 설정된 최대 잔액보다 작을 때만 deposit 함수를 실행할 수 있도록 구현되어 있습니다.
위와 같은 패턴들은 예기치 못하는 상황을 사전에 방지할 수 있으며 스마트 컨트랙트의 안정성을 높여주는 패턴이므로
꼭 염두에 두자
다음엔 Maintenance Pattern에 대해서 알아보자
'BlockChain' 카테고리의 다른 글
이더리움의 MEV (Maximal Extractable Value) (0) | 2022.12.07 |
---|---|
Fallback, Receive 그리고 재진입 공격 (0) | 2022.10.30 |
재진입 공격 방지 (Re-Entrancy) (0) | 2022.10.28 |
External Call 보안 (0) | 2022.10.28 |
채굴 (Mining) (0) | 2022.10.17 |