Introduktion till fasthet: ACL och händelser. [Del 2]

Den här artikeln är nästa i serie med den tidigare som pratade om datakontrakt. Exempelkontraktet i den föregående diskussionen ärvde från ett kontrakt som heter “ACLContract”, men vi använde ingen funktion från ACLContract eftersom vi ännu inte hade sett hur ACL (Access Control List) och “eventing” kunde användas för att leverera åtkomstkontroll och åtkomstloggningsanläggning.

Åtkomstkontroll är en mekanism för att tillhandahålla selektiv begränsning av åtkomst till en resurs. Det finns olika typer av åtkomstkontrollmodeller inom informationstekniken, de flesta centrerar sig kring användaren eller ”huvudmannen” som försöker komma åt resursen. Det finns situationer där resursen i sig kan definiera åtkomsten till den, men vi kommer inte att gå in på den. För vårt ändamål kommer vi att hålla oss till två typer av åtkomstkontroller – Rollbaserad och attributbaserad.

Introduktion till fasthet: ACL och händelser. [Del 2]

Arv:

Eftersom åtkomstkontroll är en funktion som ska kunna kopplas till viss del kommer vi att använda arv för att tillhandahålla den här funktionen till dina domänavtal. Arv i soliditet använder kopiorkodmekanismen för att plantera “super-contract” -koden i “underleverantör” – superkontrakt är det ärftliga kontraktet och underkontrakt är det ärvande kontraktet. Solidity stöder också ett Object Oriented Programming (OOPS) koncept för polymorfism, där en kontraktsinstans kan fördubblas som någon av dess subklassinstanser.

Vårt ACL-kontrakt (Access Control List) kommer att ärvas av ett domänavtal och kommer att tillhandahålla funktioner för datakontroll. Domänavtalet måste bara omge sina resursanrop med ACL-kontraktsmetoderna som det kommer att ärva.

ACL-kontrakt:

Den grundläggande förutsättningen för ACL-avtalet är att tillhandahålla metoder för att skapa / hantera en lista eller användarlistor och tillhandahålla metoder som kan kontrollera vilken specifik användare som helst mot den listan. Vårt antagande är att varje användare av ett kontrakt är en “adress” -typ – adressen är en speciell typ av variabel i soliditet som representerar din plånbok eller kontoadress. Det är vettigt att använda det som användaruppgifter eftersom en användare bara får tillgång till ett kontrakt med sin kontoadress. Vi kan också dra ett antagande om att samtalet från en adress är giltigt eftersom det bara kan göras om användaren har tillgång till kontots privata nyckel, vilket är den grundläggande förutsättningen för äkthet på ethereum.  

Den grundläggande mallen för kontraktet kommer att ha två instansvariabler:

 

adressera allmän ägare;

adress [] offentliga användare;

Ägaradressen är skaparen av avtalet. Vi kommer att starta det under konstruktörssamtalet. Detta är ett rättvist antagande eftersom ägaren bara ska distribuera kontraktet såvida vi inte behöver delegera ägarfunktionerna till en annan adress, för vilken vi kommer att göra bestämmelser inom kontraktet som vi kommer att se.

Så om kontraktet heter ACLContract, kommer följande kod att initiera ägarens adress och också göra ägaren till en av användarna.

funktion ACLContract () {

ägare = msg.sändare;

users.push (ägare);

}

När vi har startat kontraktet behöver vi några driftsmetoder för att administrera användarlistan. Msg är en speciell typ av objekt i soliditet som innehåller data om den som ringer eller avsändaren av en transaktion. I det här fallet kommer distributionskontot att ringa upp transaktionen som distribuerar kontraktet, så vi tilldelar den ägare-adressen till den här uppringarens adress.

funktion addUser (adressanvändare) {

if (msg.sender! = ägare) kast;

users.push (användare);

}

funktion getIthUser (uint i) konstant returnerar (adress) {

returnera användare [i];

}

funktion getUserCount () konstant returnerar (uint) {

returnera användare. längd;

}

funktion deleteIthUser (uint i) {

if (msg.sender! = ägare) kast;

ta bort användare [i];

}

Dessa metoder kommer att användas av klienter för att hantera användarens lista. Vi ser att endast ägaren har möjlighet att administrera listan med den här kontrollen:

if (msg.sender! = ägare) kast;

Så den här koden matchar uppringarens adress med ägaren och misslyckas transaktionerna med ett kast om det inte finns någon matchning. Innan vi går vidare måste vi titta lite på att kasta undantag eftersom det här är det huvudsakliga skyddet vi kommer att sätta om vår åtkomstkontrollmekanism misslyckas.

Undantag:

Undantag är mekanismen i soliditet för att indikera en felsituation i en transaktion. Resultatet av ett undantag är att det aktuella samtalet stoppas och alla transaktionens effekter vänds. Om undantaget förekommer i en samtalsstack, returneras undantaget upp i stacken till den första uppringaren. För närvarande är det inte möjligt att återhämta sig från undantaget i soliditet, eftersom den partiella tillståndsförändringen som har inträffat kanske inte är säker för att fortsätta transaktionen, så för att bibehålla transaktionens atomicitet återställs alla ändringar.

Det finns två typer av undantag, runtimeundantag och undantag från användaren.

Runtimeundantag inträffar automatiskt om koden stöter på de 12 situationer som anges i soliditetsdokumentationen (se dokumentationen – för voluminös och överflödig för att klistra in här), det här är oftast avvikelser som kan uppstå i tillståndet för det uttalande / transaktion som utförs är framgångsrik.

Användaranpassade undantag kastar manuellt in kod. Det finns två sätt att skapa dem – att använda kräver med ett villkor som visar sig vara falskt eller använder ett uttryckligt kast. Vi använder det villkorliga kastet, och som vi vill kommer detta att återställa transaktionseffekterna och misslyckas samtalet i händelse av brott mot den åtkomstkontroll som har införts.

Kommer tillbaka till vårt ACLContract har vi slutfört skapandet av användarlistan och de metoder som vi behöver för att administrera den. Det finns några försiktighetsåtgärder för vad vi gjorde, det är möjligt att skapa två listor – en för skrivskyddade användare och en annan för läs- och skrivanvändare.

Faktum är att alla data som finns i ethereum blockchain är offentliga, så det är inte meningsfullt att skapa en skrivskyddad användare, eftersom vem som helst kan se den informationen, men i fall där datatillgången är krypterad på ett sätt som gör att den kan länkas till användarkontot kan vi tänka på en skrivskyddad användare. Det diskuteras i eterumsamhället för att göra etereum blockchain integritetsvänligt, och det finns flera förslag på hur det kan göras.

Om vi ​​kan dra ett antagande att vi med något av dessa förslag eller genom ett anpassat schema kan kryptera våra data och vi kan se till att datatillgång endast kan göras genom hela avtalskoden, då kommer vi att hitta det användbart att skapa två listor – en skrivskyddad användare och en skriv-skrivanvändare. Koden för det kommer att vara mycket lik den vi har skrivit för våra användare med en enda grupp. Vi behöver bara fyra administrationsmetoder för varje lista (läsanvändare och skrivanvändare).

Skapa åtkomstkontroll:

För att veterinära en användare mot åtkomstkontrollistan måste vi matcha den med adresslistan. Vi kan skapa en enkel metod som accepterar en användaradress och försöker matcha den med listan:

funktionen isUser (adresskandidat, strängmetod) returnerar (bool) {

för (uint8 i = 0; i < användare. längd; i ++) {

om (användare [i] == kandidat) {

återvänd sant;

}

}

returnera falsk;

}

Logiken är enkel att förstå om vi hittar användaren i listan, vi avslutar slingan med true, om vi har slut på element i listan och sedan returnerar falskt. Strängmetodsparametern som skickas kommer att användas senare när vi pratar om händelse för att logga användarens åtkomst och resultatet av åtkomstförsöket.

Loggningsåtkomst med händelser:

Det grundläggande konceptet som definieras i säkerhetsprinciper är AAA (Authentication, Authorization, and Auditing).

Autentiseringen tillhandahålls av ethereum när användaren initierar en transaktion med ett visst konto. Det antas att användaren äger kontot eftersom han kan använda det för att initiera transaktionen. Ansvaret för den valideringen som resulterar i autentisering av användaren med sitt kontolösenord görs på klientnivå för eterumnoden.

Auktoriseringsdelen av AAA har implementerats av ACLContract där rollbaserad åtkomstkontroll verkställs.

Den tredje delen av AAA är granskning – Kravet på granskning är att användaråtkomst ska loggas. För att göra detta använder vi händelser.

Fasthetshändelser:

Händelser är precis som vanliga instansvariabler i ett kontrakt, de kan ärvas som alla variabler. Händelser används för att returnera värden till klienten om en lista med värden ska returneras, men vi kommer bara att undersöka dem som ett sätt att skapa loggar i blockchain. Händelser när de ”avfyras” från en del av blockkedjan med de parametrar som levereras till dem.

För att implementera en logghändelse definierar vi en händelsevariabel:

händelse LogAccess (adress indexerad av, inte indexerad accessTime, strängmetod, strängbeskrivning);

Den här händelsen kommer att användas i vår åtkomstkontrollmetod isUser () för att logga den åtkomst som försöks med resultatet.

funktionen isUser (adresskandidat, strängmetod) returnerar (bool) {

för (uint8 i = 0; i < användare. längd; i ++) {

om (användare [i] == kandidat) {

LogAccess (kandidat, nu, metod, "framgångsrik åtkomst");

återvänd sant;

}

}

LogAccess (kandidat, nu, metod, "misslyckad åtkomst");

returnera falsk;

}

 

Händelsen parameteriserar åtkomstkontot (kandidat) tiden, (nu) resursen (metod) och resultatet (misslyckad åtkomst, lyckad åtkomst). Vi använder en sträng för att beskriva resultatet, men det rekommenderas att du använder uint-konstanter för att möjliggöra enklare sökning.

Händelsen kommer att avfyras varje gång isUser () nås och loggar åtkomst i blockchain för granskningsändamål. Händelserna kan nås via ett web3-klientsamtal som vi kommer att se i följande avsnitt.

Att sätta ACLContrakt att använda:

Kontraktet som vi skapade kan ärvas av alla andra kontrakt för att återanvända ACL-listorna som tillhandahålls av det. Vårt datakontrakt ärvde det med hjälp av konstruktionen.

contrat DataContract är ACLContract {

För att använda ACL-anläggningen kommer vi att fånga upp metodanropen i kontraktet med isUser ():

function updateCustomer (uint index, string name) {

om (isUser (msg.sender, "updateCustomer")) {

om (index > räkna) kasta;

kunder [index] .namn = namn;

}

annars kasta;

}

funktionsuppdateringCustomerStatus (uint index, uint status) {

om (isUser (msg.sender, "updateCustomer")) {

om (index > räkna) kasta;

kunder [index] .status = status;

}

annars kasta;

}

funktion createCustomer (

uint id,

strängnamn,

uint dateOfBirth,

uint social) {

om (isUser (msg.sender, "createCustomer")) {

kunder [count] = Kund (id, namn, dateFödsel, socialt, väntande);

räkna ++;

}

annars kasta;

}

Vi tillhandahåller endast begränsningar för åtkomstkontroll till metoder som uppdaterar data, om vi hade krypterat kunddata inom kontraktet kan vi också implementera begränsningar för dess läsfunktioner.

Kontraktet kan inte komma åt de händelser som det skapar, så för att komma åt händelserna behöver vi vår web3-klient för att skapa ett samtal:

Förutsatt att ABI har kontrakterat ABI och adress är dess plats i blockchain.

var DataContract = web3.eth.contract (abi) .at (adress);

var eventLogs = DataContract.allEvents (). get ();

console.log (eventLogs);

Det finns mycket mer i händelserna än hur vi använder det ovan, vårt mål är att hämta dem för granskningsändamål.

Attributbaserad åtkomstkontroll:

Det är möjligt att ha en annan typ av åtkomstkontroll där behöriga användare identifieras av ett attribut. Vi diskuterar detta för att exemplifiera den ”Attributbaserade åtkomstkontroll” vi pratade om i inledningen. Detta är bara en variant av isUser () -samtalet:

funktionen isUserAuthorized (adresskandidat, strängmetod) returnerar (bool) {

för (uint8 i = 0; i < användare. längd; i ++) {

if (kandidat. balans > 100) {

LogAccess (msg.sender, nu, metod, "framgångsrik åtkomst");

återvänd sant;

}

}

LogAccess (msg.sender, nu, metod, "misslyckad åtkomst");

returnera falsk;

}

Detta är det mycket triviella exemplet där en auktoriserad användare är den som har en balansetrar som är större än 100.

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