2. Ethereum, introductie smart contract

Door xos op zondag 22 november 2015 10:23 - Reacties (5)
Categorie: -, Views: 2.809

Na een Ethereum introductie gaan we in deze post een smart contract maken, uitrollen en gebruiken. Het doel van dit smart contact is om de verkoop van een product te volgen waarbij zowel voor verkoper als koper een belang wordt gecreŽerd om juist te handelen.


Probleem
In veel gevallen kennen verkoper en koper elkaar op een online marktplaats/webshop niet en is het niet mogelijk om het product op te halen. Dat geeft diverse risico's, de verkoper weet niet of de koper het geld heeft en dit zal overmaken. De koper heeft geen garantie dat hij het juiste product zal ontvangen.

Het risico voor de verkoper wordt vaak afgedekt om de koper (een deel van) het bedrag vooruit te laten betalen waarna het product pas verstuurd wordt. De koper neemt hiermee een risico. Dit is op te lossen door een onafhankelijke derde partij aan te wijzen. Deze zal het product van de verkoper en het geld van de koper ontvangen. Als beide partijen hun afspraak zijn nagekomen zal deze partij het product naar de koper versturen en de verkoper haar geld ontvangen. In veel gevallen is dit geen oplossing, deze dienst kost vaak een hoop geld en staat niet in verhouding tot de verkoopprijs van het product, zorgt voor extra vertraging of mist de expertise om het product te kunnen beoordelen.


Oplossing
Ethereum biedt in de vorm van smart contract een oplossing. Een smart contract kan als onafhankelijke partij functioneren en reageren op signalen van verkoper en koper. Het werkt als volgt:
  1. De koper en verkoper zijn een prijs overeen gekomen.
  2. De verkoper maakt een smart contract en stuurt 2 keer de afgesproken prijs naar het smart contract.
  3. De koper stuurt 2 * de afgesproken prijs naar het smart contract.
  4. De verkoper stuurt het product op.
  5. De koper ontvangt het product. Koper is tevreden en geeft dit door aan het smart contract waarna de transactie is afgerond en de verkoper 3/4 (de helft was zijn eigen inleg, en de andere helft was 2 * de verkoopprijs van de koper) van het geld in het smart contract ontvangt en de koper 1/4. In geval de koper ontevreden is meldt ze dit bij het smart contract en stuurt het product terug.
  6. Verkoper ontvangt het teruggestuurde product, meldt dit bij het smart contract waarna beide partijen hun ingelegde geld terug krijgen.
Belangrijk om op te merken dat zowel de verkoper als de koper een belang hebben om de transactie af te ronden na stap 3. Beide hebben 2 keer de afgesproken prijs ingelegd en kunnen dit alleen terug krijgen door de transactie af te ronden op een manier dat beide partijen akkoord zijn.

in de praktijk zijn nog extra maatregels nodig om vast te leggen wat er moet gebeuren als 1 van beide partijen niet meer reageert, of een incentive te creŽren voor de verkoper om het contract netjes op te ruimen nadat de transactie is afgerond. Voor nu beperken we ons tot de kern.


Stap 2, aanmaken smart contract
Het maken van een smart contract kan met een simpele tekst editor of in een omgeving die speciaal voor smart contract is ingericht. Zelf gebruikt ik meestal deze maar er zijn genoeg alternatieven. Er zijn diverse talen om een smart contract op te stellen, veel gebruikte zijn Solidity (javscript gebaseerd) en Serpent (python gebaseerd). In deze post gebruiken we Solidity.

De eerste stap is het declareren van het contract (stap 2).

JavaScript:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
contract Purchase {
    address public seller;
    address public buyer;
    uint256 public price;
    
    enum State { Created, BuyerConfirmed, ProductReturned, Finished }
    State state;
    
    function Purchase() {
        seller = msg.sender;
        price = msg.value / 2;
        state = State.Created;
    }
}

eide partijen die een duur product willen uitwisselen wel erg veel geld opzij zetten
  • Op de eerste regel beginnen we het contract en geven we het een naam.
  • Op regels 2 en 3 worden er 2 variabelen gedeclareerd die het adres van de koper en verkoper bevatten. Het public keyword is een indicatie voor de compiler om een getter te genereren (meer hierover in de volgende post als we een DApp bouwen voor dit contract).
  • Regel 4 bevat de variable die de overeengekomen prijs bevat.
  • Regel 6 bevat een definitie van de verschillende states waarin het contract zich kan bevinden.
  • Regel 7 de variabele om de huidige state bij te houden.
  • Regels 9 t/m 13 de constructor. Als het contract uitgerold wordt wordt deze functie eenmalig aangeroepen en initialiseert enkele variabelen. Zoals beschreven in de 2e stap stuurt de verkoper met de uitrol 2 * het afgesproken bedrag mee. Als een constructor of functie wordt aangeroepen gebeurd dit door een transactie/bericht te sturen. De msg variabele verwijst naar dit bericht en bevat diverse gegevens zoals de afzender (msg.sender) en de hoeveelheid ether in Wei (msg.value) die de afzender mee heeft verzonden. Zie deze pagina voor een overzicht van de diverse velden.

Stap 3, koper stuurt 2 keer de afgesproken prijs op
Voordat de verkoper het product verzend stuurt de koper 2 keer het afsproken prijs naar het smart contract.

JavaScript:
1
2
3
4
5
6
7
8
9
10
11
event BuyerConfirmed(address buyer);
    
function ConfirmPurchase() {
    if (state != State.Created) throw;
    if (msg.value != 2 * price) throw;
        
    buyer = msg.sender;
    state = State.Confirmed;
        
    BuyerConfirmed(buyer);
}


Op de eerste regel wordt een event gedefinieerd. De Ethereum Virtual Machine heeft de mogelijkheid om logs aan te maken om gebeurtenissen te registeren. In dit geval wordt het moment dat de koper de aankoop bevestigd door 2 keer de afgesproken prijs in te leggen vastgelegd op regel 10. Wanneer de transactie succesvol wordt uitgevoerd zal een log entry worden aangemaakt. De verkoper kan wachten op deze gebeurtenis en geÔnformeerd worden wanneer dit op treedt. Op deze manier hoeft ze niet periodiek te controleren of de koper inmiddels heeft betaald.

Op regel 4 wordt gecontroleerd dat het contract zich in de juiste state bevind. Als dit niet het geval wordt de transactie afgebroken en wordt een volledige rollback gedaan van de transactie.
Op regel 5 wordt gecontroleerd dat de koper het juiste bedrag in legt. Als dit niet het geval is wordt de transactie teruggedraaid.
In geval de transactie wordt teruggedraaid is het net alsof deze niet heeft plaats gevonden. Eventuele wijzigingen in de variabelen van het contract worden terug gedraaid en meegezonden ethers worden niet afgeschreven bij de afzender.


Stap 5, koper ontvangt het product en is tevreden
Als het contract zich in de juiste state bevind kan de koper aangeven dat ze het product goed heeft ontvangen en akkoord is. Het contract zal vervolgens de eigen inbreng van de verkoper + de afgesproken prijs overmaken naar de verkoper en het extra ingelegde geld terug sturen naar de koper. Hiermee is de transactie afgerond.

JavaScript:
1
2
3
4
5
6
7
8
9
10
11
12
13
event ProductReceivedOk();
    
function ConfirmProductReceivedOk() {
    if (state != State.BuyerConfirmed) throw;
    if (buyer != msg.sender) throw;
        
    seller.send(3 * price);
    buyer.send(1 * price);

    state = State.Finished;
        
    ProductReceivedOk();
}



Stap 5, koper ontvangt product en is ontevreden
De koper stuurt het product terug en informeert het smart contract dat het product terug gezonden is.

JavaScript:
1
2
3
4
5
6
7
8
9
10
event ProductReturned();
    
function ConfirmProductReturned() {
    if (state != State.BuyerConfirmed) throw;
    if (buyer != msg.sender) throw;
      
    state = ProductReturned;
        
    ProductReturned();
}



Stap 6, verkoper ontvangt teruggestuurd product
De verkoper heeft het teruggezonden product ontvangen en wil haar inbreng terug. Ze bevestigd bij het smart contract dat het teruggezonden product is ontvangen waarna het geld naar beide partijen terug wordt gestuurd.

JavaScript:
1
2
3
4
5
6
7
8
9
10
11
12
13
event Refunded();
    
function ConfirmReturnedProductReceived() {
    if (state != State.ProductReturned) throw;
    if (seller != msg.sender) throw;
        
    seller.send(2 * price);
    buyer.send(2 * price);
        
    state = State.Finished;
        
    Refunded();
}

Uitrol contract
De eerste stap is het installeren van een Ethereum client. Er zijn 2 veel gebruikte, de c++ en de go client. Ik ga uit van de go client omdat deze het meest gebruikersvriendelijk is. Zie voor installatie instructies deze pagina.

Voordat we het contract kunnen uitrollen moeten we eerst accounts aanmaken en een beetje ether gezamelen. Het makkelijkste gaat dit door een locale development chain op te starten en te minen zodat we ethers verdienen en blokken met transacties verwerken.


code:
1
geth account new


Maak op deze manier 2 accounts aan, 1 voor de verkoper en 1 voor de koper.

De volgende stap is het starten van geth.

code:
1
geth --dev --mine --minerthreads 1 --unlock "0 1" console 2>/some/logfile


Dit zal een geth node opstartenvragen om het wachtwoord voor beide account en vervolgens een private chain en een miner met 1 cpu thread beginnen. De console optie opent een javascript console. Door eth.accounts aan te roepen zullen de eerder aangemaakte accounts


JavaScript:
1
2
3
4
5
6
7
8
9
Instance: Geth/v1.4.0-unstable-dc2b3a9c/linux/go1.5.1
 datadir: /tmp/ethereum_dev_mode
coinbase: 0x474d33a1ee742675f48aeeb460918bb1b2e16cd1
at block: 495 (Sun, 22 Nov 2015 11:56:30 CET)
modules: admin:1.0 db:1.0 debug:1.0 eth:1.0 miner:1.0 net:1.0 personal:1.0 shh:1.0 txpool:1.0 web3:1.0
> eth.accounts
["0x474d33a1ee742675f48aeeb460918bb1b2e16cd1", "0x4ed35d4650879be6113aa278dd1c7631df5223e6"]
> web3.fromWei(eth.getBalance(eth.accounts[0]), "ether")
2655


Als je de client net hebt opgestart zal het even duren voordat de miner blokken begint te genereren. Er moest eerst een groot bestand worden gegenereerd wat enkele minuten kost (tijd is sterk afhankelijk van de snelheid van de computer). Pas als er blokken worden gegenereerd zal er ether toegekend worden aan het eerste address. Je kunt het huidige bloknummer opvragen met eth.blockNumber.

De volgende stap is het uitrollen van het contract. Het volledige contract kan hier gevonden worden. Helaas werkt de online IDE niet op dit moment en deployed het contract soms wel en soms niet. Ik heb geen idee waarom dit is. Daarom doen we de uitrol handmatig.

De console heeft de web3 javascript library geladen. Deze maakt het makkelijk om contracten uit te rollen en functies aan te roepen. Copy past het volgende statement in de console:

JavaScript:
1
2
3
4
5
6
7
8
9
10
11
12
13
var purchaseContract = web3.eth.contract([{"constant":false,"inputs":[],"name":"ConfirmReturnedProductReceived","outputs":[],"type":"function"},{"constant":true,"inputs":[],"name":"seller","outputs":[{"name":"","type":"address"}],"type":"function"},{"constant":false,"inputs":[],"name":"ConfirmPurchase","outputs":[],"type":"function"},{"constant":true,"inputs":[],"name":"buyer","outputs":[{"name":"","type":"address"}],"type":"function"},{"constant":true,"inputs":[],"name":"price","outputs":[{"name":"","type":"uint256"}],"type":"function"},{"constant":false,"inputs":[],"name":"ConfirmProductReceivedOk","outputs":[],"type":"function"},{"constant":false,"inputs":[],"name":"ConfirmProductReturned","outputs":[],"type":"function"},{"inputs":[],"type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"name":"buyer","type":"address"}],"name":"BuyerConfirmed","type":"event"},{"anonymous":false,"inputs":[],"name":"ProductReceivedOk","type":"event"},{"anonymous":false,"inputs":[],"name":"ProductReturned","type":"event"},{"anonymous":false,"inputs":[],"name":"Refunded","type":"event"}]);
var purchase = purchaseContract.new(
   {
     from: web3.eth.accounts[0], 
     data: '60606040525b33600060006101000a81548173ffffffffffffffffffffffffffffffffffffffff02191690830217905550600234046002600050819055506000600360006101000a81548160ff021916908302179055505b610654806100656000396000f36060604052361561007f576000357c01000000000000000000000000000000000000000000000000000000009004806302d62ac51461008157806308551a5314610090578063495cb71c146100c95780637150d8ae146100d8578063a035b1fe14610111578063b46c93a914610134578063f85b0f3e146101435761007f565b005b61008e60048050506104d5565b005b61009d6004805050610152565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6100d660048050506101a7565b005b6100e56004805050610178565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b61011e600480505061019e565b6040518082815260200191505060405180910390f35b6101416004805050610291565b005b6101506004805050610410565b005b600060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60026000505481565b6000600360009054906101000a900460ff161415156101c557610002565b600260005054600202341415156101db57610002565b33600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908302179055506001600360006101000a81548160ff021916908302179055507ffed4f186dfc7e259255e098b92e0ab13bb1701d63b0882bf6e3065cb6e75da10600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a15b565b6001600360009054906101000a900460ff161415156102af57610002565b3373ffffffffffffffffffffffffffffffffffffffff16600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614151561030b57610002565b600060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166000600260005054600302604051809050600060405180830381858888f1935050505050600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166000600260005054600102604051809050600060405180830381858888f19350505050506003600360006101000a81548160ff021916908302179055507fed730b940b68336d3a9a25dce4d6af94d7d3e98a646caa7ef83c5a08d397dfe160405180905060405180910390a15b565b6001600360009054906101000a900460ff1614151561042e57610002565b3373ffffffffffffffffffffffffffffffffffffffff16600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614151561048a57610002565b6002600360006101000a81548160ff021916908302179055507ffbe3a63652942f8e5f3aa921252d888d2377ce012b037a3b0d347fed7875390960405180905060405180910390a15b565b6002600360009054906101000a900460ff161415156104f357610002565b3373ffffffffffffffffffffffffffffffffffffffff16600060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614151561054f57610002565b600060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166000600260005054600202604051809050600060405180830381858888f1935050505050600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166000600260005054600202604051809050600060405180830381858888f19350505050506003600360006101000a81548160ff021916908302179055507f8616bbbbad963e4e65b1366f1d75dfb63f9e9704bbbf91fb01bec70849906cf760405180905060405180910390a15b56', 
     gas: 3000000,
     value: web3.toWei(4, 'ether')
   }, function(e, contract){
    if (typeof contract.address != 'undefined') {
         console.log(e, contract);
         console.log('Contract mined! address: ' + contract.address + ' transactionHash: ' + contract.transactionHash);
    }
 })

  • from, het adres van de verkoper (eth.accounts[0])
  • data, de byte code van het contract en wordt door de Solidity computer gegenereerd.
  • value, 2 keer de afgesproken prijs. In dit geval kiezen we 2 Ether als afgesproken prijs dus sturen we 4 Ether op. Omdat transacties de hoeveelheid Ethers in Wei accepteren converteren we 4 Ethers naar Wei met web3.toWei.
  • gas, iedere transactie consumeert een hoeveelheid gas. Gas dient gekocht te worden met Ethers (de EVM trekt dit automatisch af van je account als de transactie wordt uitgevoerd). We geven een hoeveelheid maximaal gas mee, als de transactie meer gas verbruikt dan is meegegeven zal de transactie afgebroken worden. Dit beschermt het netwerk tegen spammers van transacties (DOS) of fouten in een transactie die leiden tot een eindeloze loop. Teveel verstuurd gas zal teruggestort worden.
Nu is het wachten totdat de transactie verwerkt wordt. De Ethereum blockchain streeft een blocktijd van 17 seconden na maar het kost even voordat dit bereikt is. Als het dus langer of korter duurt dan is dit normaal, net als sterke variaties in blocktijden. Als het contract is uitgevoerd zal het adres worden geprint. In mijn geval 0x000c1dec5a45fbad11d0da3f67cd460f13fb2e3c. Het purchase object bevat nu een representatie van het smart contract. De mogelijkheden zijn te zien in de console:

JavaScript:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
> purchase
{
  address: "0x000c1dec5a45fbad11d0da3f67cd460f13fb2e3c",
  transactionHash: "0xe75167e9e9870a9b6ba1c4b45a407ecd321f3de173672b34c5d75526cffcecf0",
  BuyerConfirmed: function(),
  ConfirmProductReceivedOk: function(),
  ConfirmProductReturned: function(),
  ConfirmPurchase: function(),
  ConfirmReturnedProductReceived: function(),
  ProductReceivedOk: function(),
  ProductReturned: function(),
  Refunded: function(),
  allEvents: function(),
  buyer: function(),
  price: function(),
  seller: function()
}



Net als met onze eigen accounts kan ook een contract saldo bevatten. In dit geval hebben we 4 ethers meegestuurd (2 keer de prijs van 2 ethers). We kunnen controleren dat de balans daadwerkelijk 4 ethers is:

JavaScript:
1
2
> web3.fromWei(eth.getBalance("0x000c1dec5a45fbad11d0da3f67cd460f13fb2e3c"), "ether")
4



Koper bevestigd aankoop
Nu het contract uitgerold is moet de koper haar deel betalen. De opbrengsten van de miner worden naar het eerste account (onze verkoper) gestuurd, we moeten dus een beetje overmaken naar het tweede account wat onze koper voorstelt. Hiervoor sturen we de volgende transactie:

JavaScript:
1
> eth.sendTransaction({from: eth.accounts[0], to: eth.accounts[1], value: web3.toWei(8, "ether")})


Wacht opnieuw tot de transactie is uitgevoerd, controleer of de balans van het tweede accounts daadwerkelijk 8 ethers bevat.

De volgende stap is het aanroepen van de ConfirmPurchase functie door de koper. We kunnen gebruik maken van het purchase object.

JavaScript:
1
2
> purchase.ConfirmPurchase({from: eth.accounts[1], value: web3.toWei(4, "ether")})
"0xc98f5f290cb08f273125a766973d0a9f8e72b49c99ca367be985c7325a804e54"



We kunnen nu ook de balans van het contract opvragen en zien dat deze 8 ether bevat:

JavaScript:
1
2
> web3.fromWei(eth.getBalance("0x000c1dec5a45fbad11d0da3f67cd460f13fb2e3c"), "ether")
8



De functie ConfirmPurchase genereerde ook het BuyerConfirmed event. Dat betekent dat de EVM een log heeft aangemaakt. We kunnen dit log opvragen op verschillende manier. De makkelijkste manier is door het opvragen van de transactie receipt als het transactie id bekend is.

JavaScript:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
> eth.getTransactionReceipt("0xc98f5f290cb08f273125a766973d0a9f8e72b49c99ca367be985c7325a804e54")
{
  blockHash: "0xc6ac518319bcea8084576cf056d51fe47a4c2754cc7941dea2d4ae8751ae46d6",
  blockNumber: 817,
  contractAddress: null,
  cumulativeGasUsed: 63010,
  gasUsed: 63010,
  logs: [{
      address: "0x000c1dec5a45fbad11d0da3f67cd460f13fb2e3c",
      blockHash: "0xc6ac518319bcea8084576cf056d51fe47a4c2754cc7941dea2d4ae8751ae46d6",
      blockNumber: 817,
      data: "0x00000000000000000000000066f183060253cfbe45beff1e6e7ebbe318c81e56",
      logIndex: 0,
      topics: ["0xfed4f186dfc7e259255e098b92e0ab13bb1701d63b0882bf6e3065cb6e75da10"],
      transactionHash: "0xc98f5f290cb08f273125a766973d0a9f8e72b49c99ca367be985c7325a804e54",
      transactionIndex: 0
  }],
  transactionHash: "0xc98f5f290cb08f273125a766973d0a9f8e72b49c99ca367be985c7325a804e54",
  transactionIndex: 0
}


We zien inderdaad dat de transactie heeft geleid tot het aanmaken van 1 log. In de volgende post maken we een DApp en kunnen we zien hoe we logs kunnen opvragen zonder te beschikken over het transactie id.


Verkoper stuurt product op en koper accepteert product
Nu de koper een belang heeft om de transactie goed uit te voeren stuurt de verkoper het product op. De koper ontvangt het product, is akkoord en bevestigd dit aan het smart contract.

JavaScript:
1
2
> purchase.ConfirmProductReceivedOk({from: eth.accounts[1]})
"0x901d13030aa2c9b9dafe8981b8458b4e2731a0acb6c0483c6862d2c1c52152a9"


Als deze transactie is uitgevoerd zullen beide partijen het geld waarop ze recht hebben teruggestort krijgen. In geval van de koper leidt dit tot de volgende balans:

code:
1
2
> web3.fromWei(eth.getBalance(eth.accounts[1]), "ether")
5.9947719


De koper had 8 ether, legde 4 ether is en ontvang 2 ether terug. Toch is de balans net iets minder dan 6 ether. Dat wordt veroorzaakt doordat iedere transactie gas consumeert wat gekocht wordt met ethers. In dit geval hebben de transacties de koper 0.005228100000000069 ether gekost wat tegen de huidige marktprijs van 0.9 euro/ether net geen halve cent is. Een prijs die ook heel goed te betalen valt voor kleine transacties.


Tot slot

Deze post is bedoelt als introductie over de mogelijkheden die een smart contract bieden. In de praktijk zullen smart contract veel complexer zijn, wat moet er bijvoorbeeld gebeuren als een van beide partijen niks meer van zich laat horen? En is het realistisch om in geval van een duur product beide partijen 2 keer de prijs in te laten leggen? Of is het eerlijk om een (ver)koper met een aantoonbaar goed track record dezelfde fee te laten betalen als iemand die voor de eerste keer iets (ver)koopt?

In de volgende blogpost maken we een DApp die gebruik maakt van het smart contract en een gebruikersvriendelijke user interface biedt aan gebruikers.

1. Ethereum, blockchain technologie die de wereld gaat veranderen?

Door xos op zaterdag 14 november 2015 11:19 - Reacties (13)
Categorie: -, Views: 5.185

Introductie

Ethereum heeft de potentie om de manier waarop wij met elkaar communiceren en afspraken maken fundamenteel te veranderen. Bij voldoende intresse zal ik in een serie van blogposts op een praktische en laagdrempelige manier uitleggen wat het project probeert te bereiken, welke problemen zijn en nog moeten worden overwonnen, en hoe de lezer gebruik kan maken van deze technologie. In deze post wordt een introductie gegeven over het project, hoe het ontstaan is en wat de mogelijkheden zijn.


Blockchain technologie
Om Ethereum te begrijpen is een korte uitleg over blockchain technologie noodzakelijk. Op internet zijn diverse bronnen te vinden die dit in detail uitleggen. Daarom beperkt deze uitleg zich tot het algemene principe.

De natuur geeft ons 1 universele waarheid die wetenschapper proberen te begrijpen en te formaliseren in de vorm van natuurwetten. Globaal werk het als volgt, een onderzoeker voert een experiment uit, publiceert bevindingen en doet een voorstel om de bestaande kennis uit te bereiden. Onderzoekers van over heel de wereld kunnen het onderzoek herhalen. Er kunnen dan 2 dingen gebeuren:
  1. Onderzoeker zijn niet in staat om de resultaten van het onderzoek te reproduceren, of zijn het niet eens met de conclusie van het rapport. Gevolg is dat het rapport verworpen zal worden.
  2. Onderzoekers zijn in staat om het onderzoek te reproduceren en zijn het eens met het voorstel in het rapport. Wanneer genoeg onderzoekers hun fiat hebben gegeven zal het voorstel uit het rapport toegevoegd worden aan de bestaande set aan kennis en als fundament dienen voor verder onderzoek.
Belangrijk om op te merken is dat iedereen een rapport kan publiceren en dat dit rapport door iedereen te controleren, te accepteren of te verwerpen is. Pas als de meerderheid het rapport heeft geaccepteerd zal het definitief geaccepteerd worden.

De blockchain werkt volgens een vergelijkbaar principe. In plaats van het publiceren van een rapport kan iedereen een blok publiceren. Een blok bouwt verder op een ouder blok en kan data bevatten. Ook hier geldt dat iedereen het blok en haar inhoud kan controleren, accepteren of verwerpen. Het fundamentele verschil met de wetenschap is dat de natuur een mysterie is wat wetenschappers proberen te ontrafelen terwijl in de blockchain wereld de regels waaraan een blok moet voldoen nauwgezet zijn gedefinieerd. Dit maakt het het controleren van een blok een eenvoudige taak die iedereen onafhankelijk, betrouwbaar en snel kan uitvoeren.

Om te voorkomen dat er een storm aan blokken worden gegenereerd die allemaal gecontroleerd moeten worden dient ieder blok de oplossing van een cryptografische puzzel te bevatten. In geval van Ethereum wordt er naar gestreeft om gemiddeld iedere 17 seconden om een oplossing te vinden en daarmee een geldig blok te maken (in geval van bitcoin is dit iedere 10 minuten).

Door in ieder nieuw blok een verwijzing op te nemen naar een vorig blok ontstaat een keten van blokken. Door de simpele afspraak dat de lange keten de dominante keten is kunnen deelnemers het eens worden over uit welke blokken de keten bestaat. We noemen dan dat het netwerk in consensus is. En dit biedt enorme mogelijkheden.


Bitcoin
Bitcoin was een van de eerste toepassingen van de blockchain en maakt het mogelijk om transacties in deze blokken op te nemen. Door heel precies de regels te beschrijven voor een transactie kan iedereen de transacties in het blok controleren. Op deze manier ontstaat consensus over welke transacties zijn uitgevoerd, wanneer en wat de huidige balans van een account is.

Een van de nadelen van Bitcoin is dat zich beperkt tot het sturen van een hoeveelheid bitcoins naar een adres. Daarom zijn er in de loop van de jaren diverse "alt coins" gekomen. Deze werken veelal op basis van de bitcoin technologie maar hebben een andere toepassing. Bijvoorbeeld door een domain naam aan een specifieke coin toe te kennen kan een DNS achtig systeem gemaakt worden waarbij de eigenaar van de coin eigenaar is van de domain naam. Nadeel van deze oplossing is dat de blockchains niet compatibel zijn en gebruikers dus meerdere clients moeten draaien.


Ethereum
Eind 2013 publiceerde Vitalik Buterin een white paper (https://github.com/ethereum/wiki/wiki/White-Paper) waarin hij omschreef hoe een virtuele machine (EVM) gecombineerd kan worden met de blockchain. Dit maakt het mogelijk om niet alleen eenvoudige transacties uit te voeren maar programma's op de blockchain te plaatsen waarbij iederen de uitvoer van deze programma's kan controleren. Dit biedt enorme voordelen:
  • Eens een programma op de blockchain is geplaatst kan deze niet meer gewijzigd worden. Als de maker van een programma ineens minder goede bedoelingen heeft (of een cracker) kan deze het programma niet ongemerkt aanpassen.
  • De uitvoer van een programma volgt een set aan nauw gedefinieerde regels en is dus door iedereen te controleren. Als er vreemde zaken gebeuren dan wordt het resultaat verworpen en wordt het blok met de malafide transactie verworpen.
  • Geen Single Point Of Failure, omdat de werking van de EVM zo strak is gedefinieerd kan iedereen transacties zelf uitvoeren en in een blok plaatsen en publiceren. Er is dus geen centrale partij noodzakelijk.
Vanwege deze sterke garanties worden deze applicaties smart contracts genoemd. En in feite zijn is dit ook een betere benaming. Partijen die elkaar niet kennen of vertrouwen kunnen gezamenlijk een smart contract opstellen en via dit contract zaken met elkaar doen zonder kleine letters, taal barriŤres of dat iemand het contract eenzijdig kan schenden.


Mogelijkheden
De mogelijkheden zijn op dit moment nog niet helemaal duidelijk en worden volop besproken in de community. Persoonlijk denk ik dat er grofweg 3 stadia van smart contracts zullen bestaan:
  1. De voor de hand liggende applicaties zoals een online wallet
  2. Een generatie applicaties die gebruik maken van de sterke eigenschappen van smart contracts. Denk aan een predication market zoals Augur, of de mogelijkheid om je spullen te verhuren.
  3. Decentralized Autonome Organisaties, denk aan een smart contract wat een transport dienstverlening aanbiedt. Mensen die een pakket van A naar B willen versturen kunnen een rit plaatsen en iedereen kan deze rit accepteren en het pakketje vervoeren. Een drone die is aangesloten op het Ethereum netwerk kan deze rit accepteren en de fee gebruiken voor haar onderhoud en brandstof. Wanneer deze fee onvoldoende blijkt te zijn dan is ze verouderd en kan ze niet meer concurreren met nieuwere en efficiŽntere transporteurs en dus overbodig geworden.
Bij voldoende interesse laat ik de volgende blogpost zien hoe je via een smart contract een online marktplaats gemaakt kan worden waarbij koper en verkoper beide belang hebben om integer te handelen.