05 · 컨트랙트 인터페이스 및 이벤트
이 장은 발행, 온보딩, mint, transfer, burn 프로세스를 컨트랙트 메서드에 연결하는 구현 참조입니다.
5.1 올바른 컨트랙트부터 찾기
외부 애플리케이션은 전체 Suite에 직접 연결할 필요가 없습니다. 대상 자산의 Token 프록시 주소에서 시작합니다.
권장 검색 순서:
- 공개 주소표에서 대상 환경의 Token 프록시 주소를 읽습니다.
Token.identityRegistry()로 자산 Registry를 가져옵니다.Token.compliance()로 컴플라이언스 진입점을 가져옵니다.IdFactory.getIdentity(wallet)로 지갑의 ONCHAINID를 조회합니다.- 온체인 결과와 공개 설정을 비교하고 구현 주소를 비즈니스 진입점으로 사용하지 않습니다.
5.2 권한 참조
| 호출자 | 일반적인 write 메서드 | 설명 |
|---|---|---|
| 모든 사용자 또는 앱 | 모든 view | read-only이며 트랜잭션과 사용자 gas 불필요 |
| Token 보유자 | transfer, approve, transferFrom | 신원, pause, freeze, 규칙 검사 적용 |
| 투자자 신원 관리 지갑 | deployIdentityForWallet, addClaim | 본인의 ONCHAINID 생성·관리 |
| IR Agent | registerIdentity, updateIdentity, updateCountry, deleteIdentity | 한 자산의 투자자 등록 관리 |
| Token Agent | mint, burn, pause, unpause, freeze, 강제 이전, 복구 | 자산 관리 작업 |
| Contract Owner | Registry, Compliance, 거버넌스 설정 변경 | 일반 앱 연동 범위 밖 |
작업을 표시하기 전에 현재 지갑 역할을 식별하십시오. 프런트엔드에서 버튼을 숨기는 것은 온체인 권한 제어를 대체하지 않습니다.
5.3 Token
일반 read 메서드
| 메서드 | 반환 | 용도 |
|---|---|---|
name() / symbol() | string | 자산 이름과 심볼 표시 |
decimals() | uint8 | 금액 변환 |
totalSupply() | uint256 | 현재 총공급량 |
balanceOf(wallet) | uint256 | 지갑 총잔액 |
identityRegistry() | address | 자산 자격 Registry |
compliance() | address | 컴플라이언스 진입점 |
paused() | bool | 일반 transfer의 pause 상태 |
isFrozen(wallet) | bool | 지갑 전체 freeze 상태 |
getFrozenTokens(wallet) | uint256 | 부분 freeze 수량 |
availableBalance = balanceOf(wallet) - getFrozenTokens(wallet)
보유자 write 메서드
| 메서드 | 용도 | 주요 전제 |
|---|---|---|
transfer(to, amount) | 직접 transfer | Token 활성, 지갑 상태 허용, 수신자 적격, 규칙 통과 |
approve(spender, amount) | allowance 설정 | 보유자 서명 |
transferFrom(from, to, amount) | allowance 사용 transfer | allowance, 잔액, 자격, 규칙 통과 |
Token Agent 메서드
| 메서드 | 용도 | 주요 결과 |
|---|---|---|
mint(to, amount) | Mint | Transfer(0x0, to, amount) |
burn(wallet, amount) | Burn | Transfer(wallet, 0x0, amount) |
pause() / unpause() | 일반 transfer 중지·활성화 | Paused / Unpaused |
setAddressFrozen(wallet, frozen) | 지갑 전체 freeze 또는 해제 | AddressFrozen |
freezePartialTokens(wallet, amount) | 잔액 일부 freeze | TokensFrozen |
unfreezePartialTokens(wallet, amount) | 부분 freeze 해제 | TokensUnfrozen |
forcedTransfer(from, to, amount) | 관리 강제 이전 | Transfer |
recoveryAddress(lost, new, identity) | 새 지갑으로 자산 복구 | RecoverySuccess와 Transfer |
모든 amount는 최소 단위 정수입니다. 배치 메서드는 block gas limit에 도달할 수 있으므로 분할하고 각 트랜잭션을 개별 추적합니다.
| 작업 | pause 중 차단 | 수신자 자격 | canTransfer | freeze 잔액 |
|---|---|---|---|---|
transfer / transferFrom | 예 | 검사 | 검사 | freeze 수량 전송 불가 |
mint | 아니요 | 검사 | 검사 | 해당 없음 |
burn | 아니요 | 미검사 | 미검사 | Agent가 해제해야 할 수 있음 |
forcedTransfer | 아니요 | 검사 | 미검사 | Agent가 해제해야 할 수 있음 |
recoveryAddress | 아니요 | 복구 흐름 규칙 | 미검사 | freeze 상태 이동 가능 |
pause는 주로 일반 보유자 transfer를 제한하며 Agent의 mint, burn, 강제 이전, 지갑 복구는 중지하지 않습니다.
5.4 IdentityRegistry
대상 Token의 identityRegistry()에서 주소를 가져옵니다.
일반 read 메서드
| 메서드 | 의미 |
|---|---|
contains(wallet) | 등록 레코드 존재 여부 |
isVerified(wallet) | 현재 요건을 모두 충족하는지 여부 |
identity(wallet) | 등록된 ONCHAINID |
investorCountry(wallet) | 등록된 국가 또는 지역 코드 |
topicsRegistry() | 필수 Claim Topics Registry |
issuersRegistry() | 승인 ClaimIssuers Registry |
contains == true는 등록만 확인하며 isVerified == true를 대체하지 않습니다.
IR Agent 메서드
| 메서드 | 용도 | 이벤트 |
|---|---|---|
registerIdentity(wallet, identity, country) | 최초 등록 | IdentityRegistered |
updateIdentity(wallet, identity) | 연결 신원 교체 | IdentityUpdated |
updateCountry(wallet, country) | 국가·지역 코드 갱신 | CountryUpdated |
deleteIdentity(wallet) | 자산에서 등록 삭제 | IdentityRemoved |
하나의 ONCHAINID를 여러 자산에서 참조할 수 있지만 각 자산의 IdentityRegistry에 일반적으로 별도 등록해야 합니다.
5.5 ONCHAINID Gateway, IdFactory 및 Identity
신원 생성 또는 조회
| 컨트랙트 | 메서드 | 호출자 | 용도 |
|---|---|---|---|
| ONCHAINID Gateway | deployIdentityForWallet(wallet) | 투자자 | wallet의 결정적 ONCHAINID 생성 |
| IdFactory | getIdentity(wallet) | 모든 앱 | 연결 신원 조회 |
생성 후 IdFactory는 Deployed와 WalletLinked를 발생시킵니다. getIdentity(wallet)을 다시 조회해 최종 온체인 매핑을 사용합니다.
Claim 메서드
addClaim(
uint256 topic,
uint256 scheme,
address issuer,
bytes signature,
bytes data,
string uri
) returns (bytes32 claimId)
| 메서드 | 용도 |
|---|---|
getClaim(claimId) | Claim 하나의 모든 필드 읽기 |
getClaimIdsByTopic(topic) | Topic의 Claim IDs 조회 |
isClaimValid(identity, topic, signature, data) | ClaimIssuer 서명 검증 |
주요 이벤트는 ClaimAdded, ClaimChanged, ClaimRemoved입니다. ClaimSigner는 오프체인 서명을 생성하고 ClaimIssuer는 서명이 속하는 온체인 기관 컨트랙트입니다.
5.6 ModularCompliance
canTransfer는 Token이 아니라 ModularCompliance에 정의됩니다.
canTransfer(address from, address to, uint256 amount) view returns (bool)
| 메서드 | 용도 |
|---|---|
canTransfer(from, to, amount) | 현재 규칙의 transfer 사전 검사 |
getModules() | 연결된 규칙 모듈 목록 |
getTokenBound() | 연결된 Token |
isModuleBound(module) | 모듈 연결 여부 확인 |
canTransfer == true는 조회 시점의 규칙 통과를 의미합니다. pause, freeze, 잔액, 자격, 규칙은 확정 전 변경될 수 있으므로 영수증이 최종 기준입니다. transferred, created, destroyed는 연결된 Token이 상태 변경을 알리는 callback이며 일반 앱은 직접 호출하지 않습니다.
5.7 이벤트 인덱싱
| 이벤트 | 소스 | 용도 |
|---|---|---|
Transfer | Token | Mint, burn, transfer |
Approval | Token | allowance 변경 |
Paused / Unpaused | Token | transfer 상태 변경 |
AddressFrozen | Token | 지갑 전체 freeze |
TokensFrozen / TokensUnfrozen | Token | 부분 freeze 변경 |
RecoverySuccess | Token | 지갑 복구 |
IdentityRegistered / IdentityRemoved | IdentityRegistry | 등록 변경 |
IdentityUpdated / CountryUpdated | IdentityRegistry | 신원·국가 변경 |
ClaimAdded / ClaimChanged / ClaimRemoved | ONCHAINID | 자격 증명 변경 |
ModuleAdded / ModuleRemoved | ModularCompliance | 규칙 모듈 변경 |
이벤트는 변경 사항을 보여줍니다. reorg, backfill 또는 장시간 오프라인 후에는 컨트랙트 상태를 다시 읽어 조정합니다.
5.8 최소 ABI
const tokenAbi = [
'function name() view returns (string)',
'function symbol() view returns (string)',
'function decimals() view returns (uint8)',
'function totalSupply() view returns (uint256)',
'function balanceOf(address) view returns (uint256)',
'function identityRegistry() view returns (address)',
'function compliance() view returns (address)',
'function paused() view returns (bool)',
'function isFrozen(address) view returns (bool)',
'function getFrozenTokens(address) view returns (uint256)',
'function transfer(address,uint256) returns (bool)',
'event Transfer(address indexed from,address indexed to,uint256 value)',
];
const identityRegistryAbi = [
'function contains(address) view returns (bool)',
'function isVerified(address) view returns (bool)',
'function identity(address) view returns (address)',
'function investorCountry(address) view returns (uint16)',
'event IdentityRegistered(address indexed investorAddress,address indexed identity)',
];
const complianceAbi = [
'function canTransfer(address,address,uint256) view returns (bool)',
'function getModules() view returns (address[])',
];
실제 write 작업에는 배포 버전에 맞는 공식 ABI를 사용하고 메서드 이름에서 인자 순서를 추정하지 마십시오.
5.9 권장 호출 순서
Chain ID 검증
→ Token.decimals 읽기
→ paused / isFrozen / getFrozenTokens 읽기
→ Token.identityRegistry로 올바른 Registry 가져오기
→ 수신자 contains / isVerified 조회
→ Token.compliance로 Compliance 가져오기
→ canTransfer 호출
→ estimateGas 또는 static simulation
→ 트랜잭션 전송 및 영수증 대기
→ 이벤트와 최신 상태로 앱 갱신