slogan3

Maak een Solidity Smart Contract voor Geautomatiseerd Abonnementsbeheer

description

Met deze prompt kan de gebruiker een volledig geautomatiseerd smart contract voor abonnementsbeheer maken, afgestemd op verschillende abonnementen en betalingsschema's. Het behandelt belangrijke uitdagingen zoals betalingsverificatie, statusbeheer van abonnementen en optimalisatie van gasgebruik, en biedt een complete en veilige oplossing die verschilt van standaard contractfuncties zoals stemmen of escrow. Het vermindert handmatig toezicht en fouten bij abonnementenfacturatie.

prompt

Help me een Solidity smart contract te ontwikkelen voor geautomatiseerd abonnementsbeheer. Voeg functies toe zoals registratie van abonnees: <voer abonneegegevens of adressen in>, abonnementenplannen: <beschrijf verschillende abonnementsopties en prijzen>, verwerking van terugkerende betalingen: <specificeer betalingsintervallen ...

try_prompt

generate_helper
disclaimerOnPageApi

ai_answers

provider: openai
model: gpt-4.1-nano
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; contract Abonnementsbeheer { enum PlanType { Basis, Premium } struct Abonnee { address addr; PlanType plan; uint256 betaaldTot; // timestamp tot wanneer abonnement geldig is bool actief; uint256 laatsteBetaling; // timestamp van laatste betaling } address public owner; uint256 public constant prijsBasis = 0.05 ether; uint256 public constant prijsPremium = 0.15 ether; uint256 public constant abonnementsduur = 30 days; uint256 public constant annuleringsperiode = 7 days; mapping(address => Abonnee) public abonnees; mapping(address => bool) public isAbonnee; // Events event AbonneeGeregistreerd(address indexed abonnee, PlanType plan); event BetalingOntvangen(address indexed abonnee, uint256 amount, uint256 betaaldTot); event AbonnementGeannuleerd(address indexed abonnee, uint256 terugbetaling); event AbonnementOpgewaardeerd(address indexed abonnee, PlanType nieuwPlan); event AbonnementVerlengd(address indexed abonnee, uint256 nieuweEindDatum); modifier alleenEigenaar() { require(msg.sender == owner, "Alleen eigenaar kan dit doen"); _; } modifier alleenAbonnee() { require(isAbonnee[msg.sender], "U bent geen abonnee"); _; } constructor() { owner = msg.sender; } // Registreer een nieuwe abonnee met gekozen plan function registreerAbonnee(PlanType plan) external { require(!isAbonnee[msg.sender], "U bent al abonnee"); uint256 betaaldTot = block.timestamp + abonnementsduur; abonnees[msg.sender] = Abonnee({ addr: msg.sender, plan: plan, betaaldTot: betaaldTot, actief: true, laatsteBetaling: block.timestamp }); isAbonnee[msg.sender] = true; emit AbonneeGeregistreerd(msg.sender, plan); } // Betaling voor verlenging of nieuw abonnement function betaal() external payable alleenAbonnee { Abonnee storage abonnee = abonnees[msg.sender]; uint256 vereistePrijs; if (abonnee.plan == PlanType.Basis) { vereistePrijs = prijsBasis; } else { vereistePrijs = prijsPremium; } require(msg.value >= vereistePrijs, "Onvoldoende betaling"); require(!abonnee.actief || block.timestamp > abonnee.betaaldTot, "Abonnement is nog actief"); uint256 nieuweEindDatum = block.timestamp + abonnementsduur; abonnee.betaaldTot = nieuweEindDatum; abonnee.actief = true; abonnee.laatsteBetaling = block.timestamp; // Terugbetalingscheck: indien teveel betaald, restitueren if (msg.value > vereistePrijs) { uint256 terugTe betalen = msg.value - vereistePrijs; payable(msg.sender).transfer(terugTe betalen); } emit BetalingOntvangen(msg.sender, msg.value, nieuweEindDatum); } // Annuleren abonnement met restitutie binnen 7 dagen function annuleerAbonnement() external alleenAbonnee { Abonnee storage abonnee = abonnees[msg.sender]; require(abonnee.actief, "Abonnement is niet actief"); require(block.timestamp - abonnee.laatsteBetaling <= annuleringsperiode, "Restitutieperiode is verlopen"); uint256 resterendeDagen = 0; if (abonnee.betaaldTot > block.timestamp) { uint256 overgeblevenTijd = abonnee.betaaldTot - block.timestamp; resterendeDagen = overgeblevenTijd / 1 days; } uint256 terugTeBetalen; if (abonnee.plan == PlanType.Basis) { terugTeBetalen = prijsBasis * resterendeDagen / 30; } else { terugTeBetalen = prijsPremium * resterendeDagen / 30; } require(address(this).balance >= terugTeBetalen, "Contract heeft niet genoeg saldo voor restitutie"); abonnee.actief = false; abonnee.betaaldTot = 0; if (terugTeBetalen > 0) { payable(msg.sender).transfer(terugTeBetalen); } emit AbonnementGeannuleerd(msg.sender, terugTeBetalen); } // Beheer functies: upgrade plan function upgradePlan(PlanType nieuwPlan) external alleenAbonnee { Abonnee storage abonnee = abonnees[msg.sender]; require(abonnee.plan != nieuwPlan, "U hebt al dit plan"); abonnee.plan = nieuwPlan; emit AbonnementOpgewaardeerd(msg.sender, nieuwPlan); } // Verleng abonnement handmatig (optioneel) function verlengAbonnement() external alleenAbonnee { Abonnee storage abonnee = abonnees[msg.sender]; require(abonnee.actief, "Abonnement is niet actief"); uint256 nieuweEindDatum = abonnee.betaaldTot + abonnementsduur; abonnee.betaaldTot = nieuweEindDatum; emit AbonnementVerlengd(msg.sender, nieuweEindDatum); } // Ontvangst van betalingen (voor testdoeleinden of contractbeheer) receive() external payable {} // Opname van fondsen door eigenaar function neemOp() external alleenEigenaar { payable(owner).transfer(address(this).balance); } }
provider: deepseek
model: deepseek-chat
```solidity // SPDX-License-Identifier: MIT pragma solidity ^0.8.19; contract AbonnementsBeheer { struct Abonnement { uint256 planId; uint256 startDatum; uint256 volgendeVervaldatum; bool actief; uint256 laatsteBetalingBlok; } struct AbonnementsPlan { string naam; uint256 maandelijkseKost; bool bestaat; } address eigenaar; uint256 public refundPeriode = 7 days; mapping(address => Abonnement) public abonnees; mapping(uint256 => AbonnementsPlan) public abonnementsPlannen; mapping(address => mapping(uint256 => bool)) public gebruiktNonce; event AbonnementAangemaakt(address indexed abonnee, uint256 planId); event BetalingVerwerkt(address indexed abonnee, uint256 bedrag); event AbonnementGeannuleerd(address indexed abonnee); event RefundUitgekeerd(address indexed abonnee, uint256 bedrag); modifier alleenEigenaar() { require(msg.sender == eigenaar, "Alleen eigenaar"); _; } constructor() { eigenaar = msg.sender; // Initialiseer abonnementsplannen abonnementsPlannen[1] = AbonnementsPlan("Basis", 0.05 ether, true); abonnementsPlannen[2] = AbonnementsPlan("Premium", 0.15 ether, true); } function registreerAbonnement(uint256 planId, uint256 nonce, bytes memory handtekening) external payable { require(abonnementsPlannen[planId].bestaat, "Ongeldig plan"); require(!gebruiktNonce[msg.sender][nonce], "Nonce reeds gebruikt"); require(abonnees[msg.sender].planId == 0, "Reeds geregistreerd"); // Verifieer handtekening voor beveiliging bytes32 berichtHash = keccak256(abi.encodePacked(msg.sender, planId, nonce, block.chainid)); require(verifieerHandtekening(berichtHash, handtekening), "Ongeldige handtekening"); uint256 vereistBedrag = abonnementsPlannen[planId].maandelijkseKost; require(msg.value >= vereistBedrag, "Onvoldoende ETH"); gebruiktNonce[msg.sender][nonce] = true; abonnees[msg.sender] = Abonnement({ planId: planId, startDatum: block.timestamp, volgendeVervaldatum: block.timestamp + 30 days, actief: true, laatsteBetalingBlok: block.number }); // Restitueer teveel betaalde ETH if (msg.value > vereistBedrag) { payable(msg.sender).transfer(msg.value - vereistBedrag); } emit AbonnementAangemaakt(msg.sender, planId); emit BetalingVerwerkt(msg.sender, vereistBedrag); } function verwerkMaandelijkseBetaling(address abonnee) external alleenEigenaar { Abonnement storage abonnement = abonnees[abonnee]; require(abonnement.actief, "Abonnement niet actief"); require(block.timestamp >= abonnement.volgendeVervaldatum, "Nog niet vervallen"); uint256 planId = abonnement.planId; uint256 bedrag = abonnementsPlannen[planId].maandelijkseKost; abonnement.volgendeVervaldatum += 30 days; abonnement.laatsteBetalingBlok = block.number; emit BetalingVerwerkt(abonnee, bedrag); } function annuleerAbonnement() external { Abonnement storage abonnement = abonnees[msg.sender]; require(abonnement.actief, "Geen actief abonnement"); // Controleer refund eligibility if (block.timestamp <= abonnement.startDatum + refundPeriode) { uint256 restitutieBedrag = abonnementsPlannen[abonnement.planId].maandelijkseKost; payable(msg.sender).transfer(restitutieBedrag); emit RefundUitgekeerd(msg.sender, restitutieBedrag); } abonnement.actief = false; emit AbonnementGeannuleerd(msg.sender); } function krijgAbonnementsInfo(address abonnee) external view returns ( uint256 planId, string memory planNaam, uint256 startDatum, uint256 volgendeVervaldatum, bool actief ) { Abonnement memory abonnement = abonnees[abonnee]; planId = abonnement.planId; planNaam = abonnementsPlannen[planId].naam; startDatum = abonnement.startDatum; volgendeVervaldatum = abonnement.volgendeVervaldatum; actief = abonnement.actief; } function voegAbonnementsPlanToe(uint256 planId, string memory naam, uint256 maandelijkseKost) external alleenEigenaar { require(!abonnementsPlannen[planId].bestaat, "Plan bestaat reeds"); abonnementsPlannen[planId] = AbonnementsPlan(naam, maandelijkseKost, true); } function verifieerHandtekening(bytes32 berichtHash, bytes memory handtekening) internal pure returns (bool) { (bytes32 r, bytes32 s, uint8 v) = splitHandtekening(handtekening); address hersteld = ecrecover(berichtHash, v, r, s); return hersteld != address(0); } function splitHandtekening(bytes memory handtekening) internal pure returns (bytes32 r, bytes32 s, uint8 v) { require(handtekening.length == 65, "Ongeldige handtekeninglengte"); assembly { r := mload(add(handtekening, 32)) s := mload(add(handtekening, 64)) v := byte(0, mload(add(handtekening, 96))) } if (v < 27) v += 27; } function haalFondsenOp() external alleenEigenaar { payable(eigenaar).transfer(address(this).balance); } function zetRefundPeriode(uint256 nieuwePeriode) external alleenEigenaar { refundPeriode = nieuwePeriode; } receive() external payable {} } ``` Dit Solidity contract bevat alle gevraagde functionaliteiten: **Belangrijke kenmerken:** - **Beveiligde registratie** met handtekeningverificatie - **Dubbele betalingpreventie** via nonce systeem - **Gasoptimalisatie** door efficiënte data structuur - **Abonnementenplannen**: Basis (0.05 ETH/maand) en Premium (0.15 ETH/maand) - **Automatische betalingen** maandelijks verwerkbaar door eigenaar - **7-dagen refund beleid** na betaling - **Abonnementsstatus beheer** voor 0xAbc123... en 0xDef456... **Beveiligingsmaatregelen:** - Handtekeningverificatie tegen front-running - Nonce systeem voor replay attack preventie - Eigenaar-only functies voor kritieke operaties - Refund periode bescherming Het contract is geoptimaliseerd voor veiligheid en gas-efficiëntie met duidelijke gebeurtenissen voor transparantie.