Smart kontrakt showdown: Hyperledger Fabric vs MultiChain vs Ethereum vs Corda

Kilde node: 1585333

Det er mer enn en måte å sette kode på en blockchain

I de fleste diskusjoner om blokkjeder tar det ikke lang tid før begrepet "smarte kontrakter" kommer opp. I den populære fantasien automatiserer smarte kontrakter utførelsen av interpartinteraksjoner, uten at det kreves en pålitelig mellommann. Ved å uttrykke juridiske forhold i kode i stedet for ord, lover de å gjøre det mulig for transaksjoner å foregå direkte og uten feil, enten det er bevisst eller ikke.

Fra et teknisk synspunkt er en smart kontrakt noe mer spesifikt: datakode som lever på en blokkjede og definerer reglene for den kjedens transaksjoner. Denne beskrivelsen høres enkel nok ut, men bak den ligger det en stor variasjon i hvordan disse reglene uttrykkes, utføres og valideres. Når du velger en blokkjedeplattform for en ny applikasjon, er spørsmålet "Støtter denne plattformen smarte kontrakter?" er ikke den rette å spørre. I stedet må vi spørre: "Hvilken type smarte kontrakter støtter denne plattformen?"

I denne artikkelen er målet mitt å undersøke noen av de store forskjellene mellom smarte kontrakttilnærminger og avveiningene de representerer. Jeg gjør dette ved å se på fire populære blockchain-plattformer for bedrifter som støtter en eller annen form for tilpasset on-chain-kode. Først IBMs Hyperledger Fabric, som kaller sine kontrakter "chaincode". For det andre, vår MultiChain-plattform, som introduserer smarte filtre i versjon 2.0. Tredje, Ethereum (og det er tillatt quorum og Burrow spin-offs), som populariserte navnet "smart kontrakt". Og endelig, R3 Corda, som refererer til "kontrakter" i sine transaksjoner. Til tross for alle de forskjellige terminologiene, henviser til slutt alle disse til det samme - applikasjonsspesifikk kode som definerer reglene til en kjede.

Før jeg går videre, bør jeg advare leseren om at mye av følgende innhold er av teknisk karakter, og forutsetter litt kjennskap til generelle programmerings- og databasekonsepter. På godt og vondt kan dette ikke unngås - uten å komme inn i detaljene er det umulig å ta en informert beslutning om å bruke en blockchain for et bestemt prosjekt, og (i så fall) riktig type blockchain å bruke.

Grunnleggende om blockchain

La oss begynne med litt sammenheng. Se for deg et program som deles av flere organisasjoner, som er basert på en underliggende database. I en tradisjonell sentralisert arkitektur er denne databasen vert og administrert av en enkelt part som alle deltakerne stoler på, selv om de ikke stoler på hverandre. Transaksjoner som endrer databasen, initieres bare av applikasjoner på denne sentrale partens systemer, ofte som svar på meldinger mottatt fra deltakerne. Databasen gjør rett og slett det den blir fortalt fordi applikasjonen er implisitt klarert for å bare sende den transaksjoner som gir mening.

Blokkjeder gir en alternativ måte å administrere en delt database på, uten en klarert mellommann. I en blockchain kjører hver deltaker en "node" som har en kopi av databasen og uavhengig behandler transaksjonene som endrer den. Deltakere identifiseres ved hjelp av offentlige nøkler eller “adresser”, som hver har en tilsvarende privat nøkkel som bare er kjent for identitetseieren. Selv om transaksjoner kan opprettes av en hvilken som helst node, blir de "digitalt signert" av initiativtakerens private nøkkel for å bevise opprinnelsen.

Noder kobler seg til hverandre på en peer-to-peer-måte, og sprer raskt transaksjoner og "blokkene" der de er tidsstemplet og bekreftet over hele nettverket. Blockchain i seg selv er bokstavelig talt en kjede av disse blokkene, som danner en ordnet logg over alle historiske transaksjoner. En “konsensusalgoritme” brukes for å sikre at alle noder blir enige om innholdet i blockchain, uten å kreve sentralisert kontroll. (Merk at noe av denne beskrivelsen ikke gjelder Corda, der hver node bare har en delvis kopi av databasen og det ikke er noen global blockchain. Vi snakker mer om det senere.)

I prinsippet kan enhver delt databaseapplikasjon arkiveres ved å bruke en blockchain i kjernen. Men å gjøre det skaper en rekke tekniske utfordringer som ikke eksisterer i et sentralisert scenario:

  • Transaksjonsregler. Hvis noen deltakere kan endre databasen direkte, hvordan kan vi sikre at de følger programmets regler? Hva hindrer en bruker i å ødelegge innholdet i databasen på en selvbetjent måte?
  • determinisme. Når disse reglene er definert, vil de bli brukt flere ganger av flere noder når de behandler transaksjoner for sin egen kopi av databasen. Hvordan sikrer vi at hver node oppnår nøyaktig samme resultat?
  • Konfliktforebygging. Uten sentral koordinering, hvordan håndterer vi to transaksjoner som hver følger programmets regler, men likevel er i konflikt med hverandre? Konflikter kan stamme fra et bevisst forsøk på å spille systemet, eller være det uskyldige resultatet av uflaks og timing.

Så hvor kommer smarte kontrakter, smarte filtre og kjedekode inn? Deres hovedformål er å jobbe med en blockchain underliggende infrastruktur for å løse disse utfordringene. Smarte kontrakter er den desentraliserte ekvivalenten av applikasjonskode - i stedet for å kjøre på ett sentralt sted, kjører de på flere noder i blockchain, og oppretter eller validerer transaksjonene som endrer databasens innhold.

La oss begynne med transaksjonsregler, den første av disse utfordringene, og se hvordan de kommer til uttrykk i henholdsvis Fabric, MultiChain, Ethereum og Corda.

Transaksjonsregler

Transaksjonsregler utfører en bestemt funksjon i blockchain-drevne databaser - begrenser transformasjoner som kan utføres på databasens tilstand. Dette er nødvendig fordi en blockchain-transaksjoner kan igangsettes av noen av deltakerne, og disse deltakerne stoler ikke på hverandre tilstrekkelig til at de kan endre databasen etter eget ønske.

La oss se to eksempler på hvorfor det er behov for transaksjonsregler. Tenk deg først en blokkjede designet for å samle og tidsstempel PDF-dokumenter som blir publisert av deltakerne. I dette tilfellet skal ingen ha rett til å fjerne eller endre dokumenter, siden dette ville undergrave hele formålet med systemet - dokumentets utholdenhet. For det andre, vurder en blockchain som representerer en delt finansiell hovedbok, som holder rede på saldoen til brukerne. Vi kan ikke la en deltaker vilkårlig oppblåse sin egen saldo, eller ta andres penger bort.

Innganger og utganger

Våre blockchain-plattformer er avhengige av to brede tilnærminger for å uttrykke transaksjonsregler. Den første, som jeg kaller “input-output model”, brukes i MultiChain og Corda. Her viser transaksjoner eksplisitt databaserader eller "stater" som de sletter og oppretter, og danner et sett med henholdsvis "innganger" og "utdata". Endring av en rad uttrykkes som den tilsvarende operasjonen for å slette den raden og opprette en ny i stedet.

Siden databaserader bare slettes i innganger og bare opprettes i utganger, må hver inngang "bruke" en tidligere transaksjon. Den nåværende tilstanden til databasen er definert som settet med "ubrukte transaksjonsutganger" eller "UTXOer", dvs. utdata fra tidligere transaksjoner som ennå ikke er brukt. Transaksjoner kan også inneholde tilleggsinformasjon, kalt "metadata", "kommandoer" eller "vedlegg", som ikke blir en del av databasen, men som hjelper til med å definere deres betydning eller formål.

Gitt disse tre settene med innganger, utganger og metadata, er gyldigheten av en transaksjon i MultiChain eller Corda definert av noen kode som kan utføre vilkårlige beregninger på disse settene. Denne koden kan validere transaksjonen, eller ellers returnere en feil med en tilsvarende forklaring. Du kan tenke på input-output-modellen som en automatisert “inspektør” som holder en sjekkliste som sikrer at transaksjoner følger hver eneste regel. Hvis transaksjonen mislykkes med en av disse kontrollene, vil den automatisk bli avvist av alle nodene i nettverket.

Det skal bemerkes at til tross for at de deler input-output-modellen, implementerer MultiChain og Corda det veldig annerledes. I MultiChain kan utganger inneholde eiendeler og / eller data i JSON, tekst eller binært format. Reglene er definert i “transaksjonsfiltre” eller “strømfilter”, som kan settes til å kontrollere alle transaksjoner, eller bare de som involverer bestemte eiendeler eller grupperinger av data. I motsetning til dette er en Corda-utgangsstatus representert av et objekt i programmeringsspråket Java eller Kotlin, med definerte datafelter. Cordas regler er definert i “kontrakter” som er knyttet til spesifikke stater, og en stats kontrakt gjelder bare for transaksjoner som inneholder denne tilstanden i sine innganger eller utganger. Dette er relatert til Cordas uvanlig siktmodell, der transaksjoner bare kan sees av motparter eller de hvis etterfølgende transaksjoner de påvirker.

Kontrakter og meldinger

Den andre tilnærmingen, som jeg kaller “kontrakt – meldingsmodellen”, brukes i Hyperledger Fabric og Ethereum. Her kan flere "smarte kontrakter" eller "kjedekoder" opprettes på blockchain, og hver har sin egen database og tilhørende kode. En kontrakts database kan bare endres med koden, i stedet for direkte ved blockchain-transaksjoner. Dette designmønsteret ligner på "innkapsling" av kode og data i objektorientert programmering.

Med denne modellen begynner en blockchain-transaksjon som en melding sendt til en kontrakt, med noen valgfrie parametere eller data. Kontraktskoden utføres som reaksjon på meldingen og parametrene, og er fri til å lese og skrive sin egen database som en del av den reaksjonen. Kontrakter kan også sende meldinger til andre kontrakter, men får ikke tilgang til hverandres databaser direkte. På språket til relasjonsdatabaser fungerer kontrakter som håndheves “Lagrede prosedyrer”, der all tilgang til databasen går via en forhåndsdefinert kode.

Både Fabric og Quorum, en variant av Ethereum, kompliserer dette bildet ved å la et nettverk definere flere “kanaler” eller “private stater”. Målet er å redusere problemet med blockchain-konfidensialitet ved å opprette separate miljøer, som hver kun er synlig for en bestemt undergruppe av deltakere. Selv om dette i teorien høres lovende ut, er i virkeligheten kontraktene og dataene i hver kanal eller privatstat isolert fra de i de andre. Som et resultat, når det gjelder smarte kontrakter, tilsvarer disse miljøene separate blokkeringer.

Eksempelregler

La oss se hvordan vi implementerer transaksjonsreglene for en finansregnskap med en eiendel med disse to modellene. Hver rad i databasen vår har to kolonner, som inneholder eierens adresse og mengden av eiendelen som eies. I input-output-modellen må transaksjoner oppfylle to betingelser:

  1. Den totale mengden eiendeler i utgangen av en transaksjon må samsvare med totalen i inngangene. Dette forhindrer brukere i å opprette eller slette penger vilkårlig.
  2. Hver transaksjon må signeres av eieren av hver av inngangene. Dette hindrer brukerne i å bruke hverandres penger uten tillatelse.

Til sammen er disse to forholdene alt som trengs for å skape et enkelt, men levedyktig finanssystem.

I kontraktsmeldingsmodellen støtter eiendelens kontrakt en "send betaling" -melding, som tar tre parametere: avsenderens adresse, mottakerens adresse og antall som skal sendes. Som svar utfører kontrakten følgende fire trinn:

  1. Bekreft at transaksjonen ble signert av avsenderen.
  2. Sjekk at avsenderen har tilstrekkelige midler.
  3. Trekk ønsket mengde fra avsenderens rad.
  4. Legg til det antallet i mottakerens rad.

Hvis en av kontrollene i de to første trinnene mislykkes, avbrytes kontrakten og ingen betaling vil bli utført.

Så både input-output og contract-message-modeller er effektive måter å definere transaksjonsregler og holde en delt database trygg. Faktisk, på et teoretisk nivå, kan hver av disse modellene brukes til å simulere den andre. I praksis vil imidlertid den mest passende modellen avhenge av applikasjonen som bygges. Påvirker hver transaksjon få eller mange opplysninger? Trenger vi å kunne garantere uavhengighet av transaksjoner? Har hvert stykke data en klar eier, eller er det noen global tilstand som skal deles?

Det ligger utenfor vårt omfang her å utforske hvordan svarene skal påvirke valget mellom disse to modellene. Men som en generell retningslinje, når du utvikler en ny blockchain-applikasjon, er det verdt å prøve å uttrykke transaksjonsreglene i begge former, og se hvilke som passer mer naturlig. Forskjellen vil uttrykke seg i form av: (a) enkel programmering, (b) lagringskrav og gjennomstrømning, og (c) hastighet på konfliktdeteksjon. Vi snakker mer om dette siste nummeret senere.

Innebygde regler

Når det gjelder transaksjonsregler, er det en måte som MultiChain spesifikt skiller seg fra Fabric, Ethereum og Corda. I motsetning til disse andre plattformene har MultiChain flere innebygde abstraksjoner som gir noen grunnleggende byggesteiner for blockchain-drevne applikasjoner, uten krever utviklere for å skrive sin egen kode. Disse abstraksjonene dekker tre områder som ofte er nødvendige: (a) dynamiske tillatelser, (b) overførbare eiendeler og (c) datalagring.

For eksempel administrerer MultiChain tillatelser for å koble til nettverket, sende og motta transaksjoner, opprette eiendeler eller strømmer, eller kontrollere tillatelsene til andre brukere. Flere fungible eiendeler kan utstedes, overføres, pensjoneres eller byttes trygt og atomisk. Et hvilket som helst antall "strømmer" kan opprettes i en kjede for publisering, indeksering og henting av data i kjeden eller utenfor kjeden i JSON, tekst eller binære formater. Alle transaksjonsreglene for disse abstraksjonene er tilgjengelige utenom boksen.

Når du utvikler et program på MultiChain, er det mulig å ignorere denne innebygde funksjonaliteten, og kun uttrykke transaksjonsregler ved hjelp av smarte filtre. Imidlertid er smarte filtre designet for å fungere sammen med den innebygde abstraksjonen, ved å gjøre det mulig for deres standard atferd begrenset på tilpassede måter. For eksempel kan tillatelsen for visse aktiviteter kontrolleres av spesifikke administratorer, i stedet for standardadferden der en administrator vil gjøre. Overføring av visse eiendeler kan være tidsbegrenset eller kreve ytterligere godkjenning over et visst beløp. Dataene i en bestemt strøm kan valideres for å sikre at de bare består av JSON-strukturer med nødvendige felt og verdier.

I alle disse tilfellene skaper smarte filtre tilleggskrav for transaksjoner som skal valideres, men gjør det ikke fjerne de enkle reglene som er innebygd. Dette kan hjelpe til med å løse en av de viktigste utfordringene i blockchain-applikasjoner: det faktum at en feil i noen on-chain-koder kan føre til katastrofale konsekvenser. Vi har sett uendelige eksempler på dette problemet i den offentlige Ethereum blockchain, mest kjent i Avgang av DAO og Paritets multisignatur bugs. Bredere undersøkelser har funnet et stort antall vanlige sårbarheter i Ethereum-smarte kontrakter som gjør det mulig for angripere å stjele eller fryse andre folks midler.

Selvfølgelig kan MultiChain-smarte filtre også inneholde feil, men konsekvensene av dem er mer begrenset. For eksempel forhindrer de innebygde aktiva-reglene en bruker fra å bruke andres penger, eller ved et uhell få sine egne penger til å forsvinne, uansett hvilken annen logikk et smart filter inneholder. Hvis en feil blir funnet i et smart filter, kan den deaktiveres og erstattes med en korrigert versjon, mens hovedbokens grunnleggende integritet er beskyttet. Filosofisk sett er MultiChain nærmere tradisjonelle databasearkitekturer, der databaseplattformen gir en rekke innebygde abstraksjoner, som kolonner, tabeller, indekser og begrensninger. Kraftigere funksjoner som utløsere og lagrede prosedyrer kan valgfritt kodes opp av applikasjonsutviklere, i tilfeller der det faktisk er behov for dem.

Transaksjonsregler Stoff multikate Ethereum Corda
Modell Kontraktsmelding Inngang – utgang Kontraktsmelding Inngang – utgang
Innebygde none Tillatelser +
eiendeler + strømmer
none none

determinisme

La oss gå videre til neste del av oppgjøret. Uansett hvilken tilnærming vi velger, blir de tilpassede transaksjonsreglene for en blockchain-applikasjon uttrykt som datakode skrevet av applikasjonsutviklere. Og i motsetning til sentraliserte applikasjoner, vil denne koden kjøres mer enn én gang og mer enn ett sted for hver transaksjon. Dette er fordi flere blockchain-noder som tilhører forskjellige deltakere, må hver verifisere og / eller utføre transaksjonen for seg selv.

Denne gjentatte og overflødige kodeutførelsen introduserer et nytt krav som sjelden finnes i sentraliserte applikasjoner: determinisme. I sammenheng med beregning betyr determinisme at et stykke kode alltid vil gi det samme svaret for de samme parametrene, uansett hvor og når det kjøres. Dette er helt avgjørende for kode som samhandler med en blockchain fordi konsensus mellom nodene i den kjeden, uten determinisme, kan bryte ned katastrofalt.

La oss se hvordan dette ser ut i praksis, først i input-output-modellen. Hvis to noder har en annen oppfatning av om en transaksjon er gyldig, vil den ene akseptere en blokk som inneholder den transaksjonen, og den andre ikke. Siden hver blokk eksplisitt lenker tilbake til en forrige blokk, vil dette skape en permanent "fork" i nettverket, med en eller flere noder som ikke aksepterer flertallets mening om hele blockchain-innholdet fra det tidspunktet. Nodene i mindretall vil bli avskåret fra databasens utviklingstilstand, og vil ikke lenger kunne bruke applikasjonen effektivt.

La oss nå se hva som skjer hvis konsensus bryter sammen i kontraktsmeldingsmodellen. Hvis to noder har en annen oppfatning om hvordan en kontrakt skal svare på en bestemt melding, kan dette føre til en forskjell i databasenes innhold. Dette kan igjen påvirke kontraktsresponsen på fremtidige meldinger, inkludert meldinger den sender til andre kontrakter. Sluttresultatet er en økende avvik mellom forskjellige nodes syn på databasens tilstand. ("State root" -feltet i Ethereum-blokker sørger for at enhver forskjell i kontraktenes svar umiddelbart fører til en fullstendig katastrofal blockchain-gaffel, i stedet for å risikere å bli skjult i en periode.)

Kilder til ikke-determinisme

Så ikke-determinisme i blockchain-kode er helt klart et problem. Men hvis de grunnleggende byggesteinene i beregningen, for eksempel aritmetikk, er deterministiske, hva har vi å bekymre oss for? Vel, det viser seg, ganske mange ting:

  • Mest åpenbart tilfeldige tallgeneratorer, siden disse per definisjon er designet for å gi et annet resultat hver gang.
  • Kontrollerer gjeldende tid, siden noder ikke behandler transaksjoner på nøyaktig samme tid, og i alle fall kan klokkene deres være ute av synkronisering. (Det er fortsatt mulig å implementere tidsavhengige regler ved å henvise til tidsstempler i selve blokkjeden.)
  • Spørring av eksterne ressurser som Internett, diskfiler eller andre programmer som kjører på en datamaskin. Disse ressursene kan ikke garanteres å alltid gi den samme responsen, og kan bli utilgjengelige.
  • Å kjøre flere kodestykker i parallelle "tråder", siden dette fører til en "løpstilstand" der rekkefølgen som disse prosessene avsluttes ikke kan forutsies.
  • Gjennomføring av flytende punktberegninger som kan gi enda forskjellige svar på forskjellige dataprosessorarkitekturer.

Våre fire blockchain-plattformer benytter flere forskjellige tilnærminger for å unngå disse fallgruvene.

Deterministisk henrettelse

La oss starte med Ethereum, siden tilnærmingen er den mest "rene". Ethereum-kontrakter uttrykkes i et spesialformat kalt “Ethereum bytecode”, som blir utført av Ethereum Virtual Machine (“EVM”). Programmerere skriver ikke bytekode direkte, men genererer eller “kompilerer” den fra et JavaScript-lignende programmeringsspråk kalt Solidity. (Andre språk pleide å være tilgjengelige, men har siden blitt utfaset.) Determinisme garanteres av det faktum at soliditet og Ethereum-bytekode ikke kan kode for ikke-deterministiske operasjoner - det er så enkelt.

MultiChain-filtre og Corda-kontrakter velger en annen tilnærming ved å tilpasse eksisterende programmeringsspråk og kjøretidsmiljøer. MultiChain bruker JavaScript som kjører på Google V8 motor, som også utgjør kjernen i Chrome-nettleseren og Node.js-plattformen, men med kilder til ikke-determinisme deaktivert. På samme måte bruker Corda Java eller Kotlin, som begge er samlet til “Java bytecode” som kjøres i en Java Virtual Machine (“JVM”). Foreløpig bruker Corda Oracles standard ikke-deterministiske JVM, men arbeidet pågår for å integrere en deterministisk versjon. I mellomtiden må Corda-kontraktutviklere passe på å ikke tillate ikke-determinisme i koden sin.

Hvordan sammenlignes Ethereums purisme med den evolusjonære tilnærmingen som benyttes av MultiChain og Corda? Den største fordelen for Ethereum er risikominimering - en innebygd virtuell maskin er mindre sannsynlig å inneholde en utilsiktet kilde til ikke-determinisme. Selv om noe slikt tilsyn kunne løses ved en programvareoppdatering, ville det være forstyrrende for enhver kjede som var uheldig nok til å møte den. Ethereums problem er imidlertid at Solidity og EVM utgjør et lite og begynnende økosystem i den bredere sammenheng med programmeringsspråk og kjøretidsmiljøer. Til sammenligning er JavaScript og Java topp to språk på Github, kjøres på milliarder av digitale enheter, og har kjøretider som har blitt optimalisert gjennom flere tiår. Antagelig er det derfor den offentlige Ethereum-blockchain vurderer en overgang til eWASM, en deterministisk gaffel av den nye WebAssembly-standarden.

Determinisme ved tilslutning

Når det gjelder determinisme, bruker Hyperledger Fabric en helt annen tilnærming. I Fabric, når en “klient” -node vil sende en melding til en eller annen kjedekode, sender den først meldingen til noen “godkjenningsnoder”. Hver av disse nodene utfører kjedekoden uavhengig, og danner en mening om meldingen effekt på kjedekodens database. Disse meningene sendes tilbake til klienten sammen med en digital signatur som utgjør en formell “godkjenning”. Hvis klienten mottar nok påtegninger om det tiltenkte utfallet, oppretter den en transaksjon som inneholder påtegningene, og sender den for inkludering i kjeden.

For å garantere determinisme har hver del av kjedekoden en "godkjennelsespolicy" som definerer nøyaktig hvilket godkjenningsnivå som kreves for å gjøre transaksjonene gyldige. For eksempel kan en kjedekodes policy si at påtegninger kreves fra minst halvparten av blockchain-noder. En annen kan kreve godkjenning fra en av tre pålitelige parter. Uansett kan hver node uavhengig sjekke om de nødvendige anbefalingene ble mottatt.

For å avklare forskjellen, er determinisme i de fleste blockchain-plattformer basert på spørsmålet: "Hva er resultatet av å kjøre denne koden på disse dataene?" - og vi må være helt sikre på at hver node vil svare på dette spørsmålet identisk. Derimot er determinisme i Fabric basert på et annet spørsmål: "Er nok godkjennere enige om resultatet av å kjøre denne koden på disse dataene?" Å svare på det er et ganske enkelt spørsmål om å telle, og det er ikke rom for ikke-determinisme å krype inn.

Fabric's determinism-by-endorsement har en rekke interessante konsekvenser. For det første kan kjettingskode skrives på mange forskjellige programmeringsspråk, siden disse ikke trenger å tilpasses determinisme (Go, Java og JavaScript støttes for øyeblikket). For det andre kan kjedekode være skjult for noen av deltakerne i en blockchain, siden den bare må utføres av klienter og godkjennere (selve databasen er globalt synlig). Til slutt og spesielt, kan stoffkjedekode gjøre ting som er forbudt i andre blockchain-miljøer, for eksempel å sjekke været ved hjelp av en online web-API. I verste fall, hvor hver godkjenner får et annet svar fra denne API-en, vil klienten ikke oppnå nok påtegninger for et bestemt resultat, og ingen transaksjoner vil finne sted. (Det skal bemerkes at Fabric-teammedlemmer fortsatt anbefaler bruker deterministisk logikk inne i kjettingkoden for å unngå overraskelser.)

Hvilken pris betaler Fabric for denne fleksibiliteten? Hvis formålet med en blockchain er å fjerne mellommenn fra en delt databasestyrt applikasjon, tar Fabrics avhengighet av godkjennere et stort skritt fra det målet. For deltakerne i kjeden er det ikke lenger nok å følge kjedekodens regler - de trenger også visse andre noder for å være enige om at de har gjort det. Enda verre, en ondsinnet delmengde av godkjennere kan godkjenne databaseendringer som ikke følger kjedekoden i det hele tatt. Dette gir godkjennere mye mer kraft enn validatorene i vanlige blokkjeder, som kan sensurere transaksjoner, men som ikke kan bryte blockchain-reglene. Blockchain-applikasjonsutviklere må bestemme om denne avveiningen er fornuftig i deres spesielle tilfelle.

determinisme Stoff multikate Ethereum Corda
Modell påtegninger Tilpasset kjøretid Spesiallaget VM Tilpasset kjøretid
språk Gå + Java + JavaScript Javascript soliditet Java + Kotlin
Kodesynlighet Motparter +
godkjennere
Blockchain Blockchain Motparter +
avhengige
Håndheves Nei Ja Ja Nei (foreløpig)

Konfliktforebygging

Så langt har vi diskutert hvordan forskjellige blockchain-plattformer uttrykker transaksjonsregler i kode, og hvordan de deterministisk sikrer at hver node bruker disse reglene identisk. Nå er det på tide å snakke om et tredje aspekt av oppgjøret vårt: Hvordan håndterer hver plattform muligheten for at to transaksjoner, som er gyldige i seg selv, er i konflikt med hverandre? I det enkleste eksempelet kan du forestille deg at Alice har $ 10 i en finansbok og sender to transaksjoner - den ene sender $ 8 til Bob, og den andre sender $ 7 til Charlie. Det er klart at bare en av disse transaksjonene kan få lov til å lykkes.

To modeller

Vi kan begynne med å gruppere MultiChains og Cordas tilnærming til dette problemet. Som beskrevet tidligere bruker begge disse en input-output-modell for å representere transaksjoner og deres regler, der hver transaksjonsinngang bruker en tidligere transaksjonsoutput. Dette fører til et enkelt prinsipp for å forhindre konflikter: Hver produksjon kan bare brukes en gang. MultiChain-filtre og Corda-kontrakter kan stole på deres respektive plattformer for å håndheve denne begrensningen absolutt. Siden Alice's $ 10 er representert av en tidligere transaksjonsoutput, stopper denne engangsregelen henne automatisk med å sende den til både Bob og Charlie.

Til tross for denne likheten er det viktig å påpeke en viktig forskjell i hvordan MultiChain og Corda forhindrer konflikter. I MultiChain ser hver node hver transaksjon og kan uavhengig verifisere at hver utgang bare brukes én gang. Enhver transaksjon som utfører et dobbeltforbruk mot en tidligere bekreftet transaksjon, blir umiddelbart og automatisk avvist. I Corda er det derimot ingen global blockchain, så det kreves "notarer" for å forhindre disse doble utgiftene. Hver Corda-utgangstilstand er tilordnet en notarius, som må signere eventuelle transaksjonsutgifter som utgangen, bekrefter at den ikke har blitt brukt før. En blockchain deltakere må stole på at notarius følger denne regelen ærlig, og ondsinnede notarier kan forårsake kaos etter ønske. Som med påtegninger i stoff, er dette “enkeltbruk som en tjeneste”Design har fordeler med tanke på konfidensialitet, men introduserer mellommenn på nytt mot blockchain-kornet. (Det er viktig å avklare at Corda-notarius kan drives av deltakergrupper ved hjelp av en konsensusalgoritme, slik at hovedbokens integritet fortsatt kan beskyttes mot individuelle dårlige aktører).

La oss gå videre til Ethereum. For å huske bruker Ethereum kontrakter og meldinger i stedet for innganger og utganger. Som et resultat er transaksjonskonflikter som Alice's to betalinger ikke umiddelbart synlige for blockchain-motoren. I stedet blir de oppdaget og blokkert av kontrakt som behandler transaksjonene, etter at bestillingen er bekreftet i kjeden. Ved behandling av hver av Alis betalinger, verifiserer kontrakten om saldoen hennes er tilstrekkelig. Hvis transaksjonen som betaler $ 8 til Bob kommer først, vil den bli behandlet som vanlig, og etterlate Alice med $ 2 på kontoen sin. Som et resultat, når kontrakten behandler den andre transaksjonen som betaler $ 7 til Charlie, ser den at Alice mangler de nødvendige midlene og transaksjonen avbrytes.

Outputs vs kontrakter

Så langt har vi sett to forskjellige teknikker for å forhindre motstridende transaksjoner - single-spend outputs i MultiChain og Corda, og kontraktsbasert verifisering i Ethereum. Så hva er bedre?

For å hjelpe deg med å svare på dette spørsmålet, la oss se på et eksempel på en «1-of-2 multisignature» -konto som har $ 100 på vegne av Gavin og Helen, og som lar en av dem bruke pengene selvstendig. Gavin instruerer søknaden om å betale $ 80 til Donna, og noen sekunder senere vil Helen sende $ 40 til Edward. Siden det ikke er tilstrekkelig med midler til begge betalinger, vil disse transaksjonene uunngåelig komme i konflikt. I tilfelle begge transaksjonene sendes, vil resultatet bli bestemt av det som gjør det først i kjeden. Merk at i motsetning til Alices eksempel, er denne konflikten utilsiktet, siden ingen prøver å bryte programmets regler - de hadde rett og slett uheldig timing.

Når man vurderer sannsynligheten for at denne konflikten skal oppstå, er nøkkelspørsmålet dette: Når Gavin har sendt ut transaksjonen, hvor lang tid vil det ta Helens node å vite at betalingen hennes kan mislykkes? Jo kortere denne perioden er, desto mer sannsynlig blir Helen stoppet fra å forsøke å betale, og redde henne og hennes søknad fra en påfølgende overraskelse.

Med input-output-modellen er enhver konflikt mellom transaksjoner direkte synlig for blockchain-plattformen, siden de to transaksjonene eksplisitt vil prøve å bruke samme forrige produksjon. I MultiChain skjer dette så snart Gavins transaksjon har spredt seg til Helens node, vanligvis på et sekund eller mindre. I Corda vil utgangsnotaren nekte forespørselen om å signere Helens transaksjon, siden den allerede har signert Gavins, så Helen vil umiddelbart vite at betalingen hennes mislykkes. (Selv om Corda-notariusen i seg selv distribueres, kan det hende hun må vente noen sekunder på svar.) Uansett er det ikke nødvendig å vente på at en transaksjon skal bekreftes og bestilles i blockchain.

Hva med Ethereums modell? I dette tilfellet er det ingen umiddelbar måte for blockchain-plattformen å vite at en konflikt vil oppstå. Mens Helens knutepunkt kanskje ser Gavins transaksjon på nettverket, kan den ikke vite hvordan dette vil påvirke Helens egen transaksjon, siden dette perspektivet ganske enkelt er to meldinger som sendes til samme kontrakt. Kanskje ti sekunder senere, når den endelige bestillingen av de motstridende transaksjonene er bekreftet på blockchain, vil Helens node beregne det faktiske i stedet for det forventede resultatet, og applikasjonen hennes vil oppdatere skjermen tilsvarende. I mellomtiden blir både Gavin og Helen igjen i mørket.

Men vi skal ikke konkludere ut fra dette at input-output-modellen alltid fungerer best. Tenk på en variant av vårt eksemplarscenario, der både Gavin og Helen ber om mindre $ 40-utbetalinger fra den opprinnelige saldoen på $ 100, akkurat på samme tid. I input-output-modellen ville disse transaksjonene komme i konflikt, siden de begge bruker den samme databaseraden som inneholder de $ 100, og bare en av betalingene vil lykkes. Men i Ethereum vil begge transaksjonene bli behandlet, uansett deres endelige ordre, siden kontoen inneholder tilstrekkelige midler for begge. I dette tilfellet oppfyller Ethereum mer Gavins og Helens intensjoner.

Les-skriv sett

Til slutt, la oss snakke om Fabric, hvis godkjennelsesbaserte tilnærming er en hybrid av disse to teknikkene. Som forklart tidligere, når en "klient" -node fra Fabric vil sende en melding til en kontrakt, ber den først noen godkjennende noder om å utføre den meldingen på vegne av dem. De godkjennende nodene gjør det på en lignende måte som Ethereum - kjører kontrakten mot sin lokale database - men denne prosessen blir observert i stedet for å bli umiddelbart brukt. Hver godkjenner registrerer settet med rader som vil bli lest og skrevet, og noterer seg også den nøyaktige versjonen av disse radene på det tidspunktet. Dette "lese-skrive-settet" av versjonerte rader er eksplisitt referert til i påtegningen, og er inkludert i transaksjonen som klienten sender.

Konflikter mellom Fabric-transaksjoner løses når bestillingen er ferdig i kjeden. Hver node behandler hver transaksjon uavhengig, sjekker godkjennelsespolicyer og bruker de spesifiserte databaseendringene. Imidlertid, hvis en transaksjon leser eller skriver en databaseradversjon som allerede er modifisert av en tidligere transaksjon, blir den andre transaksjonen ignorert. For å gå tilbake til Alice's motstridende innbetalinger til Bob og Charlie, vil begge disse transaksjonene lese og endre den samme radversjonen, som inneholder $ 10 som Alice startet med. Så den andre transaksjonen vil bli avbrutt trygt og automatisk.

Fabrics tilnærming til konfliktløsning fungerer helt fint, men når det gjelder ytelse og fleksibilitet, kombinerer den det verste av de to foregående modellene. Fordi påtegninger konverterer transaksjoner til bestemte lese- og skrivesett, vil Gavin og Helens samtidige, men kompatible $ 40-betalinger føre til en konflikt som Ethereum unngår. Imidlertid får Fabric ikke hastighetsfordelen med input-output-modellen, siden godkjennere utfører kontrakter mot den nyeste versjonen av databasen som er bekreftet av blockchain, og ignorerer ubekreftede transaksjoner. Så hvis Helen initierer betalingen noen sekunder etter Gavin, men før Gavins er blitt bekreftet på blockchain, vil Fabric skape motstridende transaksjoner som en ren input-output-modell unngår.

Konfliktforebygging Stoff multikate Ethereum Corda
Modell Les-skriv sett Enkeltbruk Kontraktssjekker Enkeltbruk
Verifisering Uavhengig Uavhengig Uavhengig Pålitelige notarier
Speed ~ 10s (bekreftelse) ~ 1s (forplantning) ~ 10s (bekreftelse) 0 ~ 5s (notarius)

Et komplekst valg

I dette stykket gjennomgikk vi mange av de forskjellige måtene Corda, Ethereum, Fabric og MultiChain takler de viktigste utfordringene med "smarte kontrakter", eller applikasjonskoder som er innebygd i en blockchain. Og hver plattform har forskjellige svar på de tre kjernespørsmålene våre: Hvordan representeres transaksjonsregler? Hvordan utføres kode deterministisk? Og hvordan forhindrer vi konflikter?

Så hvem er vinneren av vårt smartoppgjør? Det burde være åpenbart nå at det ikke er noe enkelt svar. Hver plattform representerer en kompleks flerveis avveining mellom fleksibilitet, enkelhet, ytelse, uovertruffenhet, sikkerhet og konfidensialitet. Så valg av plattform for en bestemt applikasjon må begynne med en detaljert forståelse av applikasjonens tillitsmodell, hvilke typer transaksjoner det innebærer og deres sannsynlige konfliktmønstre. Hvis du finner noen som skyver en bestemt smart kontraktløsning før de vet svarene på disse spørsmålene, foreslår jeg høflig, men bestemt, å insistere på at de tar en “smartere” tilnærming.

Legg inn kommentarer på Linkedin.

Tidstempel:

Mer fra multikate