Wat is solidity?

Solidity is een programmeertaal die wordt toegepast binnen het netwerk van Ethereum. De Ethereum-blockchain is een decentraal, gedistribueerd platform dat gebruikmaakt van de cryptovaluta ether (ETH). Blockchaintechnologie is vooral bekend als de achterliggende digitale infrastructuur van Bitcoin, de eerste en meest bekende cryptocurrency die ooit werd ontwikkeld. Ethereum biedt echter meer mogelijkheden dan Bitcoin, omdat er binnen de Ethereum-blockchain allerlei soorten decentrale toepassingen (dapps) kunnen worden geprogrammeerd. Een voorbeeld daarvan zijn de smart contracts, transactieprotocollen waarmee specifieke juridisch relevante acties kunnen worden uitgevoerd.

 

Programming is like poetry. Een citaat van Ed Fries. Solidity is een programmeertaal die wordt toegepast binnen het Ethereum netwerk.

 

Serpent, LLL en Vyper

Solidity is een object-georiënteerde, domeinspecifieke programmeertaal voor de Ethereum-blockchain. Solidity werd voor het eerst voorgesteld in augustus 2014 door Gavin Wood, een Britse computerwetenschapper en grondlegger van Ethcore. Wood was tevens een van de oprichters van Ethereum. Solidity werd later verder ontwikkeld door het Solidity-team van het Ethereum-project. Dat team stond onder leiding van Christian Reitwiessner, een expert op het gebied van computationele complexiteit. Naast Solidity zijn er ook nog een aantal andere programmeertalen, die speciaal zijn ontworpen voor de Ethereum Virtual Machine (EVM). Daaronder zijn de programmeertalen Serpent, LLL en Vyper.

 

JavaScript

Blockchaintechnologie wint steeds meer aan populariteit. Met name voor de smart contract-functionaliteit is veel belangstelling. Solidity is een programmeertaal die enigszins lijkt op JavaScript. Daarom is het voor Java-ontwikkelaars relatief eenvoudig om met Solidity aan de slag te gaan. Volgens Gavin Wood is Solidity ontwikkeld rondom het zogenaamde ECMAScript (ook gebaseerd op JavaScript). Dit script wordt voornamelijk gebruikt voor serverside-scripting, een technologie die op het internet wordt toegepast om dynamische HTML-pagina’s te creëren. Dergelijke pagina’s kunnen specifieke bezoekers van een bepaalde website, een andere inhoud of ontwerp tonen.

 

ECMAScript

Solidity is ontsproten uit het ECMAScript, om ontwikkelaars bekend te maken met nieuwe blockchaintoepassingen. In tegenstelling tot het ECMAScript heeft Solidity een ‘statisch typesysteem’. Dit is een systeem waarin bepaald wordt, hoe de desbetreffende programmeertaal gegevens classificeert, in verschillende datatypen. Vervolgens kijkt het systeem dan hoe deze datatypen met elkaar kunnen worden samengevoegd. Ook maakt deze programmeertaal gebruik van zogenaamde ‘variadic return types’, een wiskundige functie die een variabel aantal argumenten accepteert.

 

 

Ledenfuncties

In vergelijking met de andere gebruikte programmeertalen die kunnen draaien in de Ethereum Virtual Machine, heeft Solidity een aantal hele belangrijke verschillen in zich. Er wordt namelijk ondersteuning geboden voor ingewikkelde lidvariabelen voor smart contracts met willekeurige, hiërarchische correspondentie en Decentrale Autonome Organisaties (DAO). Deze lidvariabelen zijn variabelen die geassocieerd worden met specifieke objecten en zijn toegankelijk voor ledenfuncties. De met solidity geprogrammeerde smart contracts ondersteunen ook zogenaamde ‘overerving’. Dit is een methode in het kader van object-georiënteerd programmeren, waarbij een klasse variabelen (bepaalde eigenschappen), functies en procedures ‘erft’ van een superklasse. De smart contracts worden zo geprogrammeerd, dat ook alle variabelen door alle nodes (knooppunten binnen de Ethereum-blockchain) kunnen worden gecontroleerd.

 

MIST-browser

Ontwikkelaars bij Ethereum werkten eerder aan de Ethereum browser MIST. Deze browser moest het eenvoudiger maken, om alle toepassingen binnen het Ethereum blockchainnetwerk te lokaliseren en in te schakelen. Daarnaast moest MIST de gebruiksvriendelijkheid van de Ethereum-blockchain vergroten, waardoor het potentieel van blockchaintechnologie onder gebruikers duidelijker werd. Het project met de MIST-browser werd echter in 2019 beëindigd, omdat de technische vereisten van een volledig gedecentraliseerde dapp-browser verder reikten, dan wat de huidige blockchaintechnologie toelaat.

 

Solidity smart contract voor de supply chain

Smart contracts kunnen worden gebruikt in allerlei sectoren en industrieën, waaronder de gezondheidszorg, de verzekeringsbranche, de vastgoedsector, detailhandel, energie en nutsvoorzieningen, onderwijs en de supply chain. Hieronder volgt een vereenvoudigd voorbeeld van hoe een smart contract in Solidity dat wordt toegepast binnen supply chain management eruit zou kunnen zien. Het smart contract registreert bijvoorbeeld goederen, hun eigenaren en de status van iedere stap in het ketenbeheer.

 

Een magazijnmedewerker in een opslagloods van een distributiebedrijf met een iPad, supply chain management

 

Voorbeeld:

 

// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

 

contract SupplyChain {

 

enum ProductStatus { Manufactured, InTransit, Delivered }

 

struct Product {

uint productId;

string productName;

address manufacturer;

address currentOwner;

ProductStatus status;

}

 

mapping(uint => Product) public products;

uint public productCounter = 0;

 

event ProductCreated(uint productId, string productName, address manufacturer);

event OwnershipTransferred(uint productId, address from, address to);

event ProductStatusChanged(uint productId, ProductStatus status);

 

// Functie om een nieuw product aan te maken

function createProduct(string memory _productName) public {

productCounter++;

products[productCounter] = Product(productCounter, _productName, msg.sender, msg.sender, ProductStatus.Manufactured);

 

emit ProductCreated(productCounter, _productName, msg.sender);

}

 

// Functie om het eigendom van een product over te dragen

function transferOwnership(uint _productId, address _newOwner) public {

require(products[_productId].currentOwner == msg.sender, “Je bent niet de eigenaar van dit product.”);

require(_newOwner != address(0), “Nieuw adres is ongeldig.”);

 

address previousOwner = products[_productId].currentOwner;

products[_productId].currentOwner = _newOwner;

 

emit OwnershipTransferred(_productId, previousOwner, _newOwner);

}

 

// Functie om de status van een product te wijzigen (bijvoorbeeld: naar ‘InTransit’ of ‘Delivered’)

function updateProductStatus(uint _productId, ProductStatus _status) public {

require(products[_productId].manufacturer == msg.sender, “Alleen de fabrikant kan de status wijzigen.”);

products[_productId].status = _status;

 

emit ProductStatusChanged(_productId, _status);

}

 

// Functie om de details van een product op te vragen

function getProduct(uint _productId) public view returns (string memory, address, address, ProductStatus) {

Product memory product = products[_productId];

return (product.productName, product.manufacturer, product.currentOwner, product.status);

}

}

 

Uitleg van bovenstaand smart contract:

Struct Product

Struct Product is de definitie van een product, met informatie zoals productId, productName, manufacturer, currentOwner en status.

Enums

Enums wordt gebruikt de mogelijke statussen van een product te definiëren, zoals Manufactured, InTransit en Delivered.

Events

Het contract genereert events zoals ProductCreated, OwnershipTransferred en ProductStatusChanged. Deze events worden gelogd op de blockchain zodat gebruikers kunnen zien wanneer belangrijke gebeurtenissen plaatsvinden.

Create Product

Een fabrikant kan een nieuw product aanmaken, waarbij het initiële eigendom wordt ingesteld op de fabrikant.

Transfer Ownership

De eigenaar van het product kan het eigendom overdragen aan een nieuwe eigenaar.

Update Product Status

De fabrikant kan de status van het product updaten, naarmate het product door de supply chain beweegt.

View Product

Iedereen kan de gegevens van een product opvragen door het product-ID te gebruiken.

 

Hoe werkt dit precies in de supply chain:

Fabrikant

De fabrikant voegt een product toe en is de eerste eigenaar binnen de supply chain.

Distributeur of transporteur

De distributeur of transporteur kan de status van het product aanpassen naar InTransit en later naar Delivered.

Detailhandelaar

De detailhandelaar kan het eigendom overnemen nadat het product is geleverd.

 

Eenvoudige basisstructuur

Bovenstaand voorbeeld biedt een basisstructuur voor een eenvoudige supply chain op de blockchain. Door het gebruik van smart contracts kunnen alle onderdelen van de keten (zoals fabrikanten, transporteurs en klanten) transparant en veilig samenwerken.

 

Solidity smart contract voor energie en nutsvoorzieningen

Een smart contract voor energie en nutsvoorzieningen kan worden gebruikt voor een energieverhandelingsplatform om de levering van energie, facturering, en betalingen te automatiseren en transparant te maken. Dit kan bijvoorbeeld worden toegepast in een systeem voor hernieuwbare energie, waarbij energieleveranciers en consumenten energie verhandelen en betalingen doen via de blockchain. Het smart contract stelt energieproducenten (zoals bijvoorbeeld zonnepaneeleigenaren) in staat om overtollige energie te verkopen aan consumenten. Hieronder volgt een vereenvoudigd voorbeeld van hoe een smart contract voor energie en nutsvoorzieningen eruit zou kunnen zien.

 

Zonnepanelen op een dak

 

Voorbeeld:

 

// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

 

contract EnergyTrading {

 

struct EnergyProducer {

address producer;

uint availableEnergy;  // in kWh

uint energyPrice;      // in wei per kWh

}

 

struct Consumer {

address consumer;

uint energyPurchased;  // in kWh

}

 

mapping(address => EnergyProducer) public producers;

mapping(address => Consumer) public consumers;

 

event EnergyProduced(address indexed producer, uint amount, uint pricePerKwh);

event EnergyPurchased(address indexed consumer, address indexed producer, uint amount, uint totalPrice);

 

// Functie voor een producent om beschikbare energie en prijs te registreren

function registerEnergy(uint _energyAmount, uint _energyPrice) public {

producers[msg.sender] = EnergyProducer(msg.sender, _energyAmount, _energyPrice);

emit EnergyProduced(msg.sender, _energyAmount, _energyPrice);

}

 

// Functie voor consumenten om energie te kopen van een specifieke producent

function buyEnergy(address _producer, uint _energyAmount) public payable {

EnergyProducer storage producer = producers[_producer];

require(producer.availableEnergy >= _energyAmount, “Niet genoeg energie beschikbaar.”);

uint totalPrice = _energyAmount * producer.energyPrice;

require(msg.value == totalPrice, “Verkeerd bedrag overgemaakt.”);

 

// Update de energie van de producent en registreer de aankoop van de consument

producer.availableEnergy -= _energyAmount;

consumers[msg.sender].consumer = msg.sender;

consumers[msg.sender].energyPurchased += _energyAmount;

 

// Overdracht van geld aan de producent

payable(_producer).transfer(msg.value);

 

emit EnergyPurchased(msg.sender, _producer, _energyAmount, totalPrice);

}

 

// Functie om de beschikbare energie van een producent op te vragen

function getProducerInfo(address _producer) public view returns (uint availableEnergy, uint energyPrice) {

return (producers[_producer].availableEnergy, producers[_producer].energyPrice);

}

 

// Functie om te controleren hoeveel energie een consument heeft gekocht

function getConsumerInfo(address _consumer) public view returns (uint energyPurchased) {

return consumers[_consumer].energyPurchased;

}

}

Uitleg van bovenstaand smart contract:

Stucts voor Producenten en Consumenten

  • EnergyProducer: Bevat informatie over de energieproducent, zoals de beschikbare energie in kWh en de prijs per kWh.
  • Consumer: Houdt bij hoeveel energie een consument precies heeft gekocht.

Events

  • EnergyProduced: Gelogd wanneer een producent energie beschikbaar stelt voor verkoop.
  • EnergyPurchased: Gelogd wanneer een consument energie koopt van een producent.

Functies

  • registerEnergy: Producenten kunnen hun beschikbare energie en de prijs per kWh registreren.
  • buyEnergy: Consumenten kunnen energie kopen van een producent. De betaling wordt uitgevoerd door de consument (met de juiste hoeveelheid ether (ETH) en de energievoorraad van de producent wordt bijgewerkt.
  • getProducerInfo: Geeft de huidige energievoorraad en prijs per kWh van een producent terug.
  • getConsumerInfo: Geeft het aantal kWh dat een consument heeft gekocht.

Betalingen

  • Consumenten betalen rechtstreeks via het Solidity smart contract. Het juiste bedrag wordt berekend op basis van de prijs per kWh van de producent en het aantal kWh dat de consument wil kopen. De betaling in ether wordt dan overgemaakt naar de producent.

 

Gedecentraliseerd energieverdelingssysteem

Bovenstaand smart contract kan worden gebruikt in een gedecentraliseerd energieverdelingssysteem, waar consumenten en producenten rechtstreeks energie kunnen verhandelen. Denk hierbij aan toepassingen zoals bijvoorbeeld:

  • Huishoudens met zonnepanelen die overtollige energie verkopen aan hun buren.
  • Het automatiseren van betalingen tussen energieleveranciers en consumenten zonder tussenpersonen.

Ook dit is nog maar een eenvoudig voorbeeld van een Solidity smart contract, maar het kan worden uitgebreid met meer functies, zoals dynamische prijsstelling, slimme contracten voor energienetwerken, of integratie met IoT-apparaten om automatisch verbruik en productie bij te houden.

 

Solidity smart contract voor een pensioenfonds

Smart contracts kunnen pensioenfondsen helpen om de administratie van pensioensparen, bijdragen en uitbetalingen transparanter en efficiënter te maken. Het slimme contract kan bijvoorbeeld bijdragen inhouden, pensioenuitkeringen automatiseren, en zorgen voor een gecontroleerde verdeling van fondsen wanneer een deelnemer met pensioen gaat. Hieronder volgt een vereenvoudigd voorbeeld van hoe een smart contract voor energie en nutsvoorzieningen eruit zou kunnen zien.

 

Gepensioneerd echtpaar in een hangmat

 

Voorbeeld:

 

// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

 

contract PensionFund {

 

struct Participant {

address participantAddress;

uint totalContributions;  // in wei

uint pensionBalance;      // in wei

bool isRetired;

}

 

address public fundManager;

uint public retirementAge = 65;  // Leeftijden kunnen in jaren worden aangepast in een reële implementatie

mapping(address => Participant) public participants;

uint public totalFunds;  // Totaal geld in pensioenfonds

 

event ContributionMade(address indexed participant, uint amount);

event PensionWithdrawn(address indexed participant, uint amount);

event ParticipantRetired(address indexed participant);

 

modifier onlyFundManager() {

require(msg.sender == fundManager, “Alleen de fondsbeheerder heeft toegang.”);

_;

}

 

modifier onlyParticipants() {

require(participants[msg.sender].participantAddress == msg.sender, “Je moet een deelnemer zijn.”);

_;

}

 

constructor() {

fundManager = msg.sender;

}

 

// Functie voor een deelnemer om bij te dragen aan het pensioenfonds

function contribute() public payable {

require(msg.value > 0, “Bijdrage moet groter zijn dan nul.”);

 

Participant storage participant = participants[msg.sender];

 

if (participant.participantAddress == address(0)) {

// Voeg een nieuwe deelnemer toe als hij/zij nog niet bestaat

participants[msg.sender] = Participant(msg.sender, 0, 0, false);

}

 

participant.totalContributions += msg.value;

totalFunds += msg.value;

 

emit ContributionMade(msg.sender, msg.value);

}

 

// Functie om een deelnemer met pensioen te laten gaan

function retire() public onlyParticipants {

require(participants[msg.sender].isRetired == false, “Deelnemer is al met pensioen.”);

participants[msg.sender].isRetired = true;

 

emit ParticipantRetired(msg.sender);

}

 

// Functie voor een deelnemer om hun pensioenuitkering op te nemen

function withdrawPension(uint _amount) public onlyParticipants {

require(participants[msg.sender].isRetired, “Je moet met pensioen zijn om je pensioen op te nemen.”);

require(participants[msg.sender].pensionBalance >= _amount, “Onvoldoende pensioenbalans.”);

 

participants[msg.sender].pensionBalance -= _amount;

payable(msg.sender).transfer(_amount);

 

emit PensionWithdrawn(msg.sender, _amount);

}

 

// Functie om pensioenen uit te keren aan alle gepensioneerde deelnemers

function distributePensions() public onlyFundManager {

for (uint i = 0; i < address(this).balance; i++) {

if (participants[i].isRetired && participants[i].totalContributions > 0) {

// Eenvoudige uitkeringsformule, deze kan complexer worden

participants[i].pensionBalance = participants[i].totalContributions;

}

}

}

 

// Functie om de bijdrage van een deelnemer te bekijken

function getParticipantInfo(address _participant) public view returns (uint totalContributions, uint pensionBalance, bool isRetired) {

Participant memory participant = participants[_participant];

return (participant.totalContributions, participant.pensionBalance, participant.isRetired);

}

}

Uitleg van bovenstaand smart contract:

Struct voor Deelnemers

  • Participant: Dit struct houdt de informatie bij over elke deelnemer, zoals hun adres, hun totale bijdragen, hun pensioenbalans en of ze al met pensioen zijn.

Events

  • ContributionMade: Gelogd wanneer een deelnemer een bijdrage doet.
  • PensionWithdrawn: Gelogd wanneer een deelnemer pensioen opneemt.
  • ParticiptantRetired: Gelogd wanneer een deelnemer met pensioen gaat.

Functies

  • Contribute: Deelnemers kunnen geld bijdragen aan het pensioenfonds. Deze functie registreert nieuwe deelnemers als ze nog niet bestaan en houdt hun bijdragen bij.
  • retire: Hiermee kan een deelnemer met pensioen gaan. Dit moet expliciet worden aangeroepen door de deelnemer, en de pensioenstatus wordt automatisch bijgewerkt.
  • withdrawPension: Gepensioneerde deelnemers kunnen hun pensioenuitkering opnemen. De opname kan niet hoger zijn dan hun beschikbare balans.
  • distributePensions: De fondsbeheerder kan deze functie aanroepen om pensioenen uit te keren aan alle gepensioneerde deelnemers, op basis van hun totale bijdragen. Dit is een relatief eenvoudige formule, maar deze kan worden uitgebreid met complexere berekeningen (bijvoorbeeld op basis van looptijd, investeringsrendement, enz.).

Betalingen

  • Deelnemers dragen bij in ether (ETH) en deze bijdragen worden opgeslagen in het contract (totalFunds).
  • Wanneer een deelnemer met pensioen gaat, kan hij of zij via de withdrawPension-functie geld opnemen.

Fondsbeheerder

  • De fondsbeheerder heeft speciale privileges, zoals het distribueren van pensioenen aan alle gepensioneerde deelnemers.

 

Uitbreidingen van het smart contract:

  • Investeringen: Het slimme contract kan worden uitgebreid om bijdragen te investeren in bepaalde beleggingsstrategieën, waarbij rendementen worden toegevoegd aan de pensioenbalans van de deelnemers.
  • Pensioenleeftijd: In bovenstaand voorbeeld is de pensioenleeftijd niet strikt afgedwongen, maar het kan worden uitgebreid met een leeftijdsverificatie (bijvoorbeeld door het geboortejaar op te slaan).
  • Verzekeringen: Het contract kan integreren met verzekeringsmechanismen in het geval van overlijden van de deelnemer, waarbij de pensioenbalans wordt uitgekeerd aan erfgenamen.

Bovenstaand smart contract biedt een basisstructuur voor een pensioensysteem op de blockchain, dat kan zorgen voor transparantie en zekerheid voor zowel deelnemers als fondsbeheerders.

 

Leren programmeren in Ethereum?

Dan is Introducing Ethereum and Solidity een goede basis!

 

Wat leer je in dit boek?

  • Hoe Ethereum en cryptocoins werken.
  • Wat het verschil is tussen dapps (decentrale applicaties) en apps.
  • Het schrijven van smart contracts in de programmeertaal Solidity.
  • Ethereum smart contracts en HTML/CSS/JavaScript web applicaties aan elkaar koppelen.
  • Het creëren en uitvoeren van je eigen cryptovaluta, dapp of blokketen.

Boek: Introducing Ethereum and Solidiy

 

Dit boek is niet alleen een aanrader voor beginners op het gebied van blockchain-applicaties, maar zeker ook voor ervaren JavaSript-programmeurs!

 

Op de hoogte blijven van de ontwikkelingen op het gebied van blockchaintechnologie? Meld je dan nu aan voor de blogpost!

 

Meld je aan voor de blogpost!
Ik ga ermee akkoord dat mijn naam en e-mailadres worden gedeeld met Mailchimp.
Met de blogpost van Uitleg Blockchain blijf je automatisch op de hoogte van de nieuwste ontwikkelingen omtrent de blockchain technologie.
We hebben een hekel aan spam. Uw e-mailadres zal niet worden verkocht of gedeeld met anderen (afgezien van het marketing automation platform dat wij gebruiken voor onze e-maillijst).