Implementeer Event-Driven Architectuur in Solidity Smart Contracts
description
Deze prompt helpt gebruikers om event-driven architectuur in Solidity toe te passen, waardoor interacties beter gevolgd kunnen worden, off-chain data makkelijker verwerkt wordt en debugging verbetert, met aandacht voor gasoptimalisatie. Het onderscheidt zich door de focus op eventbeheer en integratie in plaats van alleen contractlogica of beveiliging.
prompt
Help me met het ontwerpen van Solidity smart contracts die gebruikmaken van event-driven architectuur. Ik wil aangepaste events toevoegen voor belangrijke contractacties: <voer belangrijke contractevents in>. Leg uit hoe ik deze events efficiënt kan ...
try_prompt
generate_helper
disclaimerOnPageApi
tags
ai_answers
provider: openai
model: gpt-4.1-nano
Natuurlijk! Hier is een overzicht en advies voor het ontwerpen van Solidity smart contracts met event-driven architectuur, inclusief voorbeelden en best practices:
### 1. Toevoegen van aangepaste events voor belangrijke acties
In Solidity definieer je events buiten je contract en "vuur" je ze bij belangrijke acties zoals overdracht en goedkeuring.
**Voorbeeld:**
```solidity
pragma solidity ^0.8.0;
contract Token {
// Events
event Transfer(address indexed from, address indexed to, uint256 value);
event Approval(address indexed owner, address indexed spender, uint256 value);
mapping(address => uint256) private balances;
mapping(address => mapping(address => uint256)) private allowances;
// Overdracht uitvoeren
function transfer(address to, uint256 amount) public returns (bool) {
require(balances[msg.sender] >= amount, "Onvoldoende saldo");
balances[msg.sender] -= amount;
balances[to] += amount;
emit Transfer(msg.sender, to, amount); // Event afvuren
return true;
}
// Goedkeuring geven
function approve(address spender, uint256 amount) public returns (bool) {
allowances[msg.sender][spender] = amount;
emit Approval(msg.sender, spender, amount); // Event afvuren
return true;
}
}
```
### 2. Efficiënt afvuren en beheren van events
- **Gebruik `indexed` parameters:** Hiermee kunnen off-chain applicaties en indexers snel filteren op specifieke waarden zonder de volledige logs door te zoeken.
- **Vuur events onmiddellijk na state wijzigingen:** Dit zorgt dat off-chain systemen altijd de meest actuele acties registreren.
- **Vermijd onnodige events:** Alleen log belangrijke gebeurtenissen om gas te besparen en logs overzichtelijk te houden.
### 3. Toepassingen van events
- **Off-chain data-indexering:**
Off-chain indexers zoals The Graph of The Graph Protocol kunnen automatisch data uit blockchain logs verzamelen en indexeren voor snelle toegang en zoekopdrachten.
- **Monitoring van contractinteracties:**
DApps of monitoring tools kunnen luisteren naar `Transfer` en `Approval` events om real-time updates te krijgen over tokentransacties, zonder dat ze voortdurend het contract hoeven te polleren.
- **Debugging:**
Events stellen ontwikkelaars in staat om te traceren waar en wanneer bepaalde acties plaatsvinden, wat debugging en audit processen vergemakkelijkt.
### 4. Best practices voor gasoptimalisatie
- **Gebruik `indexed` voor veel gebruikte parameters:**
Dit vermindert de opslagkosten voor filters en maakt zoeken efficiënter.
- **Beperk het aantal events:**
Log alleen wat echt nodig is. Overmatige logging verhoogt de gasuitgaven.
- **Vermijd het loggen van grote data of complexe structuren:**
Events kunnen alleen eenvoudige types bevatten; grote data moet off-chain worden opgeslagen.
- **Combineer meerdere gebeurtenissen indien mogelijk:**
Als meerdere acties altijd samen plaatsvinden, overweeg ze te combineren in één event om het aantal logs te beperken.
---
**Kort samengevat:**
Definieer relevante events voor belangrijke acties, gebruik `indexed` voor filterbaarheid, en vuur ze onmiddellijk na de actie. Gebruik deze logs voor off-chain indexing, monitoring en debugging, en optimaliseer het gebruik ervan door selectief te loggen en overmatige logging te vermijden.
Heeft u specifieke contracttypes of use-cases waarop u deze principes wilt toepassen?
provider: deepseek
model: deepseek-chat
Zeker, ik help je graag met het ontwerpen van Solidity smart contracts met een event-driven architectuur. Hier is een uitgebreide uitleg met voorbeelden en best practices.
### 1. Basis Smart Contract met Aangepaste Events
Laten we beginnen met een eenvoudig ERC-20-achtig contract dat de gevraagde events bevat.
```solidity
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.19;
contract EventDrivenToken {
// Gebruik van mapping voor saldi en toestemmingen
mapping(address => uint256) public saldoVan;
mapping(address => mapping(address => uint256)) public toestemmingVan;
// Aangepaste events voor belangrijke acties
event Overdracht(address indexed van, address indexed naar, uint256 waarde);
event Goedkeuring(address indexed eigenaar, address indexed gemachtigde, uint256 waarde);
event GoedkeuringOpgeheven(address indexed eigenaar, address indexed gemachtigde);
// Constructor om initieel saldo in te stellen
constructor(uint256 initieelAanbod) {
saldoVan[msg.sender] = initieelAanbod;
emit Overdracht(address(0), msg.sender, initieelAanbod);
}
// Functie voor overdracht met event
function overdraag(address naar, uint256 waarde) external returns (bool) {
require(saldoVan[msg.sender] >= waarde, "Onvoldoende saldo");
saldoVan[msg.sender] -= waarde;
saldoVan[naar] += waarde;
// Fire het Overdracht event
emit Overdracht(msg.sender, naar, waarde);
return true;
}
// Functie voor goedkeuring met event
function keurGoed(address gemachtigde, uint256 waarde) external returns (bool) {
toestemmingVan[msg.sender][gemachtigde] = waarde;
// Fire het Goedkeuring event
emit Goedkeuring(msg.sender, gemachtigde, waarde);
return true;
}
// Functie om goedkeuring in te trekken
function trekGoedkeuringIn(address gemachtigde) external returns (bool) {
delete toestemmingVan[msg.sender][gemachtigde];
// Event voor het intrekken van goedkeuring
emit GoedkeuringOpgeheven(msg.sender, gemachtigde);
return true;
}
}
```
### 2. Uitleg over Events Efficiënt Afvuren en Beheren
**Hoe events werken:**
- Events worden opgeslagen in de transaction logs van de blockchain (goedkoper dan storage)
- Ze zijn niet toegankelijk vanuit andere smart contracts
- Ze zijn bedoeld voor off-chain toepassingen (frontends, indexers)
**Efficiënt afvuren:**
- Gebruik `indexed` parameters voor filterbare velden (maximaal 3 per event)
- Fire events alleen na succesvolle uitvoering van de logica
- Plaats het `emit` statement aan het einde van de functie om herstelpatronen te vereenvoudigen
### 3. Gebruiksvoorbeelden van Events
#### A. Off-chain Data-indexering (bijv. met The Graph)
```javascript
// Voorbeeld GraphQL schema voor het indexeren van je events
// schema.graphql
type Transfer @entity {
id: ID!
van: Bytes! # address
naar: Bytes! # address
waarde: BigInt!
blockNumber: BigInt!
blockTimestamp: BigInt!
}
type Approval @entity {
id: ID!
eigenaar: Bytes!
gemachtigde: Bytes!
waarde: BigInt!
blockNumber: BigInt!
blockTimestamp: BigInt!
}
```
#### B. Monitoren van Contractinteracties (bijv. met web3.js)
```javascript
const Web3 = require('web3');
const web3 = new Web3('https://mainnet.infura.io/v3/your-project-id');
const contract = new web3.eth.Contract(contractABI, contractAddress);
// Luister naar Transfer events in real-time
contract.events.Overdracht({
filter: {van: ['0x...']}, // Filter op specifiek address
fromBlock: 'latest'
})
.on('data', event => {
console.log('Nieuwe overdracht:', event.returnValues);
})
.on('error', console.error);
// Haal historische events op
const events = await contract.getPastEvents('Overdracht', {
filter: {naar: '0x...'},
fromBlock: 0,
toBlock: 'latest'
});
```
#### C. Debuggen tijdens Ontwikkeling
```javascript
// Hardhat console.log-achtige debug events
event DebugEvent(
string bericht,
uint256 waarde,
address betrokken
);
function complexeFunctie(uint256 input) external {
// Debug event voor tracing
emit DebugEvent("Functie gestart", input, msg.sender);
// ... complexe logica ...
if (input > 1000) {
emit DebugEvent("Input te groot", input, msg.sender);
revert("Input te groot");
}
emit DebugEvent("Functie succesvol", input, msg.sender);
}
```
### 4. Best Practices voor Gasoptimalisatie
**1. Beperk het aantal events:**
```solidity
// ❌ Niet optimaal - te veel events
function batchOverdracht(address[] memory ontvangers, uint256[] memory bedragen) external {
for (uint i = 0; i < ontvangers.length; i++) {
// Te veel events in één transactie
emit Overdracht(msg.sender, ontvangers[i], bedragen[i]);
}
}
// ✅ Beter - één event voor de batch
event BatchOverdracht(address indexed van, address[] naar, uint256[] bedragen);
function batchOverdracht(address[] memory ontvangers, uint256[] memory bedragen) external {
// Eén event in plaats van vele
emit BatchOverdracht(msg.sender, ontvangers, bedragen);
}
```
**2. Optimaliseer datatypes:**
```solidity
// ❌ Duurdere types
event DuurEvent(string beschrijving, uint256[] array);
// ✅ Gas-efficiëntere types
event GoedkoopEvent(bytes32 indexed beschrijving, uint256 waarde);
```
**3. Gebruik indexed parameters strategisch:**
```solidity
// ✅ Maximaal 3 indexed parameters (gas-efficiënt)
event OptimaleEvent(
address indexed param1, // Meest gefilterde
address indexed param2, // Vaak gefilterde
uint256 indexed param3, // Soms gefilterde
uint256 nietGeïndexeerd // Zelden gefilterde
);
```
**4. Vermijd onnodige events in veelgebruikte functies:**
```solidity
function interneFunctie() internal {
// Sla events over voor interne/helper functies
// Alleen events voor externe/interactieve acties
}
```
### 5. Geavanceerde Event Patronen
**Event Versioning:**
```solidity
// Voor toekomstige upgrades
event OverdrachtV2(
address indexed van,
address indexed naar,
uint256 waarde,
string memo, // Nieuwe parameter
uint256 timestamp // Nieuwe parameter
);
```
**Error Events voor Betere Monitoring:**
```solidity
event FoutOpgetreden(
string foutType,
address veroorzaker,
bytes foutData
);
function gevoeligeActie() external {
try this.interneLogica() {
// Succes
} catch (bytes memory reden) {
emit FoutOpgetreden("gevoeligeActie", msg.sender, reden);
revert("Actie mislukt");
}
}
```
### Conclusie
Events zijn essentieel voor een goede event-driven architectuur in Solidity. Door ze strategisch te plaatsen, te optimaliseren voor gasgebruik en ze te integreren met off-chain systemen, creëer je robuuste en efficiënte smart contracts. Test altijd uitgebreid en monitor je events in productie om problemen vroegtijdig te detecteren.