For the complete documentation index, see llms.txt. This page is also available as Markdown.

Bangun aplikasi jalur ganda

Panduan langkah demi langkah untuk aplikasi jalur ganda — satu kontrak Solidity yang digunakan oleh pengguna MetaMask dan pengguna Phantom (Solana), dengan tepat apa yang terjadi di setiap langkah.

A aplikasi dua-lajur adalah satu kontrak Solidity yang baik seorang MetaMask (EVM) pengguna dan seorang Phantom (Solana) menggunakan langsung — kontrak yang sama, state yang sama, masing-masing dengan dompet yang sudah mereka miliki. Halaman ini menjelaskan secara tepat apa yang terjadi pada setiap langkah, di setiap sisi.

Contohnya adalah sebuah vault: Anda setor USDC dan nanti tarik kembali. "Stake / unstake", "supply / redeem", "tip / claim" memiliki pola yang sama.

Yang Anda tulis — sebuah vault ERC-20 standar

Di Rome, USDC milik pengguna Solana muncul di sisi EVM sebagai sebuah token ERC-20 — wrapper SPL untuk mint tersebut (mis. wUSDC). Jadi kontrak Anda adalah vault token biasa: ia menarik token dengan transferFrom dan mengembalikannya dengan transfer. Tidak ada yang khas Rome:

interface IERC20 {
    function transfer(address to, uint256 amount) external returns (bool);
    function transferFrom(address from, address to, uint256 amount) external returns (bool);
}

contract Vault {
    IERC20 public immutable token;                 // pembungkus wUSDC
    mapping(address => uint256) public balanceOf;
    constructor(IERC20 _token) { token = _token; }

    function deposit(uint256 amount) external {
        require(token.transferFrom(msg.sender, address(this), amount));
        balanceOf[msg.sender] += amount;
    }
    function withdraw(uint256 amount) external {
        balanceOf[msg.sender] -= amount;
        require(token.transfer(msg.sender, amount));
    }
}

Mengapa ERC-20, bukan payable / msg.value? Saldo yang dapat dibelanjakan oleh pengguna Solana adalah akun token SPL milik dompet mereka, ditampilkan 1:1 sebagai pembungkus ERC-20 ini — bukan saldo native EVM. Jadi pengguna Solana selalu bisa mendanai sebuah transferFrom, tetapi sebuah deposit() payable akan membutuhkan nilai native yang tidak mereka simpan saat tidak digunakan. Bangun di sekitar token, dan kedua lajur bekerja dengan cara yang sama.

Deploy dengan Foundry atau Hardhat, arahkan konstruktor ke alamat pembungkus untuk token Anda (dari register). Di Rome, token gas adalah USDC, jadi Anda memerlukan sedikit saldo gas USDC untuk deploy.

Dua lajur

Lajur
Dompet
Cara aplikasi memanggilnya

EVM

MetaMask (kunci EVM)

submitRomeTx — penulisan standar Rome

Solana

Phantom (kunci Solana)

submitRomeTxSolanaLane — tidak memerlukan kunci EVM

Lajur EVM bersifat biasa. Sisa halaman ini adalah lajur Solana — bagian yang menarik.

Gagasan utamanya: synthetic adalah penerus lewat

Identitas EVM pengguna Solana adalah alamat synthetickeccak256(solana_pubkey)[12:]. Itu adalah msg.sender di kontrak, tetapi ia tidak menyimpan apa pun saat tidak digunakan. Uang pengguna tersimpan di dompet Solana (sebagai SPL USDC), dan di sisi EVM saldo yang sama itulah yang wUSDC.balanceOf(synthetic) dibaca. Nilai mengalir melalui synthetic:

  • Masuk (setor): akun token dompet → akun token synthetic → kontrak (melalui transferFrom).

  • Keluar (tarik): kontrak → akun token synthetic → akun token dompet.

Synthetic kembali netral menjadi nol setelah setiap perjalanan bolak-balik.

Sekali saja: Aktifkan (siapkan synthetic)

Akun on-chain synthetic yang baru tidak ada sampai Anda membuatnya. Saat pertama kali pengguna Solana bertindak, synthetic mereka disediakan dengan sebuah create_pda panggilan — setelah itu, panggilan yang memindahkan nilai (ERC-20 transferFrom, sweep) dapat ditandatangani olehnya.

submitRomeTxSolanaLane melakukan ini secara otomatis saat pertama kali digunakan (autoProvision aktif secara default). Jika Anda lebih suka menampilkan layar "Aktifkan" yang eksplisit (penyiapan akun sekali pakai), lakukan sendiri:

Apa yang dibutuhkan masing-masing sisi

Kebutuhan
Mengapa

Pengguna Solana (Phantom)

SOL (sedikit)

membayar biaya transaksi Solana pada setiap tx lajur

USDC sebagai token SPL di dompet mereka

nilai yang mereka setorkan (terlihat di sisi EVM sebagai wUSDC)

Pengguna EVM (MetaMask)

USDC sebagai saldo gas Rome mereka

gas + nilai; mereka menambahnya dengan menjembatani USDC ke Rome (tidak ada faucet)

Anda (pembangunnya)

dompet dengan USDC gas di Rome

untuk men-deploy kontrak

Nilai MASUK — setor (langkah demi langkah)

Pengguna Solana memiliki SOL + USDC di dompet Phantom mereka. Setiap transaksi lajur adalah ditandatangani Phantom — dompet menandatanganinya dan mengirimkannya ke RPC Solana (proxy hanya digunakan untuk menemukan akun):

  1. Bagian pendanaanbuildFundLeg(...)submitSolanaInstructions(...). Membuat akun token USDC synthetic (jika perlu) dan menjalankan ActivateAta, memindahkan amount USDC dari akun token dompet ke milik synthetic. Sekarang wUSDC.balanceOf(synthetic) menampilkan saldo tersebut.

  2. SetujuisubmitRomeTxSolanaLane({ to: wUSDC, data: approve(vault, amount) }). Memungkinkan vault menarik token. (Ini biasanya panggilan lajur pertama, jadi synthetic diprovisioning otomatis di sini.)

  3. SetorsubmitRomeTxSolanaLane({ to: vault, data: deposit(amount) }). Vault menjalankan transferFrom(synthetic, vault, amount) — USDC berpindah dari synthetic ke vault, dan dikreditkan ke alamat synthetic.

Efek bersih: USDC berpindah dompet Phantom → (synthetic) → vault.

Nilai KELUAR — tarik (langkah demi langkah)

Sekarang pengguna menarik. Juga ditandatangani Phantom:

  1. TariksubmitRomeTxSolanaLane({ to: vault, data: withdraw(amount) }). vault.withdraw menjalankan transfer(synthetic, amount) — USDC bergerak dari vault kembali ke milik synthetic akun token.

  2. Bagian penyapuanbuildSweepLeg(...) memberi Anda HelperProgram.transfer_spl panggilan + akun; jalankan (buat akun token dompet jika perlu, lalu DoTxUnsigned ke precompile Helper) untuk memindahkan USDC dari synthetic kembali ke dompet Solana milik pengguna. Synthetic menjadi nol.

Efek bersih: USDC berpindah vault → (synthetic) → dompet Phantom milik pengguna. Tidak ada yang tertinggal.

Hal-hal yang sering keliru — semuanya ditangani oleh SDK

Inilah hal-hal yang sering salah pada transaksi lajur Solana yang dibuat manual; submitRomeTxSolanaLane melakukannya untuk Anda:

  • Penyediaan. Akun synthetic baru harus dibuat (create_pda) sebelum panggilan yang memindahkan nilai apa pun, atau ia tidak bisa menandatangani transfer. Otomatis saat pertama digunakan; nonaktifkan dengan autoProvision: false + provisionSynthetic.

  • Gunakan pembungkusnya, bukan msg.value. Saldo pengguna Solana adalah akun token SPL mereka, yang ditampilkan sebagai pembungkus ERC-20 — pindahkan dengan transfer / transferFrom, jangan pernah nilai native.

  • ComputeBudget. EVM Rome memerlukan batas CU yang dinaikkan (~1,35 juta) dan heap frame besar (~250 KB). Default Solana 200K-CU / 32-KB akan gagal.

  • Dompet treasury. Eksekusi membayar biaya kecil ke akun treasury per-chain; penemuan akun tidak menyertakannya, jadi SDK menambahkannya.

  • Ke mana dikirim. Dompet menandatangani transaksi Solana dan mengirimkannya ke RPC Solana — bukan ke proxy. Proxy hanya digunakan untuk penemuan akun. Di on-chain, program menurunkan msg.sender dari penanda tangan Solana.

  • Gas adalah USDC. Tidak ada faucet — jembatani USDC masuk (lihat Cara mendapatkan dana).

Aplikasi yang sama dari MetaMask

Pengguna EVM memanggil kontrak yang identik dengan submitRomeTx — tooling EVM standar, gas dalam USDC. Mereka tetap menyetujui lalu setor (ERC-20 seperti biasa), tanpa bagian pendanaan/penyapuan (token mereka sudah berada di alamat EVM mereka). Kedua pengguna berbagi balanceOf state yang sama.

Apa berikutnya

Terakhir diperbarui

Apakah ini membantu?