Pendanaan berupa TransferChecked biasa ke escrow milik leg, sehingga dompet atau
sistem kustodi apa pun yang dapat mengirim transfer token dapat mendanai sebuah leg. Hanya pembacaan
catatan perdagangan sebelum pendanaan yang membutuhkan klien DvP. Program memeriksa
saldo escrow hanya pada saat penyelesaian; tidak ada yang memeriksa transfer saat transfer itu masuk,
jadi setiap pihak membaca catatan perdagangan sebelum mentransfer.
Halaman ini melanjutkan dari membuat perdagangan; klien dan penanda tangan dibawa terus.
Verifikasi ketentuan
Pembuatan catatan bersifat permissionless, dan alamat escrow diturunkan dari
catatan dan mint saja, tidak pernah dari ketentuan. Karena itu, transfer ke escrow dapat
masuk berdasarkan ketentuan yang tidak pernah Anda setujui, termasuk tujuan
penyelesaian yang mengalihkan hasil milik counterparty Anda ke alamat ketiga.
Sebelum mendanai, baca akun SwapDvp dan periksa terhadap perdagangan
yang disepakati.
verifySwapDvp di TypeScript dan verify::decode_swap_dvp_account di Rust
memastikan bahwa akun dimiliki oleh program DvP, berukuran tepat 458 byte, dan
berada di alamat yang diturunkan dari field-nya sendiri (fetchSwapDvpChecked hanya melakukan
dua pemeriksaan pertama). Pembaca fetchSwapDvp dan decodeSwapDvp biasa
tidak melakukan satu pun dari pemeriksaan ini. Pemeriksaan terhadap pihak, jumlah, waktu, dan tujuan
dilakukan oleh pemanggil terhadap perdagangan yang disepakati.
import { unwrapOption } from "@solana/kit";import { verifySwapDvp } from "./dvp";const trade = await verifySwapDvp(client.rpc, swapDvp);const t = trade.data;const expectedAmountA = 1_000_000_000n;const expectedAmountB = 998_500_000n;const expectedEarliestSettlement: bigint | null = null; // as agreedconst expectedExpiry = 1_798_761_600n; // as agreed, unix secondsif (t.userA !== userA ||t.userB !== userB ||t.mintA !== mintA ||t.mintB !== mintB ||t.settlementAuthority !== settlementAuthority ||t.tokenProgramA !== tokenProgramA ||t.tokenProgramB !== tokenProgramB ||t.amountA !== expectedAmountA ||t.amountB !== expectedAmountB ||unwrapOption(t.earliestSettlementTimestamp) !== expectedEarliestSettlement ||t.expiryTimestamp !== expectedExpiry ||t.userASettlementDestination !== userA ||t.userBSettlementDestination !== userB) {throw new Error("Stored terms do not match the agreed trade; do not fund");}if (t.expiryTimestamp <= BigInt(Math.floor(Date.now() / 1000)) + 60n) {throw new Error("Trade expires too soon to fund safely");}
Jika catatan dibuat oleh counterparty Anda atau otoritas penyelesaian, bandingkan setiap field dengan ketentuan yang Anda sepakati di luar ledger. Jika Anda membuatnya sendiri, pembacaan ini memastikan catatan masuk sebagaimana yang dikirim.
Transfer ke escrow
Danai leg tepat sesuai jumlah yang disepakati. Program membatasi penyelesaian pada
amount_x dan mengembalikan kelebihan apa pun kepada pihak leg tersebut, sehingga kelebihan tidak hilang,
tetapi hal itu menambah transfer kedua saat penyelesaian dan dapat gagal pada beberapa transfer
hook (lihat catatan di bawah).
Gunakan TransferChecked, bukan Transfer tanpa pemeriksaan. Mint Token-2022 dengan
ekstensi yang bergantung pada mint account, seperti Pausable, menolak transfer
yang tidak menyertakannya, dan mint dengan transfer hook memerlukan akun-akun hook
diselesaikan dan ditambahkan dengan cara yang sama seperti pada transfer token
lainnya.
Pihak leg aset, yang menandatangani sebagai userASigner, mendanai escrow A:
import {findAssociatedTokenPda,getTransferCheckedInstruction,} from "@solana-program/token-2022";const [userAAtaA] = await findAssociatedTokenPda({mint: mintA,owner: userA,tokenProgram: tokenProgramA,});const [userBAtaB] = await findAssociatedTokenPda({mint: mintB,owner: userB,tokenProgram: tokenProgramB,});const fundAssetLeg = getTransferCheckedInstruction({source: userAAtaA,mint: mintA,destination: escrowA,authority: userASigner,amount: t.amountA,decimals: 6,}, { programAddress: tokenProgramA });await client.sendTransaction([fundAssetLeg]);
Pihak leg tunai melakukan hal yang sama untuk escrow B dengan userBAtaB, mintB,
userBSigner, t.amountB, dan { programAddress: tokenProgramB }.
Transfer pendanaan yang terlihat pada status confirmed
masih dapat digantikan. Program membaca saldo escrow onchain saat
penyelesaian, sehingga Settle yang dikirim terhadap transfer pendanaan yang tidak masuk akan gagal
dengan LegNotFunded dan tidak ada yang berpindah; biayanya adalah Settle yang gagal dan percobaan ulang.
Anggap sebuah leg sudah terdanai ketika transfernya berstatus finalized.
Catatan
- Leg SOL terbungkus (wrapped). Program membaca saldo escrow native setelah menyinkronkannya, sehingga lamport yang dikirim ke escrow wrapped-SOL melalui transfer sistem ikut dihitung. Jangan pernah mengirim SOL ke escrow untuk mint lain: program tidak dapat mengembalikannya, dan SOL tersebut menjadi milik siapa pun yang menutup akun.
- Mint dengan pembatasan (gated). Pada mint dengan Default Account State frozen, escrow dibuat dalam keadaan frozen dan transfer gagal sampai penerbit membuka pembekuan atau mengizinkannya. Bagian ikhtisar menjelaskan interaksi dengan Token ACL.
- Transfer hook. Danai escrow yang memiliki hook tepat sesuai jumlah yang disepakati. Jika kelebihan memaksa pengembalian dana saat penyelesaian, pengembalian tersebut menggunakan ulang akun hook milik leg dengan tujuan dan jumlah yang berbeda, yang ditolak oleh beberapa hook. Pemulihannya adalah Reclaim, danai ulang dengan jumlah yang tepat, lalu lakukan penyelesaian lagi.
- Pendanaan setelah kedaluwarsa. Tidak ada yang menghentikan transfer setelah
expiry_timestamp. Transfer tetap masuk, penyelesaian tidak lagi dimungkinkan, dan pihak leg memulihkannya dengan Reclaim selama perdagangan masih terbuka atau Recover setelah ditutup. Lihat membatalkan perdagangan. - Siapa yang mendanai lebih dulu. Program tidak mengatur urutan kedua leg. Urutannya diserahkan kepada para pihak; masing-masing pihak dapat mengklaim kembali leg miliknya kapan saja sebelum penyelesaian, kecuali otoritas mint (freeze, pause, atau transfer hook) memblokir escrow.
Langkah berikutnya
- Selesaikan perdagangan: otoritas penyelesaian menukar kedua leg dalam satu transaksi
- Batalkan perdagangan: memulihkan leg yang sudah didanai ketika perdagangan tidak diselesaikan
Is this page helpful?