Toimitus maksua vastaan (DvP) -ohjelma

DvP-ohjelma on Solanan vakio-ohjelma toimitukselle maksua vastaan (delivery versus payment). Sitä ylläpitää Solana Foundation, ja Cantina on auditoinut sen. Kaksi osapuolta sopii kaupasta, kumpikin lähettää oman osuutensa escrow-tilille tavallisella tokensiirrolla, ja selvitysvaltuutettu selvittää molemmat osuudet yhdessä transaktiossa, joten joko molemmat siirtyvät tai kumpikaan ei siirry. Selvitysvaltuutettu on kolmas, kaupassa nimetty osoite, kuten kaupan järjestänyt kauppapaikka tai agentti. Kumpikaan osapuoli ei kirjoita tai julkaise ohjelmaa, ja lompakko tai säilyttäjä, joka voi lähettää standardin tokensiirron (TransferChecked), voi rahoittaa osuuden ilman DvP-kohtaista integraatiota. Ennen selvitystä kumpikin osapuoli voi ottaa oman osuutensa takaisin tai purkaa kaupan.

Lue tietue ennen kuin toimit sen perusteella

Kauppatietueen luominen on luvatonta (permissionless), joten tietue ei todista sopimuksesta. Kunkin osapuolen tulee lukea tallennetut ehdot ennen rahoitusta, ja selvitysvaltuutetun ennen selvitystä (katso varmennus).

Miten se toimii

Jokaiselle kaupalle luodaan ohjelman omistama tietue ja kaksi escrow-tiliä, yksi kutakin osuutta varten. Omaisuusosuuden osapuoli (user_a) ja käteisosuuden osapuoli (user_b) rahoittavat kumpikin oman osuutensa siirtämällä tokeneita kyseisen osuuden escrow-tilille. Selvitysvaltuutettu on ainoa allekirjoittaja, joka voi suorittaa selvityksen. Selvityksessä kummankin osuuden sovittu määrä siirtyy toiselle osapuolelle, mahdollinen ylijäämä palautetaan osuuden omistavalle osapuolelle, ja tietue sekä molemmat escrow-tilit suljetaan. Atomisuus syntyy Solanan transaktioista: molemmat siirrot ovat yhdessä transaktiossa, joten joko molemmat toteutuvat tai kumpikaan ei toteudu.

Jokainen hyvitys, takaisinotto ja ylijäämän palautus menee osapuolen omalle associated token account -tilille: user_a:n tilille mint_a:lle ja user_b:n tilille mint_b:lle. Säilyttäjä tai treasury-järjestelmä voi rahoittaa osuuden omalta tililtään, mutta kaikki palautettava laskeutuu osapuolen tilille, ei takaisin säilyttäjälle. Jokainen kauppa jättää myös pysyvän merkkitilin (katso Tila).

Oppaat

Vaihesivut kuljettavat yhden kaupan luonnista selvitykseen, ja jokaisesta instruktiosta on esimerkit TypeScriptillä ja Rustilla.

Devnet-demo käy kaupan läpi alusta loppuun: se luo kaupan, rahoittaa molemmat escrow-tilit tavallisilla tokensiirroilla ja selvittää molemmat osuudet yhdessä transaktiossa.

Valinta ohjelman ja delegoinnin välillä

Toimitus maksua vastaan (DvP) delegoinnilla selvittää samanlaisen vaihdon ilman ohjelmaa: kumpikin osapuoli delegoi positionsa selvitysagentille, joka siirtää molemmat osuudet yhdessä transaktiossa.

  • Ohjelma ei vaadi delegointia, joten rajoitus yhdestä delegatesta per token account ei koske sitä, eikä selvitysvaltuutettu voi ohjata tuottoja muualle. Jokainen kauppa riippuu päivitettävästä ohjelmasta ja sen päivitysvaltuudesta.
  • Delegointimalli ei riipu ohjelmasta ja toimii mintien kanssa, joilla on Scaled UI Amount. Ohjelma hylkää nämä mintit, mikä sulkee pois kaikki Mosaicin tokenized-security-mallista luodut mintit (katso mintin konfiguraatiorajoitukset).

Roolit

Ohjelma on symmetrinen. Sen rajapinnassa kaksi osapuolta ovat user_a, joka toimittaa mint_a:n, ja user_b, joka toimittaa mint_b:n. README ja generoidut clientit kutsuvat mint_a:ta omaisuusosuudeksi ja mint_b:tä käteisosuudeksi, ja nämä sivut noudattavat samaa käytäntöä, mutta ohjelma ei vaadi, että käteisosuus on käteisinstrumentti. Kaksi omaisuuserää tai kaksi stablecoinia selvitetään samalla tavalla.

RooliKukaAllekirjoittaaHuomautukset
Omaisuusosuuden osapuoliuser_a, toimittaa mint_a:nOman rahoitussiirtonsa; Reclaim, Reject, Recoverkeypair-lompakko tai PDA-pohjainen älylompakko, kuten multisig-holvi. SPL Token multisig -tili tai program account ei voi olla osapuoli: Create epäonnistuu virheeseen PartyNotSignerCapable
Käteisosuuden osapuoliuser_b, toimittaa mint_b:nOman rahoitussiirtonsa; Reclaim, Reject, RecoverSama vaatimus
SelvitysvaltuutettuLuontivaiheessa nimetty kolmas osoiteSettle, CancelAinoa allekirjoittaja, joka voi suorittaa selvityksen. Se ei voi ohjata tuottoja muualle, sillä ne lukitaan luontivaiheessa. Se saa suljettujen tilien rent-talletukset, kun se selvittää tai peruu kaupan
Rent-maksajaSe, joka allekirjoittaa CreateDvp:nCreateKattaa rent-kulut (SOL-talletus, joka pitää tilin avoinna) tietueelle, nonce tombstonelle ja molemmille escrow-tileille. Ei tallenneta rentin saajaksi: suljettujen tilien rent menee sille, joka sulkee kaupan

Ohjelman ID

dvp34bdbcEm4f4FCUjGV4mDAkDshaQR4LkK8fdcsyZq
KlusteriOhjelmaPäivitysvaltuusViimeisin käyttöönotto-slot
mainnet-betadvp34bdbcEm4f4FCUjGV4mDAkDshaQR4LkK8fdcsyZqDXtFpbPjcn2hxPnw79x1Pfoj35vXh5AsWBkS37YnXMVv452 058 374
devnetdvp34bdbcEm4f4FCUjGV4mDAkDshaQR4LkK8fdcsyZq5EX1zFeJWj4rGYZv432WnYw8CbaSUeTdxPx4r573UgYU479 376 863

Ohjelma on päivitettävissä molemmissa klusterissa. Yllä olevat luvut ovat sitä, mitä solana program show ilmoitti 2. lokakuuta 2026; aja sama komento saadaksesi ajantasaiset arvot. Devnet-versio on vanhempi kuin commit, jota vasten vaihesivut kirjoitettiin (katso Asennus), mutta instruktiot ja virheet ovat samat.

Elinkaari

Kauppa on avoin CreateDvp:stä siihen asti, kunnes Settle, Cancel tai Reject sulkee sen. Rahoituksella ei ole omaa instruktiota: osuus on rahoitettu, kun sen escrow-tili sisältää vähintään sovitun määrän. Reclaim toimii osuuskohtaisesti ja jättää kaupan auki, joten yhden osuuden ongelma ei pakota toista osapuolta peruuttamaan koko kauppaa.

Tila

Jokaisella kaupalla on yksi 458 tavun SwapDvp-tili, jonka ohjelma omistaa. Sen osoite johdetaan selvitysvaltuutetusta, kahdesta osapuolesta, kahdesta mintistä ja noncesta (seedit ["dvp", settlement_authority, user_a, user_b, mint_a, mint_b, nonce]). Määrät ja ajat tallennetaan tilin sisään, eivätkä ne vaikuta osoitteeseen, joten ne on luettava eikä niitä voi päätellä. Pieni merkkitili, nonce tombstone osoitteessa ["nonce", swap_dvp], luodaan kaupan mukana eikä sitä koskaan suljeta, joten kutakin osapuolten, mintien, valtuutetun ja noncen yhdistelmää voi käyttää vain yhteen kauppaan.

KenttäTyyppiMerkitys
bumpu8PDA bump
user_a, user_bPubkeyKaksi osapuolta
mint_a, mint_bPubkeyOmaisuusosuuden ja käteisosuuden mintit
settlement_authorityPubkeyAinoa allekirjoittaja, joka voi selvittää tai peruuttaa
token_program_a, token_program_bPubkeyToken program, joka omistaa kunkin mintin; kaupassa voi yhdistää SPL Token- ja Token-2022-osuuksia
amount_a, amount_bu64Kunkin osuuden sovittu määrä mintin pienimmässä yksikössä (perusyksiköissä)
expiry_timestampi64Tämän verkkoajan (ketjun kellon) jälkeen Settle hylätään. Reclaim, Cancel ja Reject toimivat edelleen
nonceu64Erottaa toisistaan kaupat, joilla on samat muut seedit. Kertakäyttöinen
ref_string[u8; 64]Läpinäkymätön clientin viite, täytetty nollilla; ohjelma ei koskaan lue sitä
user_a_settlement_destinationPubkeyVastaanottaa käteisosuuden Settlessä; oletuksena user_a
user_b_settlement_destinationPubkeyVastaanottaa omaisuusosuuden Settlessä; oletuksena user_b
mint_a_authority, mint_b_authorityPubkeyLuontihetkellä tallennetut mint-valtuudet; Settle epäonnistuu, jos jompikumpi on muuttunut
earliest_settlement_timestampOption<i64>Jos asetettu, Settle hylätään ennen tätä verkkoaikaa

Kenttäluettelo on otettu ohjelman IDL:stä kohdassa Luo kauppa mainitusta commitista.

Instruktiot

InstruktioAllekirjoittajaVaikutus
CreateDvpMikä tahansa maksajaLuo SwapDvp-tietueen, sen nonce tombstonen ja molemmat escrow-tilit. Ei siirrä tokeneita
ReclaimDvpuser_a tai user_bPalauttaa allekirjoittajan oman osuuden escrow-tililtä. Kauppa pysyy avoinna ja osuuden voi rahoittaa uudelleen
SettleDvpSelvitysvaltuutettuSiirtää amount_a:n user_b:n määränpäähän ja amount_b:n user_a:n määränpäähän, palauttaa mahdollisen ylijäämän osuuden osapuolelle, sulkee tietueen ja molemmat escrow-tilit
CancelDvpSelvitysvaltuutettuPalauttaa kaiken escrow A:n sisältämän user_a:lle ja escrow B:n sisältämän user_b:lle, sulkee tietueen ja molemmat escrow-tilit
RejectDvpuser_a tai user_bSama vaikutus kuin Cancelilla, mutta osapuolen allekirjoittama
RecoverDvpuser_a tai user_bKaupan sulkemisen jälkeen: tyhjentää uudelleen luodun escrow-tilin allekirjoittajan omalle token accountille ja sulkee sen. Kattaa talletuksen, joka saapui Settlen, Cancelin tai Rejectin jälkeen

Jokainen hyvitys menee osapuolen omalle associated token account -tilille kyseisen osuuden mintille riippumatta siitä, kuka escrow-tilin rahoitti.

Kunkin instruktion tilit ja argumentit ovat kyseisen vaiheen sivulla.

Virheet

KoodiVirheMilloin
0SignerNotPartyReclaim, Reject tai Recover on allekirjoitettu osoitteella, joka ei ole user_a tai user_b
1DvpExpiredSettle expiry_timestamp-ajan jälkeen
2SettlementAuthorityMismatchSettle tai Cancel on allekirjoitettu muulla osoitteella kuin selvitysvaltuutetun
3SettlementTooEarlySettle ennen earliest_settlement_timestamp-aikaa
4LegNotFundedSettle, kun jokin escrow-tili sisältää vähemmän kuin sovitun määrän
5ExpiryNotInFutureCreate, jossa umpeutumisaika on nykyisen verkkoajan tasolla tai sitä ennen
6EarliestAfterExpiryCreate, jossa aikaisin selvitysaika on umpeutumisen jälkeen
7SelfDvpCreate, jossa user_a on sama kuin user_b
8SameMintCreate, jossa mint_a on sama kuin mint_b
9ZeroAmountCreate, jossa jommankumman osuuden määrä on nolla
10BlockedMintExtensionCreate tai Settle mintillä, jolla on TransferFee, InterestBearing, ScaledUiAmount tai NonTransferable
11SettlementAuthorityIsPartyCreate, jossa selvitysvaltuutettu on sama kuin jompikumpi osapuoli
12SettlementAuthorityExecutableCreate, jossa selvitysvaltuutettu on suoritettava (executable)
13NonceAlreadyUsedCreate, joka käyttää uudelleen (seeds, nonce)-yhdistelmää, jolla on jo tombstone
14ExpiryTooFarInFutureCreate, jossa umpeutumisaika on yli vuoden päässä
15RefStringTooLongCreate, jossa viite on yli 64 tavua pitkä
16DvpStillOpenRecover, kun kauppa on yhä auki; käytä Reclaimia
17DvpNeverCreatedPalauta siemenillä, joilla ei ole hautakiveä (tombstone)
18EscrowPreloadedWithLamportsLuo, kun ei-natiivin escrow-tilin lamport-saldo ylittää sen vuokravapaan vähimmäismäärän
19SettlementDestinationIsSwapDvpLuo siten, että selvityksen kohde on sama kuin kauppatietue
20SwapDvpPreloadedWithLamportsLuo, kun tietueen osoite sisältää lamporteja yli rent-varantonsa
21RecipientAtaMismatchVastaanottajan tai hyvityksen saajan token account ei enää kuulu odotetulle lompakolle ja mintille
22PartyNotSignerCapableLuo osapuolella, joka ei ole järjestelmän omistama, ei-suoritettava tili
23MintAuthorityChangedSelvitä, kun jalan mint authority poikkeaa luontihetkellä tallennetusta arvosta

Tapahtumat ja indeksointi

Ohjelma ei lähetä onchain-tapahtumia. Indeksoija tai täsmäytysjärjestelmä lukee SwapDvp-tilin tilan ja kahden escrow-tilin token-saldot sekä käyttää ref_string-kenttää kaupan yhdistämiseen sen off-chain-toimeksiantoon. Koska tietue suljetaan selvityksessä, järjestelmä, joka tarvitsee ehdot jälkikäteen, tallentaa ne lukiessaan ne tai rekonstruoi ne kaupan luoneesta transaktiosta.

Tuetut tokenit

Kauppa voi yhdistää SPL Token -jalan ja Token-2022-jalan; kukin jalka sisältää oman token programinsa. Wrapped SOL -jalat ovat tuettuja.

Token-2022-laajennus jalan mintissäOhjelman toiminta
TransferFee, InterestBearing, ScaledUiAmount, NonTransferableHylätään Create- ja Settle-vaiheessa virheellä BlockedMintExtension
PermanentDelegate, Pausable, DefaultAccountState, freeze authority, MintCloseAuthorityHyväksytään; kukin authority voi toimia escrow-tokeneilla
ConfidentialTransferHyväksytään; kyseisen jalan summat ovat julkisia
TransferHookTuettu, enintään 32 lisätiliä jalkaa kohden
MemoTransfer kohde- tai hyvitystililläHyväksytään; ohjelma lähettää vaaditun memon ennen siirtoa

Siirtomaksu jättäisi vastaanottavan osapuolen alle sovitun summan. Interest Bearing ja Scaled UI Amount eivät muuta raakasummia, mutta niiden korko tai kerroin voi muuttua kaupan luomisen ja selvityksen välillä, mikä muuttaa sovittujen summien näyttötapaa. NonTransferable jumittaisi molemmat jalat.

Hyväksytyt authorityt voivat siirtää, jäädyttää tai pysäyttää escrow-tokenit kaupan koko eliniän ajan (katso alla). Escrow-tiliä ei voi määrittää vastaanottamaan luottamuksellisia siirtoja, joten luottamuksellisen jalan escrow- ja selvityssummat ovat julkisia.

Hook-mintin osalta asiakas selvittää hookin lisätilit ja liittää ne Settle-, Cancel-, Reject-, Reclaim- ja Recover-instruktioihin. Jalkakohtainen 32 tilin raja sisältää hook-ohjelman ja sen validointitilin. Jos hook authority laajentaa hookin tililistaa tämän rajan yli, jokainen siirto kyseisellä jalalla epäonnistuu, mukaan lukien Reclaim, Cancel, Reject ja Recover, kunnes authority peruu muutoksen. Transaktion tilirajoitus voi tulla vastaan ennen jalkakohtaista rajaa, kun molemmilla jaloilla on hookit.

Kun kohde- tai hyvitystili vaatii memoja, ohjelma kutsuu Memo- ohjelmaa ennen siirtoa, minkä vuoksi jokainen instruktio, joka siirtää tokeneita escrow'sta pois, vaatii memo_program-tilin.

Mint-määrityksen rajoitteet

Scaled UI Amount. Mosaicin, Solana Foundationin liikkeeseenlaskuvälineistön, tokenized-security-malli lisää aina Scaled UI Amountin, joten ohjelma ei hyväksy kyseisestä mallista luotua mintiä jalaksi. Tälle ohjelmalle tarkoitettu mint voidaan luoda ilman laajennusta (katso Token Extensions); DvP delegoinnin avulla selvitetään delegoidun authorityn kautta, eikä se käytä tätä tarkistusta.

Oletuksena jäädytetyt mintit. Kunkin kaupan escrow on associated token account, jonka omistaa kyseistä kauppaa varten uusi Program Derived Address. Mintissä, jonka Default Account State on frozen, escrow luodaan jäädytettynä, ja siihen tehtävä rahoitussiirto epäonnistuu, kunnes se sulatetaan. Token ACL -ratkaisussa tämä tarkoittaa, että liikkeeseenlaskija tai sen siirtoagentti hyväksyy kaupan escrow'n ennen rahoitusta: joko lisäämällä kauppatietueen osoitteen (escrow'n omistajan) sallittujen listalle, jolloin kuka tahansa voi sulattaa escrow'n, jos mintin Token ACL -konfiguraatio sallii luvattoman sulatuksen, tai sulattamalla sen suoraan freeze authorityllä. Jäädytetty escrow estää myös Settle-, Reclaim-, Cancel-, Reject- ja Recover-toiminnot kyseisellä jalalla, joten freeze authority ja hook-mintissä hook authority on luotettu osapuoli kaupan koko eliniän ajan. Jäädytetyn escrow'n polku on kuvattu tässä, eikä sitä käytetä devnet-esimerkeissä.

Rajoitukset

  • Ei kohdistusta, hinnanmuodostusta eikä tilauskirjaa. Osapuolet sopivat ehdoista pääkirjan ulkopuolella, ja yksi heistä kirjaa ne.
  • Ei nettouttamista, ja vain kahdenvälinen: yksi tietue on yksi kauppa kahden osapuolen välillä.
  • Ei osittaisia toteutuksia. Settle siirtää täsmälleen sovitun määrän kummastakin jalasta ja palauttaa mahdollisen ylijäämän jalan osapuolelle.
  • Ei pääkirjan ulkopuolista jalkaa. Molemmat jalat ovat token accounteja Solanassa; käteisjalka olemassa olevilla väylillä selvitetään erikseen ja täsmäytetään.
  • Ei kelpoisuustarkistusta, sallittujen listaa eikä KYC:tä. Mintin omat valvontamekanismit valvovat haltijan kelpoisuutta.
  • Ei automaattista selvitystä. Selvitysauthorityn on allekirjoitettava.
  • Ei tapahtumia eikä protokollamaksua transaktiomaksujen ja rentin lisäksi.

Ohjelma poistaa osapuolten välisen pääomariskin: kumpikaan jalka ei siirry, ellei toinenkin siirry. Se ei poista kummankaan tokenin liikkeeseenlaskijan luotto- tai lunastusriskiä, mintin freeze-, pause- tai permanent delegate -authorityn mahdollisuutta toimia escrow-tokeneilla (katso tuetut tokenit) eikä riippuvuutta siitä, että selvitysauthority on käytettävissä allekirjoittamaan.

Tarkistus ennen rahoitusta ja selvitystä

CreateDvp on luvaton: vain maksaja allekirjoittaa, eivätkä osapuolet eikä selvitysauthority allekirjoita. Kuka tahansa voi siis luoda tietueen, jossa on mitkä tahansa osapuolet ja ehdot. Ennen rahoitusta ja uudelleen ennen selvitystä lue SwapDvp-tili ja varmista:

  1. Tilin omistaa DvP-ohjelma ja sen koko on täsmälleen 458 tavua. Tili, jota ohjelma ei omista, voidaan täyttää tavuilla, jotka dekoodautuvat kuin oikea tietue.
  2. user_a, user_b, mint_a, mint_b ja settlement_authority vastaavat sovittua kauppaa.
  3. amount_a, amount_b, expiry_timestamp ja earliest_settlement_timestamp vastaavat sovittuja ehtoja.
  4. Molemmat selvityksen kohteet ovat sovitut osoitteet. Väärennetty tietue voi ohjata tuotot muualle.

Jalkojen rahoitus luettelee generoitujen clientien tarkistavat lukijat ja näyttää tarkistuksen koodina.

Katso kauppa selvitetyksi, kun Settle-transaktio saavuttaa tilan finalized. Se on verkon vahvistustaso; se, merkitseekö se myös selvityksen lopullisuutta oikeudellisessa mielessä, riippuu osapuolten sopimuksista ja sovellettavista sääntelyjärjestelmistä.

Versiointi

SwapDvp-tilillä ei ole versiokenttää. Sen asettelu on kiinteästi 458 tavua (SwapDvp::LEN), ja tarkistavat lukijat hylkäävät minkä tahansa muun pituisen tilin. IDL:llä on oma versionsa, 0.1.0 2. lokakuuta 2026 alkaen.

Ohjelma on päivitettävä molemmissa klustereissa (katso Program ID). Kauppatietue on olemassa vain, kunnes se selvitetään, perutaan tai hylätään, joten tarkista repositoriosta, miten päivitys kohtelee avoimia kauppoja, ja generoi clientit uudelleen käyttöön otetun version IDL:stä.

Repositorio ja auditointi

Lähdekoodi, IDL, generoidut clientit ja testit ovat osoitteessa solana-foundation/dvp MIT-lisenssillä. Ohjelma on no_std-Pinocchio-ohjelma; clientit on generoitu IDL:stä Codamalla. Haavoittuvuusilmoitukset tehdään repositorion tietoturvatiedotteen linkin kautta SECURITY.md:n mukaisesti.

Ohjelman on auditoinut Cantina.

Aiheeseen liittyvää

Is this page helpful?

© 2026 Solana Foundation. Kaikki oikeudet pidätetään.