Introduktion til soliditet: Oprettelse af en datakontrakt [Del 1]

Soliditet er et javascript som et sprog, der bruges til at kode smarte kontrakter på Ethereum-platformen. Det kompileres til et bytecode-format, der forstås af Ethereum Virtual machine (EVM). Det er et stærkt skrevet sprog med evnen til at definere brugerdefinerede datastrukturer. Introduktion til soliditet del 1 vil lære dig at bruge et undersæt af soliditetsfunktionalitet til at oprette en skabelon til en smart kontrakt, der kan genanvendes til at formulere et komplet sæt kontrakter, der indeholder data og grundlæggende logik, der fungerer for ethvert domæne. Dette vil være en serie med flere dele, da den vil dække grundlæggende kontraktdesign og nogle relaterede bekymringer.

Introduktion til soliditet

Introduktion til soliditet: Oprettelse af et miljø

For at udføre smarte kontrakter har vi brug for et system, der er i stand til at kompilere, implementere og kalde dets metoder. For alle de tre har vi en meget enkel integreret browserbaseret app her.

Det er muligt at bruge dette værktøj til at oprette forbindelse til en levende ethereumknude eller til at danne et mock-miljø. Dette miljø kan også let udføre nogle testsager på kontraktmetoderne. Det behøver ingen installation og er helt browserbaseret. Jeg har brugt det på krom over ubuntu, men jeg er sikker på, at det fungerer lige så godt på andre platforme. Den venstre rude i appen er, hvor kontraktkoden er, og højre side har implementerings- og testmuligheder. Appen kan arbejde på kontraktfiler fra egne systemer.

Kildekoden til den kontrakt, vi diskuterer, er tilgængelig her. Nogle dele af kontraktkoden vil blive diskuteret i de senere dele af serien. Koden og downloades og indlæses i Remix for at se de sektioner, der diskuteres nedenfor. Solidity seneste uudgivne version er 4.10 om natten, og vi vil stole på funktioner, der understøttes af den specifikke version.

DataContract (grundlæggende datastruktur):

En datakontrakt er ikke standardterminologi. Der er flere typer (mønstre) af smarte kontrakter defineret i Monax (tidligere Eris industrier) dokumentation. Kontrakttypen “data” er et simpelt koncept, hvor data tilføjes, opdateres, fjernes og åbnes. I processen med at oprette datakontrakt vil vi være i stand til at arbejde med en ACL-kontrakt (Access Control List), der kan bruges til at styre rollebaseret sikkerhed på alle kontraktstyper, Eventing-mekanisme til logning og returnering af data og nogle andre funktioner i smarte kontrakter.

For at oprette en simpel datakontrakt antages et brugerdefineret datasæt på højt niveau til f.eks. Kunder

For at forenkle strukturerer vi en simpel kunde, som vi antager at være en person:

strukturer kunde {

uint id;

strengnavn

uint dateOfBirth;

uint social;

uint status;

}

Datastatus

Vi implementerer strukturen med den antagelse, at hver datapost vil have en status. Det er ikke muligt at slette og registrere og omarrangere hele samlingen, så status er en attribut, som vi vil udnytte for at definere en tilstand for posten. Kontrakter i forskellige domæner vil have et andet sæt af status. Som en simpel antagelse følger vi 3 statuser (dette er med tanken om, at en kunde muligvis afventer verifikation, er aktiv eller måske slettes):

uint konstant aktiv = 1;

uint konstant afventende = 2;

uint konstant slettet = 3;

En slettet post for enhver referencedatatype på en blockchain skal aldrig slettes hårdt, så det er en passende designpraksis at tildele en status til hver post.

Vores mål er at muliggøre en samling af kundestrukturforekomster på blockchain og lette muligheden for at få adgang til en bestemt kunde, listen over opkaldskunder og opdatere en bestemt kundeinstans. En tværgående bekymring med disse mål er at muliggøre logning og implementering af en adgangskontrolstrategi.

For at oprette en samling bruger vi kortlægningskonstruktionen.

kortlægning (uint => Kunde) kunder;

kortlægning (uint => Kunde) kunder;

Denne kortlægning er skabelonen til en kortlignende struktur, der opretter et kort over nøgleværdier, hvor nøglen er en usigneret int, og værdien er en forekomst af en kunde. Denne kortlægning har nogle begrænsninger, hvilket er, at der ikke er nogen måde at løbe igennem for at hente alle værdier. Vi kan kun få adgang til elementerne gennem en specifik get-logik:

kunder [nøgle];

På grund af dette bliver vi nødt til at opretholde en skygge-nøgle for at opretholde et antal elementer i kortlægningen og hente den baseret på antallet.

offentlig uintælling = 0;

Nu har vi vores datastruktur klar til at blive brugt til at huse kundedataene.

Datakontrakt (oprettelse af data):

For at oprette en kundeinstans og nøgle den, implementerer vi en metode, der accepterer bestanddele.

funktion Opret kunde (uint id, strengnavn, uint dateOfBirth, uint social) {

kunder [count] = kunde (id, navn, datoFødsel, social, afventende);

tælle ++;

}

Ovenstående metode tilføjer data til kortlægningen og forøger antallet af skyggetaster. Hvad der skal bemærkes er, at vi bruger den samme skygge-nøgle til at slukke for dataene.

For at få adgang til data tilfældigt skal vi levere en bestemt nøgle, som vi har indtastet dataene mod.

funktion getCustomer (uint-indeks)

konstant retur (uint id, strengnavn, uint dateOfBirth, uint social, uint status)

{

id = kunder [indeks] .id;

navn = kunder [indeks] .navn;

dateOfBirth = kunder [index] .dateOfBirth;

social = kunder [indeks]. social;

status = kunder [indeks] .status;

}

Denne metode er konstant, da den ikke ændrer tilstanden for kontraktdata (det er en skrivebeskyttet metode). Så for at kalde denne metode behøver vi ingen gas.

For at få adgang til alle kunder er vi nødt til at udnytte tælleskygttasten. Vi bliver nødt til at implementere looping-strukturen på klienten og genbruge det indeksbaserede opkald ovenfor. Dette forklares kontraktklientens forklaring.

For at få adgang til kunden baseret på en bestemt attribut i en struktur, bliver vi nødt til at implementere en loopbaseret brute-søgning. Der er mere effektive måder at læse den ved at analysere den transaktion, der var ansvarlig for at oprette disse data.

funktion getCustomerById (uint id)

konstant retur (uint idRet, strengnavn, uint dateOfBirth, uint social, uint status)

{

for (var i = 0; i< tælle; i ++)

{

hvis (kunder [i]. id == id) {

idRet = kunder [i] .id;

navn = kunder [i] .navn;

dateOfBirth = kunder [i] .dateOfBirth;

social = kunder [i]. social;

status = kunder [i] .status;

Vend tilbage;

}

}

}

Dette er en meget ineffektiv måde at hente kunden fra en attributværdi. Der er også andre problemer med denne metode bortset fra ineffektivitet. Det er ikke muligt let at matche strenge i soliditet, så det er ikke muligt at matche strengattributter. Det returnerer også den første kamp, ​​det er ikke muligt at returnere en liste over kampe. Vi vil gå ind på mere effektive metoder til at få adgang til disse data i senere dele af denne serie.

Datakontrakt (dataopdatering):

Opdateringsdatametoden er simpelthen omvendt fra adgangsmetoden. Den eneste ting at huske er, at denne metode resulterer i en ændring i blockchain-tilstanden, så ændringerne kun afspejler, når transaktionen er bekræftet. Vi vil diskutere, hvordan vi kan sikre, at transaktionen bekræftes, inden vi forsøger at få adgang til dataene i senere del af vores serie.

funktionsopdateringKunde (uint-indeks, strengnavn) {

kunder [indeks] .navn = navn;

}

Det giver mening at sætte nogle kontroller for indeksværdi (det skal være mindre end antallet)

funktionsopdateringKunde (uint-indeks, strengnavn) {

hvis (indeks > tælle) kaste;

kunder [indeks] .navn = navn;

}

funktionsopdateringCustomerStatus (uint-indeks, uint-status) {

hvis (indeks > tælle) kaste;

kunder [indeks] .status = status;

}

Den forskellige metode skal implementeres til opdatering af hver attribut, her opdaterer vi navnet. Metoden updateCustomerStatus () skal behandles som en særlig metode, der kan aktivere eller deaktivere poster.

Det er muligt at tilføje den samme afkrydsningsfelt på den adgangsmetode, der åbner indeksnøglen, men det er ikke nødvendigt, da returneringen er nul, hvis det ugyldige indeks leveres, så klienten skal kunne validere svaret og returnere passende fejl. Da adgang ville være et hyppigere kaldet metodesæt, bør det gøres så effektivt som muligt.

Test af kontrakten:

For at teste kontrakten skal du gå til fanen miljø i højre panel (boksikonet).

Du vil se kontrakten anført til højre med med muligheden for at angive en adresse (På adresse) og en mulighed for at oprette. Vælg radioknappen VM til javascript (valgt som standard og tryk Opret). Dette skaber et lokalt miljø i browseren, så du kan udføre tests på din kontrakt og fejle fejl i begivenheden.

Introduktion til soliditet: Oprettelse af en datakontrakt [Del 1]

Introduktion til soliditet: Oprettelse af en datakontrakt [Del 1]

Dette testmiljø giver dig mulighed for at kalde kontraktmetoder individuelt og se resultaterne på dataene.

Til at begynde med kalder vi oprette kontraktmetoden for at tilføje nogle data til blockchain (ikke den rigtige endnu, men hån en).

Se efter den røde markerede knap med metoden call createCustomer og tilføj parametre til tekstfeltet ved siden af ​​den adskilt af kommaer, som du ville, hvis du kalder denne metode via en javascript-klient. For f.eks. (For enkelhedens skyld har vi valgt dato for fødsel til at være enhedens tidsstempel, der kan passe ind i en enhed)

For f.eks. (For enkelhedens skyld har vi valgt dateOfBirth til at være enhedens tidsstempel, der kan passe ind i en enhed)

101, "Jack", 845078400, 1234567

Med dette parametersæt skal du klikke på Opret kunde, og du skal se følgende udskrevet under opkaldet:

Resultat: "0x"

Transaktionsomkostninger: 129390 gas.

Udførelsesomkostninger: 106454 gas.

Dette vil indikere, at metodeopkaldet er vellykket, du kan bekræfte det ved at kontrollere antallet af kunder ved at trykke på tælleknappen (Metoden opkaldstælling ()). Husk, at soliditet udsætter sine offentlige medlemmer gennem et direkte opkald med underskriftsmedlemmen ().

Opkaldet skulle udskrive noget som:

"0x00000000000000000000000000000000000000000000000000000000000000002"

Transaktionsomkostninger: 21505 gas. (advarsel)

Udførelsesomkostninger: 233 gas.

Dekodet:

uint256: 1

Denne uint256 har en værdi 1, der indikerer, at du har et enkelt medlem i dit pladesæt.

Du kan køre ovenstående createCustomer-opkald flere gange og kontrollere resultatet. Pas på, at der ikke er nogen kontrol med at tilføje duplikatposter. Dette skal kontrolleres af klienten.

Du kan hente kunden ved hjælp af den indeksbaserede getCustomer (0) – husk dit indeks starter med 0. Du skal se output som dette:

Værdi:

"0x000000000000000000000000000000000000000000000000000000000000006500000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000325edf80000000000000000000000000000000000000000000000000000000000012d687000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000044a61636b00000000000000000000000000000000000000000000000000000000"

Transaktionsomkostninger: 23404 gas. (advarsel)

Udførelsesomkostninger: 2004 gas.

Dekodet:

uint256 id: 101

strengnavn: Jack

uint256 dateOfBirth: 845078400

uint256 social: 1234567

uint256 status: 2

Den værdi, der returneres, er de kodede data, der returneres. Det afkodes og vises, og parameterværdier i rækkefølge nedenfor.

Nu har du en komplet arbejdskontrakt, der er testet mod nogle testdata.

Der er situationer, hvor din kontrakt ikke fungerer som forventet, i hvilket tilfælde du er nødt til at debugge kontrakten for at finde ud af kontraktdataens tilstand, når metoden udføres og identificere problemet. Der er i øjeblikket ingen soliditetsfejlretning. Der er en soliditet IDE – Mix, der har kapaciteten, men den understøttes i øjeblikket ikke. Du kan teste det på egen risiko.

Nu for at distribuere din kontrakt til en reel ethereum-forekomst og kalde den ved hjælp af en simpel javascript-klient.

Implementering af kontrakten:

Du kan henvise til en tidligere artikel om, hvordan du opretter lokal ethereum-node ved hjælp af paritet. Vi bruger denne kapacitet og antager, at du har en lokal kørende ethereum-forekomst, der udsætter JSON_RPC-porten på 8545. Vi antager også, at du har oprettet en konto og returneres på kontokontoen [0], også denne konto skal have tilstrækkelig etherbalance til implementere kontrakten og udføre transaktionsopkald med gasafgifterne.

Remix IDE giver dig mulighed for at implementere denne kontrakt direkte fra IDE til ethereum-forekomsten. For at gøre det skal du først vælge indstillingen Web3-udbyder fra fanen Miljø. Hvis miljøet i øjeblikket er afhentet, vil du ikke se nogen fejl under kontrakten.

Screen_3 (kontraktudrulningsmulighed)

Introduktion til soliditet: Oprettelse af en datakontrakt [Del 1]

IDE giver dig tre output fra kontraktopsamlingsprocessen BTW kontrakten kompileres automatisk. Sørg for, at du ser indstillingerne som vist i Skærm _3. ellers betyder det, at kompilering mislykkedes, og du skulle se kompileringsfejlen.

Bytecode er den EVM-kode, der oprettes, når din kode kompileres. Dette er det instruktionssæt på lavt niveau, som ethereum forstår. Det andet er Application Binær interface eller ABI i kontraktkoden. ABI er blot en liste over metodesignaturer, returneringstyper, medlemmer osv. I kontrakten i et defineret JSON-format. Dette ABI er nødvendigt, når du ringer til din kontrakt fra en rigtig javascript-klient.

Den tredje mulighed, som Web3 implementerer, er den mulighed, der giver dig mulighed for at skubbe kontrakten direkte på nodeforekomsten. Vælg bare denne mulighed, og du skal se din kontraktadresse i blockchain returneret til dig .. (Ligesom sreen_2). Denne kontraktadresse er vigtig, da den er nødvendig i javascript-klienten, som du snart opretter. Hvis du ikke er i stand til at distribuere kontrakten direkte i blockchain fra ethereum-konsollen. Kopier bare scriptet i tekstområdet mod web3 implementeringsmulighed og indsæt på konsollen. Du skal se tonekonsol.log-output med “kontrakt minet” efterfulgt af dens adresse i kæden.

At køre kontrakten fra en rigtig klient.

At integrere kontrakten med din virksomheds applikationskode. For at gøre det opretter du en simpel javascript / html-klient, der kan køre i browseren. Du kan også køre denne klient som et nodejs-program. Dette er noget, jeg vil dække i de senere dele af serien.

For at kommunikere med ethereum blockchain udsætter ethereum et lavt niveau JSON-RPC interface. Denne grænseflade accepterer transaktioner til kontrakten. Det er et meget lavt niveau interface, så det er svært at arbejde med det direkte. Der er en javascript-ramme web3.js der giver mulighed for abstraktion på højere niveau for kontraktkoder, så applikationer kan integreres med kontraktopkald.

For at aktivere web3 i et browserunderstøttet miljø skal der refereres til en enkelt scriptfil inden for sidekoden for at interagere med kontrakten.

Web3.js kan downloades fra linkene i ovennævnte dokumentation. Web3 genererer et håndtag til kontraktforekomst på ethereum for at aktivere alle metodekald, som vi implementerede i vores soliditetskilde. Disse metodeopkald kan kodes som om der er en direkte javascripthenvisning til metodeskriptet. Dette er aktiveret af JSON-RPC-grænsefladen.

Der er en skabelonet tilgang til rådighed for at få et kontrakthåndtag. Det første, der er nødvendigt, er at instantiere web3 og levere kontrakten ABI til det.

var Web3 = kræve (‘web3’);

var web3 = ny Web3 ();

web3.setProvider (“<span lang ="zxx"><a href ="http: // localhost: 8545 /">http: // localhost: 8545a>spændvidde>”);

web3.eth.defaultAccount = web3.eth.accounts [0];

Udbyderens url er din lokale JSON_RPC-grænseflade. Standardkontoindstillingen er ethereum-tegnebogen, der bruges til som fra kontoen, når vi udfører transaktionerne på kontrakten. Vi er nødt til at sikre, at kontoen er låst op, hvis vi bruger geth-node-instans, da kontoen som standard er låst hvert 30. sekund efter, at den er låst op.

Det næste trin er at iværksætte kontraktplanen ved at levere kontrakten ABI så web3.

var customerContract = web3.eth.contract ([ABI JSON]).

ABI JSON-arrayet er normalt en lang JSON-streng, så vi parafraserer bare, men du skal kopiere hele ABI-arrayet fra interface-tekstområdet som vist på skærm3. Når du har planen for kundekontrakten, skal vi instantere den ved at angive den rigtige adresse, hvor kontrakten ligger i blockchain.

var customerContractObject = customerContract.at (‘0x76bd9986c5c3e00111c82e16e01e282696d2b3fb’);

Denne adresse ville være, hvad du fik, da du implementerede kontrakten fra implementering af web3 eller fra ethereum-konsol. Når du har linket kontrakthåndtaget tilbage til implementeringsadressen, kan du udføre kontraktmetoder ved at sende transaktioner til adressen. Lad os f.eks. Sige, at du vil tilføje kundeoptegnelse, efter at din html-formular accepterer input til formularværdierne fra brugeren, så ser din html + web3-kode sådan ud:

<html>

<hoved>

<link rel = ”stylesheet” type = ”text / css” href = ”style.css”>

<script type = ”text / javascript” src = ”/ usr / local / lib / node_modules / web3 / dist / web3.js”><script type = ”text / javascript” src = ”jquery.js”>manuskript>

<script type = ”text / javascript”>

var Web3 = kræve (‘web3’);

var web3 = ny Web3 ();

web3.setProvider (ny web3.providers.HttpProvider ()); // dette er som standard – localhost: 8545

web3.eth.defaultAccount = web3.eth.accounts [0];

var customerContract = web3.eth.contract ([ABI JSON]);

var customerContractObject = customerContract.at (‘0x76bd9986c5c3e00111c82e16e01e282696d2b3fb’);

funktionsregister () {

var txn = customerContractObject.createCustomer ($ (‘id’). val (), $ (‘name’). val (), $ (‘dob’). val (), $ (‘social’). val () , {gas: 144840});

console.log (txn);

}

manuskript>

hoved>

<legeme>

<input type = ”nummer” navn = ”id” id = ”id” pladsholder = ”kunde-id” />

<input type = ”tekst” navn = ”navn” id = ”navn” pladsholder = ”Kundenavn” />

<input type = ”dato” navn = ”dob” id = ”dob” pladsholder = ”kunde fødselsdato” />

<input type = ”nummer” navn = ”social” id = ”social” pladsholder = ”Kundens socialsikringsnummer” />

<input type = ”knap” værdi = ”Registrer” onclick = ”register ();” />

legeme>

html>

Ovenstående kode fungerer ud af boksen, hvis du retter stien til web3.js og jquery. Ligesom vi har kaldt metoden på kontrakthåndtaget:

var txn = customerContractObject.createCustomer ($ (‘id’). val (), $ (‘name’). val (), $ (‘dob’). val (), $ (‘social’). val () , {gas: 144840});

Det er muligt at kalde alle andre metoder. Den anslåede gas skal indtastes fra testmetoden opkald, dette er 144840 i min konfiguration. Ovenstående opkald returnerer et transaktions-id for den transaktion, der oprettes på blockchain for at udføre denne metode. Denne transaktion er nu en del af blockchain og kan henvises til, når vi vil kontrollere, hvornår, hvordan og af hvem blev denne kunde oprettet.

Der er to typer opkald, som vi har set under kodningen af ​​kontrakten. En der opdaterer kontraktens tilstand som createCustomer, updateCustomer osv. Og andre som er skrivebeskyttet og er markeret som konstant. Førstnævnte returnerer altid en transaktion Id-hash, transaktion Id-hash er en 64 byte-identifikation af transaktionen, der kan bruges til at henvise tilbage til transaktionen. Hvis vi kører kontrakten synkront, som vi gør her. Sidstnævnte returnerer de faktiske værdier, der søges i et kommasepareret array. For eksempel opkaldet:

var kunde = customerContractObject.getCustomer ($ (‘index’). val ());

console.log (kunde)

Vil logge en række værdier som denne – 101, "Jack", 845078400, 1234567

I den næste del af serien vil vi se, hvordan nogle ikke-funktionelle bekymringer og aspekter er indbygget i den kontraktlignende adgangskontrol, hændelseslogfiler, kontraktsletning. Vi vil diskutere dele af kontrakten, der specifikt beskæftiger sig med disse spørgsmål.

Mike Owergreen Administrator
Sorry! The Author has not filled his profile.
follow me