본문으로 건너뛰기
전체 글

Polsto에서 BXB로: 블록체인 미들웨어를 만들게 된 이유

· 약 12분
Bankware Global Engineering

2023년 2월, 금융위원회가 토큰증권 발행·유통 규율체계 정비방안을 발표했다. 분산원장을 증권의 새로운 발행 형식으로 수용하고 발행과 유통을 위한 제도적 기반을 만들겠다는 방향이 구체적인 문서로 나온 시점이었다.

우리 팀은 그 흐름 안에서 토큰증권 발행 플랫폼 **Polsto(Polymophic Security Token Offering)**의 프로토타입을 만들었다. 토큰증권이라는 말을 사업계획서에 적는 데서 멈추지 않고, 실제 시스템으로 옮겼을 때 어떤 기능과 연결이 필요한지 확인하는 과정이었다.

그러나 기술을 만드는 속도와 제도가 움직이는 속도는 같지 않았다. 당시 법제화는 처음 기대했던 것보다 긴 시간이 필요했다. 시장이 열리기만을 기다리며 특정 서비스의 기능을 계속 쌓는 방식이 맞는지 다시 생각해야 했다.

그때 질문에서 토큰증권이라는 단어를 잠시 걷어냈다.

토큰증권을 제외해도 남는 기술은 무엇이었을까? 다른 블록체인 연계 프로젝트에서도 되풀이될 문제를 공통 인프라로 분리할 수는 없을까?

앞선 글인 증권의 권리를 보유기간에 따라 계산할 수 있을까와 SecurityToken.sol 설계 리뷰가 토큰화된 권리의 계산과 컨트랙트 구현을 다뤘다면, 이번 글은 그 기능을 기존 시스템과 연결하는 경계를 돌아본다.

이 글은 Polsto의 경험에서 BXB가 출발한 이유를 돌아본다. BXB에 구현된 수탁형 지갑을 바탕으로 서명 경계를 설명하되, 제품 전체 사양이나 성능·운영 검증을 다루지는 않는다. 기술 설명의 범위는 EVM(Ethereum Virtual Machine), 즉 이더리움과 호환되는 컨트랙트 실행 환경과 그 호출 규격인 ABI다.

Polsto에서 발견한 연결 문제​

Polsto에서 토큰증권의 발행과 관리를 구현하려면 스마트 컨트랙트만 작성해서는 충분하지 않았다.

그 차이를 보기 위해 고객이 기존 금융 서비스에서 토큰 10개를 다른 고객에게 이전하는 상황을 생각해 보자. 설명을 위한 예시이며 특정 고객의 실제 거래나 BXB의 API 사양은 아니다.

고객은 평소 쓰던 서비스에 로그인하고 이전을 승인한다. 하지만 서버가 그 요청을 접수한 순간에는 원장의 토큰이 아직 움직이지 않았다. 업무 계정을 블록체인 주소에 연결하고, 거래에 서명하고, 노드에 전송한 뒤, 실제로 반영됐는지 확인해야 한다. 고객이 누른 버튼 하나 뒤에 서로 다른 시스템의 일이 이어진다.

기존 금융 시스템은 고객, 계좌, 상품과 거래라는 업무 개념으로 움직인다. 시스템 사이의 연결에는 REST API와 정형화된 요청·응답이 널리 쓰이고, 인증·인가, 오류 처리, 로그와 모니터링도 그 경계에 맞춰져 있다.

블록체인은 다른 언어를 사용한다. 스마트 컨트랙트의 함수와 자료형은 ABI(Application Binary Interface)에 기술되고, 노드와는 JSON-RPC로 통신한다. 상태를 조회하는 호출과 원장을 변경하는 트랜잭션의 실행 방식이 다르다. 트랜잭션에는 서명이 필요하고, 제출 직후에는 최종 결과 대신 transaction hash만 돌아올 수 있다.

두 세계의 차이를 짧게 놓으면 다음과 같다.

경계기존 업무 시스템블록체인 실행 환경
인터페이스REST API, OpenAPI 명세ABI, JSON-RPC
주체 식별·거래 승인고객·계정, 인증 세션과 승인 정책주소, 키와 전자서명
실행 결과동기 HTTP 응답과 업무 오류즉시 조회 결과 또는 transaction hash·receipt
운영 단위request ID, 애플리케이션 로그block, transaction, event
변경 관리API version과 배포컨트랙트 주소·ABI와 네트워크 상태

프로토타입에서는 이 차이를 연결하는 코드를 작성할 수 있었다. 문제는 다음 프로젝트에서도 같은 연결을 다시 작성해야 한다는 점이었다.

주소 자체가 고객의 신원을 증명하지는 않는다. 실제 금융 서비스에서는 업무 계정과 블록체인 주소의 관계, 그 주소로 거래를 승인할 권한을 별도의 계정·권한 체계로 관리해야 한다.

토큰증권이 아닌 다른 EVM·ABI 기반 디지털 자산 서비스를 만든다고 해도 ABI를 해석하고, 업무 요청을 트랜잭션으로 바꾸고, 서명과 전송을 연결하고, 비동기 결과를 추적하는 일은 반복된다. 구체적인 업무는 달라져도 기존 시스템과 원장 사이의 번역은 사라지지 않았다.

서비스를 더 만드는 대신 경계를 제품으로​

뱅크웨어글로벌 연구소가 익숙한 영역은 개별 금융상품보다 여러 시스템을 안정적으로 연결하고 운영하는 인프라였다. 그래서 질문을 “다음 토큰증권 기능은 무엇인가”에서 “EVM·ABI 기반 서비스를 기존 시스템과 연결할 때 반복되는 공통 영역은 무엇인가”로 바꿨다.

이 관점에서 출발한 제품이 블록체인 미들웨어 **BXB(BX-Blockstream)**다.

BXB는 블록체인 원장을 대신하는 제품이 아니다. 토큰증권의 발행·유통 정책을 결정하는 업무 시스템도 아니다. 기존 애플리케이션과 블록체인 네트워크 사이에서 서로 다른 인터페이스, 실행 방식과 운영 수명주기를 연결하는 것을 제품의 역할로 삼았다.

이전 예시에서 고객과 상품의 거래 규칙은 업무 시스템이 정한다. BXB는 그 요청을 컨트랙트 호출로 변환하고, 수탁형 지갑의 서명과 블록체인 전송·결과 추적을 연결하는 경계에 놓인다.

업무 애플리케이션은 고객과 상품의 규칙에 집중하고, 미들웨어는 EVM·ABI 기반 프로젝트마다 반복되던 인터페이스 변환과 공통 실행 경로를 맡도록 역할을 나눴다. Polsto에서 작성한 연결 코드를 다른 서비스에도 재사용하는 정도가 아니라, 연결 자체를 하나의 제품 문제로 다시 정의한 것이다.

REST API가 트랜잭션이 되려면​

상태 조회만 놓고 보면 ABI와 REST API 사이의 변환으로 연결이 끝나는 것처럼 보인다. 그러나 일반적인 EOA(Externally Owned Account, 개인키로 제어하는 계정) 기반 실행에서 원장을 변경하는 요청에는 서명이 필요하다. 트랜잭션을 구성하는 서버와 그 트랜잭션을 승인할 키 사이에 경계가 하나 더 있다.

사용자가 직접 관리하는 비수탁형 지갑을 가정해 보자. API 서버는 transfer에 필요한 컨트랙트 주소와 호출 데이터를 만들 수 있지만, 사용자의 개인키로 대신 서명할 수는 없다. 브라우저나 모바일 지갑에 서명 요청을 보내고 사용자가 승인한 결과를 다시 받아야 한다. REST API가 쓸모없다는 뜻은 아니지만, 서버의 REST 요청 한 번만으로 트랜잭션 제출까지 완결되는 구조는 아니다.

여기서 EOA와 수탁형 지갑을 반대 개념으로 놓으면 정확하지 않다. Ethereum의 EOA는 개인키를 가진 주체가 제어하는 계정이다. 그 개인키를 고객이 직접 보관하면 비수탁형이고, 기관이 고객과의 계약과 통제 절차 아래 관리하면 같은 EOA도 수탁형 지갑 시스템의 계정이 될 수 있다. 차이는 계정의 종류보다 누가 키를 관리하고 어떤 정책으로 서명을 승인하는가에 있다.

여기서 수탁형은 기관의 통제 아래 키를 관리하고 서명을 실행하는 기술 구조를 뜻한다. 법률상 수탁업 해당 여부나 인허가 지위를 판단하는 표현은 아니다.

기관이 자체 서비스 안에서 고객에게 지갑 계정을 제공하고 기존 인증·인가 절차를 통해 블록체인 거래까지 처리하려면 이 차이가 중요해진다. 기관의 업무 계정과 지갑 alias(업무용 지갑 식별명)를 블록체인 주소에 연결하고, 요청자의 권한과 거래 정책을 확인한 뒤, 통제된 서명 경계에서 트랜잭션에 서명해야 한다. 서명된 결과는 eth_sendRawTransaction으로 노드에 제출하고 transaction hash를 기준으로 후속 상태를 추적할 수 있다.

앞의 토큰 10개 이전도 이 경로를 따른다. 사용자는 개인키나 블록체인 서명 형식을 직접 다룰 필요가 없다. 사용자는 기존 서비스의 인증과 거래 승인 절차를 거치고, 수탁형 지갑 시스템이 그 승인을 블록체인 서명으로 집행한다. 블록체인 서명을 없애는 것이 아니라 기관 시스템 안의 통제 가능한 실행 단계로 옮기는 것이다.

BXB에는 이 서명 경계를 담당하는 수탁형 지갑 시스템이 구현돼 있다. 이 구현이 있기 때문에 API Service Factory가 만든 REST endpoint는 단순한 API 문서나 unsigned transaction 생성에 머물지 않고, 기관의 권한 확인에서 서명·전송과 결과 추적까지 이어지는 실행 경로가 될 수 있다. 기관이 서버 측 REST API의 실행 수명주기를 책임지려면 통제된 서명 시스템이 필요하다. 수탁형 지갑은 그 구현 방식 가운데 하나이며, BXB는 이 방식을 채택했다.

물론 사용자가 블록체인 서명 방식을 몰라도 된다는 말이 사용자 동의나 거래 승인을 생략한다는 뜻은 아니다. 고객 인증, 거래 한도, 다단계 승인과 감사 기록은 여전히 기관의 업무 정책으로 남는다. 수탁형 지갑은 그 정책을 개인키 사용과 온체인 거래로 안전하게 연결해야 한다.

고객 계정에서 어떤 지갑과 키를 선택하는지, 각 단계의 책임은 어떻게 나뉘는지는 고객 계정은 어떻게 블록체인 서명으로 이어질까에서 전송 예제로 더 살펴본다.

API를 등록하는 때와 요청을 실행하는 때​

그 경계의 핵심 기능으로 구상한 것이 API Service Factory다.

Solidity 컨트랙트의 ABI JSON에는 함수명, 입력·출력 자료형과 stateMutability가 들어 있다. pure와 view는 상태를 변경하지 않는 함수이고, nonpayable과 payable은 상태를 변경하는 트랜잭션의 진입점이 될 수 있다. 다만 ABI의 이 값만으로 업무 API의 실행 정책이 모두 결정되는 것은 아니다. 상태 변경 함수도 사전 시뮬레이션을 위해 eth_call로 실행할 수 있다.

반면 OpenAPI Specification 3(OAS3)는 HTTP API의 경로, 입력과 응답 형식을 기술한다. 사람이 읽는 문서와 서버·클라이언트 도구가 함께 사용하는 인터페이스 계약이다. OpenAPI 3.0.4 명세는 이 설명에 참고한 문서이며, 2023년 구현에서 사용한 정확한 버전을 뜻하지는 않는다.

두 타입 체계도 단순한 일대일 대응은 아니다. uint256은 일부 JSON 클라이언트가 정밀하게 표현할 수 있는 정수 범위를 넘고, bytes, 배열과 tuple은 별도의 schema와 직렬화 규칙이 필요하다. 주소 형식과 숫자 범위까지 검증하지 않으면 문법적으로 맞는 OAS3 문서가 실행 시 안전한 API를 보장하지 못한다.

API Service Factory의 역할을 이해하려면 API를 준비하는 과정과 그 API를 호출하는 과정을 나누어 보는 편이 쉽다.

API를 등록할 때​

ABI에서 노출할 함수와 자료형을 읽고, OAS3의 경로와 입력·응답 형식으로 옮긴다. 이어서 해당 HTTP 요청을 어느 네트워크의 어떤 컨트랙트·함수로 연결할지 설정하고, 요청을 받을 endpoint를 등록한다.

OAS3 명세만으로 컨트랙트 주소나 서명 권한이 자동 결정되지는 않는다. 대상 함수와 실행 정책을 연결하는 정보가 함께 필요하다. 여기서는 그 정보의 필요성을 설명하며, BXB 내부의 저장 형식이나 배포별 설정을 제품 사양으로 제시하지 않는다.

등록된 API를 호출할 때​

토큰 10개 이전 요청이 들어오면 이미 정해 둔 연결 정보를 사용한다. 요청마다 API를 새로 만드는 것이 아니다.

  1. 요청자의 권한과 수신 주소·수량을 검증한다. 수량은 해당 토큰의 최소 단위로 변환해야 한다.
  2. 대상 함수와 인자를 ABI 규칙에 맞게 인코딩한다.
  3. 조회라면 eth_call로 결과를 읽는다. 상태 변경이라면 트랜잭션을 구성하고 수탁형 지갑에서 서명한다.
  4. 서명된 트랜잭션을 eth_sendRawTransaction으로 제출하고 식별자인 transaction hash로 결과를 추적한다.

Ethereum JSON-RPC 문서에서 eth_call은 온체인 트랜잭션을 만들지 않는 호출이다. eth_sendRawTransaction은 이미 서명한 트랜잭션을 제출하며, 노드가 관리하는 계정으로 서명·전송하는 eth_sendTransaction과 구분된다. 조회의 반환값과 변경 요청의 제출 식별자는 같은 종류의 결과가 아니다.

잔액 조회와 전송을 실제 HTTP 입력·출력으로 연결하는 예제는 컨트랙트 하나를 REST API로 운영하기까지에서 살펴본다. 큰 정수의 정밀도와 거래 응답의 의미까지 같은 호출 흐름을 따라간다.

같은 거래를 접수부터 확정까지 따라가기​

토큰 10개를 이전하기 전에 잔액을 확인하는 요청과, 실제로 이전하는 요청을 비교해 보자.

요청실행업무 시스템이 처음 받는 결과
잔액 조회 balanceOfeth_call조회 시점의 잔액
토큰 이전 transfer서명 후 트랜잭션 제출접수·제출 상태와 추적 식별자

조회한 잔액은 해당 시점의 상태다. 이후 다른 거래로 바뀔 수 있으므로 조회 성공이 이전 가능 여부를 확정해 주지는 않는다. 이전 요청은 다음처럼 진행 상태를 나눠 읽어야 한다. 아래는 설명용 상태 구분이며 BXB의 실제 응답 필드나 상태 코드 목록은 아니다.

단계이때 확인한 사실
접수업무 요청을 받아 추적하기 시작했다. 아직 전송됐다는 뜻은 아니다.
제출노드에 서명된 트랜잭션을 제출해 transaction hash를 받았다.
실행 확인블록에 포함된 실행의 receipt와 컨트랙트 결과를 확인했다.
업무상 확정네트워크 확정 조건과 기관의 거래 정책을 충족했다.

권한·입력 검증에서 거절되면 제출 전 단계에서 끝난다. 제출됐더라도 잔액 부족 등으로 실행이 실패할 수 있다. 고객에게 “10개 이전 완료”를 보여주는 기준은 접수 응답이나 hash 수신이 아니라 마지막 단계에 있다.

실행 성공의 뜻도 컨트랙트에 맞춰 정해야 한다. ERC-20 표준은 transfer의 false 반환 가능성을 처리하도록 요구한다. receipt의 실행 성공만으로 모든 업무 결과를 판정해서는 안 되며, 반환·이벤트·상태의 의미를 함께 고려해야 한다. 함수 반환값이 일반 receipt에 그대로 들어오는 것도 아니다.

이 예시를 HTTP API로 노출한다면 잔액 조회에 GET, 이전 요청에 POST를 사용할 수 있다.

여기서 GET과 POST는 Solidity가 정한 규칙이 아니다. 방금의 GET/POST 구분은 읽기와 상태 변경을 기존 API 사용자가 이해하기 쉽게 표현한 하나의 매핑 정책이다. 실제 시스템에서는 업무 요구에 따라 HTTP method를 바꾸거나 입력값을 query parameter, path variable 또는 request body에 배치할 수 있어야 한다. 자동 변환은 정책을 없애는 기능이 아니라, 기본 구조를 만든 뒤 정책을 일관되게 적용할 출발점을 제공한다.

자동 생성보다 더 어려운 것은 운영이다​

ABI를 OAS3로 변환하고 API endpoint를 만들었다고 블록체인 연계가 끝나는 것은 아니다. BXB의 수탁형 지갑 시스템이 서명 경계를 구현했더라도, 기관 환경에서 운영하려면 그 앞뒤의 책임을 명확하게 정해야 한다.

  • 업무 사용자가 어떤 지갑과 권한을 사용할 수 있는지 기관의 인증·인가 정책과 연결해야 한다.
  • 지갑 alias, 실제 주소와 키의 관계를 보호하고 역할 분리·감사·복구 절차를 마련해야 한다.
  • 배포 환경에 따라 키를 HSM이나 KMS 같은 보호 시스템과 어떻게 결합할지 정해야 한다.
  • timeout 뒤에 토큰 10개 이전을 다시 요청해도 같은 업무 요청을 찾아 이어갈 수 있어야 한다. 이를 위한 중복 방지(idempotency)와 발신 계정의 트랜잭션 순번인 nonce 정책이 필요하다.
  • transaction hash가 생겼다는 사실과 거래가 블록에 포함되고 최종 확정됐다는 사실을 구분해야 한다.
  • 컨트랙트 주소나 ABI가 바뀔 때 기존 API와의 호환성을 관리해야 한다.
  • HTTP 오류, RPC 오류, revert와 네트워크 장애를 업무 시스템이 처리할 수 있는 형태로 정규화해야 한다.
  • API 호출과 블록체인 transaction·event를 같은 흐름으로 추적할 로그와 모니터링이 필요하다.

미들웨어의 가치는 이 책임들을 보이지 않게 숨기는 데 있지 않다. 여러 애플리케이션이 제각각 구현하던 책임을 한 경계에 모으고, 같은 정책과 관측 방식으로 운영할 수 있게 만드는 데 있다.

그렇다고 모든 책임이 미들웨어로 이동하는 것도 아니다. 네트워크의 finality와 reorg 특성은 미들웨어가 따라야 할 기술적 제약이다. 그 상태를 어느 시점에 업무상 확정으로 받아들일지, 누가 어떤 자산을 이전할 수 있는지, 고객 확인과 승인 절차를 어떻게 둘지는 업무와 규제 정책에 따른다. API Service Factory는 그 결정을 대신하지 않는다. 결정된 정책이 블록체인 실행까지 일관되게 이어지도록 연결한다.

기다리는 동안 더 넓어진 문제​

2023년 당시 제도의 지연은 Polsto에서 했던 작업을 무의미하게 만들지 않았다. 오히려 시장 이름을 제외하고도 남는 문제를 보게 했다.

특정 토큰증권 서비스에만 필요한 기능과 여러 EVM·ABI 기반 서비스가 공유할 연결 기능을 나눴다. 전자는 시장과 업무에 따라 달라지지만, 후자는 산업이 바뀌어도 반복됐다. BXB는 그 반복되는 부분을 인프라 제품의 관점에서 다시 묶은 결과였다.

이 과정에서 정리한 기술 구조의 일부는 2025년 뱅크웨어글로벌 명의의 대한민국 등록특허 제10-2887854호 「스마트 컨트랙트 포맷 변환을 통한 API 제공 시스템 및 방법」 형태로도 정리됐다. 등록 사실은 제품의 성능을 증명하기 위한 장식이 아니라 설계의 공개 이력을 밝히기 위한 정보다.

현재 제도의 상황은 당시와 다르다. 토큰증권 도입을 위한 전자증권법과 자본시장법 개정안은 2026년 1월 국회 본회의를 통과한 뒤 공포됐다. 개정 전자증권법은 2027년 2월 4일 시행될 예정이다. 금융위원회는 그 시행에 맞춰 기술·인프라, 발행과 유통 분야의 세부 제도를 준비하고 있다.

제도의 시계가 다시 움직이기 시작했지만 인프라에 관한 결론은 달라지지 않았다. 토큰증권 시장이 열릴수록 발행 기능만큼 기존 금융 시스템, 계정 관리, 서명, 원장과 운영 체계를 어떻게 연결할지가 중요해진다.

시장마다 다른 것은 업무, 반복되는 것은 연결이다​

Polsto는 토큰증권 플랫폼을 만들어보자는 시도에서 시작했다. 그 구현을 통해 확인한 것은 하나의 시장에 대한 답보다 여러 시장에서 반복될 질문이었다.

기존 시스템은 익숙한 API와 업무 개념을 유지하고 싶어 한다. 이 글에서 다룬 EVM 실행 환경은 ABI, 트랜잭션, 서명과 비동기 확정이라는 고유한 실행 모델을 가진다. 둘 중 하나를 다른 하나처럼 보이게 만드는 것만으로는 충분하지 않다. 차이를 이해하면서도 그 차이가 모든 애플리케이션에 반복해서 새어 나오지 않게 할 경계가 필요하다.

BXB를 만들게 된 이유도 여기에 있다. 특정 EVM 기반 서비스를 더 만드는 대신, 여러 EVM·ABI 기반 서비스가 공통으로 사용할 연결 기반을 만들기로 했다. API Service Factory는 스마트 컨트랙트의 인터페이스를 기존 시스템이 사용할 수 있는 API와 실행 경로로 바꾸는 그 기반의 한 축이다.

시장마다 달라지는 것은 업무다. 반복되는 것은 연결이다.

Polsto에서 BXB로 이어진 변화는 제품 이름의 변화라기보다, 바로 그 반복을 발견하고 문제의 경계를 다시 그은 과정이었다.


이 글은 블록체인 미들웨어의 기술적 배경을 설명하는 회고이며, 토큰증권 발행을 위한 법률 자문이나 투자 권유가 아니다. 실제 시스템에는 적용 법령, 보안, 키 관리, 장애 복구와 운영 정책에 대한 별도 검토가 필요하다.