ERC-8329 주체 연동 임팩트 스냅샷 로그 (Subject-Linked Impact Snapshot Log)
Last Call · 기타 · 2026-07-05 작성
탄소 배출량, 고용, 수처리 같은 정량 임팩트 측정값을 대상과 기간, 단위, 방법론에 묶어 온체인에 추가 전용으로 기록하는 표준입니다. 과거 기록을 지우지 않고 정정 이력과 지지·이의 증명을 보존합니다.
왜 필요한가
탄소 상쇄량이나 고용 인원 같은 임팩트 측정값은 보통 보고서나 서비스마다 다른 데이터 형식으로 유통됩니다. 온체인에는 이런 값을 측정 대상, 측정 기간, 단위, 방법론과 묶어 기록하면서 나중의 정정까지 보존하는 공통 인터페이스가 없었습니다. 값 하나를 덮어쓰는 방식으로는 새 보고 기간의 값인지 과거 측정의 재작성인지 구분할 수 없고 갱신하는 순간 이전 주장이 지워집니다. 범용 증명(attestation)으로 개별 주장을 표현할 수는 있지만 지표별 시계열 색인, 정확한 기간별 유일성, 정정 체인, 방법론 전환 같은 동작은 그 자체로 정의되지 않습니다. 이 표준은 추가 전용(append-only) 기록과 정정 출처 추적, 방법론 해시 커밋으로 이 문제를 풉니다. 다만 어떤 지표나 방법론이 유효한지 판단하거나 측정값 자체를 검증하지는 않습니다.
심층 설명
스냅샷 구조와 값 표현
스냅샷 하나는 IndicatorSnapshot 구조체로 저장되며 subjectId, indicatorId, value, decimals, unit, periodStart, periodEnd, methodologyHash, methodologyURI, reportedBy, reportedAt, correctsIndex, correctedByIndex를 담습니다. 실제 수량은 value * 10^(-decimals)로 해석합니다. value가 int256인 이유는 순배출이나 기준선 대비 절감처럼 측정값이 음수가 될 수 있기 때문이며 소비자는 값이 음수가 아니라고 가정해서는 안 됩니다. decimals의 상한은 uint8 타입 한계 외에 별도로 두지 않으므로 소비자가 선언된 정밀도를 안전하게 처리해야 합니다. unit은 문서화된 정규 단위 문자열의 keccak256 해시를 쓰는 것이 권장되며 가능하면 SI나 UCUM 호환 표현을 쓰고 커스텀 단위는 대소문자, 철자, 복수형, 변환 규칙을 문서화해야 합니다.
측정 기간과 기간 슬롯 유일성
측정 기간은 시작을 포함하고 끝을 제외하는 반열린 구간 [periodStart, periodEnd)입니다. recordSnapshot은 periodStart < periodEnd <= block.timestamp 조건을 만족하지 않으면 되돌려야 하므로, 이미 끝난 기간만 기록할 수 있습니다. 정확한 기간 슬롯은 (subjectId, indicatorId, periodStart, periodEnd) 네 값으로 식별되며 한 슬롯에는 원본 스냅샷이 최대 하나만 들어갑니다. 슬롯이 채워진 뒤의 수정은 반드시 정정 출처(correction provenance)를 거쳐야 합니다. 서로 다른 기간끼리는 겹칠 수 있는데, 월간과 연간 보고처럼 정당한 중첩이 있기 때문입니다. 겹친 측정이 합산 가능한지 중복인지는 이 표준이 판단하지 않으므로 집계하는 쪽이 방법론별 규칙을 적용해야 합니다.
정정 체인과 센티널 값
구현은 NO_CORRECTION = type(uint256).max 상수를 써야 하며 correctsIndex가 이 값이면 원본 스냅샷입니다. correctedByIndex가 0이면 아직 정정되지 않은 터미널 스냅샷인데, 정정본의 인덱스는 항상 대상보다 크므로 0이 안전한 센티널이 됩니다. 정정은 같은 subjectId의 이전 스냅샷을 지목해야 하고 대상과 같은 indicatorId, periodStart, periodEnd를 써야 하며 correctedByIndex가 0인 스냅샷만 정정할 수 있습니다. 정정이 수락되면 대상의 correctedByIndex만 새 인덱스로 바뀌고 다른 필드는 변하지 않습니다. 각 스냅샷은 최대 한 번만 정정되므로 사슬이 갈라지지 않는 선형 구조가 유지됩니다. 보고 권한이 있다는 이유만으로 다른 보고자의 기록을 정정하도록 허용해서는 안 되며 원 보고자나 지정 정정자, 관리자에게 권한을 줄 수 있습니다.
기록 규칙과 조회 함수의 구분
스냅샷 인덱스는 subjectId별로 0부터 시작하고 반환되는 snapshotIndex는 추가 직전의 대상 스냅샷 수와 같아야 합니다. recordSnapshot은 승인된 보고자로 제한되어야 하고 그 권한 방식은 문서화해야 합니다. 저장 시 reportedBy는 msg.sender, reportedAt은 uint64(block.timestamp)로 설정되며 methodologyHash는 bytes32(0)일 수 없고 methodologyURI는 비어 있을 수 없습니다. 조회 쪽에서는 latestIndicatorSnapshot이 가장 최근에 기록된 스냅샷을 돌려주는데, 이는 기록 순서 기준이지 기간이 늦은 값이 아니므로 오래된 기간의 늦은 정정일 수도 있습니다. 특정 보고 기간의 현재값이 필요하면 currentSnapshotForPeriod를 써야 하며 이 함수는 정확한 기간 슬롯의 터미널 스냅샷을 반환하고 슬롯이 비어 있으면 되돌립니다.
표준 지표와 단위 식별자
지표 식별자로 CARBON_OFFSET, CARBON_EMITTED, ENERGY_GENERATED, ENERGY_SAVED, WATER_TREATED, JOBS_CREATED, BENEFICIARIES, BIODIVERSITY_AREA, WASTE_DIVERTED 아홉 개가 keccak256("ERC-8329:INDICATOR:<이름>") 형태로 정의됩니다. 커스텀 지표는 keccak256("ERC-8329:INDICATOR:<NAMESPACE>:<NAME>:<VERSION>") 패턴이 권장되고 keccak256("CUSTOM") 같은 범용 식별자는 의미를 구분하지 못하므로 쓰지 않는 것이 좋습니다. 단위는 UNIT_TCO2E, UNIT_KWH, UNIT_M3, UNIT_FTE, UNIT_PERSONS, UNIT_HECTARES, UNIT_TONNES 일곱 개가 정의됩니다. 지표 식별자가 단위를 강제하지 않으므로, 보고자와 소비자는 indicatorId만으로 단위를 추정하지 말고 저장된 unit과 방법론을 확인해야 합니다.
증명 확장의 동작 규칙
증명(attestation) 확장은 선택 사항입니다. attestSnapshot은 존재하지 않는 스냅샷과 0인 evidenceHash를 거부해야 하고 evidenceURI는 비워 둘 수 있습니다. attestor는 msg.sender, attestedAt은 uint64(block.timestamp)로 기록됩니다. 스냅샷에 저장된 보고자 주소는 그 스냅샷에 증명할 수 없는데, 이는 주소 수준의 분리일 뿐 조직이나 재정, 법적 독립성을 보장하지 않습니다. 증명은 불변이고 삭제할 수 없으며 같은 증명자가 같은 스냅샷에 생각이 바뀐 뒤의 평가를 포함해 여러 번 제출할 수 있으므로 소비자는 전체 이력을 평가해야 합니다. 이미 정정된 스냅샷에도 증명을 붙일 수 있지만 이전 스냅샷에 붙은 증명이 정정본으로 자동 승계되지는 않으므로 적용 여부는 소비자가 판단합니다.
방법론 버전 관리와 교체 조건
방법론 버전 관리 확장도 선택 사항입니다. 한 대상과 지표의 첫 스냅샷이 자신의 methodologyHash와 methodologyURI로 활성 방법론을 초기화하고 이후 스냅샷은 해당 순번에 활성인 방법론 해시를 써야 합니다. supersedeMethodology는 방법론이 초기화되어 있고 oldMethodologyHash가 활성 방법론과 일치하며 새 해시가 0이 아니고 새 URI가 비어 있지 않으며 보류 중인 교체가 없고 effectiveFromOrdinal이 현재 indicatorSnapshotCount 이상일 때만 성공합니다. 효력 순번이 현재 수와 같으면 즉시, 크면 보류 상태가 되어 pendingMethodology로 조회됩니다. 효력 순번에 도달하면 별도의 상태 변경 호출 없이도 activeMethodology가 새 방법론을 노출해야 합니다. 새 방법론으로 재계산한 과거 값은 반드시 정정으로 제출해야 하며 기존 스냅샷을 고치면 안 됩니다.
표준의 범위와 진행 상태
이 표준은 표현 방식과 수명 주기 동작만 규정합니다. 어떤 지표나 방법론이 유효한지 정의하지 않고 보고된 측정을 검증하지 않으며 보고자나 증명자의 자격을 심사하지 않고 중복 주장을 막지 않으며 임팩트 점수도 제공하지 않습니다. 준수 구현은 ERC-165를 구현해 type(IImpactSnapshotLog).interfaceId에 true를 반환해야 하고 확장을 지원하면 IImpactAttestation과 IMethodologyVersioning의 인터페이스 ID에도 true를 반환해야 합니다. 다만 ERC-165는 인터페이스 지원만 알려줄 뿐 측정 정확성이나 자격을 보장하지 않습니다. 이 제안은 현재 Last Call 상태(마감 2026-10-19)로, 최종 확정 전 마지막 의견 수렴 단계이며 내용이 바뀔 수 있습니다.
쓸 때 주의할 점
- 보고자 신뢰의 한계: 이 로그는 승인된 주소가 값을 보고했다는 사실만 증명합니다. 측정 자체, 원천 데이터, 계산, 단위, 기간 경계, 방법론 적용은 검증하지 않으므로, 거짓 데이터는 불변으로 기록되어도 여전히 거짓입니다.
- 방법론 문서의 무결성과 거버넌스: 방법론 커밋은 소비자가 정확한 문서를 구해 해시를 재현할 수 있을 때만 유효합니다. URI는 사라지거나 내용이 바뀔 수 있으므로 내구성 있는 저장이 필요합니다. 또한 권한자가 더 유리한 결과를 내는 방법론으로 교체할 수 있으며 이벤트와 보류 조회는 전환을 보이게 할 뿐 정당성을 보장하지 않습니다.
- 정정 권한과 체인 길이: 정정 정책이 약하면 한 보고자가 다른 보고자의 측정을 덮어쓸 수 있으므로 정정 권한을 문서화해야 합니다. 기간 조회는 정정 포인터를 따라가는데, 정정이 과도하게 쌓이면 온체인 해석 비용이 커질 수 있습니다.
- 증명자 자격과 상충하는 증명: 보고자 주소 차단은 직접 자기 증명만 막을 뿐이며 같은 조직이 여러 주소를 통제할 수 있습니다. 인터페이스는 다수의 지지와 이의를 합산하지 않고 주소는 값싸게 만들 수 있어 주소 수 세기는 신뢰 모델이 되지 못합니다. 외부의 증명자 선정과 가중치 정책이 필요합니다.
- 중복 계산과 겹치는 주장: 기간 유일성은 하나의 대상과 지표 슬롯 안에서만 적용됩니다. 겹치는 기간, 연관 지표, 복수의 대상, 독립 레지스트리가 같은 임팩트를 중복 표현할 수 있으므로, 집계 전에 경계와 방법론을 조정해야 합니다.