What is EIP-2612 on Solana?


EIP-2612는 ERC-20 Permit 확장으로, 토큰 소유자가 온체인 승인 트랜잭션 대신 오프체인 서명을 통해 스마트 컨트랙트나 다른 계정에 지출 한도를 부여할 수 있도록 합니다. 서명된 데이터를 단일 permit() 호출에 포함시킴으로써 사용자는 가스비를 절약하고, 통합자는 승인과 실행을 하나의 원자적 트랜잭션으로 묶을 수 있습니다.

Key Characteristics

  • Gasless, single-call approvals: 소유자가 오프체인 EIP-712 메시지에 서명하면 하나의 permit() 호출로 서명을 검증하는 동시에 즉시 한도를 설정하여, 별도의 온체인 승인이 필요 없어지고 사용자 경험이 간소화됩니다.
  • Security & backward compatibility: Each permit consumes a unique, ever-increasing nonce and the signature is bound to the token's EIP-712 domain (name, chain ID, contract address). The extension adds < 200 bytes to a standard ERC-20, leaving balances and transfers untouched.
  • Seamless DeFi & wallet integration: DEXs, lending protocols, routers, and meta-TX relayers can batch permit -> action in one atomic transaction, while wallets like MetaMask and Ledger present it as a familiar Sign Message flow instead of a gas-priced approval.

Why EIP-2612 Is Unnecessary on Solana

Since Solana lets you combine approval and action in one atomic transaction and allows someone else to cover the fees by default, the two pain points that EIP-2612 solves on Ethereum (duplicated approvals and user-paid gas) are already removed at the protocol level. There is no need for an additional permit function, typed-data domain, or contract upgrade; the standard SPL-Token program satisfies those requirements out of the box.

Token Approval Model

On Ethereum, transferring ERC20 tokens between two addresses often requires approve + transferFrom if you're doing it on behalf of a user. On Solana, each user already has an ATA (Associated Token Accounts) recognized by the Token Program. A single Solana transaction can atomically call multiple instructions, so no separate approval step is required. You can directly transfer from one user's token account to another in one go.

Fee-Payer (Gas Delegation) Model

Every Solana transaction explicitly names both its signers and a fee-payer. A user can sign the transaction while designating a third party (a wallet service, dApp backend, or relayer) to pay the fees. The protocol therefore delivers the same gasless user experience that EIP-2612 targets, but without introducing a special off-chain signature scheme such as EIP-712.

How to do EIP-2612 on Solana

Below are two minimal, copy-paste-ready examples that map the two most common permit -> action scenarios to Solana's native primitives. Both use @solana/web3.js and @solana/spl-token.

1. Owner Pays the Fee (Self-Sponsored Transfer)

The owner both signs and pays the fee. All we do is bundle Approve -> Transfer into a single atomic transaction, no extra permit function required.

javascript
import { Connection, Keypair, PublicKey, Transaction } from "@solana/web3.js";
import {
  createApproveInstruction,
  createTransferInstruction,
  getAssociatedTokenAddressSync
} from "@solana/spl-token";

const connection = new Connection("https://api.devnet.solana.com");
const owner = Keypair.generate();
const delegate = owner.publicKey;
const recipient = new PublicKey("DESTINATION_WALLET");
const mint = new PublicKey("TOKEN_MINT");
const amount = 1_000_000;

const ownerATA = getAssociatedTokenAddressSync(mint, owner.publicKey);
const recipientATA = getAssociatedTokenAddressSync(mint, recipient);

const ixApprove = createApproveInstruction(ownerATA, delegate, owner.publicKey, amount);
const ixTransfer = createTransferInstruction(ownerATA, recipientATA, owner.publicKey, amount);

const tx = new Transaction().add(ixApprove, ixTransfer);
tx.feePayer = owner.publicKey;
tx.recentBlockhash = (await connection.getLatestBlockhash()).blockhash;

tx.sign(owner);
const sig = await connection.sendRawTransaction(tx.serialize());
console.log("Sent (self-sponsored):", sig);

2. Third Party Pays the Fee (Relayed Transfer)

Here the holder signs the instruction, but a relayer (or dApp back-end) covers the SOL fee. Solana supports this natively via the feePayer field plus partial signatures.

javascript
import { Connection, Keypair, PublicKey, Transaction } from "@solana/web3.js";
import { createTransferInstruction, getAssociatedTokenAddressSync } from "@solana/spl-token";

const connection = new Connection("https://api.devnet.solana.com");
const owner     = Keypair.generate();          // replace with real keypair
const feePayer  = Keypair.generate();          // replace with real keypair
const recipient = new PublicKey("DESTINATION_WALLET");
const mint      = new PublicKey("TOKEN_MINT");
const amount    = 500_000;

const ownerATA     = getAssociatedTokenAddressSync(mint, owner.publicKey);
const recipientATA = getAssociatedTokenAddressSync(mint, recipient);

const ix = createTransferInstruction(ownerATA, recipientATA, owner.publicKey, amount);

const tx = new Transaction().add(ix);
tx.feePayer        = feePayer.publicKey;
tx.recentBlockhash = (await connection.getLatestBlockhash()).blockhash;

tx.partialSign(owner);
tx.sign(feePayer);

const sig = await connection.sendRawTransaction(tx.serialize());
console.log("Sent (relayer-sponsored):", sig);
EVM TO SVM

Start building on Solana

Node storing all data and participating in consensus

  • Ethereum: Archive Node
  • Solana: [n/a]

Node storing some data and participating in consensus

  • Ethereum: Full Node
  • Solana: Consensus Node

Node storing some data and not participating in consensus

  • Ethereum: Light Node
  • Solana: RPC Node

Node storing all data and participating in consensus

  • Ethereum: Archive Node
  • Solana: [n/a]

Node storing some data and participating in consensus

  • Ethereum: Full Node
  • Solana: Consensus Node

Node storing some data and not participating in consensus

  • Ethereum: Light Node
  • Solana: RPC Node

관리자

© 2026 솔라나 재단.
모든 권리 보유.
연결하기
What is EIP-2612 on Solana? | Solana