De legs financieren

Financieren is een gewone TransferChecked naar de escrow van de leg, dus elke wallet of bewaarsysteem dat een tokentransfer kan versturen, kan een leg financieren. Alleen het uitlezen van het trade-record vóór de financiering vereist de DvP-client. Het programma controleert de escrow-saldi pas bij de afwikkeling; niets controleert de transfer op het moment dat deze binnenkomt, dus elke partij leest het trade-record uit voordat er wordt overgemaakt.

Deze pagina vervolgt op een trade aanmaken; de client en de ondertekenaars blijven dezelfde.

De voorwaarden controleren

Het aanmaken van een record is permissionless, en de escrow-adressen worden afgeleid van het record en de mint alleen, nooit van de voorwaarden. Een transfer naar een escrow kan daarom terechtkomen bij voorwaarden waarmee je nooit akkoord bent gegaan, inclusief afwikkelbestemmingen die de opbrengst van je tegenpartij omleiden naar een derde adres. Lees vóór het financieren het SwapDvp-account uit en controleer het aan de hand van de afgesproken trade.

verifySwapDvp in TypeScript en verify::decode_swap_dvp_account in Rust bevestigen dat het account eigendom is van het DvP-programma, precies 458 bytes groot is en zich bevindt op het adres dat uit de eigen velden wordt afgeleid (fetchSwapDvpChecked voert alleen de eerste twee controles uit). De gewone readers fetchSwapDvp en decodeSwapDvp voeren geen van deze controles uit. De controles op partijen, bedragen, tijdstippen en bestemmingen worden door de aanroeper uitgevoerd aan de hand van de afgesproken trade.

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 agreed
const expectedExpiry = 1_798_761_600n; // as agreed, unix seconds
if (
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");
}

Als het record is aangemaakt door je tegenpartij of de afwikkelautoriteit, vergelijk dan elk veld met de voorwaarden die je buiten de ledger hebt afgesproken. Als je het zelf hebt aangemaakt, bevestigt deze uitlezing dat het is aangekomen zoals verzonden.

Overmaken naar de escrow

Financier de leg met exact het afgesproken bedrag. Het programma begrenst de afwikkeling op amount_x en stuurt elk overschot terug naar de partij van de leg, dus een overschot gaat niet verloren, maar het voegt bij de afwikkeling een tweede transfer toe en kan bij sommige transfer hooks mislukken (zie de opmerkingen hieronder).

Gebruik TransferChecked, niet een ongecontroleerde Transfer. Token-2022-mints met extensies die afhankelijk zijn van het mint account, zoals Pausable, weigeren een transfer die dit niet meegeeft, en een mint met een transfer hook vereist dat de accounts van de hook worden opgelost en op dezelfde manier worden toegevoegd als bij elke andere transfer van dat token.

De partij van de assetleg, die ondertekent als userASigner, financiert 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]);

De partij van de cashleg doet hetzelfde voor escrow B met userBAtaB, mintB, userBSigner, t.amountB en { programAddress: tokenProgramB }.

Een financieringstransfer die op confirmed wordt gezien, kan nog steeds worden vervangen. Het programma leest het escrow-saldo onchain uit bij de afwikkeling, dus een Settle die wordt verstuurd terwijl de financieringstransfer niet is aangekomen, mislukt met LegNotFunded en er beweegt niets; de kosten zijn een mislukte Settle en een nieuwe poging. Beschouw een leg pas als gefinancierd wanneer de transfer finalized is.

Opmerkingen

  • Wrapped SOL-legs. Het programma leest het saldo van een native escrow uit na synchronisatie, dus lamports die met een systeemtransfer naar een wrapped-SOL-escrow worden gestuurd, worden meegeteld. Stuur nooit SOL naar een escrow voor een andere mint: het programma kan het niet terugsturen, en het gaat naar wie het account sluit.
  • Gated mints. Bij een mint met Default Account State frozen wordt de escrow bevroren aangemaakt en mislukt de transfer totdat de uitgever deze ontdooit of toelaat. Het overzicht beschrijft de interactie met Token ACL.
  • Transfer hooks. Financier escrows met hooks met exact het afgesproken bedrag. Als een overschot bij de afwikkeling een terugbetaling afdwingt, hergebruikt die terugbetaling de hook-accounts van de leg met een andere bestemming en een ander bedrag, wat sommige hooks weigeren. Het herstel is Reclaim, opnieuw financieren met het exacte bedrag en opnieuw afwikkelen.
  • Financieren na de vervaldatum. Niets voorkomt een transfer na expiry_timestamp. Die komt aan, afwikkeling is niet meer mogelijk, en de partij van de leg haalt het terug met Reclaim zolang de trade open is of met Recover nadat deze is gesloten. Zie een trade ongedaan maken.
  • Wie financiert eerst. Het programma bepaalt niet de volgorde van de twee legs. De volgorde is een zaak van de partijen; elke kant kan zijn eigen leg op elk moment vóór de afwikkeling terugvorderen, tenzij een mint authority (freeze, pause of transfer hook) de escrow blokkeert.

Volgende stappen

Is this page helpful?

Inhoudsopgave

Pagina Bewerken
© 2026 Solana Foundation. Alle rechten voorbehouden.