Solana Token-2022 확장: 전송 수수료와 훅, 계정 상태
Token-2022의 민트·토큰 계정 확장이 전송 수량, 추가 프로그램과 계정, 동결 상태, 메모 규칙, 지갑 호환성을 어떻게 바꾸는지 설명합니다.
이 글에서 다루는 내용Token-2022 확장은 민트와 토큰 계정에 상태를 더합니다
짧은 요약
Token-2022도 민트 계정과 토큰 계정을 사용하지만, 선택된 확장에 따라 전송 결과가 달라질 수 있습니다. 보내기 전에 전체 민트 주소, 계정을 소유한 토큰 프로그램, 민트·토큰 계정의 확장, 권한자, 받는 계정 상태를 확인해야 합니다. 익숙한 티커만으로 전송 규칙을 알 수는 없습니다.
Token-2022 확장은 민트와 토큰 계정에 상태를 더합니다
Token Extensions Program, 보통 Token-2022라고 부르는 프로그램은 확장 상태와 별도 명령을 통해 선택 기능을 추가합니다. 일부 확장은 민트에 저장되어 그 민트의 토큰 전반에 영향을 줍니다. 다른 확장은 각 토큰 계정에 저장되어 특정 보유자나 받는 계정에만 적용될 수 있습니다. 예를 들어 민트에는 전송 수수료 설정이 있고, 해당 민트의 토큰 계정에는 보류 중인 수수료 잔액이 따로 기록될 수 있습니다.
Token-2022라는 프로그램 이름만으로 모든 토큰의 동작이 같다고 볼 수 없습니다. 실제로 켜진 확장 목록은 온체인 상태에 있고, 일부는 계정 생성 시 선택해야 하며, 어떤 확장 조합은 서로 함께 쓸 수 없습니다. Solana 공식 안내는 양도 불가 확장과 전송 수수료 확장을 한 민트에서 함께 설정할 수 없다고 설명합니다. 프로그램 표지보다 실제 확장 목록을 확인하세요. Token Extensions 안내에서 확장 위치와 호환성 범위를 볼 수 있습니다.
확장이 놓인 위치가 중요합니다. 민트 확장은 그 민트의 토큰을 보내는 여러 계정에 적용될 수 있고, 토큰 계정 확장은 특정 계정이 관여할 때만 적용됩니다. 계정을 만들 때 추가 데이터 공간과 계정 확장이 필요할 수도 있습니다. 그러므로 지갑이나 거래소가 기본 토큰 전송을 지원하더라도 특정 민트의 계정 생성이나 전송까지 지원한다고 단정할 수 없습니다.
민트 주소가 자산을 식별하고 티커는 표시 이름입니다
이름과 심볼은 지갑 목록을 읽기 쉽게 하지만 고유 식별자는 아닙니다. Solana 토큰 문서는 토큰마다 고유한 민트 주소가 있다고 설명합니다. 민트를 소유한 토큰 프로그램도 확인해야 합니다. 기존 Token Program과 Token-2022는 서로 다른 프로그램이며, 화면에 같은 티커가 보여도 토큰 계정이 자동으로 서로 바뀌지는 않습니다.
자산을 신뢰하기 전에 전체 민트 주소를 이미 신뢰하는 출처와 대조하고, 민트를 소유한 토큰 프로그램을 확인합니다. 티커, 로고, 메타데이터만 보지 말고 민트의 확장과 권한자도 살핍니다. 닮은 심볼이 다른 민트를 가리킬 수 있고, 비슷한 이름의 두 민트가 서로 다른 전송 규칙을 가질 수도 있습니다. 민트 생성 안내와 용어집은 민트 주소가 토큰을 식별하는 방식을 설명합니다.
민트 확장만 확인해서도 충분하지 않습니다. 받는 토큰 계정에 메모 요구 사항이나 보류 수수료가 따로 있을 수 있습니다. 거래가 실패하면 민트 설정과 실제 받는 계정 상태를 모두 확인하세요.
전송 수수료는 받는 사람의 사용 가능 수량을 줄입니다
TransferFeeConfig 민트 확장은 전송 수수료율과 최대 수수료를 정합니다. 전송 시 보낸 사람의 요청 총액이 차감되고, 받는 사람의 일반 사용 가능 잔액은 그보다 적게 늘며, 수수료는 받는 토큰 계정에 보류액으로 기록됩니다. 수수료가 받는 사람의 사용 가능 잔액에 추가되는 구조는 아닙니다.
가상의 10.00 토큰 전송에 수수료율 1.5%, 상한 0.20 토큰이 적용된다고 합시다. 계산된 수수료는 0.15 토큰으로 상한보다 낮습니다. 명령이 총 10.00 토큰을 전송하면 받는 사람의 일반 잔액은 9.85 증가하고, 0.15는 보류됩니다. 수수료율이 더 높으면 상한에 걸릴 수 있으므로 현재 온체인 설정과 정확한 수량·소수 자릿수로 계산해야 합니다.
보류액은 받는 계정의 일반 토큰 잔액과 따로 관리됩니다. 토큰 계정에서 직접 인출하거나 먼저 민트로 모을 수 있지만, 수수료 수령 계정으로 옮길 때는 민트의 withdraw_withheld_authority가 승인해야 합니다. 이 권한은 수수료 설정을 변경하는 권한과 별개입니다. 전송 수수료 안내는 보류와 인출 단계, 예상 수수료를 확인하는 명령을 설명합니다.
수수료는 basis point 비율로 계산한 뒤 설정된 최대액을 넘지 않게 제한합니다. TransferCheckedWithFee는 전송 요청에 예상 수수료를 포함하고 프로그램이 현재 설정과 일치하는지 검사합니다. TransferChecked도 설정된 수수료를 적용하므로 이 명령을 골랐다고 수수료가 사라지지 않습니다.
TransferFeeAmount는 목적지 토큰 계정에 붙어 보류 수수료를 기록하는 확장입니다. 이 민트의 계정을 초기화할 때 필요한 계정 상태도 맞춰야 합니다. 토큰 계정들에서 보류액을 민트로 모으는 harvest는 허가 없이 누구나 실행할 수 있지만, 최종적으로 수수료 수령 계정에 인출하려면 withdraw_withheld_authority가 승인해야 합니다.
수수료 설정에는 현재 적용 중인 값과 다음 epoch 적용을 기다리는 값이 함께 있을 수 있습니다. 민트의 설정 권한자가 새 값을 제출해도 공식 안내상 변경분은 두 epoch 뒤부터 적용됩니다. 전송을 준비할 때는 공지된 다음 값만 보지 말고 그 시점에 실제 활성화된 요율과 상한을 다시 읽습니다.
전송 훅은 프로그램 실행과 추가 계정을 요구합니다
전송 훅이 설정된 민트에는 훅 프로그램 주소가 기록됩니다. 토큰을 보낼 때마다 해당 프로그램을 교차 프로그램 호출(CPI)로 실행하므로 허용 목록, 전송 상한, 사전 등록 같은 자체 규칙을 적용할 수 있습니다. 앱이 쓰지 않는 규칙이라고 건너뛸 수 있는 선택 기능은 아닙니다. 민트에 훅이 있으면 전송은 훅을 실행해야 합니다.
일반 전송에는 보내는 토큰 계정, 민트, 받는 계정, 권한자가 필요합니다. 훅은 온체인 ExtraAccountMetaList에 적힌 추가 계정을 요구할 수 있습니다. 목록에는 고정 주소뿐 아니라 민트, 프로그램, 명령 정보, 계정 데이터로 파생하는 주소가 들어갈 수 있습니다. 보내는 지갑이나 앱은 최신 목록을 해석해 필요한 계정을 알맞은 순서로 붙여야 합니다.
필요한 계정이 빠졌거나 오래되었거나 훅 자체 조건이 충족되지 않으면 트랜잭션 전체가 원자적으로 실패합니다. 훅을 건너뛰고 토큰 일부만 전달하는 처리는 없습니다. 발행자가 훅 프로그램이나 추가 계정 목록을 바꿀 수 있으므로 오래된 캐시는 전송을 막을 수 있습니다. Solana는 서명 전에 훅 전송을 시뮬레이션하도록 안내합니다. 전송 훅 통합 안내에서 계정 해석과 호환성, 실패 원인을 확인할 수 있습니다.
새 계정의 기본 상태가 동결일 수 있습니다
DefaultAccountState 확장은 민트에 저장되며 새 토큰 계정의 초기 상태를 정합니다. 민트가 새 계정을 동결 상태로 시작하게 설정할 수 있습니다. 동결된 계정은 민트의 freeze authority가 해제하기 전까지 일반 토큰 작업에 사용할 수 없습니다. 지갑에 받는 주소가 표시되어도 해당 토큰 계정이 아직 전송에 참여할 수 없는 상태일 수 있습니다.
민트의 기본 상태를 바꾸면 이후 생성되는 계정의 초기 상태가 바뀌지만, 이미 동결된 계정까지 자동으로 해동되지는 않습니다. 해동 권한은 민트의 freeze authority에 있으며 발행자나 받는 사람 외의 주체가 보유할 수 있습니다. 받는 계정의 현재 상태와 권한자를 함께 확인하세요. 기본 계정 상태 안내와 계정 동결 안내를 참고할 수 있습니다.
이 상태는 훅이 트랜잭션을 거절하는 경우와 다릅니다. 동결 여부는 토큰 계정에 기록되지만 전송 훅은 전송마다 프로그램으로 실행됩니다. 둘 다 전송을 막을 수 있지만 확인할 상태와 권한자가 다를 수 있습니다.
메모 요구 사항은 받는 토큰 계정에 설정됩니다
MemoTransfer 확장은 민트가 아니라 받는 토큰 계정에서 켭니다. 켜져 있으면 그 계정으로 들어오는 Transfer 또는 TransferChecked 명령 바로 앞에 같은 트랜잭션의 메모 명령이 있어야 합니다. 해당 계정에서 토큰을 보내는 경우에는 이 확장만으로 메모가 요구되지 않습니다.
메모가 없거나 명령 순서가 맞지 않으면 토큰 프로그램이 전송을 거절합니다. 거래소 입금 주소처럼 메모로 입금자를 구분하는 서비스에서 이 규칙이 중요할 수 있습니다. 메모가 있다고 수신 주소 확인을 생략할 수는 없고, 다른 사람의 받는 계정에 설정된 요구 사항을 보내는 사람이 해제할 수도 없습니다. Memo Transfer 안내와 수신 서비스의 입금 지침을 확인하세요.
지갑 호환성은 민트의 확장 구성에 따라 달라집니다
Token-2022를 표시한다고 해서 모든 지갑이 모든 확장을 처리한다는 뜻은 아닙니다. 전송 훅 계정을 해석하지 못하는 클라이언트는 훅이 설정된 토큰을 보낼 수 없습니다. 받기만 하는 동작은 훅을 실행하지 않지만, 다시 보내려면 훅을 구성하는 계정을 처리하는 클라이언트가 필요합니다. 전송 수수료가 있으면 표시되는 순수신량을 계산하고, 계정 상태나 메모 규칙 때문에 목적지가 사용 불가할 수 있다는 점도 다뤄야 합니다.
받기, 표시, 계정 생성, 보내기는 각각 다른 지원 범위입니다. 앱이 티커를 알아도 새로운 확장을 읽거나 추가 훅 계정을 구성하지 못하거나 보류 수수료를 일반 잔액과 구분하지 못할 수 있습니다. 서비스가 민트를 받더라도 한 번의 계정 설정이나 특정 수신 계정을 요구할 수 있습니다. 목적지가 지원하는 민트 주소, 토큰 프로그램, 확장 구성을 확인하고 주소 검색만 성공한 것을 전송 가능으로 해석하지 않습니다.
일부 설정은 권한자가 변경할 수 있고, 일부 확장은 계정 초기화 뒤에 추가할 수 없습니다. 훅은 프로그램 주소와 추가 계정 목록이 바뀔 수 있습니다. 새 전송을 시작할 때 변경 가능한 구성을 다시 읽고, 전체 트랜잭션을 시뮬레이션한 뒤, 서명 전 알아볼 수 있는 오류를 보여주는 편이 안전합니다. 확장 초기화와 호환되지 않는 조합은 Token Extensions 개요에 정리되어 있습니다.
서명 전에는 전송 전체를 확인합니다
먼저 전체 민트 주소와 그 민트를 소유한 토큰 프로그램을 확인합니다. 민트의 확장과 관련 권한자를 읽고, 받는 계정의 동결 상태, 메모 요구 사항, 계정별 확장 데이터도 살핍니다. 티커나 토큰 목록 항목만으로 실제 명령의 결과를 예측할 수는 없습니다.
전송 수수료 민트라면 총전송량, 현재 비율, 상한, 소수 자릿수와 예상 순수신량을 계산합니다. 받는 서비스가 총량을 요구하는지 순수신량을 요구하는지도 확인합니다. 훅이 있다면 현재 프로그램 주소와 추가 계정 목록을 읽고, 필요한 선행 설정을 마친 뒤 계정이 포함된 트랜잭션을 시뮬레이션합니다. 메모가 필요한 목적지라면 메모를 전송 명령 바로 앞에 둡니다.
예를 들어 같은 민트라도 목적지 A에는 MemoTransfer가 없고 목적지 B에는 켜져 있다면, 티커와 받는 지갑이 같아 보여도 한 전송은 통과하고 다른 전송은 메모 누락으로 실패할 수 있습니다. 전송 가능 여부는 민트만이 아니라 실제 토큰 계정에 달려 있으므로 주소를 붙여 넣은 다음 도착 계정의 상태를 읽습니다.
지갑이 목적지로 10.00 토큰을 보내려 한다고 가정해 보겠습니다. 확인된 민트에 1.5%, 상한 0.20 토큰이 있으면 받는 사람의 일반 잔액은 9.85 늘어납니다. 받는 계정이 동결되어 있으면 이 계산만으로 계정을 쓸 수 없고, 메모 요구가 있으면 올바른 위치의 메모가 추가로 필요합니다. 훅이 발신자를 거절하면 토큰은 도착하지 않습니다. 승인 전에 시뮬레이션 결과와 수신 지침을 확인하세요.
실무 순서는 민트와 프로그램 확인, 확장과 권한자 확인, 받는 계정 확인, 순수신량 계산, 필요한 훅 계정이나 메모 추가, 시뮬레이션입니다. 이 설명은 트랜잭션 동작을 다루며 투자 결과를 뜻하지 않습니다. 계정 주소의 파생 원리는 [Solana PDA와 연관 토큰 계정 안내](/ko/learn/solana-program-derived-addresses-seeds-bump-off-curve-explained)를, 실패한 트랜잭션의 네트워크 비용은 [Solana 수수료 안내](/ko/learn/solana-transaction-fees-base-priority-compute-units-explained)에서 확인할 수 있습니다.
자주 묻는 질문
Q1Token-2022 토큰은 모두 전송 수수료를 내나요?
아닙니다. 전송 수수료는 선택 가능한 민트 확장입니다. 해당 민트의 실제 확장과 현재 수수료 설정을 확인하세요.
Q2지갑이 훅 토큰을 받을 수는 있지만 보내지는 못할 수 있나요?
그럴 수 있습니다. 받기 동작은 훅을 실행하지 않습니다. 보내려면 훅 프로그램이 요구하는 계정을 해석하고 전송을 구성할 수 있는 클라이언트가 필요합니다.
Q3티커가 같으면 같은 토큰인가요?
아닙니다. 전체 민트 주소와 이를 소유한 토큰 프로그램을 확인하세요. 이름과 심볼은 표시용 메타데이터이지 고유 식별자가 아닙니다.
출처와 더 읽을 자료
내용 정정 제보
이 아티클 링크를 담은 이메일 초안을 준비합니다. 직접 보내야 Mark에 제보가 접수됩니다
QUICK CHECK
글을 다 읽었다면, 3문항으로 확인해보세요
Question 01
Token-2022 전송 수수료는 어디에 보류되나요?
정답을 고르면 바로 설명을 볼 수 있어요