Úvod do Solidity: ACL a události. [Část 2]

Tento článek navazuje na předchozí článek, který hovořil o kontraktech dat. Ukázková smlouva v předchozí diskusi byla zděděna od smlouvy s názvem „ACLContract“, ale nepoužívali jsme žádnou funkci poskytovanou ACLContract, protože jsme ještě neviděli, jak lze použít ACL (Access Control List) a „eventing“ k doručení kontrola přístupu a protokolování přístupu.

Řízení přístupu je mechanismus, který poskytuje selektivní omezený přístup k prostředku. V informačních technologiích existují různé druhy modelů řízení přístupu, většinou se točí kolem uživatele nebo „hlavního“, který se pokouší o přístup ke zdroji. Existují situace, kdy samotný zdroj může definovat přístup k němu, ale do toho nebudeme. Pro náš účel se budeme držet dvou druhů řízení přístupu – na základě rolí a atributů.

Úvod do Solidity: ACL a události. [Část 2]

Dědictví:

Vzhledem k tomu, že řízení přístupu je funkce, kterou by do jisté míry mělo být možné připojit, využijeme dědičnost k zajištění této funkce pro vaše doménové smlouvy. Dědičnost v solidnosti využívá mechanismus kopírování kódu k zasazení „superkontraktačního“ kódu do „subdodávky“ – superkontrakt je dědičnou smlouvou a subkontrakt je dědičnou smlouvou. Solidity také podporuje koncept polymorfismu Object Oriented Programming (OOPS), kde se instance kontraktu může zdvojnásobit jako kterákoli z instancí své podtřídy.

Naše smlouva ACL (Access Control List) bude zděděna doménovou smlouvou a bude poskytovat funkce řízení přístupu k datům. Smlouva o doméně bude muset obklopit svá volání prostředků metodami ACL kontraktů, které zdědí.

Smlouva ACL:

Základním předpokladem smlouvy ACL je poskytnout metody pro vytvoření / správu seznamu nebo seznamů uživatelů a poskytnout metody, které mohou porovnat kteréhokoli konkrétního uživatele s tímto seznamem. Náš předpoklad je, že každý uživatel smlouvy je typu „adresa“ – adresa je speciální typ proměnné, která představuje vaši peněženku nebo adresu účtu. Má smysl jej použít jako pověření uživatele, protože uživatel přistupuje ke smlouvě pouze podle adresy svého účtu. Můžeme také vyvodit předpoklad, že volání z adresy je autentické, protože ho lze uskutečnit pouze v případě, že má uživatel přístup k soukromému klíči účtu, což je základní předpoklad autenticity na ethereum.  

Základní šablona smlouvy bude mít dvě proměnné instance:

 

adresa veřejného vlastníka;

adresa [] veřejní uživatelé;

Autorem smlouvy bude adresa vlastníka. Vytvoříme instanci během volání konstruktoru. Toto je spravedlivý předpoklad, protože vlastník by měl smlouvu pouze nasazovat, pokud nebudeme muset delegovat funkce vlastníka na jinou adresu, pro kterou provedeme ustanovení ve smlouvě, jak uvidíme.

Pokud se tedy smlouva nazývá ACLContract, následující kód vytvoří instanci adresy vlastníka a také z něj udělá vlastníka jako jednoho z uživatelů.

funkce ACLContract () {

vlastník = msg.sender;

users.push (vlastník);

}

Jakmile vytvoříme instanci smlouvy, budeme potřebovat nějaké provozní metody ke správě seznamu uživatelů. Zpráva je speciální typ objektu, který obsahuje data o volajícím nebo odesílateli transakce. V takovém případě bude účet zavaděče volajícím transakce, která nasazuje smlouvu, takže této adrese vlastníka přiřadíme adresu tohoto volajícího.

funkce addUser (adresa uživatele) {

if (msg.sender! = owner) throw;

users.push (uživatel);

}

funkce getIthUser (uint i) konstantní výnosy (adresa) {

vrátit uživatele [i];

}

funkce getUserCount () konstantní výnosy (uint) {

návrat users.length;

}

funkce deleteIthUser (uint i) {

if (msg.sender! = owner) throw;

mazat uživatele [i];

}

Tyto metody budou klienti používat ke správě seznamu uživatelů. Vidíme, že pouze vlastník bude mít možnost spravovat seznam pomocí této kontroly:

if (msg.sender! = owner) throw;

Takže tento kód odpovídá adrese volajícího s vlastníkem a selže transakce s hodem v případě, že dojde k neshodě. Než se posuneme dále, musíme se trochu podívat na vyvolání výjimek, protože toto je hlavní ochrana, kterou vložíme v případě, že náš mechanismus kontroly přístupu selže.

Výjimky:

Výjimkou je mechanismus solidnosti, který označuje chybovou situaci v transakci. Výsledkem výjimky je, že aktuální volání je zastaveno a všechny účinky transakce jsou obráceny. Pokud k výjimce dojde v zásobníku volání, pak se výjimka vrátí zpět do zásobníku prvnímu volajícímu. V současné době není možné zotavit se z výjimky solidně, protože částečná změna stavu, ke které došlo, nemusí být bezpečné pokračovat v transakci, takže pro zachování atomicity transakce se všechny změny vrátí.

Existují dva druhy výjimek, runtime výjimky a výjimky poskytované uživatelem.

Výjimky za běhu se vyskytují automaticky v případě, že kód narazí na 12 situací uvedených v dokumentaci solidity (viz dokumentace – příliš objemná a nadbytečná na to, aby se sem vložila), jedná se většinou o anomálie, které se mohou vyskytnout ve stavu prováděného příkazu / transakce je úspěšný.

Uživatelem poskytnuté výjimky vyvolávají ručně v kódu. Existují dva způsoby, jak je vytvořit – pomocí require s podmínkou, která se ukáže jako nepravdivá, nebo pomocí explicitního hodu. Používáme podmíněný hod a jak chceme, vrátí efekty transakce a nepovede hovor v případě porušení kontroly přístupu, která je zavedena.

Vrátíme-li se k naší ACLContract, dokončili jsme vytvoření seznamu uživatelů a metod, které k jeho správě potřebujeme. K tomu, co jsme udělali, existuje několik upozornění, je možné vytvořit dva seznamy – jeden pro uživatele pouze pro čtení a druhý pro uživatele pro čtení a zápis.

Faktem je, že všechna data, která jsou v ethereum blockchainu, mají veřejnou povahu, takže nemá smysl vytvářet uživatele jen pro čtení, protože tato data vidí kdokoli, ale v případě, že je přístup k datům šifrován způsobem to umožňuje jeho propojení s uživatelským účtem, pak můžeme myslet na uživatele jen pro čtení. V komunitě ethereum se diskutuje o tom, jak zajistit soukromí ethereum blockchainu, a existuje několik návrhů, jak toho dosáhnout.

Pokud můžeme odvodit předpoklad, že s některým z těchto návrhů nebo prostřednictvím vlastního schématu dokážeme zašifrovat naše data a dokážeme zajistit, že přístup k datům bude možné provést pouze v celém smluvním kódu, bude pro nás užitečné vytvořit dva seznamy – uživatel pouze pro čtení a uživatel pro čtení a zápis. Kód pro to bude velmi podobný tomu, co jsme napsali pro naše uživatele s jedním polem. Budeme potřebovat pouze čtyři způsoby správy pro každý seznam (readUsers a writeUsers).

Vytváření řízení přístupu:

Abychom uživatele ověřili proti seznamu řízení přístupu, musíme jej porovnat se seznamem adres. Můžeme vytvořit jednoduchou metodu, která přijme adresu uživatele a pokusí se ji porovnat se seznamem:

funkce isUser (kandidát adresy, metoda řetězce) vrátí (bool) {

pro (uint8 i = 0; i < users.length; i ++) {

if (uživatelé [i] == kandidát) {

návrat true;

}

}

návrat false;

}

Logika je snadno pochopitelná, pokud najdeme uživatele v seznamu, ukončíme smyčku s true, pokud nám dojdou prvky v seznamu, pak vrátíme false. Předaný parametr řetězcové metody se použije později, když mluvíme o událostech k přihlášení přístupu uživatele a výsledku pokusu o přístup.

Protokolování přístupu pomocí událostí:

Základní koncept definovaný v principech zabezpečení je AAA (ověřování, autorizace a auditování).

Ověření poskytuje ethereum, když uživatel zahájí transakci s určitým účtem. Předpokládá se, že uživatel vlastní účet, protože je schopen jej použít k zahájení transakce. Odpovědnost za toto ověření, jehož výsledkem je autentizace uživatele pomocí hesla k jeho účtu, se provádí na úrovni klienta uzlu ethereum.

Autorizační část AAA byla implementována ACLContract, kde je vynuceno řízení přístupu na základě rolí.

Třetí část AAA je Auditing- Požadavek auditu je, že by měl být zaznamenán přístup uživatele. K tomu použijeme Události.

Solidní události:

Události jsou stejně jako proměnné běžné instance smlouvy, mohou být zděděny jako každá proměnná. Události se používají k vrácení hodnot klientovi v případě, že má být vrácen seznam hodnot, ale prozkoumáme je pouze jako prostředek k vytvoření protokolů na blockchainu. Události, když jsou „vystřeleny“ z části blockchainu s parametry, které jsou jim dodávány.

K implementaci události protokolu definujeme proměnnou události:

událost LogAccess (adresa indexována, uint indexován accessTime, metoda řetězce, řetězec desc);

Tato událost bude použita v naší metodě řízení přístupu isUser () k protokolování přístupu, o který se pokoušíte s jeho výsledkem.

funkce isUser (kandidát adresy, metoda řetězce) vrátí (bool) {

pro (uint8 i = 0; i < users.length; i ++) {

if (uživatelé [i] == kandidát) {

LogAccess (kandidát, nyní, metoda, "úspěšný přístup");

návrat true;

}

}

LogAccess (kandidát, nyní, metoda, "selhal přístup");

návrat false;

}

 

Událost parametrizuje čas (nyní) přístupového účtu (kandidáta), prostředek (metodu) a výsledek (neúspěšný přístup, úspěšný přístup). K popisu výsledku používáme řetězec, ale pro snazší vyhledávání se doporučuje použít konstanty uint.

Událost bude spuštěna pokaždé, když se přistoupí k isUser (), a pro účely auditu zaznamená přístup na blockchain. K událostem lze přistupovat prostřednictvím volání klienta web3, které uvidíme v následující části.

Uvedení ACLContrahovat použít:

Smlouva, kterou jsme vytvořili, může být zděděna jakoukoli jinou smlouvou k opětovnému použití seznamů ACL, které poskytuje. Naše datová smlouva to děděla pomocí konstrukce.

contrat DataContract je ACLContract {

Chcete-li použít zařízení ACL, budeme zachycovat volání metod ve smlouvě s isUser ():

funkce updateCustomer (uint index, název řetězce) {

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

if (index > count) hod;

customers [index] .name = name;

}

jiný hod;

}

funkce updateCustomerStatus (uint index, uint status) {

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

if (index > count) hod;

zákazníci [index] .status = stav;

}

jiný hod;

}

funkce createCustomer (

uint id,

název řetězce,

uint dateOfBirth,

uint social) {

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

customers [count] = Customer (id, name, dateOfBirth, social, pending);

count ++;

}

jiný hod;

}

Omezení řízení přístupu dodáváme pouze metodám, které aktualizují data, pokud bychom v rámci smlouvy zašifrovali údaje o zákaznících, mohli bychom implementovat omezení i na jeho možnosti čtení.

Smlouva nemůže přistupovat k událostem, které vytváří, takže pro přístup k událostem budeme potřebovat, aby náš web3 klient vytvořil hovor:

Za předpokladu, že ABI uzavřela smlouvu s ABI a adresa je jeho umístění na blockchainu.

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

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

console.log (eventLogs);

Událostí je mnohem víc, než jak je používáme výše, naším cílem je je načíst pro účely auditu.

Atributové řízení přístupu:

Je možné mít jiný typ řízení přístupu, kde jsou oprávnění uživatelé identifikováni pomocí atributu. Diskutujeme o tom, abychom ilustrovali „řízení přístupu na základě atributů“, o kterém jsme hovořili v úvodu. Toto je jen variace volání isUser ():

funkce isUserAuthorized (kandidát adresy, metoda řetězce) vrací (bool) {

pro (uint8 i = 0; i < users.length; i ++) {

if (candidate.balance > 100){

LogAccess (msg.sender, nyní, metoda, "úspěšný přístup");

návrat true;

}

}

LogAccess (msg.sender, nyní, metoda, "selhal přístup");

návrat false;

}

Toto je velmi triviální příklad, kdy oprávněným uživatelem je ten, kdo má rovnováhu etherů větší než 100.

Mike Owergreen Administrator
Sorry! The Author has not filled his profile.
follow me
Like this post? Please share to your friends:
map