스마트 컨트랙트는 암호학자 닉 사보가 구상한 것으로 90년대 초부터 존재했습니다. 역사가 오래됐음에도 불구하고, 스마트 컨트랙트는 2015년 이더리움이 도입된 이후에야 주류가 되었습니다. 그리고 현재 스마트 컨트랙트는 거의 모든 블록체인 활동의 기반이 되고 있습니다.
스마트 컨트랙트를 읽는 것은 구조와 코드 블록을 이해하는 것입니다. 스마트 컨트랙트 읽기에 어느 정도 익숙해지면 결국 솔리디티 프로그래밍 언어나 다른 플랫폼별 언어를 사용해 스마트 컨트랙트를 작성할 수 있습니다. 하지만 여기서 스마트 컨트랙트를 읽고 쓰는 데서 끝나는 것이 아닙니다. 스마트 컨트랙트는 복잡한 탈중앙화 금융(DeFi) 프로토콜과 탈중앙화 애플리케이션(DApp)의 기반이 되는 만큼, 위험과 취약점이 없어야 합니다. 이 지점에서 스마트 컨트랙트 감사가 도움이 됩니다. 이번 글에서는 스마트 컨트랙트 읽기, 쓰기, 감사와 관련한 모든 것을 다룹니다.
- 스마트 컨트랙트 읽기
- 스마트 컨트랙트의 중요성
- 스마트 컨트랙트의 특징
- 특징에 따른 스마트 컨트랙트 읽기
- 스마트 컨트랙트의 다른 부분 읽기
- 디앱과 스마트 컨트랙트
- 스마트 컨트랙트를 위한 블록체인
- 올바른 블록체인 플랫폼 선택하기
- 스마트 컨트랙트를 읽는 법을 배워야 하는 이유
- 스마트 컨트랙트 작성 방법
- 누구나 스마트 컨트랙트를 작성할 수 있나요?
- 프로그래밍 시작하기
- 첫 번째 스마트 컨트랙트 작성 및 배포
- 스마트 컨트랙트 개발 및 모범 사례
- 배포된 스마트 컨트랙트와 상호작용
- 스마트 컨트랙트를 어떻게 감사하나요?
- 스마트 컨트랙트를 감사 전략
- 코드를 올바르게 검토하는 방법
- 기타 체인과 코드 검토
- 스마트 컨트랙트 감사의 유형
- 최고의 스마트 컨트랙트 감사 사례
- 스마트 컨트랙트 개발과 인공지능
- 자주 찾는 질문/답
스마트 컨트랙트 읽기
스마트 컨트랙트는 일련의 조건이 충족될 때 실행되는 프로그래밍 가능한 코드 조각입니다. 이는 법적 구속력이 있는 실제 계약과 동일한 것이며, 블록체인에서는 코드가 법이 됩니다. 스마트 컨트랙트는 블록체인에 존재하므로 변조할 수 없는 불변성을 지닙니다. 스마트 컨트랙트를 특별하게 만드는 것은 무엇보다도 이 불변함입니다.
스마트 컨트랙트 이해: 기본 사항과 목적
스마트 컨트랙트는 블록체인 특정 트랜잭션을 자동화하기 위한 것입니다. 조건에 따른 계약이므로 중개자가 필요하지 않습니다. 스마트 컨트랙트가 유용한 이유는 금융 서비스와 공급망 관리 등 다양한 곳에 호환할 수 있기 때문입니다. 또, 한 번에 프로그래밍되는 기존의 코드 덩어리와 달리 스마트 컨트랙트는 매우 안전하며 시간 집약적인 전략이 필요합니다.
스마트 컨트랙트는 이더리움 블록체인의 ERC-20과 같은 블록체인 전용 토큰과 함께 작동하며 트랜잭션을 이동시킬 수 있습니다. 코드와 조건, 비용이 수반되기 때문에 읽고, 쓰고, 감사할 때 주의해야 합니다.
스마트 컨트랙트의 중요성
스마트 컨트랙트의 진정한 의미는 그 성격과 포지셔닝에 관한 것입니다. 특정 시나리오(예: A라는 사람이 B라는 사람에게 서비스를 완료할 때 자금을 이체하는 경우)의 경우, 스마트 컨트랙트의 사본이 블록체인 노드에 저장되고 실행됩니다. 스마트 컨트랙트는 체인 내에 컨트랙트 코드로 저장됩니다. 이러한 다중 경로 유효성 검사는 블록체인의 핵심 특성이며 보안이 유지되어야 합니다.
또한 순차적 또는 동기식 스마트 컨트랙트와 작업이 병렬로 실행되는 비동기식 스마트 컨트랙트도 존재합니다. 따라서 스마트 컨트랙트의 유형과 목적에 따라 작성, 읽기, 감사 방식이 결정됩니다.
스마트 컨트랙트에 의해 관리되는 표준 유동성 풀을 예로 들어보겠습니다.
토큰 풀을 거래에 사용할 수 있고, 거래가 성공할 때마다 총 거래 가치의 0.3%가 해당 거래를 가능하게 하거나 유동성을 추가한 유동성 공급자에게 전송된다고 상상해 보겠습니다. 거래 시나리오와 거래 수수료, 규정 미준수 및 거래 실패 조건을 강조하는 모든 조건은 스마트 컨트랙트로 코딩되어 체인 내에 코드로 저장됩니다.
스마트 컨트랙트의 특징
계약의 특성을 알지 못하면 계약의 읽기, 쓰기, 감사에 대해 자세히 알아볼 수 없습니다. 다음은 꼭 알아두어야 할 표준 스마트 컨트랙트 특성입니다.
프로그래밍 가능한 계약
스마트 컨트랙트는 단순한 코드 조각입니다. 개발자는 특정 조건에 따라 명령과 시나리오를 실행하는 스마트 컨트랙트를 작성할 수 있습니다. 현재 대부분의 탈중앙 금융 공간에서 유동성 풀의 거래 수수료 처리, APY 비율 유지 등과 같은 복잡한 거래를 처리하기 위해 스마트 컨트랙트에 의존하고 있습니다.
신뢰가 필요 없음
블록체인에서 작동하는 스마트 컨트랙트는 사람의 개입을 원천적으로 차단합니다. 이 때문에 개별 사용자나 기관 사이의 상호 신뢰를 필요로 하지 않습니다. 예를 들어, 스마트 컨트랙트가 적용되는 특정 탈중앙 금융 프로토콜이 자산 가치가 임계값 아래로 떨어지면 자산을 청산하기로 합의하면 사람이 개입할 수 없으며, 개입해서는 안 됩니다. 이 코드는 결제와 성능, 관리, 규칙을 처리하는 데 인간의 개입을 통제합니다.
자율성
앞서 언급했듯이 스마트 컨트랙트에는 자체 실행 명령어 세트가 탑재되어 있습니다. 코딩 측면에서 이는 상용구 안에 반복 명령어가 내장되어 있다는 것을 의미합니다. 이를 통해 결제와 출금, 입금 등을 통한 검증인 처벌 및 기타 여러 작업을 자율적으로 처리할 수 있습니다.
보안
스마트 컨트랙트는 암호화를 사용해 보안이 유지되므로 이를 위반하는 것은 매우 어렵습니다. 내장된 취약점이 없다면 스마트 컨트랙트를 우회한다는 것은 전체 블록체인이 보는 앞에서 공개적으로 규칙 위반을 시도하는 것을 의미합니다. 이 때문에 보안성이 매우 높습니다.
검증 가능
스마트 컨트랙트를 통해 처리된 트랜잭션은 자체 검증이 가능합니다. 인간의 활동이 개입되지 않습니다. 자체 검증이 가능한 메커니즘 덕분에 스마트 컨트랙트는 기존 은행 설정을 관리하는 기존 계약보다 신뢰성 부분에서 우위를 점할 수 있습니다.
특징에 따른 스마트 컨트랙트 읽기
다음은 에스크로 계좌를 나타내는 간단한 스마트 컨트랙트입니다. 사용자가 에스크로에 자금을 예치하고 특정 기간이 지나면 수취인에게 동일한 금액이 이동합니다.
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
// Basic Smart Contract Boilerplate
contract SimpleTrustlessEscrow {
// State variables
address public depositor; // Account depositing ether
address payable public beneficiary; // Account receiving ether
uint256 public releaseTime; // Timestamp to release ether
// Events for verifying contract activity
event Deposited(address indexed _from, uint256 _value);
event Released(address indexed _to, uint256 _value);
// The contract constructor initializes the smart contract
constructor(address payable _beneficiary, uint256 _releaseTime) {
require(_releaseTime > block.timestamp, “Release time must be in the future”);
// Secure and Trustless: Contract binds depositor and beneficiary
depositor = msg.sender;
beneficiary = _beneficiary;
releaseTime = _releaseTime;
}
// Deposit function – autonomous execution (fallback function)
receive() external payable {
emit Deposited(msg.sender, msg.value);
}
// Release the ether to the beneficiary
function release() public {
// Programmable: Can only be executed after releaseTime
require(block.timestamp >= releaseTime, “Too early to release”);
// Autonomous: Automatically executes based on condition
uint256 amount = address(this).balance;
beneficiary.transfer(amount);
emit Released(beneficiary, amount);
}
}
이 스마트 컨트랙트를 자세히 해독하고 읽어보겠지만, 앞서 언급한 컨트랙트 특성을 준수하는지 확인해 보겠습니다.
프로그래밍 가능한 부분
컨트랙트에서 이 코드를 자세히 살펴보세요.
require(block.timestamp >= releaseTime, “Too early to release”);
uint256 amount = address(this).balance;
beneficiary.transfer(amount);
특정한 ‘릴리스 타임(releaseTime)’ 조건이 충족될 때만 자금이 해제됩니다. 이러한 조건들은 계약이 프로그래밍으로 설정될 수 있게 합니다.
신뢰가 필요 없는 부분
다음은 위의 간단한 코드 조각입니다.
depositor = msg.sender;
beneficiary = _beneficiary;
releaseTime = _releaseTime;
컨트랙트에서는 입금자부터 자금을 받는 사람까지 모두 코드에 묶여 있습니다. 자금 이체 기능은 코드 기반 매개변수인 릴리스타임에 묶여 있기 때문에 누구도 상대방과 상호 작용하거나 신뢰할 필요가 없습니다.
자율 부분
다음은 코드의 ‘자금 릴리스(fund release)’ 부분입니다.
function release() public {
require(block.timestamp >= releaseTime, “Too early to release”);
uint256 amount = address(this).balance;
beneficiary.transfer(amount);
emit Released(beneficiary, amount);
}
릴리스 타임이 특정 기준을 충족할 때만 자금이 해제되므로 전체 프로세스는 자율적으로 이루어집니다. 코드가 부분적으로 프로그래밍 가능한 것이 아니라 완전히 자율적이라는 점에 유의해야 합니다.
스마트 컨트랙트 코드의 추가 요소에 따라 기능을 완전히 자율적으로 만들 수 있습니다. 예를 들어, 사용자의 지갑이 100달러를 넘을 때마다 반복 입금 플랜을 시작하고 초과 금액은 수취인에게 이체할 수 있습니다.
보안 부분
어떤 요소가 계약에 보안성을 제공하는지 궁금하신가요? 코드의 아래 부분을 확인해 보세요.
constructor(address payable _beneficiary, uint256 _releaseTime) {
require(_releaseTime > block.timestamp, “Release time must be in the future”);
depositor = msg.sender;
beneficiary = _beneficiary;
releaseTime = _releaseTime;
}
릴리스타임(releaseTime) 함수의 우선순위가 어떻게 설정되어 있는지 살펴보세요. 임의적인 것은 없으며 조건이 충족되어야 합니다.
검증 가능한 부분
스마트 컨트랙트와 관련된 모든 트랜잭션은 별도의 로그 활동을 통해 체인 내에 기록됩니다.
event Deposited(address indexed _from, uint256 _value);
event Released(address indexed _to, uint256 _value);
emit Deposited(msg.sender, msg.value);
emit Released(beneficiary, amount);
스마트 컨트랙트의 다른 부분 읽기
스마트 컨트랙트의 주요 특성을 확인했으니 다음은 추가 요소에 대해 살펴보겠습니다. 다음과 같습니다.
Pragma solidity ^0.8.0; – 스마트 컨트랙트를 작성하는 데 필요한 솔리디티(Solidity) 프로그래밍 언어입니다.
// SPDX-License-Identifier: MIT – 소프트웨어 패키지 데이터 교환이라고 하는 이 식별자는 코드 릴리스(code release.)의 라이선스를 나타냅니다. 오픈 소스이며 우회할 수 있는지 여부를 사용자에게 알리기 위해 이 정보를 포함하는 것이 좋습니다.
Contract TimeLock { – 스마트 컨트랙트에 레이블과 같은 이름을 할당합니다.
주소 공개 예금자; (Address public depositor) – 계약에 예금자와 수익자가 포함되므로, 예금자의 공개 주소가 언급되는 지점입니다. 이 변수는 이더리움 지갑 주소이며 공개적으로 볼 수 있습니다.
수취인 주소; (Address payable public beneficiary;) – 에스크로가 자금을 송금하는 수취인의 공개 주소입니다. 블록체인 기반 스마트 컨트랙트에 투명성을 부여하고 읽을 수 있습니다.
Uint256 공개 릴리스 시간; (Uint256 public releaseTime;) – 시간 제한이 있는 컨트랙트이므로, uint256은 시간 기반 변수를 컨트랙트에 할당합니다. 이는 펀드의 공개가 이루어지는 시간 프레임이 됩니다.
솔리디티에서 uint(부호 없는 정수)은 정수 기반 값을 할당하는 방식입니다. 256은 대용량 숫자 저장을 의미합니다.
구문과 표현식 및 기타 코드 요소에 익숙해지려면 솔리디티 설명서를 읽어보세요.
기타 요소
constructor(주소 지불 가능 _수취인, uint256 _releaseTime) { – 생성자(Constructor)는 스마트 컨트랙트가 배포될 때 호출되는 일회성 특수 함수입니다. 이는 컨트랙트를 가동합니다. 이 시점에서 이전에 선언한 모든 주소 변수가 호출되고 초기화되는 것을 확인할 수 있습니다.
Receive() 외부 지급 가능 { – 외부에서 컨트랙트 주소로 자금이 이동할 때 호출되는 특수 함수입니다. 외부에서 외부를 의미하며, ‘지급 가능(Payable)’은 이동의 성격, 즉 ERC-20 토큰을 받는 것을 정의합니다.
함수 release() public { – 컨트랙트 주소에서 수익자로의 ERC-20 토큰 이동을 명시하는 공개 함수입니다. 이 함수는 릴리스타임(releaseTime)에 따라 달라집니다.
이 모든 요소는 앞서 설명한 가상의 에스크로 컨트랙트의 일부입니다. 솔리디티에 대해 더 자세히 알아보려면 솔리디티 문서 전체를 읽어보시기 바랍니다.
디앱과 스마트 컨트랙트
지금쯤이면 이미 작성된 스마트 컨트랙트를 읽고 이해하는 데 어느 정도 익숙해졌을 것입니다. 그리고 앞서 설명한 것과 같은 많은 스마트 컨트랙트는 탈중앙화 애플리케이션의 백엔드, 즉 표준 모바일 애플리케이션의 블록체인 버전을 구성합니다.
계약 보안과 자율적이고 프로그래밍 가능한 실행, 거래의 무신뢰성 등 스마트 계약의 모든 특성은 탈중앙화 애플리케이션을 개발하는 동안 쉽게 구현할 수 있습니다.
스마트 컨트랙트를 위한 블록체인
이더리움을 통해 대규모 소프트웨어 솔루션과 같은 스마트 컨트랙트를 개발할 수 있습니다. 하지만 이더리움만이 유일한 블록체인 프로토콜은 아닙니다. 스마트 컨트랙트 개발의 세계를 더 깊이 들여다보고 싶다면, 다른 블록체인을 살펴볼 수도 있습니다. 각 블록체인은 각기 다른 용어를 사용해 컨트랙트를 작성합니다.
먼저 이더리움에 대해 알아보겠습니다.
이더리움
이더리움의 스마트 컨트랙트는 솔리디티 프로그래밍 언어로 작성됩니다. 이 스마트 컨트랙트 개발 플랫폼의 토큰 인터페이스는 ERC-20입니다.
ERC-20 토큰은 스마트 컨트랙트 집약적인 기능을 갖추고 있으며 스마트 컨트랙트를 작성을 용이하게 합니다. 다음은 기본적인 코드 구조입니다. 비인크립토가 토큰을 출신하다고 가정하고 작성했습니다.
pragma solidity ^0.8.0;
import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
contract BICToken is ERC20 {
constructor(uint256 initialSupply) ERC20("BIC Token", "BIC") {
_mint(msg.sender, initialSupply);
}
}
스마트 컨트랙트를 작성할 때, 이 코드의 모든 요소에 대해 설명하겠습니다.
기타 블록체인
이더리움과 마찬가지로 함수형 프로그래밍 언어인 하스켈(Haskell)의 하위 집합인 플루터스(Plutus)를 사용하여 러스트(Rust)와 카르다노를 사용하는 솔라나와 같은 플랫폼에서도 스마트 컨트랙트를 만들 수 있습니다.
Rust(Solana)의 코드 구조는 다음과 같습니다.
Note: It is a simple contract where a counter gets incremented.
use anchor_lang::prelude::*;
declare_id!(“Fg6PaFpoGXkYsidMpWTK6W2BeZ7FEfcYkg476zPFsLnS”);
#[program]
pub mod hello_world {
use super::*;
pub fn initialize(ctx: Context<Initialize>) -> ProgramResult {
let greeting_account = &mut ctx.accounts.greeting_account;
greeting_account.counter = 0;
Ok(())
}
pub fn increment(ctx: Context<Increment>) -> ProgramResult {
let greeting_account = &mut ctx.accounts.greeting_account;
greeting_account.counter += 1;
Ok(())
}
}
솔라나 문서는 러스트 전용 스마트 컨트랙트 언어를 이해하는 데 도움이 될 것입니다.
마찬가지로 카르다노는 플루투스, 폴카닷은 잉크!(Ink!), 알고랜드는 TEAL, NEO는 C# 등의 언어를 따릅니다. 호환 가능한 스마트 컨트랙트를 작성하기 위해 체인별 문서를 자세히 학습하는 것이 좋습니다.
올바른 블록체인 플랫폼 선택하기
스마트 컨트랙트 작성에 적합한 블록체인을 선택하기 위해 고민하고 계신가요? 다음은 각 블록체인에 대한 요약입니다.
이더리움
개요:
- 출시: 2015년
- 합의 메커니즘: 이더리움 2.0 업그레이드 이후 지분 증명(PoS)
- 스마트 컨트랙트 언어: 솔리디티
- 주요 특징
- 튜링 완전성: 복잡한 계산 지원
- 최대 규모의 개발자 커뮤니티: 광범위한 리소스 및 지원
- 폭넓은 채택: 이더리움에 구축된 수많은 탈중앙 금융 및 NFT 프로젝트
장점
- 보안: 지분 증명 합의 메커니즘과 많은 수의 검증자를 통해 높은 보안성을 제공합니다.
- 생태계: 다양한 도구, 라이브러리, 프레임워크(예: 트러플, 하드햇, 리믹스)를 갖춘 풍부한 생태계.
- 유동성 및 상호운용성: 토큰의 유동성이 높고 다른 블록체인 및 디앱과의 상호운용성이 뛰어납니다.
단점:
- 확장성 문제: 네트워크 혼잡으로 인해 높은 가스 수수료와 느린 트랜잭션 시간이 발생할 수 있습니다.
- 비용: 특히 피크 시간대에 거래 수수료가 높습니다.
사용 사례:
- 탈중앙 금융 플랫폼과 복잡한 디앱처럼 높은 보안과 탈중앙화가 필요한 프로젝트에 이상적입니다.
바이낸스 스마트 체인(BSC)
개요:
- 출시: 2020년
- 합의 메커니즘: 지분 증명 권위(PoSA)
- 스마트 컨트랙트 언어: 솔리디티(이더리움과 호환)
- 주요 특징
- 높은 처리량: 이더리움보다 더 많은 초당 트랜잭션(TPS)을 처리할 수 있습니다.
- 낮은 거래 수수료: 이더리움에 비해 비용 효율적입니다.
장점:
- 속도: PoSA 컨센서스로 인해 트랜잭션 시간이 더 빠릅니다.
- 비용: 트랜잭션 수수료가 낮아 사용자와 개발자에게 경제적입니다.
- 호환성: EVM 호환성을 통해 이더리움 디앱(dApp)을 BSC로 쉽게 마이그레이션할 수 있습니다.
단점:
- 중앙화 우려: 이더리움에 비해 검증자 수가 적기 때문에 중앙 집중화에 대한 우려가 있습니다.
- 보안: 일반적으로 안전하지만, 유명한 해킹 사건에 직면하여 보안에 대한 우려가 제기되고 있습니다.
사용 사례:
- 게임, 소규모 탈중앙 금융 프로젝트, NFT 등 빠르고 저렴한 트랜잭션이 필요한 애플리케이션에 적합합니다.
폴카닷
개요:
- 출시: 2020년
- 합의 메커니즘: 지명 지분 증명(NPoS)
- 스마트 컨트랙트 언어: 서브스트레이트(Substrate) 프레임워크로 맞춤형 블록체인 개발 가능
- 주요 특징
- 상호운용성: 여러 블록체인을 연결할 수 있도록 설계되었습니다.
- 확장성: 파라체인을 사용하여 확장성을 향상시킵니다.
장점:
- 상호운용성: 여러 블록체인과 상호 작용해야 하는 프로젝트에 탁월합니다.
- 커스터마이징: 개발자가 특정 요구에 맞는 맞춤형 블록체인을 만들 수 있습니다.
- 확장성: 파라체인과 병렬 처리를 통해 높은 확장성을 제공합니다.
단점:
- 복잡성: 이더리움 및 BSC에 비해 개발 및 배포가 더 복잡합니다.
- 단계:이더리움에 비해 확립된 프로젝트가 적습니다.
사용 사례:
- 크로스체인 디앱, 맞춤형 블록체인 솔루션이 필요한 기업 등 높은 상호운용성과 확장성을 필요로 하는 프로젝트에 적합합니다.
적절한 플랫폼 선택 기준
- 프로젝트 요구사항:
- 복잡성: 매우 복잡한 스마트 컨트랙트와 디앱의 경우, 이더리움의 성숙한 생태계가 유용합니다.
- 트랜잭션 속도 및 비용: 프로젝트에 높은 처리량과 낮은 거래 수수료가 필요한 경우, BSC가 유력한 후보입니다.
- 상호운용성: 여러 블록체인에서 운영해야 하는 프로젝트의 경우, 폴카닷은 상당한 이점을 제공합니다.
- 보안:
- 탈중앙화: 이더리움의 높은 탈중앙화는 보안을 강화하지만 비용이 더 많이 들 수 있습니다.
- 검증자 모델: 각 플랫폼의 검증자 모델을 평가하여 잠재적인 보안 위험을 파악하세요.
- 개발자 지원:
- 도구 및 리소스: 이더리움은 가장 광범위한 리소스를 보유하고 있지만, BSC와 폴카닷이 이를 따라잡고 있습니다.
- 커뮤니티: 강력한 개발자 커뮤니티는 지원을 제공하고 개발을 가속화할 수 있습니다.
- 향후 확장성:
- 장기적인 비전: 플랫폼의 로드맵과 확장성 및 향후 업그레이드 계획을 고려하세요.
- 생태계 성장: 생태계가 성장하는 플랫폼은 협업과 통합을 위한 더 나은 기회를 제공할 수 있습니다.
- 비용:
- 예산: 각 플랫폼에서 스마트 컨트랙트를 배포하고 유지하는 데 드는 비용을 평가하세요. 이더리움은 피크 시간대에는 비용이 많이 들 수 있지만, 일반적으로 BSC가 더 경제적입니다.
이러한 요소를 고려해, 프로젝트의 요구와 목표에 가장 적합한 블록체인을 선택할 수 있습니다.
스마트 컨트랙트를 읽는 법을 배워야 하는 이유
스마트 컨트랙트를 작성하는 능력은 높은 평가를 받고 있지만, 읽을 수 있는 능력도 나름의 장점이 있습니다.
- 탈중앙 금융 앱과 관련된 자동화 복잡성에 대해 배울 수 있습니다.
- 자산 토큰화와 관련된 소유권 표준을 분석할 수 있습니다.
- 탈중앙화된 자율 조직(DAO)의 작동 방식 이해.
- 보험, 콘텐츠 수익화, 투표 시스템, 로열티 및 기타 업종과 관련된 사용 사례 중심 로직을 이해하고 구현합니다.
스마트 컨트랙트 작성 방법
이제 스마트 컨트랙트 읽기는 끝났으니 스마트 컨트랙트 작성에 집중해 보겠습니다. 더 자세히 알아보기 전에 블록체인마다 스마트 컨트랙트 개발과 관련된 표준과 언어가 다를 수 있다는 점을 다시 한 번 강조할 필요가 있습니다. 스마트 컨트랙트 작성과 배포를 시작하려면 특정 블록체인에서 정의한 표준에 초점을 맞출 필요가 있습니다.
이 글에서는 이더리움과 작성 언어 솔리디티에 초점을 맞추겠습니다.
프로그래밍 역할
스마트 컨트랙트 프로그래밍은 개발 주기에서 가장 중요한 부분입니다. 스마트 컨트랙트 개발을 시작하려면 자바스크립트와 같은 비블록체인 프로그래밍 언어에 대한 경험이 어느 정도 있어야 합니다.
스마트 컨트랙트를 프로그래밍하는 기능을 사용하면 로직을 구현하고, 보안 요소를 처리하고, 가스 요금에 맞게 코드를 최적화할 수 있습니다. 또, 사용자를 지정하고, 필요한 경우 상호 운용할 수 있도록 만들 수도 있습니다.
이더리움 가상 머신과 스마트 컨트랙트
이더리움에서 스마트 컨트랙트를 작성하려는 개발자는 누구나 이더리움 가상 머신(EVM)이 무엇이며, 스마트 컨트랙트와 어떻게 작동하는지 이해해야 합니다. 우선, EVM은 프로그램이 작동할 수 있는 독립되고 통제된 환경을 제공하는 이더리움의 구성 요소입니다. 이더리움에 있는 모든 컨트랙트 코드를 호스팅하는 전체 컴퓨터라고 생각하시면 됩니다. 이더리움 네트워크의 모든 노드는 EVM을 실행합니다.
스마트 컨트랙트 개발자가 되고자 한다면, 스마트 컨트랙트와 EVM에 대해 알아야 할 사항은 다음과 같습니다.
하이레벨 언어인 솔리디티로 프로그램을 작성했다면, 이를 기계가 이해할 수 있는 로우레벨 형식인 바이트코드(bytecode)로 작성해야 합니다. 이 바이트코드는 이더리움 블록체인에 들어가 그곳에 자리잡습니다. 스마트 컨트랙트와 상호작용하는 사람은 누구나 트랜잭션을 컨트랙트의 주소로 보내야 합니다.
EVM이 설치된 모든 노드는 이 트랜잭션을 볼 수 있으며, 검증자가 이를 승인하면 스마트 컨트랙트 코드가 실행됩니다. 모든 노드가 트랜잭션 가시성을 가지므로 어떤 것도 변조할 수 없으며, 코드는 작성된 대로 실행됩니다. 코드가 실행되면 블록체인의 상태가 변경되므로 프로세스가 엔드투엔드로 완전히 투명해집니다.
누구나 스마트 컨트랙트를 작성할 수 있나요?
스마트 컨트랙트를 작성하려면 기술적 노하우가 필요합니다. 하지만 그게 다가 아닙니다. 블록체인 기술의 작동 방식과 대상 블록체인과 관련된 언어별 요구 사항, 상호 운용성 등에 대해서도 철저히 이해해야 합니다. 또 코드를 작성할 때 피해야 할 스마트 컨트랙트의 취약점에 대해서도 잘 알고 있어야 합니다. 마지막으로, 컨트랙트 테스트와 컨트랙트 배포 지식도 필수입니다.
이 모든 것이 부담스러울 수 있습니다. 하지만 이를 시작하기 위한 간단한 방법이 있습니다.
- 먼저 작업할 플랫폼이나 체인을 선택하세요.
- 이더리움용 솔리디티와 같이 해당 체인과 관련된 프로그래밍 언어를 배워보세요.
- 리믹스(Remix)와 같은 통합 개발 환경과 같은 개발 도구 사용에 대해 알아보세요.
- 첫 번째 컨트랙트를 작성한 다음 테스트넷을 사용해 테스트해봅니다.
- 코드의 요소가 만족스러우면 온체인에 배포할 수 있습니다. 컨트랙트를 온체인에 배포하면 가스비 형태로 비용이 발생한다는 점을 기억하세요.
다음은 더 나은 스마트 컨트랙트를 작성하기 위한 몇 가지 팁입니다.
프로그래밍 시작하기
이제 스마트 컨트랙트의 기술적 측면을 살펴볼 차례입니다. 솔라나나 카르다노와 같은 체인으로 스마트 컨트랙트를 개발할 수 있지만, 이더리움이 여전히 가장 인기 있는 스마트 컨트랙트 개발 플랫폼입니다.
왜 이더리움인가요?
이더리움에는 거대한 개발자 커뮤니티가 있습니다. 여러분이 개발하는 모든 것이 이들로부터 즉시 주목을 받을 것입니다. 또, 기본 언어인 솔리디티는 파이썬이나 자바스크립트를 잘 아는 사람이라면 비교적 쉽게 사용할 수 있습니다. 특히 이더리움 글로벌 소프트웨어인 EVM은 원활한 컨트랙트의 실행을 돕습니다.
솔리디티 기본 사항
이더리움과 솔리디티로 스마트 컨트랙트를 개발하기 전, 확인해야 할 사항이 있습니다. 다음과 같습니다.
- 프라그마(Pragmas) 또는 컴파일러 버전(compiler version)
- 라벨링을 위한 컨트랙트 정의
- 데이터 저장을 위한 상태 변수
- EVM 로깅을 위한 이벤트
- 특정 기관에 특정 권한을 부여하기 위한 수정자
- 함수 또는 실행 중인 스마트 컨트랙트 활동
- 상호운용성을 위한 상속
- 루프, 문자열, 정수 등의 데이터 유형에 대한 if, else와 같은 제어 구조 이해
첫 번째 스마트 컨트랙트 작성 및 배포
이제 온체인에서 어떻게 일이 진행되는지 알아보았으니, 첫 번째 스마트 컨트랙트를 작성하고 배포해 보겠습니다. 100% 잠금 해제된 공급량 100만 개의 비인크립토(BIC) 토큰을 출시해 보겠습니다. 다시 말하지만, 가상의 시도입니다.
기본 사항
첫 번째 단계는 최신 버전의 Node.js와 NPM 또는 노드 패키지 관리자를 설치하는 것입니다. 이렇게 하면 개발 도구와 개발을 위한 로컬 환경이 준비됩니다. 또한, Node.js와 NPM을 사용하면 스마트 컨트랙트의 웹 프런트엔드를 설정할 수 있습니다.
이제 컨트랙트 코드를 작성할 IDE를 설정해야 합니다. 이를 위해 비주얼 스튜디오 코드(Visual Studio Code)를 빠르게 설치해야 합니다. 또는 복잡한 과정을 생략하고 블록체인 개발 플랫폼인 알케미(Alchemy)를 사용할 수도 있습니다. 알케미를 사용하면 테스트넷 이더리움을 얻을 수 있습니다. 이는 스마트 컨트랙트를 고얼리(Goerli) 테스트넷이나 세포리아(Sepolia) 테스트넷에 배포할 때 가스비를 충당할 수 있습니다.
세포리아(Sepolia)는 신생 테스트넷입니다. 노드 배포 시 디스크 공간을 덜 차지한다는 점에 유의하세요.
현재로서는 배포된 애플리케이션 수가 더 많은 고얼리(Goerli) 테스트넷을 계속 사용할 것입니다.
테스트넷과 가짜 이더리움이 준비되었으니 이제 스마트 컨트랙트를 구체적으로 작성해 보겠습니다. 다음은 100만 개의 고정 공급량을 가진 비인크립토(BIC) 토큰을 생성하는 코드 조각입니다.
참고: 스마트 컨트랙트를 테스트넷이 아닌 맥OS에 로컬로 배포할 것입니다. 스마트 컨트랙트의 테스트넷과 메인넷 배포에 대해서는 이 논의의 범위를 벗어나는 별도의 글이 있을 것입니다.
작성 및 배포 단계
다음은 가상의 토큰에 대한 간단한 코드입니다.
pragma solidity ^0.8.0;
import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
contract BICToken is ERC20 {
constructor() ERC20("BIC Token", "BIC") {
_mint(msg.sender, 1000000 * 10 ** decimals());
}
}
구문을 알고 있다면 각 코드 구성 요소가 무엇을 의미하는지 알 수 있습니다. 오픈젭린(Openzepplin)은 ERC-20 스마트 컨트랙트를 가져올 때 사용하는 라이브러리입니다. 이 라이브러리는 ERC-20 토큰의 기본 운영 표준을 제공합니다.
mint 함수는 스마트 컨트랙트 주소 또는 msg.sender에 배포되는 초기 공급에 대해 이야기합니다.
이 코드를 로컬에서 설정하고 테스트하려면 세 가지 구성 요소가 필요합니다:
- Node.js와 NPM(이미 설명한 바 있음): 스마트 컨트랙트를 구동하는 엔진처럼 작동합니다.
- 트러플(Truffle): 도구 상자처럼 작동하여 코드, 스크립트 및 계약의 다른 부분을 구성하는 데 도움이 됩니다.
- 가나슈(Ganache): 가상의 온디바이스 놀이터처럼 작동합니다. 개인 블록체인이라고 생각하시면 됩니다.
컨트랙트 실행이란
스마트 컨트랙트를 작성하는 자세한 과정을 살펴보셨다면, 컨트랙트 실행에 대해 어느 정도는 알고 계셔야 합니다. 이는 스마트 컨트랙트 코드가 노드에 의해 체인에서 실행되는 과정입니다.
스마트 컨트랙트를 투명하고 불변하게 만드는 것은 컨트랙트 실행과 관련된 균일성입니다. 이제 컨트랙트 실행과 관련된 단계별 프로세스를 이해해 보겠습니다:
1단계
우리가 작성한 코드 조각은 어딘가에서 실행되어야 합니다. 스마트 컨트랙트의 경우, 이 실행 장소가 바로 블록체인입니다. 체인의 노드 또는 참여 멤버가 컨트랙트 실행을 돕습니다.
2단계
노드는 체인 관련 인센티브를 받는 대가로 컨트랙트 코드 블록을 실행하는 책임을 수락합니다. 체인 내에서 발생하는 모든 명령이나 행동은 스마트 컨트랙트에 의해 주도됩니다.
3단계
모든 스마트 컨트랙트에는 특정 주소가 있습니다. 컨트랙트를 실행하기 위해 트랜잭션은 해당 컨트랙트 주소로 전송됩니다. 모든 노드는 스마트 컨트랙트 코드의 사본을 가지고 있는 EVM을 실행하므로 거래의 진위 여부를 쉽게 확인할 수 있습니다.
4단계
스마트 컨트랙트를 대상으로 하는 트랜잭션은 검증자가 선택한 다음 특정 블록에 포함합니다.
5단계
트랜잭션이 푸시되고 성공적으로 검증되면 블록체인의 일부가 됩니다. 그런 다음 트랜잭션과 관련된 스마트 컨트랙트 함수가 호출되어 블록체인 노드 전체에서 실행됩니다.
6단계
스마트 컨트랙트를 실행하는 모든 노드는 동일한 입력 세트에 대해 동일한 출력이라는 결정론적 결론에 도달해야 하며, 이는 계약의 성격을 완전히 신뢰할 수 없고 투명하게 만듭니다.
참고: 코드 실행과 관련된 오류나 가스 수수료와 관련된 문제가 발생하면 트랜잭션이 취소됩니다. 즉, 특정 스마트 컨트랙트 코드에 기반한 트랜잭션이 더 이상 존재하지 않게 됩니다. 특정 규범을 준수하지 못하면 전체 거래가 취소되어 마치 처음부터 자금이 이동하지 않은 것처럼 보이는 것이 바로 플래시 대출(flash loans)에서 일어나는 일입니다.
스마트 컨트랙트와 관련된 모든 상태 변경은 블록체인에 기록되며, 이는 변경할 수 없는 부분이 됩니다.
스마트 컨트랙트 개발 및 모범 사례
이제 스마트 컨트랙트에 대해 어느 정도 이해하셨으니, 이제 컨트랙트 개발을 위한 몇 가지 팁을 알려드리겠습니다.
- 컨트랙트를 작성하는 동안 원하는 코드 최적화 및 보안 표준을 준수하기 위해 오픈제플린(OpenZeppelin)과 같은 신뢰할 수 있는 라이브러리를 사용하는 것이 좋습니다.
- 이 아이디어는 컨트랙트를 모듈식으로 더 단순하게 유지하여 테스트와 검토가 더 쉬워지도록 합니다.
- 좋은 아이디어는 컨트랙트별 액세스 제어를 구현하는 것입니다. 이는 특정 사람이나 단체만 계약의 중요한 특성을 변경할 수 있는 코드 비트를 선언하는 것입니다. 접근 제어를 사용하면 스마트 컨트랙트의 보안을 더 쉽게 유지할 수 있습니다.
- 컨트랙트를 작성할 때는 항상 여러 테스트를 작성하면서 특별한 사례(edge cases)와 예외를 처리할 수 있는 조항을 마련해야 합니다.
코드 지속 가능성 관리하기
위에서 언급한 각 사례는 코드 최적화 및 보안 관련 구현에 도움이 됩니다. 그러나 코드 지속 가능성을 관리하기 위해 반드시 따르고 구현해야 하는 몇 가지 계약 관련 관행이 있습니다. 이는 컨트랙트 코드를 가볍고 사용 가능한 상태로 유지하여 모든 노드가 동일한 코드를 실행하고 실행하는 데 많은 연산 능력을 투입할 필요가 없도록 하는 것을 목표로 합니다.
- 더 작은 데이터 세트를 사용하여 스토리지를 효율적으로 처리합니다. 예를 들어, 컨트랙트를 작성할 때 연산 값으로 uint256 대신 uint8을 사용하세요.
- 컨트랙트를 작성하는 동안 여러 연산을 하나로 결합하여 코드를 최적화하는 것이 좋습니다. 이에 대해서는 스마트 컨트랙트 작성에 대한 자세한 글에서 더 자세히 살펴보겠습니다.
- 스마트 컨트랙트 실행과 관련해 지연 평가를 사용하는 것도 좋은 아이디어입니다. 이렇게 하면 스마트 컨트랙트 주소에 무언가를 푸시할 때마다 실행하는 것이 아니라 필요할 때만 함수를 실행하면 됩니다.
- 마지막으로, 오프체인 계산에 의존하는 것도 지속 가능성에 집중하는 좋은 방법입니다. 이는 가스비 요건을 낮추는 데 도움이 되며, 컨트랙트 실행 속도도 높일 수 있습니다.
스마트 컨트랙트를 작성하고 개발하는 동안 모범 사례를 따르더라도, 이를 메인넷에 푸시하는 동안에는 컨트랙트 보안에 관한 취약점을 꼭 살펴봐야 합니다.
배포된 스마트 컨트랙트와 상호작용
스마트 컨트랙트가 블록체인에 배포된 후, 그 기능을 활용하기 위해서는 스마트 컨트랙트와 상호작용하는 것이 중요합니다. 다음은 메타마스크 및 블록체인 탐색기와 같은 도구를 사용하여 배포된 스마트 컨트랙트와 상호 작용하는 방법입니다.
1. 메타마스크 사용
메타마스크는 암호화폐 지갑이자 이더리움 블록체인의 가교 역할을 하는 인기 있는 브라우저 확장 프로그램이자 모바일 앱입니다. 이를 사용해 스마트 컨트랙트와 상호작용하는 방법은 다음과 같습니다.
a. 메타마스크 설정하기:
- 메타마스크를 설치합니다: 브라우저(크롬, 파이어폭스, 브레이브, 엣지에서 사용 가능)에 메타마스크 확장 프로그램을 추가하거나 모바일 앱을 다운로드합니다.
- 지갑 만들기: 설정 프로세스에 따라 새 지갑을 만들거나 기존 지갑을 가져옵니다.
- 네트워크에 연결: 메타마스크가 올바른 이더리움 네트워크(예: 메인넷, 롭스텐(Ropsten), 코반(Kovan))에 연결되어 있는지 확인합니다.
b. 스마트 컨트랙트와 상호 작용하기
- 컨트랙트 주소 추가: 메타마스크에 스마트 컨트랙트 주소를 입력하여 추가합니다.
- 컨트랙트 함수에 액세스: 메타마스크를 사용해 컨트랙트 내 함수를 호출합니다. 이를 위해서는 일반적으로 컨트랙트와 통신하는 디앱(dApp) 인터페이스와의 상호작용이 필요합니다.
예시:
- 디앱에 연결하기: 배포된 스마트 컨트랙트를 사용하는 탈중앙화 애플리케이션(dApp)을 방문합니다.
- 메타마스크 승인: 메타마스크 지갑과 상호 작용할 수 있도록 디앱(dApp)을 승인합니다.
- 함수 실행: 트랜잭션 전송과 스마트 컨트랙트 함수 실행 또는 데이터 검색과 같은 작업을 수행합니다.
함수 호출: 간단한 스토리지 컨트랙트에서 set와
같은 함수를 호출합니다.
함수 set(uint x) public {
storedData = x;
}
- 트랜잭션 시작하기: 디앱을 열고
x에
원하는 값을 입력한 후 제출합니다. - 메타마스크에서 확인: 메타마스크에서 트랜잭션을 확인하고 가스 요금을 지불하라는 메시지가 표시됩니다.
데이터 읽기: 컨트랙트에서 데이터를 읽습니다:
함수 get() public view returns (uint) {
저장된 데이터를 반환합니다;
}
- 읽기 작업을 실행합니다: 디앱에서 관련 버튼을 클릭하여
get
함수를 호출합니다. - 가스 요금 없음: 데이터 읽기에는 가스 요금이 필요하지 않습니다.
2. 블록체인 탐색기 사용
이더스캔(Etherscan)과 같은 블록체인 탐색기는 브라우저에서 직접 스마트 컨트랙트와 상호작용할 수 있는 사용자 친화적인 방법을 제공합니다.
a. 컨트랙트에 액세스하기:
- 컨트랙트 검색: 이더스캔과 같은 블록체인 탐색기의 검색창에 컨트랙트 주소를 입력합니다.
- 컨트랙트 개요: 잔액, 트랜잭션, 소스 코드 등 컨트랙트에 대한 기본 정보를 확인합니다.
b. 컨트랙트와 상호작용하기:
- 읽기 및 쓰기 기능: 컨트랙트 탭으로 이동한 다음 컨트랙트 읽기(Read Contract) 또는 컨트랙트 쓰기(Write Contract) 섹션으로 이동합니다.
- 함수 호출: 읽기 함수를 실행하여 데이터를 검색하거나 쓰기 함수를 실행하여 컨트랙트 상태를 업데이트합니다.
예시:
- 예:읽기 함수:
- 데이터 보기: 컨트랙트 읽기 섹션에서
get
함수를 찾아 클릭하면 저장된 데이터를 검색할 수 있습니다.
- 데이터 보기: 컨트랙트 읽기 섹션에서
- 쓰기 함수:
- 메서드(Method) 호출: 컨트랙트 쓰기 섹션에서 메타마스크 지갑을 연결하고
설정된
함수에 대한 파라미터를 입력한 후 트랜잭션을 제출합니다.
- 메서드(Method) 호출: 컨트랙트 쓰기 섹션에서 메타마스크 지갑을 연결하고
3. 간단한 스토리지 컨트랙트와 상호작용
스마트 컨트랙트 코드:
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
contract SimpleStorage {
uint public data;
function set(uint x) public {
data = x;
}
function get() public view returns (uint) {
return data;
}
}
배포 및 상호 작용:
- 컨트랙트 배포: 리믹스(Remix)를 사용하여
SimpleStorage
컨트랙트를 컴파일하고 배포합니다. - 메타마스크 사용: 배포를 위해 메타마스크를 리믹스(Remix)에 연결합니다.
- 이더스캔 상호 작용:
- 데이터 읽기: 이더스캔의
get
함수를 사용하여데이터의
현재 값을 확인합니다. - 데이터 쓰기: 이더스캔의
set
함수를 사용하여 원하는 값을 입력한 후 메타마스크를 통해 트랜잭션을 확인합니다.
- 데이터 읽기: 이더스캔의
개발자와 사용자는 메타마스크와 블록체인 탐색기와 같은 도구를 활용하여 배포된 스마트 컨트랙트와 효율적으로 상호작용하여 탈중앙화 애플리케이션의 사용성과 기능을 향상시킬 수 있습니다.
스마트 컨트랙트를 어떻게 감사하나요?
메인넷에 존재하는 모든 스마트 컨트랙트는 코드 성능과 보안, 기타 특성에 대해 평가되어야 합니다. 이때 엄격한 계약 테스트 프로세스인 감사를 통해 잠재적인 계약 취약성과 약점을 발견할 수 있습니다.
다음은 감사 과정에서 실행되는 것에 대한 체크리스트입니다.
스마트 컨트랙트를 감사하는 이유
감사는 특별한 위치에서 스마트 컨트랙트의 기본 로직을 확인하는 것입니다. 블록체인 기반 코드 실행과 관련해서는 모든 것이 불변하며, 계약 실행 시 치명적인 문제가 발생하면 돌이킬 수 없는 결과를 초래할 수 있습니다. 그렇기 때문에 감사를 통해 컨트랙트 코드와 다양한 측면을 철저히 점검해야 합니다.
컨트랙트 취약점 및 수정
스마트 컨트랙트의 취약점에는 재진입 공격과 오버플로우 또는 언더플로우, 액세스 제어와 관련된 문제 등이 있습니다. 감사를 통해 이러한 문제를 확인합니다. 또 감사자는 해당 문제를 극복한 모범 사례를 네트워크에 제안할 수 있습니다.
침해 사례 연구 및 학습
스마트 컨트랙트의 감사가 네트워크에 어떻게 도움이 될 수 있는지 아직 잘 모르시겠어요? 재진입 문제를 악용하여 약 360만 이더리움의 손실을 초래한 2016년의 악명 높은 다오(DAO) 해킹 사례를 떠올려 보세요. 마찬가지로 2017년에는 패리티 지갑(Parity wallet) 컨트랙트 해킹으로 이더리움 약 50만 개가 손실됐습니다. 이러한 문제는 적절한 감사를 통해 피할 수 있었습니다.
스마트 컨트랙트를 감사 전략
스마트 컨트랙트를 감사하는 전략에는 여러 가지가 있습니다. 가장 많이 사용되는 전략은 다음과 같습니다.
감사 도구
이러한 도구는 첫 번째 방어 수단으로 사용되며 일반적인 취약점을 찾는 데 가장 적합합니다. 코드의 정적 분석을 수행하고 침해 패턴을 탐지하며, 보안 관련 선행 조치를 취할 수 있는 시큐리티파이(Securify)와 마이쓰릴(Mythril) 등이 인기 있는 도구입니다.
코드 검토
수동 코드 검토자가 코드베이스를 면밀히 검토하고 복잡한 취약점이 있는 경우 이를 식별하는 역할을 합니다. 수동 검토는 비즈니스 로직과 컨텍스트 및 사용 패턴을 관리하는 데 도움이 될 수 있습니다.
수동 코드 검토가 위협 요소를 포착하는 데 도움이 되는 방법은 다음과 같습니다.
자동 스캔
코드가 업데이트될 때마다 호출되는 보안 구현인 자동 계약 스캔은 싱크(Snyk) 및 가드레일즈(GuardRails)와 같은 도구가 도움이 됩니다. 이러한 형태의 감사는 코드에 대한 새로운 변경 사항이 안전하고 본질적으로 비침습적임을 보장합니다.
공식 검증
이는 코드의 비즈니스 로직을 확인하는 데만 의존하는 복잡한 프로세스입니다. 형식적 검증은 실제로 구문을 검증하는 것이 아니라 코드가 원하는 대로 실행되는지 확인하는 로직만을 의미한다는 점에 유의하세요.
앞서 언급한 전략 외에도 스마트 컨트랙트 감사는 동료 리뷰, 버그 바운티 프로그램, 솔리디티 커버리지와 같은 도구를 통해 효율성을 극대화할 수 있습니다.
코드를 올바르게 검토하는 방법
스마트 컨트랙트 감사를 처음하는 경우, 코드를 분석하고 문제를 식별하는 방법에는 두 가지가 있습니다. 다음과 같습니다.
정적 분석
이러한 유형의 코드 분석은 주어진 코딩 표준 및 규칙에 따라 기본적인 보안 취약성, 코딩 오류 및 기타 문제를 식별하는 데 도움이 됩니다. 정적 분석을 사용하면 외부 소스에 대한 확인되지 않은 호출, 정수 오버플로(integer overflows) 등과 같은 위협을 강조 표시할 수 있습니다. 정적 분석의 가장 좋은 점은 코드를 실행하지 않아도 확인이 가능하다는 점입니다.
동적 분석
감사에 대한 이 접근 방식은 코드와 EVM의 정렬을 테스트합니다. 동적 분석은 코드만 검사하는 대신 다양한 입력에 대한 스마트 컨트랙트의 응답을 교차 검사합니다. 동적 분석은 일관성 없는 가스 소비나 잘못된 컨트랙트 로직과 같은 문제를 식별할 수 있습니다. 가나슈와 같은 개인 블록체인 환경은 동적 분석 플랫폼으로 작동하여 개발자가 트랜잭션을 만들고, 명령을 실행하고, 컨트랙트를 통해 훨씬 더 많은 작업을 수행할 수 있게 해줍니다.
실제 코드 테스트
다음은 출금 기능이 있는 자금 저장소로 작동하는 스마트 컨트랙트 코드입니다.
pragma solidity ^0.6.1;
contract VulnerableContract {
mapping(address => uint256) public balances;
function deposit() public payable {
balances[msg.sender] += msg.value;
}
function withdraw(uint256 _amount) public {
require(balances[msg.sender] >= _amount, "Insufficient balance.");
(bool success, ) = msg.sender.call{value: _amount}("");
require(success, "Transfer failed.");
balances[msg.sender] -= _amount;
}
}
코드를 자세히 살펴보면 중요한 취약점이 있습니다.
이전 사례에서 자금을 받는 사용자도 악의적이긴 하지만 스마트 컨트랙트인 경우 ‘출금’ 기능을 다시 호출할 수 있습니다. 따라서 마지막 기능이나 잔액 업데이트가 발생하기 전 추가 자금을 이체하기 위한 재입금 공격이 시작될 수 있습니다. 숙련된 감사자들은 이러한 종류의 취약점을 식별할 수 있습니다.
이에 대한 수정 코드는 다음과 같습니다.
function withdraw(uint256 _amount) public {
require(balances[msg.sender] >= _amount, "Insufficient balance.");
balances[msg.sender] -= _amount;
(bool success, ) = msg.sender.call{value: _amount}("");
require(success, “Transfer failed.”);
}
잔액 업데이트 함수가 먼저 호출된 다음 사용자에게 먼저 이동하는 방법을 확인합니다. 이러한 작업 순서 변경이 컨트랙트를 수정하는 것입니다.
기타 체인과 코드 검토
탈중앙화 애플리케이션과 스마트 컨트랙트의 세계는 이더리움을 넘어섰습니다. 대부분의 작업은 여전히 이더리움 생태계 내에서 이루어지지만, 스마트 컨트랙트를 지원하고 다른 감사 표준을 요구하는 카르다노, 솔라나 등 다른 체인도 존재합니다.
플랫폼마다 고유한 이유
블록체인마다 서로 다른 프로그래밍 언어를 사용합니다. 코드의 의미론, 구문, 속성이 다르기 때문에 스마트 컨트랙트는 서로 다른 작성 및 감사 관행에 따라 반응합니다. 예를 들어, 이더리움은 솔리디티를 사용하는 반면, 폴카닷은 잉크와 러스트를 사용하여 특정 감사 표준에 반응합니다.
비 이더리움으로 전환하기 위한 도구
개발자가 이더리움 네트워크에서 벗어나고자 한다면 몇 가지 전문 감사 도구가 도움이 될 수 있습니다. 예를 들어, 카르다노의 경우 공식적인 검증과 감사를 위한 마로우(Marlowe) 제품군이 있습니다. 솔라나의 경우, 감사 및 컨트랙트 테스트를 위한 러스트(Rust) 전용 리브퍼저(libfuzzer)와 카고 퍼즈(cargo-fuzz)가 있습니다. 멀티체인 감사자는 이러한 개념에 익숙해야 컨트랙트 취약성을 방지할 수 있습니다.
스마트 컨트랙트 감사의 유형
다시 말씀드리자면, 스마트 컨트랙트 감사는 수동과 자동, 하이브리드의 세 가지 유형으로 구분할 수 있습니다. 심층적인 비즈니스 로직이 포함된 복잡한 계약의 경우 하이브리드 감사 전략이 가장 포괄적이기 때문에 사람들이 선호한다는 점에 유의하세요.
감사 아웃소싱
코딩 지식이 거의 없는 조직과 개인은 작성 및 감사 요구 사항을 평판이 좋은 회사에 아웃소싱하는 경우가 많습니다. 감사에 있어서는 챗GPT와 같은 인공지능(AI) 도구가 스마트 컨트랙트 코드 작성에 도움을 줄 수 있지만, 이를 확인하려면 수작업으로 인사이트를 확보해야 하므로 올바른 회사를 선택하는 것이 더욱 중요해집니다.
또한 감사 작업을 아웃소싱할 때 주의해야 할 요소는 다음과 같습니다.
올바른 회사 선택
적합한 아웃소싱 업체를 선정하기 전에 과거 감사를 확인하고, 경험을 평가하고, 핵심 팀원에게 집중하는 것이 중요합니다.
책임, 비용 및 간접비 이해
아웃소싱 업체를 고용하기 전에 감사와 관련된 비용과 서비스에 대해 알아보세요. 먼저 문제 식별, 문제 해결 등 제공되는 서비스의 특성을 이해하는 것이 중요합니다. 또한 첫 번째 수정 사항을 구현한 후 재감사도 제공되는지 확인해야 합니다. 스마트 컨트랙트 감사 비용은 서비스에 따라 달라질 수 있으므로 진행하기 전에 모든 요구 사항과 오퍼링을 추적해야 합니다.
최고의 스마트 컨트랙트 감사 사례
스마트 컨트랙트 감사를 대행업체에 맡기지 않고 직접 감사를 진행하고자 하는 경우, 염두에 두어야 할 최고의 전략과 관행은 다음과 같습니다.
- 항상 구문과 논리를 포함한 철저한 코드 검토에 집중하세요.
- 슬리더(Slither)와 미스엑스(MythX)와 같은 도구를 사용해 일반적인 취약점을 찾아내는 것부터 시작하세요.
- 스마트 컨트랙트 취약점 분류 레지스트리 또는 SWC를 검색하여 알려진 취약점을 찾아 미리 확인합니다.
- 통합 테스트, 단위 테스트 등을 포함해 스마트 컨트랙트를 엄격하게 테스트하여 다양한 시나리오에서 코드를 스트레스 테스트합니다.
- 특히 재진입 공격의 가능성을 확인하는 것이 중요합니다. 이를 방지하는 가장 좋은 방법은 해커가 첫 번째 스마트 컨트랙트 함수 전에 호출할 수 있는 재귀 호출이 있는지 확인하는 것입니다.
- 외부 호출로 이어지는 함수에 집중하세요. 이와 관련된 오류는 상태와 제어 흐름을 변경할 수 있으며, 이는 바람직하지 않습니다.
- 가스 사용량을 가리키는 코드 비트를 항상 주시하세요. 컨트랙트가 엄청나게 비싼 상호작용을 시작하는 것은 원치 않을 것입니다.
스마트 컨트랙트 개발과 인공지능
AI가 스마트 컨트랙트 작성을 더 쉽게 만들어주는 것은 사실입니다. 그러나 AI 혁신과 관계없이 스마트 컨트랙트를 최상의 방식으로 감사하는 능력은 여전히 사람의 개입이 필요합니다. 따라서 스마트 컨트랙트와 탈중앙화 애플리케이션을 강조하는 웹3.0 제품을 구축할 계획이라면, 스마트 컨트랙트를 위한 최고의 감사 리소스를 활용하는 것이 좋습니다. 암호화폐 해킹과 보안 침해가 날이 갈수록 증가하고 해커들이 새로운 전략을 세우고 있는 상황에서, 컨트랙트를 완벽하게 감사하는 것은 현대의 중요한 기술 중 하나가 됐습니다.
자주 찾는 질문/답
스마트 컨트랙트를 작성하려면 먼저 자바스크립트나 파이썬과 같은 고급 프로그래밍 언어로 로직을 작성하는 방법을 알고 있어야 합니다. 또는 이더리움의 기본 프로그래밍 언어인 솔리디티를 사용해 코딩하는 방법을 알고 있다면 도움이 됩니다. 로직을 제대로 이해했다면, 구문을 주의 깊게 작성하고 수정자, 함수, 변수 등과 같은 코딩 요소를 알아야 합니다.
솔리디티는 일반적인 스마트 컨트랙트 언어이지만, 대부분 이더리움 생태계와 관련이 있습니다. 폴카닷와 카르다노, 솔라나와 같은 다른 체인과 상호작용하고 싶다면 러스트와 잉크, 심지어 플루투스 같은 언어를 사용할 수 있습니다. 블록체인마다 서로 다른 블록체인 개발 언어를 지원하므로 스마트 컨트랙트를 작성하고 감사하는 방식이 달라질 수 있다는 점에 유의해야 합니다.
이더리움 기반 스마트 컨트랙트는 솔리디티로 작성됩니다. 솔리디티는 자바스크립트, 파이썬, 심지어 C++와 유사한 컨트랙트 지향 언어입니다. 카르다노와 솔라나의 경우, 다른 스마트 컨트랙트 언어를 사용합니다.
스마트 컨트랙트 감사는 컨트랙트 코드를 주의 깊게 살펴보고, 취약점이 있는지 검토하고, 테스트넷에서 테스트하는 과정을 포함합니다. 메인넷에서 컨트랙트를 테스트하면 높은 가스 수수료가 발생할 수 있습니다. 또한 정적 및 동적 스마트 컨트랙트 분석이 필요하며, 자동화 도구와 수동 검토, 일반적인 취약점 점검이 필요합니다.
스마트 컨트랙트에서 데이터를 읽으려면 블록체인 탐색기, API, 심지어 웹3 라이브러리까지 사용해야 합니다. 이러한 도구는 체인과 상호 작용하고 상태 변수에서 데이터를 검색할 수 있습니다. ABI 또는 애플리케이션 바이너리 인터페이스를 사용해 컨트랙트에서 데이터를 읽을 수도 있으며, 이는 컨트랙트 기능의 JSON 표현을 제공합니다.
감사자는 스마트 컨트랙트 개발 초기 단계에서 대부분 화이트박스 감사(white-box audits)를 수행합니다. 이러한 유형의 감사는 클리어 박스(clear box) 또는 투명 박스 감사(transparent box audit)라고도 합니다. 여기서는 로직과 코드의 설계, 구조, 구현을 검토하고 테스트하는 것이 목적입니다. 스마트 컨트랙트에 대한 화이트박스 감사는 또한 기능을 검증하고 코드의 컨트랙트 보안 분석을 수행합니다.
스마트 컨트랙트를 배포하려면 몇 가지 주요 단계가 필요합니다. 처음에는 솔리디티와 같은 프로그래밍 언어를 사용하여 스마트 컨트랙트를 작성해야 합니다. 코드가 작성되면 이더리움 가상 머신(EVM)이 이해할 수 있는 바이트코드로 컴파일해야 합니다. 이 작업은 리믹스(Remix)와 같은 통합 개발 환경(IDE)을 사용해 수행할 수 있습니다. 컴파일이 완료되면 배포 트랜잭션 비용을 지불하는 데 필요한 이더를 보관할 메타마스크와 같은 암호화폐 지갑을 설정합니다. 테스트 목적으로 이더리움의 메인넷 또는 로브스텐(Ropsten)과 같은 테스트넷과 같은 적절한 네트워크를 선택합니다. 리믹스 내에서 메타마스크 지갑에 연결하고 트랜잭션을 확인하여 컨트랙트를 배포합니다. 트랜잭션이 채굴되면 스마트 컨트랙트가 블록체인에 게시됩니다. 그런 다음 이더스캔과 같은 블록체인 탐색기를 사용해 배포를 확인하고 컨트랙트와 상호작용할 수 있습니다.
스마트 컨트랙트는 몇 가지 일반적인 취약점에 취약합니다. 재진입 공격은 컨트랙트가 자체 상태를 확인하기 전에 신뢰할 수 없는 다른 컨트랙트를 외부에서 호출하여 호출된 컨트랙트가 원래 컨트랙트로 다시 들어가 상태를 조작할 수 있을 때 발생합니다. 정수 오버플로우와 언더플로는 산술 연산이 변수 유형의 저장 용량을 초과하여 의도하지 않은 동작이 발생할 수 있는 문제입니다. 보호되지 않은 함수는 적절한 액세스 제어가 없는 경우 악용될 수 있으며, 권한이 없는 사용자가 중요한 함수를 실행할 수 있습니다. 타임스탬프 의존성은 컨트랙트가 중요한 기능을 위해 블록 타임스탬프에 의존하는 취약점으로, 채굴자가 자신에게 유리하도록 조작할 수 있습니다. 마지막으로 서비스 거부(DoS) 공격은 악의적인 공격자가 가스 한도를 소진하기 위해 수많은 트랜잭션을 전송하여 컨트랙트를 사용할 수 없게 만듭니다.
비인크립토 웹사이트에 포함된 정보는 선의와 정보 제공의 목적을 위해 게시됩니다. 웹사이트 내 정보를 이용함에 따라 발생하는 책임은 전적으로 이용자에게 있습니다.
비인크립토는 투자가이드를 통해 독자에게 유익한 양질의 교육 콘텐츠를 제공하기 위해, 콘텐츠를 검증하고 연구하는 데 많은 시간을 할애하고 있습니다.
비인크립토의 파트너사는 글이 게시되는 대가로 수수료를 제공할 수 있으나, 이는 공정하고 정직하고 유용한 콘텐츠 제작 프로세스에 어떠한 영향도 미치지 않습니다.