Smart uppsägning: Hyperledger Fabric vs MultiChain vs Ethereum vs Corda

Källnod: 1585333

Det finns mer än ett sätt att sätta kod i en blockchain

I de flesta diskussioner om blockkedjor tar det inte lång tid innan begreppet "smarta kontrakt" kommer upp. I den populära fantasin automatiserar smarta kontrakt genomförandet av interpartinteraktioner utan att kräva en betrodd mellanhand. Genom att uttrycka juridiska förhållanden i kod snarare än i ord lovar de att möjliggöra transaktioner direkt och utan fel, oavsett om de är avsiktliga eller inte.

Ur teknisk synvinkel är ett smart kontrakt något mer specifikt: datorkod som lever på en blockkedja och definierar reglerna för den kedjans transaktioner. Denna beskrivning låter enkel nog, men bakom den ligger en stor variation i hur dessa regler uttrycks, utförs och valideras. När du väljer en blockchain-plattform för en ny applikation, frågan "Stöder den här plattformen smarta kontrakt?" är inte rätt att fråga. Istället måste vi fråga: "Vilken typ av smarta kontrakt stöder den här plattformen?"

I den här artikeln är mitt mål att undersöka några av de stora skillnaderna mellan smarta kontraktsmetoder och de avvägningar de representerar. Jag gör det genom att titta på fyra populära blockchain-plattformar för företag som stöder någon form av anpassad on-chain-kod. Först IBM: s Hyperledger Fabric, som kallar sina kontrakt "kedjekod". För det andra, vår MultiChain-plattform, som introducerar smarta filter i version 2.0. Tredje, Ethereum (och dess tillstånd Quorum och Håla spin-offs), som populariserade namnet "smart kontrakt". Och slutligen, R3 Corda, som refererar till "kontrakt" i sina transaktioner. Trots alla de olika terminologierna hänvisar i slutändan alla dessa till samma sak - applikationsspecifik kod som definierar reglerna för en kedja.

Innan jag går vidare bör jag varna läsaren om att mycket av följande innehåll är av teknisk karaktär och förutsätter viss kunskap om allmänna programmerings- och databaskoncept. På gott och ont kan detta inte undvikas - utan att komma in i detaljerna är det omöjligt att fatta ett välgrundat beslut om huruvida man ska använda en blockchain för ett visst projekt, och (i så fall) rätt typ av blockchain att använda.

Blockchain grunder

Låt oss börja med något sammanhang. Föreställ dig en applikation som delas av flera organisationer, som är baserad på en underliggande databas. I en traditionell centraliserad arkitektur är denna databas värd och administreras av en enda part som alla deltagare litar på, även om de inte litar på varandra. Transaktioner som modifierar databasen initieras endast av applikationer på denna centrala parts system, ofta som svar på meddelanden som tas emot från deltagarna. Databasen gör helt enkelt vad den får veta eftersom applikationen implicit är betrodd att bara skicka transaktioner som är vettiga.

Blockchains är ett alternativt sätt att hantera en delad databas utan en betrodd mellanhand. I en blockchain kör varje deltagare en "nod" som innehåller en kopia av databasen och oberoende bearbetar de transaktioner som ändrar den. Deltagare identifieras med hjälp av offentliga nycklar eller “adresser”, som alla har en motsvarande privat nyckel som endast är känd för identitetsägaren. Även om transaktioner kan skapas av vilken nod som helst, signeras de "digitalt" av initiativtagarens privata nyckel för att bevisa sitt ursprung.

Noder ansluter till varandra på ett peer-to-peer-sätt, snabbt sprider transaktioner och "blocken" där de tidsstämplas och bekräftas över nätverket. Blockchain själv är bokstavligen en kedja av dessa block, som bildar en ordnad logg över varje historisk transaktion. En ”konsensusalgoritm” används för att säkerställa att alla noder når överenskommelse om blockkedjans innehåll, utan att det krävs centraliserad kontroll. (Observera att en del av denna beskrivning inte gäller Corda, där varje nod bara har en delkopia av databasen och det inte finns någon global blockchain. Vi kommer att prata mer om det senare.)

I princip kan alla delade databasapplikationer arkiveras genom att använda en blockchain i sin kärna. Men detta skapar ett antal tekniska utmaningar som inte finns i ett centraliserat scenario:

  • Transaktionsregler. Om någon deltagare direkt kan ändra databasen, hur ser vi till att de följer programmets regler? Vad hindrar en användare från att skada databasens innehåll på ett självbetjäande sätt?
  • Determinism. När dessa regler har definierats kommer de att tillämpas flera gånger av flera noder när de behandlar transaktioner för sin egen kopia av databasen. Hur ser vi till att varje nod får exakt samma resultat?
  • Konfliktförebyggande. Utan central samordning, hur hanterar vi två transaktioner som var och en följer programmets regler, men ändå strider mot varandra? Konflikter kan härröra från ett medvetet försök att spela systemet, eller vara det oskyldiga resultatet av otur och timing.

Så var kommer smarta kontrakt, smarta filter och kedjekod in? Deras huvudsyfte är att arbeta med en blockchains underliggande infrastruktur för att lösa dessa utmaningar. Smarta kontrakt är den decentraliserade motsvarigheten till applikationskod - istället för att köras på en central plats, körs de på flera noder i blockchain, vilket skapar eller validerar de transaktioner som ändrar databasens innehåll.

Låt oss börja med transaktionsregler, den första av dessa utmaningar, och se hur de uttrycks i Fabric, MultiChain, Ethereum respektive Corda.

Transaktionsregler

Transaktionsregler utför en specifik funktion i blockchain-drivna databaser - vilket begränsar transformationer som kan utföras i databasens tillstånd. Detta är nödvändigt eftersom en blockchains transaktioner kan initieras av någon av dess deltagare, och dessa deltagare litar inte på varandra tillräckligt för att de ska kunna ändra databasen efter eget önskemål.

Låt oss se två exempel på varför transaktionsregler behövs. Föreställ dig först en blockchain utformad för att sammanställa och tidsstämpla PDF-dokument som publiceras av dess deltagare. I det här fallet bör ingen ha rätt att ta bort eller ändra dokument, eftersom detta skulle undergräva systemets hela syfte - dokumentets uthållighet. För det andra, överväga en blockchain som representerar en delad ekonomisk huvudbok, som håller reda på saldot för sina användare. Vi kan inte tillåta en deltagare att godtyckligt blåsa upp sin egen balans eller ta bort andras pengar.

In- och utgångar

Våra blockchain-plattformar är beroende av två breda metoder för att uttrycka transaktionsregler. Den första, som jag kallar ”input-output-modellen”, används i MultiChain och Corda. Här listar transaktionerna uttryckligen databasraderna eller "staterna" som de tar bort och skapar, och bildar en uppsättning "ingångar" respektive "utdata". Att ändra en rad uttrycks som motsvarande operation för att radera den raden och skapa en ny i dess ställe.

Eftersom databasrader bara raderas i ingångar och bara skapas i utgångar, måste varje ingång "spendera" en tidigare transaktions output. Databasens nuvarande tillstånd definieras som uppsättningen "outnyttjade transaktionsutgångar" eller "UTXOs", dvs. utdata från tidigare transaktioner som ännu inte har använts. Transaktioner kan också innehålla ytterligare information, som kallas "metadata", "kommandon" eller "bilagor", som inte blir en del av databasen utan hjälper till att definiera deras mening eller syfte.

Med tanke på dessa tre uppsättningar ingångar, utgångar och metadata, definieras giltigheten för en transaktion i MultiChain eller Corda av någon kod som kan utföra godtyckliga beräkningar på dessa uppsättningar. Denna kod kan validera transaktionen eller returnera ett fel med motsvarande förklaring. Du kan tänka på input-output-modellen som en automatiserad "inspektör" som håller en checklista som säkerställer att transaktioner följer varje regel. Om transaktionen misslyckas med någon av dessa kontroller kommer den automatiskt att avvisas av alla noder i nätverket.

Det bör noteras att, trots att de delar input-output-modellen, implementerar MultiChain och Corda det väldigt annorlunda. I MultiChain kan utgångar innehålla tillgångar och / eller data i JSON, text eller binärt format. Reglerna definieras i "transaktionsfilter" eller "strömfilter", som kan ställas in för att kontrollera alla transaktioner, eller endast de som involverar specifika tillgångar eller grupperingar av data. Däremot representeras ett Corda-utgångsläge av ett objekt i programmeringsspråket Java eller Kotlin, med definierade datafält. Cordas regler definieras i ”kontrakt” som är knutna till specifika stater, och ett stats kontrakt tillämpas endast på transaktioner som innehåller det tillståndet i dess ingångar eller utdata. Detta hänför sig till Cordas ovanlig siktmodell, där transaktioner endast kan ses av deras motparter eller de vars efterföljande transaktioner de påverkar.

Kontrakt och meddelanden

Det andra tillvägagångssättet, som jag kallar ”kontrakt – meddelandemodellen”, används i Hyperledger Fabric och Ethereum. Här kan flera "smarta kontrakt" eller "kedjekoder" skapas på blockchain och var och en har sin egen databas och tillhörande kod. Ett kontrakts databas kan endast modifieras med dess kod, snarare än direkt genom blockchain-transaktioner. Detta designmönster liknar "inkapsling" av kod och data i objektorienterad programmering.

Med den här modellen börjar en blockchain-transaktion som ett meddelande som skickas till ett kontrakt, med några valfria parametrar eller data. Kontraktskoden körs som reaktion på meddelandet och parametrarna och är fri att läsa och skriva sin egen databas som en del av den reaktionen. Kontrakt kan också skicka meddelanden till andra kontrakt, men kan inte komma åt varandras databaser direkt. På språket för relationsdatabaser fungerar kontrakt som verkställas ”Lagrade procedurer”, där all tillgång till databasen sker via någon fördefinierad kod.

Både Fabric och Quorum, en variant på Ethereum, komplicerar den här bilden genom att låta ett nätverk definiera flera "kanaler" eller "privata stater". Målet är att mildra problemet med blockchain-sekretess genom att skapa separata miljöer, som alla är synliga för en viss undergrupp av deltagare. Medan detta låter lovande i teorin är i själva verket kontrakten och data i varje kanal eller privat stat isolerade från de i de andra. Som ett resultat, när det gäller smarta kontrakt, motsvarar dessa miljöer separata blockkedjor.

Exempelregler

Låt oss se hur man implementerar transaktionsreglerna för en finansiell huvudbok med en tillgång med dessa två modeller. Varje rad i vår databas har två kolumner som innehåller ägarens adress och kvantiteten av tillgången som ägs. I input-output-modellen måste transaktioner uppfylla två villkor:

  1. Den totala kvantiteten av tillgångar i transaktionens output måste matcha summan i dess input. Detta hindrar användare från att skapa eller radera pengar godtyckligt.
  2. Varje transaktion måste undertecknas av ägaren till var och en av dess ingångar. Detta hindrar användare från att spendera varandras pengar utan tillstånd.

Sammantaget är dessa två villkor allt som behövs för att skapa ett enkelt men hållbart finansiellt system.

I kontrakt-meddelandemodellen stöder tillgångens kontrakt ett meddelande ”skicka betalning”, som tar tre parametrar: avsändarens adress, mottagarens adress och kvantitet som ska skickas. Som svar utför kontraktet följande fyra steg:

  1. Kontrollera att transaktionen undertecknades av avsändaren.
  2. Kontrollera att avsändaren har tillräckligt med pengar.
  3. Dra av det begärda kvantiteten från avsändarens rad.
  4. Lägg till den kvantiteten i mottagarens rad.

Om någon av kontrollerna i de två första stegen misslyckas avbryts kontraktet och ingen betalning kommer att göras.

Så både input-output och contract-message-modellerna är effektiva sätt att definiera transaktionsregler och hålla en delad databas säker. På en teoretisk nivå kan faktiskt var och en av dessa modeller användas för att simulera den andra. I praktiken beror dock den mest lämpliga modellen på vilken applikation som byggs. Påverkar varje transaktion få eller många uppgifter? Behöver vi kunna garantera transaktionens oberoende? Har varje datadel en tydlig ägare eller finns det någon global stat som ska delas?

Det ligger utanför vårt räckvidd här att utforska hur svaren ska påverka valet mellan dessa två modeller. Men som en allmän riktlinje är det värt att försöka uttrycka sina transaktionsregler i båda formerna när man utvecklar en ny blockchain-applikation och se vilka som passar mer naturligt. Skillnaden kommer att uttrycka sig i termer av: (a) enkel programmering, (b) lagringskrav och genomströmning, och (c) hastighet för konfliktdetektering. Vi kommer att prata mer om den här senaste utgåvan senare.

Inbyggda regler

När det gäller transaktionsregler finns det ett sätt på vilket MultiChain specifikt skiljer sig från Fabric, Ethereum och Corda. Till skillnad från dessa andra plattformar har MultiChain flera inbyggda abstraktioner som ger några grundläggande byggstenar för blockchain-driven applikationer, utan kräver utvecklare att skriva sin egen kod. Dessa abstraktioner täcker tre områden som vanligtvis behövs: (a) dynamiska behörigheter, (b) överförbara tillgångar och (c) datalagring.

Till exempel hanterar MultiChain behörigheter för att ansluta till nätverket, skicka och ta emot transaktioner, skapa tillgångar eller strömmar eller kontrollera behörigheterna för andra användare. Flera fungibla tillgångar kan utfärdas, överföras, pensioneras eller bytas säkert och atomiskt. Valfritt antal "strömmar" kan skapas i en kedja för publicering, indexering och hämtning av on-chain eller off-chain data i JSON, text eller binärt format. Alla transaktionsregler för dessa abstraktioner är tillgängliga direkt.

När du utvecklar en applikation på MultiChain är det möjligt att ignorera denna inbyggda funktionalitet och endast uttrycka transaktionsregler med smarta filter. Smarta filter är dock utformade för att fungera tillsammans med dess inbyggda abstraktioner, genom att deras standardbeteende kan göras begränsad på skräddarsydda sätt. Till exempel kan behörigheten för vissa aktiviteter styras av specifika administratörer, snarare än standardbeteendet där någon administratör kommer att göra. Överföringen av vissa tillgångar kan begränsas med tiden eller kräva ytterligare godkännande över ett visst belopp. Data i en viss ström kan valideras för att säkerställa att den endast består av JSON-strukturer med nödvändiga fält och värden.

I alla dessa fall skapar smarta filter ytterligare krav för att transaktioner ska valideras, men gör det inte ta bort de enkla reglerna som är inbyggda. Detta kan hjälpa till att ta itu med en av de viktigaste utmaningarna i blockchain-applikationer: det faktum att ett fel i någon kedjekod kan leda till katastrofala konsekvenser. Vi har sett oändliga exempel på detta problem i den offentliga Ethereum blockchain, mest känt i Dödsfall av DAO och Paritet multisignatur buggar. Bredare undersökningar har hittat ett stort antal vanliga sårbarheter i Ethereums smarta kontrakt som gör det möjligt för angripare att stjäla eller frysa andra människors medel.

Naturligtvis kan MultiChain-smartfilter också innehålla buggar, men deras konsekvenser är mer begränsade. Till exempel hindrar de inbyggda tillgångsreglerna en användare från att spendera andras pengar eller av misstag låta sina egna pengar försvinna, oavsett vilken annan logik ett smart filter innehåller. Om ett fel hittas i ett smart filter kan det inaktiveras och ersättas med en korrigerad version medan huvudbokens grundläggande integritet skyddas. Filosofiskt sett är MultiChain närmare traditionella databasarkitekturer, där databasplattformen tillhandahåller ett antal inbyggda abstraktioner, såsom kolumner, tabeller, index och begränsningar. Kraftfullare funktioner som triggers och lagrade procedurer kan valfritt kodas av applikationsutvecklare, i de fall de verkligen behövs.

Transaktionsregler Tyg MultiKedja Ethereum Corda
Modell Kontrakt – meddelande Ingång – utgång Kontrakt – meddelande Ingång – utgång
Inbyggda ins Ingen Behörigheter +
tillgångar + strömmar
Ingen Ingen

Determinism

Låt oss gå vidare till nästa del av vår showdown. Oavsett vilket tillvägagångssätt vi väljer uttrycks de anpassade transaktionsreglerna för en blockchain-applikation som datorkod skriven av applikationsutvecklare. Och till skillnad från centraliserade applikationer kommer den här koden att köras mer än en gång och på mer än en plats för varje transaktion. Detta beror på att flera blockchain-noder som tillhör olika deltagare måste verifiera och / eller utföra den transaktionen för sig själva.

Denna upprepade och redundanta kodkörning introducerar ett nytt krav som sällan finns i centraliserade applikationer: determinism. I beräkningssammanhang betyder determinism att en kodkod alltid ger samma svar för samma parametrar, oavsett var och när den körs. Detta är helt avgörande för kod som interagerar med en blockchain, eftersom konsensus mellan noder i den kedjan utan determinism kan brytas ned katastrofalt.

Låt oss se hur detta ser ut i praktiken, först i input-output-modellen. Om två noder har en annan uppfattning om huruvida en transaktion är giltig, kommer en att acceptera ett block som innehåller den transaktionen och den andra inte. Eftersom varje block uttryckligen länkar tillbaka till ett tidigare block, kommer detta att skapa en permanent "gaffel" i nätverket, med en eller flera noder som inte accepterar majoritetsuppfattningen om hela blockchain-innehållet från och med den tiden. Noder i minoritet kommer att stängas av från databasens utvecklande tillstånd och kommer inte längre att kunna använda applikationen effektivt.

Låt oss nu se vad som händer om konsensus går sönder i kontraktsmeddelandemodellen. Om två noder har en annan åsikt om hur ett kontrakt ska svara på ett visst meddelande kan detta leda till skillnad i deras databasers innehåll. Detta kan i sin tur påverka kontraktets svar på framtida meddelanden, inklusive meddelanden som skickas till andra kontrakt. Slutresultatet är en ökande skillnad mellan olika noders syn på databasens tillstånd. ("State root" -fältet i Ethereum-block säkerställer att alla skillnader i kontrakts svar omedelbart leder till en helt katastrofal blockchain-gaffel, snarare än att riskera att förbli dold under en tidsperiod.)

Källor till icke-determinism

Så icke-determinism i blockchain-koden är helt klart ett problem. Men om de grundläggande byggstenarna för beräkning, som aritmetik, är deterministiska, vad har vi då att oroa oss för? Tja, det visar sig, en hel del saker:

  • Det är uppenbarligen slumptalsgeneratorer, eftersom de per definition är utformade för att ge ett annat resultat varje gång.
  • Kontrollerar aktuell tid, eftersom noder inte kommer att behandla transaktioner på exakt samma tid, och i alla fall kan deras klockor vara osynkroniserade. (Det är fortfarande möjligt att implementera tidsberoende regler genom att hänvisa till tidsstämplar i själva blockkedjan.)
  • Fråga efter externa resurser som Internet, diskfiler eller andra program som körs på en dator. Dessa resurser kan inte garanteras att alltid ge samma svar och kan bli otillgängliga.
  • Att köra flera kodbitar i parallella "trådar", eftersom detta leder till ett "rasförhållande" där den ordning i vilken dessa processer slutar inte kan förutsägas.
  • Utföra alla flytande beräkningar som kan ge till och med minutiöst olika svar på olika datorprocessorarkitekturer.

Våra fyra blockchain-plattformar använder flera olika sätt att undvika dessa fallgropar.

Deterministiskt utförande

Låt oss börja med Ethereum, eftersom dess strategi är den mest "rena". Ethereum-kontrakt uttrycks i ett specialformat som kallas "Ethereum bytecode", som körs av Ethereum Virtual Machine ("EVM"). Programmerare skriver inte bytecode direkt utan genererar eller “kompilerar” den från ett JavaScript-liknande programmeringsspråk som heter Solidity. (Andra språk brukade vara tillgängliga men har sedan dess upphört.) Determinism garanteras av det faktum att soliditet och Ethereum-bytkod inte kan koda några icke-deterministiska operationer - så enkelt är det.

MultiChain-filter och Corda-kontrakt väljer ett annat tillvägagångssätt genom att anpassa befintliga programmeringsspråk och runtime-miljöer. MultiChain använder JavaScript som körs på Google V8 motor, som också utgör kärnan i Chrome-webbläsaren och Node.js-plattformen, men med källor till icke-determinism inaktiverade. På samma sätt använder Corda Java eller Kotlin, vilka båda är sammanställda till “Java bytecode” som körs i en Java Virtual Machine (“JVM”). För tillfället använder Corda Oracles standard icke-deterministiska JVM, men arbetet pågår för att integrera en deterministisk version. Under tiden måste Corda-kontraktsutvecklare se till att inte tillåta icke-determinism i sin kod.

Hur jämför Ethereums purism med MultiChain och Cordas evolutionära tillvägagångssätt? Den största fördelen för Ethereum är riskminimering - en inbyggd virtuell maskin är mindre benägna att innehålla en oavsiktlig källa till icke-determinism. Medan någon sådan tillsyn kunde åtgärdas genom en programuppdatering, skulle det vara störande för alla kedjor som hade turen att stöta på den. Ethereums problem är dock att Soliditet och EVM utgör ett litet och framväxande ekosystem i ett bredare sammanhang av programmeringsspråk och runtime-miljöer. Som jämförelse är JavaScript och Java topp två språk på Github, körs på miljarder digitala enheter och har körtider som har optimerats under årtionden. Antagligen är det därför som den offentliga Ethereum-blockchain överväger en övergång till eWASM, en deterministisk gaffel av den framväxande standarden WebAssembly.

Bestämning genom godkännande

När det gäller determinism antar Hyperledger Fabric ett helt annat tillvägagångssätt. I Fabric, när en "klient" -nod vill skicka ett meddelande till någon kedjekod, skickar den först meddelandet till vissa "godkännande" -noder. Var och en av dessa noder kör kedjekoden oberoende och bildar en åsikt om meddelandet effekt på kedjekodens databas. Dessa åsikter skickas tillbaka till klienten tillsammans med en digital signatur som utgör en formell ”godkännande”. Om klienten får tillräckligt med godkännanden av det avsedda resultatet skapar den en transaktion som innehåller dessa godkännanden och sänder den för inkludering i kedjan.

För att garantera determinism har varje kedjekod en ”godkännandepolicy” som definierar exakt vilken nivå av godkännande som krävs för att göra sina transaktioner giltiga. Till exempel kan en kedjekods policy ange att godkännanden krävs från minst hälften av blockkedjans noder. En annan kan kräva godkännande från någon av tre pålitliga parter. Hursomhelst kan varje nod oberoende kontrollera om nödvändiga godkännanden mottogs.

För att klargöra skillnaden är determinism i de flesta blockchain-plattformar baserad på frågan: "Vad är resultatet av att köra den här koden på dessa data?" - och vi måste vara helt säkra på att varje nod kommer att besvara denna fråga identiskt. Däremot bygger determinism i Fabric på en annan fråga: "Håller tillräckligt många godkännare om resultatet av att koden körs på denna information?" Att svara på det är en ganska enkel fråga om att räkna, och det finns inget utrymme för icke-determinism att krypa in.

Fabric's determinism-by-endorsement har ett antal intressanta konsekvenser. Först kan kedjekod skrivas på många olika programmeringsspråk, eftersom dessa inte behöver anpassas för determinism (Go, Java och JavaScript stöds för närvarande). För det andra kan kedjekod döljas från några av en blockchains deltagare, eftersom den bara behöver köras av klienter och godkännare (själva databasen är synlig globalt). Slutligen och framför allt kan tygkedjekod göra saker som är förbjudna i andra blockchain-miljöer, som att kontrollera vädret med ett webb-API. I värsta fall, där varje godkännare får ett annat svar från detta API, kommer klienten inte att få tillräckligt med godkännanden för ett visst resultat och ingen transaktion kommer att ske. (Det bör noteras att Fabric-teammedlemmar fortfarande rekommenderar använder deterministisk logik inuti kedjekoden för att undvika överraskningar.)

Vilket pris betalar Fabric för denna flexibilitet? Om syftet med en blockchain är att ta bort mellanhänder från en delad databasdriven applikation, tar Fabrics beroende av godkännare ett stort steg bort från det målet. För deltagarna i kedjan räcker det inte längre att följa kedjekodens regler - de behöver också vissa andra noder för att komma överens om att de har gjort det. Ännu värre, en skadlig delmängd av godkännare kan godkänna databasändringar som inte följer kedjekoden alls. Detta ger godkännare mycket mer kraft än validatorer i vanliga blockkedjor, som kan censurera transaktioner men inte kan bryta mot blockchains regler. Blockchain-applikationsutvecklare måste avgöra om denna avvägning är meningsfull i deras specifika fall.

Determinism Tyg MultiKedja Ethereum Corda
Modell påskrifter Anpassad körtid Syftebyggd virtuell dator Anpassad körtid
Språk Gå + Java + JavaScript JavaScript soliditet Java + Kotlin
Kodsynlighet Motparter +
godkännare
Blockchain Blockchain Motparter +
anhöriga
verk Nej Ja Ja Nej (för tillfället)

Konfliktförebyggande

Hittills har vi diskuterat hur olika blockchain-plattformar uttrycker transaktionsregler i kod och hur de bestämt ser till att varje nod tillämpar dessa regler identiskt. Nu är det dags att prata om en tredje aspekt av vår uppgörelse: Hur hanterar varje plattform möjligheten att två transaktioner, som är giltiga i och för sig, strider mot varandra? I det enklaste exemplet kan du tänka dig att Alice har $ 10 i en finansbok och sänder två transaktioner - en skickar $ 8 till Bob och den andra skickar $ 7 till Charlie. Det är uppenbart att endast en av dessa transaktioner kan tillåtas lyckas.

Två modeller

Vi kan börja med att gruppera MultiChains och Cordas strategi för detta problem. Som beskrivits tidigare använder båda dessa en input-output-modell för att representera transaktioner och deras regler, där varje transaktionsingång spenderar en tidigare transaktionsoutput. Detta leder till en enkel princip för att förebygga konflikter: Varje produktion kan bara spenderas en gång. MultiChain-filter och Corda-kontrakt kan förlita sig på deras respektive plattformar för att genomföra denna begränsning absolut. Eftersom Alice $ 10 representeras av en tidigare transaktionsoutput, stoppar den här regeln för att automatiskt spendera henne automatiskt att skicka den till både Bob och Charlie.

Trots denna likhet är det viktigt att påpeka en viktig skillnad i hur MultiChain och Corda förhindrar konflikter. I MultiChain ser varje nod alla transaktioner och kan så självständigt verifiera att varje utmatning bara spenderas en gång. Alla transaktioner som utför dubbla utgifter mot en tidigare bekräftad transaktion avvisas omedelbart och automatiskt. Däremot finns det ingen global blockchain i Corda, så "notarier" krävs för att förhindra dessa dubbla utgifter. Varje Corda-utgångstillstånd tilldelas en notarie, som måste underteckna alla transaktionsutgifter som utdata, vilket bekräftar att det inte har använts tidigare. En blockchains deltagare måste lita på att notarier följer denna regel ärligt, och skadliga notarier kan orsaka kaos efter behag. Som med påståenden i tyg, detta “engångsutgifter som en tjänst”Design har fördelar när det gäller konfidentialitet men återinför mellanhänder och går emot blockchain-spannmålen. (Det är viktigt att klargöra att Corda-notarier kan drivas av deltagargrupper som använder en konsensusalgoritm, så att redovisningens integritet fortfarande kan skyddas mot individuella dåliga aktörer).

Låt oss gå vidare till Ethereum. För att komma ihåg använder Ethereum kontrakt och meddelanden snarare än in- och utdata. Som ett resultat är transaktionskonflikter som Alice's två betalningar inte direkt synliga för blockchain-motorn. Istället upptäcks och blockeras de av kontrakt som behandlar transaktionerna, efter att deras order har bekräftats i kedjan. Vid behandlingen av var och en av Alice betalningar verifierar kontraktet om hennes saldo är tillräcklig. Om transaktionen som betalar 8 $ till Bob kommer först kommer den att behandlas som vanligt, vilket ger Alice 2 $ på sitt konto. Som ett resultat, när kontraktet behandlar den andra transaktionen som betalar 7 dollar till Charlie, ser den att Alice saknar nödvändiga medel och transaktionen avbryts.

Outputs kontra kontrakt

Hittills har vi sett två olika tekniker för att förhindra motstridiga transaktioner - output för engångsutgifter i MultiChain och Corda och kontraktsbaserad verifiering i Ethereum. Så vilken är bättre?

För att hjälpa till att svara på den här frågan, låt oss överväga ett exempel på ett “1-av-2 multisignatur” -konto som innehar $ 100 på uppdrag av Gavin och Helen och tillåter någon av dem att spendera pengarna självständigt. Gavin instruerar sin ansökan om att betala 80 dollar till Donna, och några sekunder senare vill Helen skicka 40 dollar till Edward. Eftersom det inte finns tillräckligt med medel för båda betalningarna skulle dessa transaktioner oundvikligen komma i konflikt. I händelse av att båda transaktionerna sänds bestäms resultatet av det som gör det först i kedjan. Observera att denna konflikt till skillnad från Alice oavsiktligt, eftersom ingen försöker bryta programmets regler - de hade helt enkelt oturstid.

När man överväger sannolikheten för att denna konflikt ska inträffa är nyckelfrågan denna: När Gavin skickar ut sin transaktion, hur lång tid tar det Helenas nod att veta att hennes betalning kanske misslyckas? Ju kortare denna period är, desto mer sannolikt kommer Helen att hindras från att försöka den betalningen, vilket sparar henne och hennes ansökan från en efterföljande överraskning.

Med input-output-modellen är alla konflikter mellan transaktioner direkt synliga för blockchain-plattformen, eftersom de två transaktionerna uttryckligen försöker spendera samma tidigare output. I MultiChain händer detta så snart Gavins transaktion har spridit sig till Helens nod, vanligtvis på en sekund eller mindre. I Corda kommer produktionens notarie att vägra begäran om att underteckna Helens transaktion, eftersom den redan har undertecknat Gavins, så Helen kommer omedelbart att veta att hennes betalning misslyckas. (Även om Corda-notarie själv distribueras kan hon behöva vänta några sekunder på ett svar.) Hur som helst behöver du inte vänta på att en transaktion ska bekräftas och beställas i blockchain.

Vad sägs om Ethereums modell? I det här fallet finns det inget omedelbart sätt för blockchain-plattformen att veta att en konflikt kommer att inträffa. Helens nod kanske ser Gavins transaktion i nätverket, men den kan inte veta hur detta kommer att påverka Helens egen transaktion, eftersom det ur sitt perspektiv helt enkelt är två meddelanden som skickas till samma kontrakt. Kanske tio sekunder senare, när den slutliga beställningen av de motstridiga transaktionerna har bekräftats på blockchain, kommer Helens nod att räkna om det faktiska istället för det förväntade resultatet, och hennes applikation kommer att uppdatera dess skärm i enlighet med detta. Under tiden kommer både Gavin och Helen att lämnas i mörkret.

Men vi bör inte dra slutsatsen att input-output-modellen alltid fungerar bäst. Tänk på en variant på vårt exempelscenario, där både Gavin och Helen begär mindre $ 40-betalningar från det ursprungliga saldot på $ 100, exakt samtidigt. I input-output-modellen skulle dessa transaktioner komma i konflikt, eftersom de båda spenderar samma databaserad som innehåller de $ 100, och endast en av betalningarna skulle lyckas. Men i Ethereum skulle båda transaktionerna behandlas framgångsrikt, oavsett deras slutliga order, eftersom kontot innehåller tillräckligt med pengar för båda. I det här fallet uppfyller Ethereum troget Gavins och Helens avsikter.

Läs-skriv uppsättningar

Slutligen, låt oss prata om Fabric, vars godkännandebaserade tillvägagångssätt är en hybrid av dessa två tekniker. Som förklarats tidigare, när en "klient" -nod för Fabric vill skicka ett meddelande till ett kontrakt, ber den först några godkännande noder att köra meddelandet för dess räkning. De godkännande noder gör det på ett liknande sätt som Ethereum - kör kontraktet mot sin lokala databas - men denna process observeras snarare än omedelbart tillämpas. Varje godkännare registrerar den uppsättning rader som ska läsas och skrivas och noterar också den exakta versionen av dessa rader vid den tidpunkten. Denna "läs-skrivuppsättning" av versionerade rader hänvisas uttryckligen till godkännandet och ingår i transaktionen som klienten sänder.

Konflikter mellan Fabric-transaktioner löses när deras order har slutförts i kedjan. Varje nod behandlar varje transaktion oberoende, kontrollerar godkännandepolicyer och använder de angivna databasändringarna. Men om en transaktion läser eller skriver en databasradversion som redan har modifierats av en tidigare transaktion ignoreras den andra transaktionen. För att gå tillbaka till Alice motstridiga betalningar till Bob och Charlie kommer båda dessa transaktioner att läsa och ändra samma radversion, som innehåller $ 10 som Alice startade med. Så den andra transaktionen avbryts säkert och automatiskt.

Fabrics strategi för konfliktlösning fungerar bra, men när det gäller prestanda och flexibilitet kombinerar den det värsta av de tidigare två modellerna. Eftersom påståenden omvandlar transaktioner till specifika läs-skrivuppsättningar skulle Gavin och Helens samtidiga men kompatibla $ 40-betalningar leda till en konflikt som Ethereum undviker. Fabric får dock inte hastighetsfördelen med input-output-modellen, eftersom godkännare utför kontrakt mot den senaste versionen av databasen som bekräftats av blockchain och ignorerar obekräftade transaktioner. Så om Helen initierar sin betalning några sekunder efter Gavin, men innan Gavins har bekräftats på blockchain, kommer Fabric att skapa motstridiga transaktioner som en ren input-output-modell undviker.

Konfliktförebyggande Tyg MultiKedja Ethereum Corda
Modell Läs-skriv uppsättningar Enkelt spendera Kontraktskontroller Enkelt spendera
Verifiering Oberoende Oberoende Oberoende Betrodda notarier
Fart ~ 10s (bekräftelse) ~ 1s (förökning) ~ 10s (bekräftelse) 0 ~ 5s (notarie)

Ett komplext val

I det här stycket granskade vi många av de olika sätten på vilka Corda, Ethereum, Fabric och MultiChain hanterar de viktigaste utmaningarna med "smarta kontrakt" eller applikationskod som är inbäddad i en blockchain. Och varje plattform har olika svar på våra tre kärnfrågor: Hur representeras transaktionsregler? Hur körs kod deterministiskt? Och hur förhindrar vi konflikter?

Så vem är vinnaren av vårt smarta kontrakt? Det borde vara uppenbart nu att det inte finns något enkelt svar. Varje plattform representerar en komplex mångvägsavvägning mellan flexibilitet, enkelhet, prestanda, avbrott, säkerhet och konfidentialitet. Så valet av plattform för en viss applikation måste börja med en detaljerad förståelse av applikationens förtroendemodell, vilka typer av transaktioner det innebär och deras troliga konfliktmönster. Om du hittar någon som driver en specifik smart kontraktslösning innan de känner till svaren på dessa frågor, föreslår jag artigt men bestämt att de använder sig av en ”smartare” strategi.

Skicka eventuella kommentarer på Link.

Tidsstämpel:

Mer från Multikedja