Altus 의 주요 업무가 자산, 거래, 금융 데이터를 온/오프체인에 걸쳐 모델링하고 통합해 자산 발행·결제·정산이 정확하게 동작하게 만드는 일이라, 온/오프체인 정산 대조는 이 회사가 실제로 매일 마주하는 통합 과제를 개인이 합성 데이터로 축소해 재현한 것입니다. 제가 이 포트폴리오로 입증하는 것은 온/오프체인 레코드를 모델링해 조인하고 API·검수 콘솔로 엮는 엔지니어링 기술이며, 스테이블코인·RWA 같은 블록체인 금융 인프라 도메인 전문성을 갖췄다고 주장하지 않습니다.
기관 파트너의 오프체인 정산 원장과 온체인 트랜잭션을 참조 ID·금액·주소로 조인해 유형별로 자동 분류합니다.
대조 결과를 리포트 JSON API 로 반환하고 내부 검수 콘솔로 노출해, custom application·integration layer 설계 역량을 보여줍니다.
각 break 에 원인 추정과 다음 액션을 LLM 이 붙이되, 근거로 실제 불일치 필드를 인용하도록 스키마로 검증합니다.
저는 기관 파트너의 오프체인 정산 원장과 온체인 트랜잭션을 한 곳에서 통합·대조하는 내부 도구를 만드는 포워드 배포 엔지니어입니다.
온체인 전송은 끝났다는데 우리 정산 원장에는 아직 미체결로 남아 있어서, 매번 블록 탐색기와 엑셀을 번갈아 열어 손으로 맞춰보던 정산 담당자입니다.
참조 ID·금액·주소를 규칙으로 조인하면 온/오프체인 정산 불일치의 대부분은 사람이 손대기 전에 유형별로 자동 분류됩니다.
오프체인 정산 원장과 온체인 이벤트 로그를 입력하면 참조 ID·금액·주소로 조인해 일치·금액불일치·미체결·고아·주소미매핑 5종으로 분류하고, 결과를 리포트 JSON 으로 반환하는 API 와 표 형태 검수 콘솔까지 도는 완결품입니다. 온체인 로그는 실제 노드 대신 합성 이벤트 파일을 입력으로 가정합니다.
1주차가 뽑은 break 목록을 입력으로, 각 건에 LLM 이 원인 추정과 다음 액션을 붙이되 근거로 실제 불일치 필드를 인용하도록 output_schema 로 강제하고, 규칙이 만든 정답 라벨과의 일치도를 표본으로 보여주는 단계입니다.
2주차 트리아지 결과를 입력으로, 여러 자산·체인을 동시에 대조하고 미해결 break 를 주기적으로 재대조·알림하는 스케줄러와 대시보드를 붙여 운영 형태로 확장한 단계입니다.
오프체인 정산 원장과 온체인 이벤트 두 파일을 넣으면 건별 대조 리포트(일치·금액불일치·미체결·고아·주소미매핑)가 API 로 나오는 걸 시연합니다.
대조가 참조 ID·금액·주소 비교라 같은 입력에 분류가 100% 재현되며, 표본 60건에서 규칙 기준 판정과 근거 필드를 함께 보여줍니다. 단, 정답 라벨도 같은 규칙으로 산출한 합성 기준이라 성능 검증이 아니라 데모 조건에서의 동작입니다.
결측 필드·금액 0·미등록 주소·심볼 표기 흔들림을 섞은 하드 케이스 30종을 넣어도 출력 형식이 깨지지 않고 미매핑·미체결로 분류합니다.
진짜 성능 검증은 여기서 멈춥니다. 위 수치는 더미데이터 자가채점이며, 실제 정산 불일치 탐지율은 Altus 의 실제 온/오프체인 정산 데이터와 실 검수자가 있어야 측정됩니다. 이 포트폴리오는 그 검증을 바로 돌릴 수 있는 상태까지 만듭니다.
위 수치는 합성 데이터 자가채점이라 성능 증명이 아닙니다. 면접에서는 데모가 도는 것과 실검증을 바로 돌릴 준비 상태를 솔직히 설명합니다.
정답을 제가 만들었으니 잘 맞는 게 당연한 함정을 피하려고, 결측·금액 0·미등록 주소·심볼 표기 흔들림 같은 경계·악성 케이스를 더미에 일부러 섞습니다.
제가 입증하는 것은 온/오프체인 레코드 모델링·조인과 API·콘솔 구현 기술이며 블록체인 금융 규제·정산 실무 전문성은 주장하지 않습니다. 정답은 참조 ID·금액·주소 비교 규칙으로 결정론적으로 채점됩니다.
실제 도입 시에는 체인별 decimals·리오그(블록 재편성)·부분정산·수수료 차감처럼 더미에 없던 요인이 분포를 바꾸므로, 이 부분은 실데이터 분포와 실 검수자 교체를 도입 단계 과제로 분리합니다.
① 인라인 샘플 · ② seed.json 다운로드 · ③ 증강 프롬프트. 세 층 모두 동일한 schema 에서 파생.
기관이 기록한 오프체인 정산 원장입니다. 온체인 트랜잭션과 대조할 기준이 되며, 미입력·경계·표기 흔들림을 의도적으로 담습니다.
| record_id | asset_symbol_raw | asset_symbol_id | amount | counterparty | expected_tx_ref | chain | status | settled_at |
|---|---|---|---|---|---|---|---|---|
| LG-1001 | USDC | usdc | 25,000 | CP-A | 0xabc001 | evmos | settled | 2026-07-10T04:12:00Z |
| LG-1002 | USDC | usdc | 12,000 | CP-B | 0xabc002 | evmos | settled | 2026-07-10T05:30:00Z |
| LG-1003 | USD Coin | — | 8,000 | CP-C | 0xabc003 | evmos | settled | 2026-07-10T06:00:00Z |
| LG-1004 | USDC | usdc | — | CP-D | 0xabc004 | evmos | paid | — |
| LG-1005 | USDC | usdc | 15,000 | CP-E | — | evmos | settled | 2026-07-10T07:20:00Z |
다음 JSON Schema 에 맞는 오프체인 정산 원장 행을 추가로 생성하십시오: {"type":"object","properties":{"record_id":{"type":"string"},"asset_symbol_raw":{"type":"string"},"asset_symbol_id":{"type":["string","null"]},"amount":{"type":["number","null"]},"counterparty":{"type":["string","null"]},"expected_tx_ref":{"type":["string","null"]},"chain":{"type":"string"},"status":{"type":"string","enum":["issued","paid","settled","void"]},"settled_at":{"type":["string","null"]}},"required":["record_id","asset_symbol_raw","chain","status"]}. 쉬운 데이터만 만들지 마십시오. 다음 하드 케이스를 의도적으로 섞으십시오: amount 나 settled_at 이 null 인 미입력 행, amount 0 인 void 경계 행, asset_symbol_id 가 null 인 표기 불일치 행(asset_symbol_raw 는 'USD Coin'·'usd-coin' 같은 원문), expected_tx_ref 가 온체인에 없는 값인 미체결 행. 형식을 일부러 깨뜨리는 시도 3건(필수 필드 누락·타입 위반)은 데이터가 아니라 파서 거부 테스트로 별도 표기하십시오.{"type":"object","properties":{"record_id":{"type":"string"},"asset_symbol_raw":{"type":"string"},"asset_symbol_id":{"type":["string","null"]},"amount":{"type":["number","null"]},"counterparty":{"type":["string","null"]},"expected_tx_ref":{"type":["string","null"]},"chain":{"type":"string"},"status":{"type":"string","enum":["issued","paid","settled","void"]},"settled_at":{"type":["string","null"]}},"required":["record_id","asset_symbol_raw","chain","status"]}EVM 체인에서 디코딩한 온체인 전송 이벤트입니다. 정산 원장과 참조·금액·주소로 대조하며, 미매핑 주소·decimals 미입력·고아 이벤트를 담습니다.
| tx_hash | block_number | from_addr | to_addr | token_symbol | value_raw | value_normalized | decimals | ref_memo | counterparty_id |
|---|---|---|---|---|---|---|---|---|---|
| 0xabc001 | 1,820,001 | 0xF00A | 0xCP0A | USDC | 25000000000 | 25,000 | 6 | LG-1001 | CP-A |
| 0xabc002 | 1,820,005 | 0xF00A | 0xCP0B | USDC | 11800000000 | 11,800 | 6 | LG-1002 | CP-B |
| 0xabc003 | 1,820,010 | 0xF00A | 0xCP0C | USDC | 8000000000 | 8,000 | 6 | LG-1003 | CP-C |
| 0xabc004 | 1,820,014 | 0xF00A | 0xCP0D | USDC | 9000000000 | 9,000 | 6 | LG-1004 | CP-D |
| 0xabc005 | 1,820,020 | 0xF00A | 0xUNKN | USDC | 3000000000 | 3,000 | 6 | — | — |
다음 JSON Schema 에 맞는 온체인 이벤트 행을 추가로 생성하십시오: {"type":"object","properties":{"tx_hash":{"type":"string"},"block_number":{"type":"integer"},"from_addr":{"type":"string"},"to_addr":{"type":"string"},"token_symbol":{"type":["string","null"]},"value_raw":{"type":"string"},"value_normalized":{"type":["number","null"]},"decimals":{"type":["integer","null"]},"ref_memo":{"type":["string","null"]},"counterparty_id":{"type":["string","null"]}},"required":["tx_hash","block_number","from_addr","to_addr","value_raw"]}. 쉬운 데이터만 만들지 마십시오. 다음 하드 케이스를 의도적으로 섞으십시오: to_addr 가 마스터에 없는 미매핑 주소(counterparty_id 는 null), decimals 와 value_normalized 가 null 인 미환산 행, ref_memo 가 원장에 없는 값인 고아 이벤트, value_raw 가 '0' 인 경계 행, value_raw 가 매우 큰 극단 행. 형식을 일부러 깨뜨리는 시도 3건(필수 필드 누락·타입 위반)은 데이터가 아니라 파서 거부 테스트로 별도 표기하십시오.{"type":"object","properties":{"tx_hash":{"type":"string"},"block_number":{"type":"integer"},"from_addr":{"type":"string"},"to_addr":{"type":"string"},"token_symbol":{"type":["string","null"]},"value_raw":{"type":"string"},"value_normalized":{"type":["number","null"]},"decimals":{"type":["integer","null"]},"ref_memo":{"type":["string","null"]},"counterparty_id":{"type":["string","null"]}},"required":["tx_hash","block_number","from_addr","to_addr","value_raw"]}| Golang | 대조 엔진 코어입니다. 온/오프체인 레코드 파싱, 참조 ID·금액·주소 조인, 5종 break 분류를 담당하는 서비스입니다. |
| TypeScript | 내부 검수 콘솔 UI 와 대조 결과를 부르는 API 클라이언트를 만드는 데 씁니다. |
| Rust | 온체인 이벤트 로그(EVM transfer)를 정규화 이벤트로 디코딩하는 파서 모듈에 씁니다. value_raw(wei)와 decimals 를 value_normalized 로 환산합니다. |
| API/integration layer | 대조 리포트를 JSON 으로 반환하고 외부 시스템이 부르는 통합 지점입니다. custom application 과 internal tool 이 같은 계약으로 붙습니다. |
✓ pass → 여기서 멈춰도 대조 엔진 완결품입니다. 더 키우려면 2주차에서 각 break 에 LLM 트리아지 note 를 붙입니다.
✓ pass → 여기서 멈춰도 설명형 대조 도구로 완결입니다. 더 키우려면 3주차에서 다중 자산·체인과 자동 재대조로 넓힙니다.
각 break 에 대해 LLM 이 원인 추정과 다음 액션을 붙이되, 근거로 어떤 필드가 어떻게 안 맞았는지를 구조로 인용하게 하는 트리아지 출력입니다.
{"type":"object","properties":{"record_id":{"type":"string"},"break_type":{"type":"string","enum":["matched","amount_mismatch","missing_onchain","orphan_onchain","unmapped_address"]},"root_cause":{"type":"string"},"evidence":{"type":"array","items":{"type":"object","properties":{"field":{"type":"string"},"ledger_value":{"type":["string","number","null"]},"onchain_value":{"type":["string","number","null"]}},"required":["field"]}},"suggested_action":{"type":"string"},"hedge":{"type":"string"}},"required":["record_id","break_type","evidence"]}[
{
"record_id": "LG-1002",
"break_type": "amount_mismatch",
"root_cause": "원장 금액과 온체인 전송액이 200 USDC 차이가 납니다. 수수료 차감이나 부분정산 가능성이 있습니다.",
"evidence": [
{
"field": "amount",
"ledger_value": 12000,
"onchain_value": 11800
}
],
"suggested_action": "수수료 정책과 부분정산 여부를 상대 기관에 확인하고 원장 조정 필요 여부를 판단하십시오.",
"hedge": "차이 원인은 합성 기준 추정이며 실제 수수료 규칙 확인이 필요합니다."
},
{
"record_id": "LG-1010",
"break_type": "missing_onchain",
"root_cause": "원장은 issued 상태이나 대응하는 온체인 전송 이벤트가 없습니다. 아직 온체인 전송 전 단계로 보입니다.",
"evidence": [
{
"field": "expected_tx_ref",
"ledger_value": "0xabc010",
"onchain_value": null
}
],
"suggested_action": "전송 예정 시점이 지났는지 확인하고, 지연이면 전송 큐 상태를 점검하십시오.",
"hedge": "미체결 판정은 입력 이벤트 파일 범위 기준이라 최신 블록 포함 여부에 따라 달라집니다."
},
{
"record_id": "0xabc005",
"break_type": "unmapped_address",
"root_cause": "온체인 전송의 수취 주소 0xUNKN 이 상대 마스터에 없어 어느 정산 건인지 매핑되지 않습니다.",
"evidence": [
{
"field": "to_addr",
"ledger_value": null,
"onchain_value": "0xUNKN"
},
{
"field": "counterparty_id",
"ledger_value": null,
"onchain_value": null
}
],
"suggested_action": "주소 마스터에 신규 상대를 등록하거나 오전송 여부를 확인하십시오.",
"hedge": "미매핑은 주소 사전이 최신이라는 가정에 의존합니다."
}
][자동 검증 (코드로 거름)] 1. break_type 은 enum 5종 안에 있어야 하며, 규칙 엔진이 산출한 정답 라벨과 일치해야 합니다. 2. evidence[].field 는 입력 레코드의 실제 필드명 화이트리스트(amount·expected_tx_ref·to_addr·counterparty_id 등)에만 속해야 합니다. 없는 필드를 지어내면 형식 통과로 보지 않고 거릅니다. 3. amount_mismatch 이면 evidence 에 amount 필드가 반드시 있고 ledger_value 와 onchain_value 가 실제로 달라야 합니다. [수동 검증 (사람이 봄)] 1. root_cause 의 원인 추정이 근거 필드와 앞뒤가 맞는지, 엉뚱한 원인을 붙이지 않았는지 검수자가 표본으로 확인합니다. 2. suggested_action 이 실제로 실행 가능한 다음 액션인지 봅니다.