Dit artikel is het volgende in serie op het vorige waarin werd gesproken over datacontracten. Het voorbeeldcontract in de vorige discussie was afkomstig van een contract met de naam ‘ACLContract’, maar we gebruikten geen enkele functie van het ACLContract omdat we nog moesten zien hoe ACL (Access Control List) en ‘eventing’ konden worden gebruikt om toegangscontrole en toegangsregistratiefaciliteit.

Toegangscontrole is een mechanisme om selectieve toegang tot een bron te beperken. Er zijn verschillende soorten toegangscontrolemodellen in de informatietechnologie, de meeste zijn gericht op de gebruiker of “opdrachtgever” die probeert toegang te krijgen tot de bron. Er zijn situaties waarin de bron zelf de toegang ertoe kan bepalen, maar daar gaan we niet op in. Voor ons doel houden we ons aan twee soorten toegangscontroles: op rollen gebaseerd en op kenmerken.

Inleiding tot Solidity: ACL en evenementen. [Deel 2]

Erfenis:

Aangezien toegangscontrole een functie is die tot op zekere hoogte inplugbaar zou moeten zijn, maken we gebruik van overerving om deze functie aan uw domeincontracten toe te voegen. Overerving in soliditeit gebruikt het kopieercodemechanisme om de “supercontract” -code in “subcontract” te plaatsen – supercontract is het overerfbare contract en subcontract is het overervende contract. Solidity ondersteunt ook een Object Oriented Programming (OOPS) -concept van polymorfisme, waarbij een contractinstantie kan verdubbelen als een van de subklasse-instanties.

Ons ACL-contract (Access Control List) wordt overgenomen door een domeincontract en biedt functies voor beheer van gegevenstoegang. Het domeincontract hoeft alleen zijn resource-oproepen te omringen met de ACL-contractmethoden die het zal erven.

ACL-contract:

Het uitgangspunt van het ACL-contract is om methoden te bieden voor het maken / beheren van een lijst of lijsten met gebruikers en om methoden te bieden die elke specifieke gebruiker met die lijst kunnen vergelijken. Onze aanname is dat elke gebruiker van een contract een “adrestype” is – adres is een speciaal type variabele in soliditeit dat uw portemonnee of accountadres vertegenwoordigt. Het is logisch om het als gebruikersreferentie te gebruiken, aangezien een gebruiker alleen toegang heeft tot een contract via zijn accountadres. We kunnen er ook van uitgaan dat de oproep van een adres authentiek is, omdat deze alleen kan worden gedaan als de gebruiker toegang heeft tot de privésleutel van het account, wat het uitgangspunt is van authenticiteit op ethereum.  

Het basissjabloon van het contract zal twee instantievariabelen hebben:

 

adres openbare eigenaar;

adres [] openbare gebruikers;

Het adres van de eigenaar is de maker van het contract. We zullen het instantiëren tijdens de constructor-aanroep. Dit is een redelijke veronderstelling, aangezien de eigenaar het contract alleen mag inzetten, tenzij we de functies van de eigenaar moeten delegeren aan een ander adres, waarvoor we voorzieningen zullen treffen in het contract, zoals we zullen zien.

Dus als het contract ACLContract wordt genoemd, zal de volgende code het adres van de eigenaar instantiëren en ook de eigenaar tot een van de gebruikers maken.

functie ACLContract () {

eigenaar = msg.sender;

users.push (eigenaar);

Zodra we het contract hebben opgesteld, hebben we enkele bedieningsmethoden nodig om de lijst met gebruikers te beheren. Het bericht is een speciaal type object in soliditeit dat gegevens bevat over de beller of afzender van een transactie. In dit geval zal het implementatieaccount de beller van de transactie die het contract implementeert, toewijzen, dus zullen we dat eigenaaradres toewijzen aan het adres van deze beller.

function addUser (adres gebruiker) {

if (msg.sender! = eigenaar) worp;

users.push (gebruiker);

functie getIthUser (uint i) constante retourneert (adres) {

gebruikers teruggeven [i];

functie getUserCount () constante retourneert (uint) {

gebruikers teruggeven. lengte;

functie deleteIthUser (uint i) {

if (msg.sender! = eigenaar) worp;

gebruikers verwijderen [i];

Deze methoden worden door klanten gebruikt om de gebruikerslijst te beheren. We zien dat alleen de eigenaar de mogelijkheid heeft om de lijst te beheren met deze controle:

if (msg.sender! = eigenaar) worp;

Dus deze code komt overeen met het adres van de beller met de eigenaar en mislukt de transacties met een worp voor het geval er een mismatch is. Voordat we verder gaan, moeten we een beetje kijken naar het gooien van uitzonderingen, omdat dit de belangrijkste bescherming is die we zullen plaatsen voor het geval ons toegangscontrolemechanisme faalt.

Uitzonderingen:

Uitzonderingen zijn het mechanisme in soliditeit om een ​​foutsituatie in een transactie aan te geven. Het resultaat van een uitzondering is dat het huidige gesprek wordt gestopt en alle effecten van de transactie worden teruggedraaid. Als de uitzondering optreedt in een oproepstapel, wordt de uitzondering teruggestuurd naar de eerste aanroeper. Momenteel is het niet mogelijk om te herstellen van de uitzondering in soliditeit, aangezien de gedeeltelijke statuswijziging die heeft plaatsgevonden mogelijk niet veilig is om de transactie voort te zetten, dus om de atomiciteit van de transactie te behouden, worden alle wijzigingen teruggedraaid.

Er zijn twee soorten uitzonderingen: runtime-uitzonderingen en door de gebruiker opgegeven uitzonderingen.

Runtime-uitzonderingen treden automatisch op in het geval de code de 12 situaties tegenkomt die worden vermeld in de solidity-documentatie (raadpleeg de documentatie – te omvangrijk en overbodig om hier te plakken), dit zijn meestal afwijkingen die kunnen optreden in de staat van de afschrift / transactie die wordt uitgevoerd is succesvol.

Door de gebruiker aangeleverde uitzonderingen zijn het handmatig invoeren van code. Er zijn twee manieren om ze aan te maken: gebruik vereisen met een voorwaarde die onwaar blijkt te zijn, of gebruik een expliciete worp. We gebruiken de voorwaardelijke worp, en zoals we willen, zal dit de transactie-effecten ongedaan maken en de oproep mislukken in geval van schending van de toegangscontrole die is ingesteld.

Terugkomend op ons ACLContract, we hebben het maken van de lijst met gebruikers en de methoden die we nodig hebben om het te beheren voltooid. Er zijn enkele kanttekeningen bij wat we hebben gedaan. Het is mogelijk om twee lijsten te maken: een voor alleen-lezen gebruikers en een andere voor gebruikers die lezen en schrijven.

Het feit is dat alle gegevens die aanwezig zijn in ethereum blockchain openbaar van aard zijn, dus het heeft geen zin om alleen-lezen gebruikers te maken, omdat iedereen die gegevens kan zien, maar in het geval dat de gegevenstoegang op een bepaalde manier is gecodeerd waardoor het kan worden gekoppeld aan een gebruikersaccount, dan kunnen we denken aan een alleen-lezen gebruiker. Er zijn discussies in de ethereum-gemeenschap om ethereum blockchain privacyvriendelijk te maken, en er zijn meerdere voorstellen over hoe dat kan worden gedaan.

Als we ervan uitgaan dat we met een van die voorstellen of via een aangepast schema onze gegevens kunnen versleutelen en we ervoor kunnen zorgen dat gegevenstoegang alleen mogelijk is via contractcode, dan zullen we het nuttig vinden om twee lijsten – een alleen-lezen gebruiker en een lezen-schrijven gebruiker. De code daarvoor zal erg lijken op wat we hebben geschreven voor onze enkele array-gebruikers. We hebben slechts vier beheermethoden nodig voor elke lijst (readUsers en writeUsers).

Toegangscontrole creëren:

Om een ​​gebruiker te toetsen aan de toegangscontrolelijst, moeten we deze matchen met de lijst met adressen. We kunnen een eenvoudige methode maken die een gebruikersadres accepteert en probeert het te matchen met de lijst:

function isUser (adreskandidaat, stringmethode) retourneert (bool) {

voor (uint8 i = 0; i < gebruikerslengte; i ++) {

if (gebruikers [i] == kandidaat) {

terugkeer waar;

teruggeven false;

De logica is eenvoudig te begrijpen als we de gebruiker in de lijst vinden, we de lus verlaten met true, als we geen elementen meer in de lijst hebben, dan retourneren we false. De parameter string method die wordt doorgegeven, wordt later gebruikt als we het hebben over eventing om de toegang van de gebruiker en het resultaat van de toegangspoging te loggen.

Toegang loggen met behulp van gebeurtenissen:

Het basisconcept dat is gedefinieerd in beveiligingsprincipes is AAA (authenticatie, autorisatie en audit).

De authenticatie wordt geleverd door ethereum wanneer de gebruiker een transactie start met een bepaald account. Aangenomen wordt dat de gebruiker eigenaar is van de rekening, aangezien hij deze kan gebruiken om de transactie te starten. De verantwoordelijkheid van die validatie die resulteert in de authenticatie van de gebruiker met zijn accountwachtwoord, wordt gedaan op het clientniveau van de ethereum-knooppunt.

Het autorisatiegedeelte van de AAA is geïmplementeerd door het ACLContract waar op rollen gebaseerde toegangscontrole wordt afgedwongen.

Het derde deel van AAA is Auditing. De vereiste van auditing is dat gebruikerstoegang moet worden geregistreerd. Om dit te doen zullen we evenementen gebruiken.

Solidity-evenementen:

Gebeurtenissen zijn net als normale instantievariabelen van een contract, ze kunnen worden overgenomen zoals elke variabele. Gebeurtenissen worden gebruikt om waarden naar de klant terug te sturen in het geval dat een lijst met waarden moet worden geretourneerd, maar we zullen ze alleen onderzoeken als een middel om logboeken op de blockchain te maken. Gebeurtenissen waarbij ze worden “afgevuurd” vanuit een deel van de blockchain met de parameters die aan hen worden geleverd.

Om een ​​loggebeurtenis te implementeren, zullen we een gebeurtenisvariabele definiëren:

event LogAccess (adres geïndexeerd door, uint geïndexeerde accessTime, stringmethode, string desc);

Deze gebeurtenis wordt gebruikt in onze toegangscontrolemethode isUser () om de toegang die wordt geprobeerd te loggen met het resultaat.

function isUser (adreskandidaat, stringmethode) retourneert (bool) {

voor (uint8 i = 0; i < gebruikerslengte; i ++) {

if (gebruikers [i] == kandidaat) {

LogAccess (kandidaat, nu, methode, "succesvolle toegang"​

terugkeer waar;

LogAccess (kandidaat, nu, methode, "mislukte toegang"​

teruggeven false;

 

De gebeurtenis parametriseert het toegangsaccount (kandidaat) de tijd, (nu) de bron (methode) en het resultaat (mislukte toegang, succesvolle toegang). We gebruiken een tekenreeks om het resultaat te beschrijven, maar het wordt aanbevolen om uint-constanten te gebruiken om gemakkelijker te kunnen zoeken.

De gebeurtenis wordt geactiveerd elke keer dat isUser () wordt geopend en zal de toegang op de blockchain registreren voor controledoeleinden. De evenementen zijn toegankelijk via een web3-clientoproep die we in de volgende sectie zullen zien.

Zetten ACLContract gebruiken:

Het contract dat we hebben gemaakt, kan worden overgenomen door elk ander contract om de ACL-lijsten die door het contract worden verstrekt, opnieuw te gebruiken. Ons datacontract erfde het met behulp van het construct.

contrat DataContract is ACLContract {

Om de ACL-faciliteit te gebruiken, zullen we de methodeaanroepen in het contract met de isUser () onderscheppen:

functie updateCustomer (uint index, string naam) {

if (isUser (msg.sender, "updateCustomer"​

if (index > count) gooien;

klanten [index] .name = naam;

anders gooien;

functie updateCustomerStatus (uint index, uint status) {

if (isUser (msg.sender, "updateCustomer"​

if (index > count) gooien;

klanten [index] .status = status;

anders gooien;

functie createCustomer (

uint-id,

string naam,

uint dateOfBirth,

uint sociaal) {

if (isUser (msg.sender, "createCustomer"​

klanten [aantal] = Klant (id, naam, dateOfBirth, sociaal, in afwachting);

tel ++;

anders gooien;

We bieden alleen toegangscontrole-beperkingen voor methoden die de gegevens bijwerken, als we de klantgegevens binnen het contract hadden versleuteld, zouden we ook beperkingen op de leesmogelijkheden kunnen implementeren.

Het contract heeft geen toegang tot de evenementen die het creëert, dus om toegang te krijgen tot de evenementen hebben we onze web3-client nodig om een ​​oproep te maken:

Ervan uitgaande dat de ABI ABI heeft gecontracteerd en dat het adres de locatie op de blockchain is.

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

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

console.log (eventLogs);

Evenementen zijn veel meer dan hoe we het hierboven gebruiken, ons doel is om ze op te halen voor controledoeleinden.

Op attributen gebaseerde toegangscontrole:

Het is mogelijk om een ​​ander type toegangscontrole te hebben waarbij geautoriseerde gebruikers worden geïdentificeerd door een kenmerk. We bespreken dit om de “Attribuutgebaseerde toegangscontrole” te illustreren waar we het in de inleiding over hadden. Dit is slechts een variatie op de aanroep isUser ():

function isUserAuthorized (adreskandidaat, stringmethode) retourneert (bool) {

voor (uint8 i = 0; i < gebruikerslengte; i ++) {

if (kandidaat.balans > 100) {

LogAccess (msg.sender, nu, method, "succesvolle toegang"​

terugkeer waar;

LogAccess (msg.sender, nu, method, "mislukte toegang"​

teruggeven false;

Dit is het zeer triviale voorbeeld waarbij een geautoriseerde gebruiker degene is met een saldo-ethers groter dan 100.

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