스마트 컨트랙트는 계약이 아니라 실행 규칙이다
스마트 컨트랙트를 처음 설명할 때 흔히 “조건이 충족되면 자동으로 실행되는 계약”이라고 말한다. 직관적인 설명이지만, 실제로 개발하고 운영해 보면 이 표현만으로는 중요한 부분이 빠진다. 스마트 컨트랙트는 스스로 현실을 이해하거나 당사자의 의도를 판단하는 계약서가 아니다. 블록체인 위에서 모든 참여자에게 동일하게 적용되는 실행 규칙에 더 가깝다.
코드가 약속할 수 있는 것
일반적인 서버 프로그램은 운영자가 데이터베이스를 수정하거나 장애가 발생한 거래를 되돌릴 수 있다. 스마트 컨트랙트는 다르다. 배포된 코드는 네트워크의 여러 노드에서 같은 입력에 같은 결과를 내야 하고, 그 결과는 블록체인 상태에 기록된다. 관리자가 마음대로 장부를 바꾸기 어려운 대신, 코드에 들어간 규칙은 예상하지 못한 상황에서도 그대로 실행된다.
이 특성은 디지털 자산을 다루는 데 강력하다. 누가 토큰을 보유하고 있는지, 어떤 조건에서 자산을 이전할 수 있는지, 여러 참여자가 공동 금고를 어떻게 관리할지를 공개된 코드로 정할 수 있다. 중개자의 선의를 믿는 대신, 참여자는 코드와 네트워크의 합의 규칙을 검증한다.
다만 “신뢰가 필요 없다”는 표현은 정확하지 않다. 신뢰의 대상이 바뀔 뿐이다. 사용자는 컨트랙트 코드, 배포 권한, 오라클, 프런트엔드, 네트워크 보안과 키 관리 체계를 믿어야 한다. 스마트 컨트랙트는 신뢰를 없애기보다 신뢰가 놓이는 위치를 공개하고 제한하는 기술이다.
단순한 코드에도 결정이 들어간다
가장 간단한 저장 컨트랙트는 다음처럼 작성할 수 있다.
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
contract SimpleStorage {
uint256 private value;
function set(uint256 newValue) external {
value = newValue;
}
function get() external view returns (uint256) {
return value;
}
}
이 코드는 누구나 값을 바꿀 수 있게 설계되어 있다. 예제에서는 문제가 없지만, 실제 서비스라면 곧바로 질문이 생긴다. 특정 관리자만 변경할 수 있어야 하는가. 여러 사람의 승인이 필요한가. 잘못 입력한 값을 되돌릴 수 있어야 하는가. 관리자의 키를 잃으면 어떻게 되는가. 업그레이드가 가능하다면 누가 그 권한을 가지는가.
기능 자체보다 이런 경계 조건이 더 중요하다. 스마트 컨트랙트 개발은 정상적인 흐름을 구현하는 작업이면서 동시에, 권한이 오용되거나 외부 시스템이 실패했을 때 어디까지 피해가 번질지를 제한하는 작업이다.
자동 실행의 바깥
스마트 컨트랙트는 블록체인 안의 정보만 직접 알 수 있다. 배송이 완료되었는지, 특정 자산의 시장 가격이 얼마인지, 법원에서 어떤 판단이 내려졌는지는 외부 데이터 없이는 알 수 없다. 이 정보를 전달하는 오라클이 잘못되면 컨트랙트는 잘못된 데이터도 정확하게 실행한다.
법률상 계약과의 관계도 신중하게 보아야 한다. 코드가 자산을 자동으로 이전했다고 해서 당사자 사이의 모든 법률문제가 끝나는 것은 아니다. 착오나 사기, 강행규정, 관할과 준거법, 현실 세계의 권리 이전처럼 코드만으로 해결할 수 없는 문제가 남는다. “Code is law”라는 문장은 기술의 특성을 압축해서 보여주지만, 현실에서 법과 코드는 서로를 대체하기보다 다른 층위에서 함께 작동한다.
그래서 스마트 컨트랙트를 설계할 때에는 온체인 규칙만 보아서는 부족하다. 사용자가 무엇에 동의하는지, 분쟁이 발생하면 어떤 절차를 거칠지, 운영 주체가 어떤 책임을 지는지까지 제품과 문서 안에서 연결해야 한다.
실제 서비스에서 어려운 부분
스마트 컨트랙트의 장점은 자동화 자체보다 공유된 상태를 일관되게 유지하는 것에서 드러난다. 토큰 교환, 담보 관리, 공동 자금 집행처럼 여러 참여자가 같은 장부를 신뢰해야 하는 업무에서는 중간 정산과 대조 비용을 크게 줄일 수 있다.
반대로 모든 업무를 온체인에 올리는 것은 비효율적이다. 저장 비용이 크고, 공개 네트워크에서는 개인정보를 다루기 어렵다. 처리 속도와 수수료도 일반 서버와 다르다. 좋은 설계는 어떤 상태와 규칙을 온체인에 둘지, 어떤 계산과 데이터는 오프체인에 남길지를 구분한다.
운영 단계에서는 배포보다 이후가 더 어렵다. 이벤트와 트랜잭션을 모니터링하고, 프런트엔드가 실패 상태를 정확히 설명하며, 보안 사고에 대응할 수 있어야 한다. 업그레이드 가능한 구조는 오류를 고칠 수 있지만 관리자 권한을 키운다. 변경 불가능한 구조는 예측 가능성을 높이지만 버그까지 영구적으로 만든다. 정답이 있는 문제가 아니라, 서비스가 감당할 위험을 선택하는 문제다.
스마트 컨트랙트를 이해한다는 것
스마트 컨트랙트의 가능성은 분명하다. 자산과 규칙을 하나의 실행 환경에 두고, 국경과 조직을 넘어 같은 결과를 검증할 수 있게 한다. 그러나 그 가능성은 “중개자가 사라진다”거나 “계약이 완전히 자동화된다”는 말만으로 설명되지 않는다.
스마트 컨트랙트를 이해한다는 것은 코드가 할 수 있는 일과 할 수 없는 일을 함께 보는 것이다. 자동 실행의 편리함뿐 아니라 되돌리기 어려운 결과를 생각하고, 공개된 규칙뿐 아니라 그 규칙을 바꿀 권한도 살펴보는 것이다. 그리고 기술적 실행과 법적 책임 사이에 남는 간격을 인정하는 일이다.
결국 좋은 스마트 컨트랙트는 복잡한 기능을 많이 가진 코드가 아니다. 참여자가 어떤 조건에서 어떤 결과를 받는지 예측할 수 있고, 실패했을 때의 책임과 대응 방법까지 분명한 시스템이다. 코드를 쓰는 일보다 먼저 약속의 경계를 정하는 일. 그것이 스마트 컨트랙트 개발의 출발점이라고 생각한다.