diff --git a/public/content/translations/it/bridges/index.md b/public/content/translations/it/bridges/index.md index 2bfc863783d..4a25cd173a7 100644 --- a/public/content/translations/it/bridges/index.md +++ b/public/content/translations/it/bridges/index.md @@ -63,7 +63,7 @@ Diciamo che vuoi possedere Bitcoin (BTC) nativi, ma hai fondi soltanto sulla Ret - Inoltre, puoi fare tutto quanto descritto sopra, usando una [borsa centralizzata](/get-eth/). Tuttavia, a meno che i tuoi fondi non siano già su una borsa, comporterebbe diversi passaggi, e sarebbe più conveniente usare un ponte. + Inoltre, puoi fare tutto quanto descritto sopra, usando una [borsa centralizzata](/get-eth). Tuttavia, a meno che i tuoi fondi non siano già su una borsa, comporterebbe diversi passaggi, e sarebbe più conveniente usare un ponte. diff --git a/public/content/translations/it/community/grants/index.md b/public/content/translations/it/community/grants/index.md index 1312d04005a..2d6d26e7ac0 100644 --- a/public/content/translations/it/community/grants/index.md +++ b/public/content/translations/it/community/grants/index.md @@ -20,7 +20,7 @@ Questi programmi supportano il grande ecosistema di Ethereum offrendo sovvenzion - [Sovvenzioni accademiche](https://esp.ethereum.foundation/academic-grants) - _Sovvenzioni per sostenere il lavoro accademico correlato a Ethereum_ - [Grantfarm di Blockworks](https://blockworks.co/grants/programs) - _Blockworks ha compilato una directory esaustiva di tutte le sovvenzioni, RDP e bug bounty._ -## Programmi per progetti specifici {#project-specific} +## Programmi per progetti specifici {#grant-list-aggregators} Questi progetti hanno creato le proprie sovvenzioni per progetti volti a sviluppare e sperimentare la propria tecnologia. @@ -35,13 +35,13 @@ Questi progetti hanno creato le proprie sovvenzioni per progetti volti a svilupp - [The Graph](https://thegraph.com/ecosystem/grants/): _Ecosistema di [The Graph](https://thegraph.com/)_ - [Programma di sovvenzioni di Uniswap](https://www.uniswapfoundation.org/approach): _community di [Uniswap](https://uniswap.org/)_ -## Finanziamento quadratico {#quadratic-funding} +## Finanziamento quadratico {#comprehensive-directories} Le radici dell'open source di Ethereum hanno portato alla crescita di un nuovo modello interessante di raccolta fondi: il finanziamento quadratico. Questo finanziamento ha il potenziale di migliorare il modo in cui finanzieremo tutti i tipi di beni pubblici in futuro. Il finanziamento quadratico assicura che i progetti che riceveranno più finanziamenti siano quelli con la domanda più esclusiva. In sintesi, i progetti che cercano di migliorare la vita del maggior numero di persone. [Maggiori informazioni sul finanziamento quadratico.](/defi/#quadratic-funding) - [Gitcoin](https://gitcoin.co/grants) - [clr.fund](https://clr.fund/) -## Lavora su Ethereum {#work-in-ethereum} +## Lavora su Ethereum {#for-developers-and-builders} Non sei pronto per iniziare il tuo progetto? Ci sono centinaia di aziende che cercano attivamente persone appassionate con cui lavorare e contribuire all'ecosistema Ethereum. Cerchi maggiori informazioni? [Dai un'occhiata ai lavori relativi a Ethereum](/community/get-involved/#ethereum-jobs) diff --git a/public/content/translations/it/community/online/index.md b/public/content/translations/it/community/online/index.md index 6f38b657f11..8a75d8f69e7 100644 --- a/public/content/translations/it/community/online/index.md +++ b/public/content/translations/it/community/online/index.md @@ -71,5 +71,5 @@ Se credi che una community dovrebbe essere aggiunta o rimossa secondo queste lin Maggiori informazioni sulle DAO - + diff --git a/public/content/translations/it/community/research/index.md b/public/content/translations/it/community/research/index.md index 61e2c88901e..ce50934e2d4 100644 --- a/public/content/translations/it/community/research/index.md +++ b/public/content/translations/it/community/research/index.md @@ -242,7 +242,7 @@ I mercati degli spazi di blocco governano l'inclusione delle transazioni dell'ut - [Progettazione del meccanismo delle commissioni sulle transazioni per la blockchain di Ethereum: un'analisi economica di EIP-1559 (Tim Roughgarden, 2020)](https://timroughgarden.org/papers/eip1559.pdf) - [Simulazioni di EIP-1559 (Gruppo di incentivi robusti)](https://ethereum.github.io/abm1559) - [Economia dei rollup dai primi principi](https://barnabe.substack.com/p/understanding-rollup-economics-from?utm_source=url) -- [Flash Boys 2.0: frontrunning, riordinamento delle transazioni e instabilità del consenso nelle borse decentralizzate] (https://arxiv.org/abs/1904.05234) +- [Flash Boys 2.0: frontrunning, riordinamento delle transazioni e instabilità del consenso nelle borse decentralizzate](https://arxiv.org/abs/1904.05234) #### Ricerca recente {#recent-research-10} diff --git a/public/content/translations/it/contributing/design/adding-design-resources/index.md b/public/content/translations/it/contributing/design/adding-design-resources/index.md index f696b61a581..e5cf27c42f7 100644 --- a/public/content/translations/it/contributing/design/adding-design-resources/index.md +++ b/public/content/translations/it/contributing/design/adding-design-resources/index.md @@ -1,6 +1,6 @@ --- title: Aggiungere risorse di progettazione -description: Linee guida e requisiti per assicurare la qualità dei materiali di progettazione su ethereum.org +description: "Linee guida e requisiti per assicurare la qualità dei materiali di progettazione su ethereum.org" lang: it --- diff --git a/public/content/translations/it/contributing/index.md b/public/content/translations/it/contributing/index.md index bc5f4e1f2b4..e38f0602fb1 100644 --- a/public/content/translations/it/contributing/index.md +++ b/public/content/translations/it/contributing/index.md @@ -4,7 +4,7 @@ description: Scopri i vari modi in cui puoi contribuire a ethereum.org lang: it --- -# Contribuire a ethereum.org {#contributing-to-ethereumorg} +# Contribuire a ethereum.org {#contributing-to-ethereumorg} Ethereum.org è un progetto open source con oltre **12000** collaboratori che aiutano a tradurre, scrivere, progettare e mantenere il sito web. @@ -90,6 +90,7 @@ Se il tuo contributo viene aggiunto a ethereum.org, avrai una possibilità di ri [Maggiori informazioni sui OAT](https://help.galxe.com/en/articles/9645630-create-quest-rewards#h_1c5d63ba03) ### Come reclamare + 1. Unisciti al nostro [server Discord](https://discord.gg/ethereum-org). 2. Incolla un link ai tuoi contributi nel canale `#🥇 | proof-of-contribution`. 3. Attendi che un membro del nostro team ti invii un collegamento al tuo OAT. diff --git a/public/content/translations/it/dao/index.md b/public/content/translations/it/dao/index.md index 4c3071f0bf0..77019dfb643 100644 --- a/public/content/translations/it/dao/index.md +++ b/public/content/translations/it/dao/index.md @@ -1,11 +1,11 @@ --- -title: Cos'è una DAO? -metaTitle: Cos'è una DAO? | Organizzazione autonoma decentralizzata +title: "Cos'è una DAO?" +metaTitle: "Cos'è una DAO? | Organizzazione autonoma decentralizzata" description: Una panoramica delle DAO su Ethereum lang: it template: use-cases emoji: ":handshake:" -sidebarDepth: 3 +sidebarDepth: 2 image: /images/use-cases/dao-2.png alt: Rappresentazione di una votazione DAO su una proposta. summaryPoint1: Community posseduta dai membri, prive di leadership centralizzata. @@ -19,7 +19,7 @@ Una DAO è un'organizzazione posseduta collettivamente che opera per realizzare Le DAO ci consentono di lavorare con persone con la stessa mentalità provenienti da tutto il mondo, senza doversi fidare di un capo benevolo, per la gestione di fondi od operazioni. Non esiste alcun CEO che possa spendere i fondi secondo i propri capricci, o CFO che possa manipolare i libri contabili. Invece, le regole basate sulla blockchain, integrate nel codice, definiscono il funzionamento dell'organizzazione e come vengono spesi i fondi. -Contengono delle tesoriere integrate, a cui nessuno ha l'autorità di accedere senza l'approvazione del gruppo. Le decisioni sono governate da proposte e votazioni, per assicurarsi che tutti nell'organizzazione abbiano voce in capitolo, e che tutto si verifichi in modo trasparente [sulla catena](/glossary/#on-chain). +Contengono delle tesoriere integrate, a cui nessuno ha l'autorità di accedere senza l'approvazione del gruppo. Le decisioni sono governate da proposte e votazioni, per assicurarsi che tutti nell'organizzazione abbiano voce in capitolo, e che tutto si verifichi in modo trasparente [sulla catena](/glossary/#onchain). ## Perché abbiamo bisogno delle DAO? {#why-dao} @@ -70,9 +70,7 @@ Ci sono molte considerazioni da fare governando una DAO, ad esempio, come funzio Una delegazione è la versione della democrazia rappresentativa della DAO. I titolari di token delegano i voti agli utenti da loro stessi nominati e si impegnano a gestire il protocollo e a rimanere informati. -#### Un celebre esempio {#governance-example} - -[ENS](https://claim.ens.domains/delegate-ranking) – I titolari di ENS possono delegare i propri voti a membri impegnati della community perché li rappresentino. +#### Un celebre esempio {#governance-example}[ENS](https://claim.ens.domains/delegate-ranking) – I titolari di ENS possono delegare i propri voti a membri impegnati della community perché li rappresentino. ### Governance automatica delle transazioni {#governance-example} diff --git a/public/content/translations/it/decentralized-identity/index.md b/public/content/translations/it/decentralized-identity/index.md index 75457fe89fd..e57da4d582a 100644 --- a/public/content/translations/it/decentralized-identity/index.md +++ b/public/content/translations/it/decentralized-identity/index.md @@ -1,13 +1,13 @@ --- -title: Identità decentralizzata -description: Cos'è l'identità decentralizzata e perché è importante? +title: "Identità decentralizzata" +description: "Cos'è l'identità decentralizzata e perché è importante?" lang: it template: use-cases emoji: ":id:" sidebarDepth: 2 image: /images/eth-gif-cat.png -summaryPoint1: I sistemi di identità tradizionali hanno centralizzato l'emissione, manutenzione e controllo dei tuoi identificativi. -summaryPoint2: L'identità decentralizzata rimuove la dipendenza da terze parti centralizzate. +summaryPoint1: "I sistemi di identità tradizionali hanno centralizzato l'emissione, manutenzione e controllo dei tuoi identificativi." +summaryPoint2: "L'identità decentralizzata rimuove la dipendenza da terze parti centralizzate." summaryPoint3: Grazie alle cripto, gli utenti, ora, hanno nuovamente gli strumenti per emettere, detenere e controllare i propri identificativi e attestazioni. --- @@ -75,13 +75,13 @@ L'identità decentralizzata può aiutare a creare delle community online prive d Le applicazioni di concessione di sovvenzioni che utilizzano il [voto quadratico](/glossary/#quadratic-voting) sono vulnerabili agli [attacchi Sybil](/glossary/#sybil-attack) poiché il valore di una sovvenzione viene incrementato all'aumentare delle persone che votano, incentivando gli utenti a dividere i propri contributi tra più identità. Le identità decentralizzate aiutano a prevenirli, incrementando l'onere su ogni partecipante, per dimostrare che siano realmente umani, sebbene spesso senza dover rilevare informazioni private specifiche. -## Cosa sono le attestazioni? {#what-are-attestations} +## Cosa sono le attestazioni? {#national-and-government-id} Un'attestazione, è una dichiarazione effettuata da un'entità, in merito a un'altra entità. Se vivi in Italia, la patente di guida rilasciata dal Dipartimento dei Trasporti Terrestri (un'entità), attesta che tu (un'altra entità), sei legalmente autorizzato a guidare un'auto. Le attestazioni sono differenti dagli identificativi. Un'attestazione _contiene_ degli identificativi, riferiti a un'identità in particolare, ed effettua una dichiarazione su di un attributo, relativo a tale identità. Quindi, la tua patente di guida contiene degli identificativi (nome, data di nascita, indirizzo), ma è anche l'attestazione sul tuo diritto legale alla guida. -### Cosa sono gli identificativi decentralizzati? {#what-are-decentralized-identifiers} +### Cosa sono gli identificativi decentralizzati? {#case-study-bhutan-ndi} Gli identificativi tradizionali, come il tuo nome legale o l'indirizzo email, si affidano a terze parti: governi e fornitori di email. Gli identificativi decentralizzati (DID), sono differenti: non sono emessi, gestiti o controllati da alcuna entità centrale. @@ -89,21 +89,21 @@ Gli identificativi decentralizzati sono emessi, detenuti e controllati dagli ind Gli identificativi decentralizzati sono memorizzati su libri mastri distribuiti ([blockchain](/glossary/#blockchain)) o su [reti peer-to-peer](/glossary/#peer-to-peer-network). Ciò rende i DID [unici a livello globale, risolvibili con elevata disponibilità e crittograficamente verificabili](https://w3c-ccg.github.io/did-primer/). Un identificativo decentralizzato può essere associato a diverse entità, tra cui persone, organizzazioni, o istituzioni governative. -## Cosa rende possibili gli identificativi decentralizzati? {#what-makes-decentralized-identifiers-possible} +## Cosa rende possibili gli identificativi decentralizzati? {#case-study-buenos-aires-quarkid} -### 1. Crittografia a chiave pubblica {#public-key-cryptography} +### 1. Crittografia a chiave pubblica {#what-are-attestations} La crittografia a chiave pubblica è una misura di sicurezza informatica che genera una [chiave pubblica](/glossary/#public-key) e una [chiave privata](/glossary/#private-key) per un'entità. La [crittografia](/glossary/#cryptography) a chiave pubblica è utilizzata nelle reti blockchain per autenticare le identità degli utenti e dimostrare la proprietà delle risorse digitali. Alcuni identificativi decentralizzati, come un conto di Ethereum, includono chiavi pubbliche e private. La chiave pubblica identifica chi controlla il conto, mentre le chiavi private possono firmare e decrittografare i messaggi per tale conto. La crittografia a chiave pubblica fornisce le prove necessarie per autenticare le entità, oltre a prevenire i furti d'identità e l'utilizzo di false identità, utilizzando le [firme crittografiche](https://andersbrownworth.com/blockchain/public-private-keys/) per verificare tutte le dichiarazioni. -### 2. Datastore decentralizzati {#decentralized-datastores} +### 2. Datastore decentralizzati {#what-are-decentralized-identifiers} Una blockchain funge da registro di dati verificabili: una repository di informazioni aperta, affidabile e decentralizzata. L'esistenza delle blockchain pubbliche elimina l'esigenza di memorizzare gli identificativi nei registri centralizzati. Se qualcuno deve confermare la validità di un identificativo decentralizzato, può consultare la chiave pubblica associata sulla blockchain. Ciò differisce dagli identificativi tradizionali, che richiedono l'autenticazione da parte di terzi. -## Come fanno le attestazioni e gli identificativi decentralizzati a consentire l'identità decentralizzata? {#how-decentralized-identifiers-and-attestations-enable-decentralized-identity} +## Come fanno le attestazioni e gli identificativi decentralizzati a consentire l'identità decentralizzata? {#what-makes-decentralized-identifiers-possible} L'identità decentralizzata è l'idea che le informazioni sull'identità dovrebbero essere controllate dall'individuo, private e portatili, con attestazioni e identificativi decentralizzati come blocchi di costruzione principali. @@ -115,11 +115,11 @@ Gli identificativi decentralizzati sono il motivo per cui le attestazioni sono c Inoltre, gli identificativi decentralizzati sono fondamentali per la protezione della privacy delle informazioni personali, tramite l'identità decentralizzata. Ad esempio, se un individuo invia la prova di un'attestazione (una patente di guida), la parte che verifica non necessita di controllare la validità delle informazioni nella prova. Invece, chi verifica necessita soltanto delle garanzie crittografiche dell'autenticità dell'attestazione, e dell'identità dell'organizzazione emittente, per determinare se la prova sia valida. -## Tipi di attestazioni nell'identità decentralizzata {#types-of-attestations-in-decentralized-identity} +## Tipi di attestazioni nell'identità decentralizzata {#public-key-cryptography} Le modalità di memorizzazione e recupero delle informazioni sull'attestazione, nell'ecosistema delle identità basato su Ethereum, differiscono dalla gestione tradizionale delle identità. Ecco una panoramica dei vari approcci all'emissione, memorizzazione e verifica delle attestazioni, nei sistemi di identità decentralizzati: -### Attestazioni esterne alla catena {#off-chain-attestations} +### Attestazioni esterne alla catena {#decentralized-datastores} Un timore per la memorizzazione su catena è che potrebbero contenere informazioni che gli individui desiderano mantenere private. La natura pubblica della blockchain di Ethereum, rende poco attraente la memorizzazione di tali attestazioni. @@ -131,13 +131,13 @@ Ecco uno scenario ipotetico per spiegare le attestazioni esterne alla catena: 2. Bob si candida per un lavoro e desidera dimostrare le proprie qualifiche accademiche a un datore di lavoro, quindi, condivide l'attestazione dal proprio portafoglio mobile. L'azienda (verificatore), può quindi confermare la validità dell'attestazione, verificando il DID dell'emittente (cioè, la sua chiave pubblica su Ethereum). -### Attestazioni esterne alla catena con accesso persistente {#offchain-attestations-with-persistent-access} +### Attestazioni esterne alla catena con accesso persistente {#how-decentralized-identifiers-and-attestations-enable-decentralized-identity} In questo modo, le attestazioni sono trasformate in file JSON e memorizzate all'esterno della catena (idealmente, su una piattaforma di [archiviazione decentralizzata su cloud](/developers/docs/storage/), come IPFS o Swarm). Tuttavia, un [hash](/glossary/#hash) del file JSON è memorizzato sulla catena e collegato a un DID, tramite il registro sulla catena. Il DID associato potrebbe essere quello dell'emittente dell'attestazione, o del destinatario. Tale approccio consente alle attestazioni di ottenere persistenza basata sulla blockchain, mantenendo le informazioni delle dichiarazioni, crittografate e verificabili. Inoltre, consente la divulgazione selettiva, poiché il titolare della chiave privata può decrittografare le informazioni. -### Attestazioni sulla catena {#onchain-attestations} +### Attestazioni sulla catena {#types-of-attestations-in-decentralized-identity} Le attestazioni sulla catena sono conservate nei [contratti intelligenti](/glossary/#smart-contract) sulla blockchain di Ethereum. Il contratto intelligente (che agisce da registro), mapperà un'attestazione a un identificativo decentralizzato corrispondente sulla catena (una chiave pubblica). @@ -149,11 +149,11 @@ Ecco un esempio per dimostrare il funzionamento in pratica delle attestazioni su 3. Il contratto intelligente che vende le quote, può verificare il contratto del registro per le identità degli acquirenti verificati, rendendo possibile la determinazione di chi possa acquistare le quote e chi no. -### Token vincolati e identità {#soulbound} +### Token vincolati e identità {#offchain-attestations} I [token vincolati](https://vitalik.eth.limo/general/2022/01/26/soulbound.html) ([NFT non trasferibili](/glossary/#nft)) potrebbero essere utilizzati per raccogliere informazioni univoche per un portafoglio specifico. Ciò, effettivamente, crea un'identità univoca sulla catena, vincolata a un indirizzo di Ethereum in particolare, che potrebbe includere i token rappresentanti obiettivi (ad esempio, concludere un certo corso online o superare una soglia di punteggio in un gioco), o la partecipazione della community. -## Utilizzare l'identità decentralizzata {#use-decentralized-identity} +## Utilizzare l'identità decentralizzata {#offchain-attestations-with-persistent-access} Esistono molti progetti ambiziosi che utilizzano Ethereum come base per le soluzioni di identità decentralizzata: @@ -165,9 +165,9 @@ Esistono molti progetti ambiziosi che utilizzano Ethereum come base per le soluz - **[walt.id](https://walt.id)**: _Infrastruttura open source di identità decentralizzata e portafoglio che consente a sviluppatori e organizzazioni di sfruttare l'identità auto-sovrana e gli NFT/SBT._ - **[Veramo](https://veramo.io/)**: _Un framework di JavaScript che facilita per tutti l'utilizzo di dati verificabili crittograficamente nelle proprie applicazioni._ -## Lettura consigliate {#further-reading} +## Lettura consigliate {#onchain-attestations} -### Articoli {#articles} +### Articoli {#soulbound} - [Casi d'Uso della Blockchain: La Blockchain nell'Identità Digitale](https://consensys.net/blockchain-use-cases/digital-identity/) — _ConsenSys_ - [Cos'è l'ERC-725 di Ethereum? Gestione dell'Identità Sovrana Personale sulla Blockchain](https://cryptoslate.com/what-is-erc725-self-sovereign-identity-management-on-the-blockchain/) — _Sam Town_ @@ -175,7 +175,7 @@ Esistono molti progetti ambiziosi che utilizzano Ethereum come base per le soluz - [Cos'è l'Identità Decentralizzata e Perché Dovrebbe Interessarti?](https://web3.hashnode.com/what-is-decentralized-identity) — _Emmanuel Awosika_ - [Introduzione all'Identità decentralizzata](https://walt.id/white-paper/digital-identity) - _Dominik Beron_ -### Video {#videos} +### Video {#use-decentralized-identity} - [Identità Decentralizzata (Sessione Live Bonus)](https://www.youtube.com/watch?v=ySHNB1za_SE&t=539s) — _Un ottimo video esplicativo sull'identità decentralizzata, di Andreas Antonopolous_ - [Accedi con Ethereum e l'Identità Decentralizzata con Ceramic, IDX, React e 3ID Connect](https://www.youtube.com/watch?v=t9gWZYJxk7c) — _Tutorial di YouTube sulla creazione di un sistema di gestione dell'identità, per creare, leggere e aggiornare il profilo di un utente, utilizzandone il portafoglio di Ethereum; di Nader Dabit_ @@ -183,7 +183,7 @@ Esistono molti progetti ambiziosi che utilizzano Ethereum come base per le soluz - [L'Internet esterno alla Catena: Identità Decentralizzata e Credenziali Verificabili](https://www.youtube.com/watch?v=EZ_Bb6j87mg) — Presentazione dell'EthDenver del 2022, di Evin McMullen - [Credenziali verificabili spiegate](https://www.youtube.com/watch?v=ce1IdSr-Kig): Video esplicativo su YouTube con dimostrazione di Tamino Baumann -### Community {#communities} +### Community {#further-reading} - [ERC-725 Alliance su GitHub](https://github.com/erc725alliance) — _Sostenitori dello standard ERC-725 per la gestione dell'identità sulla blockchain di Ethereum_ - [Server Discord di EthID](https://discord.com/invite/ZUyG3mSXFD) — _Community per appassionati e sviluppatori, al lavoro su "Accedi con Ethereum"_ diff --git a/public/content/translations/it/defi/index.md b/public/content/translations/it/defi/index.md index 9d2ae0086cd..5e48954491e 100644 --- a/public/content/translations/it/defi/index.md +++ b/public/content/translations/it/defi/index.md @@ -1,16 +1,16 @@ --- title: Finanza decentralizzata (DeFi) -metaTitle: Cos'è la DeFi? | Benefici e utilizzi della finanza decentralizzata +metaTitle: "Cos'è la DeFi? | Benefici e utilizzi della finanza decentralizzata" description: Una panoramica sulla DeFi su Ethereum lang: it template: use-cases emoji: ":money_with_wings:" image: /images/use-cases/defi.png alt: Logo di Eth, composto da mattoncini Lego. -sidebarDepth: 3 +sidebarDepth: 2 summaryPoint1: Un'alternativa globale e aperta al sistema finanziario odierno. summaryPoint2: Prodotti che ti consentono di prendere in prestito, risparmiare, investire, scambiare, e molto altro. -summaryPoint3: Basata sulla tecnologia open source, con cui chiunque può programmare. +summaryPoint3: "Basata sulla tecnologia open source, con cui chiunque può programmare." --- La DeFi è un sistema finanziario aperto e globale, creato per l'era di Internet: un'alternativa a un sistema opaco, rigidamente controllato e tenuto insieme da infrastrutture e processi vecchi di decenni. Offre il controllo e la visibilità sul proprio denaro. Fornisce esposizione ai mercati globali e alternative alla tua valuta o alle opzioni bancarie locali. I prodotti della DeFi aprono i servizi finanziari a chiunque abbia una connessione a Internet, e sono prevalentemente posseduti e mantenuti dai loro utenti. Finora, decine di miliardi di dollari in criptovalute, sono confluiti per le applicazioni della DeFi, e crescono ogni giorno. diff --git a/public/content/translations/it/developers/docs/apis/json-rpc/index.md b/public/content/translations/it/developers/docs/apis/json-rpc/index.md index 9f2295b0800..3620b4aa658 100644 --- a/public/content/translations/it/developers/docs/apis/json-rpc/index.md +++ b/public/content/translations/it/developers/docs/apis/json-rpc/index.md @@ -58,7 +58,7 @@ Ecco alcuni esempi: - ERRATO: 0xf0f0f (dev'essere un numero di cifre pari) - ERRATO: 004200 (deve avere il prefisso 0x) -### Il parametro del blocco predefinito {#default-block} +### Il parametro del blocco predefinito {#block-parameter} I seguenti metodi hanno un parametro del blocco predefinito aggiuntivo: @@ -566,7 +566,7 @@ Restituisce il saldo del conto del dato indirizzo. **Parametri** 1. `DATA`, 20 byte - indirizzo per controllare il saldo. -2. `QUANTITY|TAG` - intero del numero di blocco, o la stringa `"latest"`, `"earliest"`, `"pending"`, `"safe"` o `"finalized"`, vedi il [parametro del blocco predefinito](/developers/docs/apis/json-rpc/#default-block) +2. `QUANTITY|TAG` - intero del numero di blocco, o la stringa `"latest"`, `"earliest"`, `"pending"`, `"safe"` o `"finalized"`, vedi il [parametro del blocco predefinito](/developers/docs/apis/json-rpc/#block-parameter) ```js params: ["0x407d73d8a49eeb85d32cf465507dd71d507100c1", "latest"] @@ -597,7 +597,7 @@ Restituisce il valore da una posizione di archiviazione a un dato indirizzo. 1. `DATA`, 20 byte - Indirizzo di archiviazione. 2. `QUANTITY` - intero della posizione di archiviazione. -3. `QUANTITY|TAG` - intero del numero di blocco, o la stringa `"latest"`, `"earliest"`, `"pending"`, `"safe"`, `"finalized"`, vedi il [parametro del blocco predefinito](/developers/docs/apis/json-rpc/#default-block) +3. `QUANTITY|TAG` - intero del numero di blocco, o la stringa `"latest"`, `"earliest"`, `"pending"`, `"safe"`, `"finalized"`, vedi il [parametro del blocco predefinito](/developers/docs/apis/json-rpc/#block-parameter) **Restituisce** @@ -663,7 +663,7 @@ Restituisce il numero di transazioni _inviate_da un indirizzo. **Parametri** 1. `DATA`, 20 byte - indirizzo. -2. `QUANTITY|TAG` - intero del numero di blocco, o la stringa `"latest"`, `"earliest"`, `"pending"`, `"safe"` o `"finalized"`, vedi il [parametro del blocco predefinito](/developers/docs/apis/json-rpc/#default-block) +2. `QUANTITY|TAG` - intero del numero di blocco, o la stringa `"latest"`, `"earliest"`, `"pending"`, `"safe"` o `"finalized"`, vedi il [parametro del blocco predefinito](/developers/docs/apis/json-rpc/#block-parameter) ```js params: [ @@ -724,7 +724,7 @@ Restituisce il numero di transazioni in un blocco corrispondente al numero di bl **Parametri** -1. `QUANTITY|TAG` - intero del numero di un blocco, o la stringa `"earliest"`, `"latest"`, `"pending"`, `"safe"` o `"finalized"`, come nel [parametro del blocco predefinito](/developers/docs/apis/json-rpc/#default-block). +1. `QUANTITY|TAG` - intero del numero di un blocco, o la stringa `"earliest"`, `"latest"`, `"pending"`, `"safe"` o `"finalized"`, come nel [parametro del blocco predefinito](/developers/docs/apis/json-rpc/#block-parameter). ```js params: [ @@ -784,7 +784,7 @@ Restituisce il numero di ommer in un blocco da un blocco che corrisponde all'has **Parametri** -1. `QUANTITY|TAG` - intero del numero di un blocco, o la stringa `"latest"`, `"earliest"`, `"pending"`, `"safe"` o `"finalized"`, vedi il [parametro del blocco predefinito](/developers/docs/apis/json-rpc/#default-block) +1. `QUANTITY|TAG` - intero del numero di un blocco, o la stringa `"latest"`, `"earliest"`, `"pending"`, `"safe"` o `"finalized"`, vedi il [parametro del blocco predefinito](/developers/docs/apis/json-rpc/#block-parameter) ```js params: [ @@ -816,7 +816,7 @@ Restituisce il codice ad un dato indirizzo. **Parametri** 1. `DATA`, 20 byte - indirizzo -2. `QUANTITY|TAG` - intero del numero di blocco, o la stringa `"latest"`, `"earliest"`, `"pending"`, `"safe"` o `"finalized"`, vedi il [parametro del blocco predefinito](/developers/docs/apis/json-rpc/#default-block) +2. `QUANTITY|TAG` - intero del numero di blocco, o la stringa `"latest"`, `"earliest"`, `"pending"`, `"safe"` o `"finalized"`, vedi il [parametro del blocco predefinito](/developers/docs/apis/json-rpc/#block-parameter) ```js params: [ @@ -1003,7 +1003,7 @@ Esegue immediatamente una nuova chiamata di messaggio senza creare una transazio - `value`: `QUANTITY` - (facoltativo) Intero del valore inviato con questa transazione - `input`: `DATA` - (facoltativo) Hash della firma del metodo e dei parametri codificati. Per i dettagli, consulta [ABI del Contratto di Ethereum nella documentazione di Solidity](https://docs.soliditylang.org/en/latest/abi-spec.html). -2. `QUANTITY|TAG` - intero del numero di blocco, o la stringa `"latest"`, `"earliest"`, `"pending"`, `"safe"` o `"finalized"`, vedi il [parametro del blocco predefinito](/developers/docs/apis/json-rpc/#default-block) +2. `QUANTITY|TAG` - intero del numero di blocco, o la stringa `"latest"`, `"earliest"`, `"pending"`, `"safe"` o `"finalized"`, vedi il [parametro del blocco predefinito](/developers/docs/apis/json-rpc/#block-parameter) **Restituisce** @@ -1130,7 +1130,7 @@ Restituisce informazioni su un blocco per numero di blocco. **Parametri** -1. `QUANTITY|TAG` - intero del numero di un blocco, o la stringa `"earliest"`, `"latest"`, `"pending"`, `"safe"` o `"finalized"`, come nel [parametro del blocco predefinito](/developers/docs/apis/json-rpc/#default-block). +1. `QUANTITY|TAG` - intero del numero di un blocco, o la stringa `"earliest"`, `"latest"`, `"pending"`, `"safe"` o `"finalized"`, come nel [parametro del blocco predefinito](/developers/docs/apis/json-rpc/#block-parameter). 2. `Boolean` - Se `true` restituisce gli oggetti di transazione completi, se `falso` solo gli hash delle transazioni. ```js @@ -1243,7 +1243,7 @@ Restituisce informazioni su una transazione per hash del blocco e posizione dell **Parametri** -1. `QUANTITY|TAG`: il numero di un blocco, o la stringa `"earliest"`, `"latest"`, `"pending"`, `"safe"` o `"finalized"`, come nel [parametro del blocco predefinito](/developers/docs/apis/json-rpc/#default-block). +1. `QUANTITY|TAG`: il numero di un blocco, o la stringa `"earliest"`, `"latest"`, `"pending"`, `"safe"` o `"finalized"`, come nel [parametro del blocco predefinito](/developers/docs/apis/json-rpc/#block-parameter). 2. `QUANTITY` - la posizione dell'indice della transazione. ```js @@ -1366,7 +1366,7 @@ Restituisce informazioni su un ommer di un blocco in base al numero e alla posiz **Parametri** -1. `QUANTITY|TAG` - il numero di un blocco, o la stringa `"earliest"`, `"latest"`, `"pending"`, `"safe"`, `"finalized"`, come nel [parametro predefinito del blocco](/developers/docs/apis/json-rpc/#default-block). +1. `QUANTITY|TAG` - il numero di un blocco, o la stringa `"earliest"`, `"latest"`, `"pending"`, `"safe"`, `"finalized"`, come nel [parametro predefinito del blocco](/developers/docs/apis/json-rpc/#block-parameter). 2. `QUANTITY` - la posizione dell'indice dell'ommer. ```js diff --git a/public/content/translations/it/developers/docs/blocks/index.md b/public/content/translations/it/developers/docs/blocks/index.md index ff09aa44f91..2492628c912 100644 --- a/public/content/translations/it/developers/docs/blocks/index.md +++ b/public/content/translations/it/developers/docs/blocks/index.md @@ -24,7 +24,7 @@ Per preservare la cronologia delle transazioni, i blocchi sono ordinati in modo Dopo essere stato realizzato da un validatore della rete selezionato casualmente, un blocco viene propagato al resto della rete; tutti i nodi vengono aggiunti al blocco alla fine della relativa blockchain e un nuovo validatore viene selezionato per creare il successivo. Il processo esatto di costruzione dei blocchi e il processo di invio/consenso è attualmente specificato nel protocollo "Proof of Stake" di Ethereum. -## Protocollo Proof of Stake {#proof-of-work-protocol} +## Protocollo Proof of Stake {#proof-of-stake-protocol} Proof of Stake significa quanto segue: diff --git a/public/content/translations/it/developers/docs/consensus-mechanisms/poa/index.md b/public/content/translations/it/developers/docs/consensus-mechanisms/poa/index.md index aa10661a7cb..744486b8bdc 100644 --- a/public/content/translations/it/developers/docs/consensus-mechanisms/poa/index.md +++ b/public/content/translations/it/developers/docs/consensus-mechanisms/poa/index.md @@ -1,6 +1,6 @@ --- -title: Prova di autorità (PoA) -description: Una spiegazione del protocollo di consenso a prova di autorità e del suo ruolo nell'ecosistema della blockchain. +title: "Prova di autorità (PoA)" +description: "Una spiegazione del protocollo di consenso a prova di autorità e del suo ruolo nell'ecosistema della blockchain." lang: it --- diff --git a/public/content/translations/it/developers/docs/consensus-mechanisms/pos/attack-and-defense/index.md b/public/content/translations/it/developers/docs/consensus-mechanisms/pos/attack-and-defense/index.md index 4e939b15a83..9017d3116b8 100644 --- a/public/content/translations/it/developers/docs/consensus-mechanisms/pos/attack-and-defense/index.md +++ b/public/content/translations/it/developers/docs/consensus-mechanisms/pos/attack-and-defense/index.md @@ -1,6 +1,6 @@ --- title: "Proof-of-stake Ethereum: attacchi e meccanismi di difesa" -description: Scopri di più sui vettori di attacco noti sul proof-of-stake di Ethereum e come è possibile difendersi da essi. +description: "Scopri di più sui vettori di attacco noti sul proof-of-stake di Ethereum e come è possibile difendersi da essi." lang: it --- diff --git a/public/content/translations/it/developers/docs/consensus-mechanisms/pos/rewards-and-penalties/index.md b/public/content/translations/it/developers/docs/consensus-mechanisms/pos/rewards-and-penalties/index.md index f4bac577534..5dabb469e8a 100644 --- a/public/content/translations/it/developers/docs/consensus-mechanisms/pos/rewards-and-penalties/index.md +++ b/public/content/translations/it/developers/docs/consensus-mechanisms/pos/rewards-and-penalties/index.md @@ -1,6 +1,6 @@ --- title: Ricompense e sanzioni del proof-of-stake -description: Scopri di più sugli incentivi del protocollo nel proof-of-stake di Ethereum. +description: "Scopri di più sugli incentivi del protocollo nel proof-of-stake di Ethereum." lang: it --- diff --git a/public/content/translations/it/developers/docs/consensus-mechanisms/pos/weak-subjectivity/index.md b/public/content/translations/it/developers/docs/consensus-mechanisms/pos/weak-subjectivity/index.md index 4c1b5628951..5c34d9ab106 100644 --- a/public/content/translations/it/developers/docs/consensus-mechanisms/pos/weak-subjectivity/index.md +++ b/public/content/translations/it/developers/docs/consensus-mechanisms/pos/weak-subjectivity/index.md @@ -1,6 +1,6 @@ --- -title: Soggettività debole -description: Una spiegazione della soggettività debole e del suo ruolo nell'Ethereum PoS. +title: "Soggettività debole" +description: "Una spiegazione della soggettività debole e del suo ruolo nell'Ethereum PoS." lang: it --- diff --git a/public/content/translations/it/developers/docs/consensus-mechanisms/pow/mining/mining-algorithms/ethash/index.md b/public/content/translations/it/developers/docs/consensus-mechanisms/pow/mining/mining-algorithms/ethash/index.md index cee1f041f73..6b7c5c89975 100644 --- a/public/content/translations/it/developers/docs/consensus-mechanisms/pow/mining/mining-algorithms/ethash/index.md +++ b/public/content/translations/it/developers/docs/consensus-mechanisms/pow/mining/mining-algorithms/ethash/index.md @@ -8,7 +8,7 @@ lang: it - Ethash era l'algoritmo di mining di proof-of-work di Ethereum. Il proof-of-work è ora stato **disattivato interamente** e, invece, Ethereum è ora protetto utilizzando il [proof-of-stake](/developers/docs/consensus-mechanisms/pos/). Leggi di più su [La Fusione](/roadmap/merge/), sul [proof-of-stake](/developers/docs/consensus-mechanisms/pos/) e sullo [staking](/staking/). Questa pagina è per interesse storico! + Ethash era l'algoritmo di mining di proof-of-work di Ethereum. Il proof-of-work è ora stato **disattivato interamente** e, invece, Ethereum è ora protetto utilizzando il [proof-of-stake](/developers/docs/consensus-mechanisms/pos/). Leggi di più su [La Fusione](/roadmap/merge/), sul [proof-of-stake](/developers/docs/consensus-mechanisms/pos/) e sullo [staking](/staking/). Questa pagina è per interesse storico! diff --git a/public/content/translations/it/developers/docs/data-and-analytics/index.md b/public/content/translations/it/developers/docs/data-and-analytics/index.md index 326c2658b65..2a913ee8348 100644 --- a/public/content/translations/it/developers/docs/data-and-analytics/index.md +++ b/public/content/translations/it/developers/docs/data-and-analytics/index.md @@ -32,20 +32,21 @@ Usando [GraphQL](https://graphql.org/), gli sviluppatori possono interrogare una La [diversità dei client](/developers/docs/nodes-and-clients/client-diversity/) è importante per la salute complessiva della rete di Ethereum, poiché fornisce resilienza a bug ed exploit. Attualmente esistono vari pannelli di controllo della diversità del client, tra cui [clientdiversity.org](https://clientdiversity.org/), [rated.network](https://www.rated.network), [supermajority.info](https://supermajority.info//) ed [Ethernodes](https://ethernodes.org/). -## Dune Analytics {#dune-analytics} +## Dune Analytics {#client-diversity} [Dune Analytics](https://dune.com/) pre-elabora i dati della blockchain nelle tabelle del database relazionale (DuneSQL), consente agli utenti di richiedere i dati della blockchain utilizzando SQL e crea pannelli di controllo basati sui risultati della richiesta. I dati sulla catena sono organizzati in 4 tabelle grezze: `blocks`, `transactions`, `logs` (di eventi) e `traces` (di chiamate). I contratti e protocolli popolari sono stati decodificati e ognuno ha la propria serie di tabelle di eventi e chiamate. Queste tabelle di eventi e chiamate sono ulteriormente elaborate e organizzate in tabelle di astrazione secondo il tipo di protocolli, ad esempio dex, lending, stablecoins, ecc. -## Rete di SubQuery {#subquery-network} +## Rete di SubQuery {#dune-analytics} [SubQuery](https://subquery.network/) è un indicizzatore di dati leader del settore, che fornisce agli sviluppatori API veloci, affidabili, decentralizzate e personalizzate per i loro progetti in Web3. SubQuery emancipa gli sviluppatori da oltre 165 ecosistemi (incluso Ethereum) con dati indicizzati ricchi, per creare esperienze intuitive e immersive per i propri utenti. La Rete di SubQuery alimenta le tue inarrestabili app con una rete resiliente e un'infrastruttura decentralizzata. Utilizza gli strumenti per sviluppatori di blockchain di SubQuery per creare le applicazioni Web3 del futuro, senza dover dedicare tempo a sviluppare un backend personalizzato per le attività di elaborazione dei dati. Per iniziare, visita la [guida rapida per principianti di Ethereum](https://academy.subquery.network/quickstart/quickstart_chains/ethereum-gravatar.html) per iniziare a indicizzare i dati della blockchain di Ethereum in pochi minuti in un ambiente locale di Docker per i test prima di distribuire il tuo progetto su un [servizio gestito da SubQuery](https://managedservice.subquery.network/) o su una [rete decentralizzata di SubQuery](https://app.subquery.network/dashboard). -## Ethernow - Programma dei dati del Mempool {#ethernow} +## Ethernow - Programma dei dati del Mempool {#sqd} + [Blocknative](https://www.blocknative.com/) fornisce l'accesso aperto al suo [archivio dei dati del mempool](https://www.ethernow.xyz/mempool-data-archive) storico di Ethereum. Questo consente ai ricercatori e ai progetti della community di esplorare il livello pre-catena della Rete Principale di Ethereum. La serie di dati è mantenuta attivamente e rappresenta il registro storico più completo degli eventi di transazione del mempool nell'ecosistema di Ethereum. Maggiori informazioni su [Ethernow](https://www.ethernow.xyz/). -## Letture consigliate {#further-reading} +## Letture consigliate {#subquery-network} - [Panoramica della rete Graph](https://thegraph.com/docs/en/about/) - [GraphQL Playground](https://thegraph.com/explorer/subgraph/graphprotocol/graph-network-mainnet?version=current) diff --git a/public/content/translations/it/developers/docs/data-availability/index.md b/public/content/translations/it/developers/docs/data-availability/index.md index 7b1bb070581..369d6d81788 100644 --- a/public/content/translations/it/developers/docs/data-availability/index.md +++ b/public/content/translations/it/developers/docs/data-availability/index.md @@ -1,6 +1,6 @@ --- -title: Disponibilità dei dati -description: Una panoramica dei problemi e delle soluzioni relative alla disponibilità dei dati in Ethereum +title: "Disponibilità dei dati" +description: "Una panoramica dei problemi e delle soluzioni relative alla disponibilità dei dati in Ethereum" lang: it --- diff --git a/public/content/translations/it/developers/docs/design-and-ux/heuristics-for-web3/index.md b/public/content/translations/it/developers/docs/design-and-ux/heuristics-for-web3/index.md index 2f0aaa2df51..f89f227fde2 100644 --- a/public/content/translations/it/developers/docs/design-and-ux/heuristics-for-web3/index.md +++ b/public/content/translations/it/developers/docs/design-and-ux/heuristics-for-web3/index.md @@ -1,6 +1,6 @@ --- title: 7 euristiche per la progettazione di interfacce Web3 -description: Principi per migliorare l'usabilità del Web3 +description: "Principi per migliorare l'usabilità del Web3" lang: it --- diff --git a/public/content/translations/it/developers/docs/design-and-ux/index.md b/public/content/translations/it/developers/docs/design-and-ux/index.md index 40ba1cd7f16..aa157d71d20 100644 --- a/public/content/translations/it/developers/docs/design-and-ux/index.md +++ b/public/content/translations/it/developers/docs/design-and-ux/index.md @@ -78,7 +78,7 @@ Partecipate ad organizzazioni professionali guidate dalla community o unitevi a - [We3.co](https://we3.co/) - [Openux.xyz](https://openux.xyz/) -## Sistemi di progettazione {#design-systems} +## Sistemi di progettazione {#design-systems-and-resources} - [Progettazione di Optimism](https://www.figma.com/@optimism) (Figma) - [Sistema di progettazione di Ethereum.org](https://www.figma.com/@ethdotorg) (Figma) diff --git a/public/content/translations/it/developers/docs/evm/index.md b/public/content/translations/it/developers/docs/evm/index.md index c1ae60e919f..50268badf5a 100644 --- a/public/content/translations/it/developers/docs/evm/index.md +++ b/public/content/translations/it/developers/docs/evm/index.md @@ -4,7 +4,7 @@ description: Un'introduzione alla Macchina Virtuale di Ethereum e a come si rela lang: it --- -La Macchina Virtuale di Ethereum (EVM) è un ambiente virtuale decentralizzato che esegue il codice con coerenza e sicurezza su tutti i nodi di Ethereum. I nodi eseguono l'EVM per eseguire i contratti intelligenti, utilizzando il "[gas](/gas/)" per misurare lo sforzo di calcolo necessario per le [operazioni](/developers/docs/evm/opcodes/), assicurando un'efficace allocazione delle risorse e la sicurezza della rete. +La Macchina Virtuale di Ethereum (EVM) è un ambiente virtuale decentralizzato che esegue il codice con coerenza e sicurezza su tutti i nodi di Ethereum. I nodi eseguono l'EVM per eseguire i contratti intelligenti, utilizzando il "[gas](/developers/docs/gas/)" per misurare lo sforzo di calcolo necessario per le [operazioni](/developers/docs/evm/opcodes/), assicurando un'efficace allocazione delle risorse e la sicurezza della rete. ## Prerequisiti {#prerequisites} diff --git a/public/content/translations/it/developers/docs/intro-to-ethereum/index.md b/public/content/translations/it/developers/docs/intro-to-ethereum/index.md index 26d4c9ffb8e..da74e7a90f2 100644 --- a/public/content/translations/it/developers/docs/intro-to-ethereum/index.md +++ b/public/content/translations/it/developers/docs/intro-to-ethereum/index.md @@ -111,6 +111,6 @@ Uno snippet di codice riutilizzabile (programma) che uno sviluppatore pubblica n _Conosci una risorsa della community che ti è stata utile? Modifica questa pagina e aggiungila!_ -## Tutorial correlati {#related-tutorials} +## Tutorial correlati {#visual-learner} - [Una guida per sviluppatori a Ethereum, parte 1](/developers/tutorials/a-developers-guide-to-ethereum-part-one/) _– Un'esplorazione di Ethereum pensata per i principianti usando Python e web3.py_ diff --git a/public/content/translations/it/developers/docs/networking-layer/portal-network/index.md b/public/content/translations/it/developers/docs/networking-layer/portal-network/index.md index 114400531ff..0fce61908eb 100644 --- a/public/content/translations/it/developers/docs/networking-layer/portal-network/index.md +++ b/public/content/translations/it/developers/docs/networking-layer/portal-network/index.md @@ -82,7 +82,7 @@ La presenza di più implementazioni client indipendenti aumenta la resilienza e Se un client presenta problemi o vulnerabilità, gli altri client possono continuare a funzionare senza problemi, evitando un punto di errore singolo. Inoltre, le diverse implementazioni dei clienti favoriscono l'innovazione e la concorrenza, promuovendo miglioramenti e riducendo il rischio di monopolio all'interno dell'ecosistema. -## Letture consigliate {#futher-reading} +## Letture consigliate {#further-reading} - [La Rete Portal (Piper Merriam al Devcon di Bogotà)](https://www.youtube.com/watch?v=0stc9jnQLXA). - [Discord della Rete Portal](https://discord.gg/CFFnmE7Hbs) diff --git a/public/content/translations/it/developers/docs/networks/index.md b/public/content/translations/it/developers/docs/networks/index.md index 08b89ae21e4..e2f09ac32c0 100644 --- a/public/content/translations/it/developers/docs/networks/index.md +++ b/public/content/translations/it/developers/docs/networks/index.md @@ -84,11 +84,11 @@ Hoodi è una rete di prova per testare la convalida e lo staking. La rete Hoodi Per lanciare un Validatore sulla rete di prova Hoodi, usa il [launchpad di Hoodi](https://hoodi.launchpad.ethereum.org/en/). -### Rete di prova del livello 2 {#layer-2-testnets} +### Rete di prova del livello 2 {#ephemery} [Livello 2 (L2)](/layer-2/) è un termine collettivo per descrivere un insieme specifico di soluzioni di ridimensionamento di Ethereum. Un livello 2 è una blockchain separata che estende Ethereum ed eredita le garanzie di sicurezza di Ethereum. Solitamente le reti di prova di Livello 2 sono strettamente accoppiate alle reti di prova pubbliche di Ethereum. -#### Arbitrum Sepolia {#arbitrum-sepolia} +#### Arbitrum Sepolia {#holesky} Una rete di prova per [Arbitrum](https://arbitrum.io/). @@ -97,7 +97,7 @@ Una rete di prova per [Arbitrum](https://arbitrum.io/). - [Faucet Chainlink](https://faucets.chain.link/arbitrum-sepolia) - [Faucet Alchemy](https://www.alchemy.com/faucets/arbitrum-sepolia) -#### Optimistic Sepolia {#optimistic-sepolia} +#### Optimistic Sepolia {#layer-2-testnets} Una rete di prova per [Optimism](https://www.optimism.io/). @@ -106,7 +106,7 @@ Una rete di prova per [Optimism](https://www.optimism.io/). - [Faucet Chainlink](https://faucets.chain.link/optimism-sepolia) - [Faucet Alchemy](https://www.alchemy.com/faucets/optimism-sepolia) -#### Starknet Sepolia {#starknet-sepolia} +#### Starknet Sepolia {#arbitrum-sepolia} Una rete di prova per [Starknet](https://www.starknet.io). @@ -114,28 +114,28 @@ Una rete di prova per [Starknet](https://www.starknet.io). - [Faucet Alchemy](https://www.alchemy.com/faucets/starknet-sepolia) -## Reti private {#private-networks} +## Reti private {#optimistic-sepolia} Una rete Ethereum è una rete privata se i relativi nodi non sono connessi a una rete pubblica (ossia Rete principale o una rete di prova). In questo contesto, privato significa solo riservato o isolato, e non protetto o sicuro. -### Reti di sviluppo {#development-networks} +### Reti di sviluppo {#starknet-sepolia} Per sviluppare un'applicazione Ethereum, è consigliabile eseguirla prima su una rete privata per vedere come funziona prima di distribuirla. Come quando si crea un server locale sul computer per lo sviluppo web, è possibile creare un'istanza locale della blockchain per testare una dapp. Questo offre un'iterazione molto più veloce rispetto a una rete di prova pubblica. Ci sono progetti e strumenti dedicati a questo scopo. Scopri di più sulle [reti di sviluppo](/developers/docs/development-networks/). -### Reti di consorzio {#consortium-networks} +### Reti di consorzio {#private-networks} Il processo di consenso è controllato da una serie predefinita di nodi considerati attendibili. Un esempio può essere una rete privata di istituti accademici noti, dove ogni istituto controlla un singolo nodo e i blocchi vengono convalidati da una soglia di firmatari all'interno della rete. Se una rete Ethereum pubblica è come la rete Internet pubblica, una rete di consorzio è come una Intranet privata. -## Strumenti correlati {#related-tools} +## Strumenti correlati {#development-networks} - [Chainlist](https://chainlist.org/) _Elenco di reti EVM per connettere portafogli e fornitori all'ID della Catena e ID di Rete appropriati._ - [Catene basate su EVM](https://github.com/ethereum-lists/chains) _Repository di GitHub di metadati della catena che alimentano Chainlist._ -## Letture consigliate {#further-reading} +## Letture consigliate {#consortium-networks} - [Proposta: ciclo di vita prevedibile delle reti di prova di Ethereum](https://ethereum-magicians.org/t/proposal-predictable-ethereum-testnet-lifecycle/11575/17) - [L'evoluzione delle reti di prova di Ethereum](https://etherworld.co/2022/08/19/the-evolution-of-ethereum-testnet/) diff --git a/public/content/translations/it/developers/docs/nodes-and-clients/client-diversity/index.md b/public/content/translations/it/developers/docs/nodes-and-clients/client-diversity/index.md index 06dc895256d..63192bb54f0 100644 --- a/public/content/translations/it/developers/docs/nodes-and-clients/client-diversity/index.md +++ b/public/content/translations/it/developers/docs/nodes-and-clients/client-diversity/index.md @@ -1,6 +1,6 @@ --- -title: Diversità dei client -description: Una spiegazione generica dell'importanza della diversità di client di Ethereum. +title: "Diversità dei client" +description: "Una spiegazione generica dell'importanza della diversità di client di Ethereum." lang: it sidebarDepth: 2 --- @@ -49,15 +49,15 @@ I dati del livello di esecuzione sono stati ottenuti da [Ethernodes](https://eth I dati di diversità dei client aggiornati per il livello del consenso sono ora disponibili su [clientdiversity.org](https://clientdiversity.org/). -## Livello di esecuzione {#execution-layer} +## Livello di esecuzione {#execution-clients-breakdown} Finora, la conversazione sulla diversità dei client si è concentrata sul livello del consenso. Tuttavia, il client d'esecuzione [Geth](https://geth.ethereum.org) rappresenta correntemente circa l'85% di tutti i nodi. Questa percentuale è problematica per gli stessi motivi dei client di consenso. Ad esempio, un bug su Geth che influenzi la gestione delle transazioni o la costruzione dei carichi utili d'esecuzione potrebbe condurre alla finalizzazione da parte dei client di consenso di transazioni problematiche o contenenti bug. Ethereum sarebbe più quindi più robusto con una distribuzione più equa dei client d'esecuzione, idealmente senza alcun client che rappresenti oltre il 33% della rete. -## Usare un client di minoranza {#use-minority-client} +## Usare un client di minoranza {#consensus-clients-breakdown} Per "indirizzare" la diversità dei client non basta che i singoli utenti scelgano i client di minoranza, richiede che anche i pool di mining/validatori e le istituzioni come le dApp principali e gli scambi cambino client. Tuttavia, tutti gli utenti possono fare la propria parte nel correggere l'attuale disequilibrio e normalizzare l'uso di tutti i software di Ethereum disponibili. Dopo La Fusione, tutti gli operatori di nodi dovranno eseguire un client d'esecuzione e un client di consenso. Scegliere le combinazioni dei client suggerite di seguito aiuterà ad aumentare la diversità dei client. -### Client di esecuzione {#execution-clients} +### Client di esecuzione {#execution-layer} [Besu](https://www.hyperledger.org/use/besu) @@ -67,7 +67,7 @@ Per "indirizzare" la diversità dei client non basta che i singoli utenti scelga [Go-Ethereum](https://geth.ethereum.org/) -### Client di consenso {#consensus-clients} +### Client di consenso {#use-minority-client} [Nimbus](https://nimbus.team/) @@ -83,7 +83,7 @@ Per "indirizzare" la diversità dei client non basta che i singoli utenti scelga Gli utenti tecnici possono aiutare ad accelerare questo processo scrivendo più tutorial e documentazioni per i client di minoranza e incoraggiando i propri peer che eseguono dei nodi a migrare dai client dominanti. Le guide per passare a un client di consenso di minoranza sono disponibili su [clientdiversity.org](https://clientdiversity.org/). -## Pannelli di controllo sulla diversità dei client {#client-diversity-dashboards} +## Pannelli di controllo sulla diversità dei client {#execution-clients} Diversi pannelli di controllo forniscono statistiche sulla diversità dei client in tempo reale per il livello d'esecuzione e di consenso. @@ -95,7 +95,7 @@ Diversi pannelli di controllo forniscono statistiche sulla diversità dei client - [supermajority.info](https://supermajority.info//) - [Ethernodes](https://ethernodes.org/) -## Letture consigliate {#further-reading} +## Letture consigliate {#consensus-clients} - [Diversità dei client sul livello di consenso di Ethereum](https://mirror.xyz/jmcook.eth/S7ONEka_0RgtKTZ3-dakPmAHQNPvuj15nh0YGKPFriA) - [Fusione di Ethereum: esegui il client di maggioranza a tuo rischio!](https://dankradfeist.de/ethereum/2022/03/24/run-the-majority-client-at-your-own-peril.html) – _Dankrad Fiest, 24 marzo 2022_ @@ -105,7 +105,7 @@ Diversi pannelli di controllo forniscono statistiche sulla diversità dei client - [Diversità di Ethereum e come risolverla (YouTube)](https://www.youtube.com/watch?v=1hZgCaiqwfU) - [clientdiversity.org](https://clientdiversity.org/) -## Argomenti correlati {#related-topics} +## Argomenti correlati {#client-diversity-dashboards} - [Eseguire un nodo di Ethereum](/run-a-node/) - [Nodi e client](/developers/docs/nodes-and-clients/) diff --git a/public/content/translations/it/developers/docs/nodes-and-clients/index.md b/public/content/translations/it/developers/docs/nodes-and-clients/index.md index 98eb12ebed7..74f6e768d3f 100644 --- a/public/content/translations/it/developers/docs/nodes-and-clients/index.md +++ b/public/content/translations/it/developers/docs/nodes-and-clients/index.md @@ -1,6 +1,6 @@ --- title: Nodi e client -description: Panoramica dei nodi Ethereum e del software client, come configurare un nodo e perché farlo. +description: "Panoramica dei nodi Ethereum e del software client, come configurare un nodo e perché farlo." lang: it sidebarDepth: 2 --- diff --git a/public/content/translations/it/developers/docs/nodes-and-clients/nodes-as-a-service/index.md b/public/content/translations/it/developers/docs/nodes-and-clients/nodes-as-a-service/index.md index 8a29e3a51a0..e83c721403d 100644 --- a/public/content/translations/it/developers/docs/nodes-and-clients/nodes-as-a-service/index.md +++ b/public/content/translations/it/developers/docs/nodes-and-clients/nodes-as-a-service/index.md @@ -1,6 +1,6 @@ --- title: Nodi come servizio -description: Panoramica entry-level dei servizi dei nodi, dei pro e dei contro, e dei fornitori più diffusi. +description: "Panoramica entry-level dei servizi dei nodi, dei pro e dei contro, e dei fornitori più diffusi." lang: it sidebarDepth: 2 --- diff --git a/public/content/translations/it/developers/docs/nodes-and-clients/run-a-node/index.md b/public/content/translations/it/developers/docs/nodes-and-clients/run-a-node/index.md index e3d8b368210..eda86442bcb 100644 --- a/public/content/translations/it/developers/docs/nodes-and-clients/run-a-node/index.md +++ b/public/content/translations/it/developers/docs/nodes-and-clients/run-a-node/index.md @@ -234,7 +234,7 @@ Questa sezione ti guiderà nell'avvio dei client di esecuzione. Serve solo da es Ricordati che questo è solo un esempio di base, tutte le altre impostazioni saranno predefinite. Presta attenzione alla documentazione di ogni client per conoscere i valori predefiniti, le impostazioni e le funzionalità. Per ulteriori funzionalità, ad esempio per eseguire i validatori, per il monitoraggio, ecc., fai riferimento alla documentazione del client specifico. -> Nota che i backslash `\` negli esempi servono solo a scopi di formattazione; i flag di configurazione sono definibili in una singola riga. +> Nota che i backslash `` negli esempi servono solo a scopi di formattazione; i flag di configurazione sono definibili in una singola riga. ##### Eseguire Besu diff --git a/public/content/translations/it/developers/docs/oracles/index.md b/public/content/translations/it/developers/docs/oracles/index.md index 3232aa07b4c..bac34bad496 100644 --- a/public/content/translations/it/developers/docs/oracles/index.md +++ b/public/content/translations/it/developers/docs/oracles/index.md @@ -1,6 +1,6 @@ --- title: Oracoli -description: Gli oracoli forniscono ai contratti intelligenti di Ethereum l'accesso ai dati del mondo reale, sbloccando più casi d'uso e maggiore valore per gli utenti. +description: "Gli oracoli forniscono ai contratti intelligenti di Ethereum l'accesso ai dati del mondo reale, sbloccando più casi d'uso e maggiore valore per gli utenti." lang: it --- diff --git a/public/content/translations/it/developers/docs/programming-languages/javascript/index.md b/public/content/translations/it/developers/docs/programming-languages/javascript/index.md index e6e69f0248c..81a821658c4 100644 --- a/public/content/translations/it/developers/docs/programming-languages/javascript/index.md +++ b/public/content/translations/it/developers/docs/programming-languages/javascript/index.md @@ -32,7 +32,7 @@ Di più sui [contratti intelligenti](/developers/docs/smart-contracts/). ### La macchina virtuale Ethereum {#the-ethereum-virtual-machine} -Esiste un'implementazione JavaScript della [macchina virtuale di Ethereum](/en/developers/docs/evm/), che supporta le regole più recenti relative alle diramazioni della rete. Le regole relative alle diramazioni si riferiscono alle modifiche apportate alla macchina virtuale di Ethereum (EVM) a seguito di upgrade pianificati. +Esiste un'implementazione JavaScript della [macchina virtuale di Ethereum](/developers/docs/evm/), che supporta le regole più recenti relative alle diramazioni della rete. Le regole relative alle diramazioni si riferiscono alle modifiche apportate alla macchina virtuale di Ethereum (EVM) a seguito di upgrade pianificati. È suddivisa in vari pacchetti JavaScript che puoi leggere per comprendere meglio: diff --git a/public/content/translations/it/developers/docs/scaling/index.md b/public/content/translations/it/developers/docs/scaling/index.md index 6fd3b842b9b..97da0bd92d5 100644 --- a/public/content/translations/it/developers/docs/scaling/index.md +++ b/public/content/translations/it/developers/docs/scaling/index.md @@ -1,6 +1,6 @@ --- -title: Scalabilità -description: Introduzione alle diverse opzioni di scalabilità attualmente in fase di sviluppo da parte della community Ethereum. +title: "Scalabilità" +description: "Introduzione alle diverse opzioni di scalabilità attualmente in fase di sviluppo da parte della community Ethereum." lang: it sidebarDepth: 3 --- @@ -19,7 +19,7 @@ A livello concettuale, per prima cosa occorre distinguere tra scalabilità on-ch Dovresti avere una buona conoscenza di tutti gli argomenti fondamentali. L'implementazione di soluzioni di scalabilità è un argomento avanzato, in quanto la tecnologia è meno testata sul campo e continua ad essere oggetto di ricerca e sviluppo. -## Scalabilità on-chain {#on-chain-scaling} +## Scalabilità on-chain {#onchain-scaling} La scalabilità on-chain richiede modifiche al protocollo Ethereum ([rete principale](/glossary/#mainnet) di livello 1). Per molto tempo si è pensato che lo sharding della blockchain avrebbe ridimensionato Ethereum. Questo avrebbe coinvolto la divisione della blockchain in pezzi discreti (shard), che sarebbero stati verificati da sottoinsiemi dei validatori. Tuttavia, il ridimensionamento dai rollup di livello 2 ha preso il controllo come la tecnica di ridimensionamento principale. Questa è supportata dall'aggiunta di una nuova e più economica forma di dati connessi ai blocchi di Ethereum, progettati specificamente per rendere i rollup economici per gli utenti. @@ -27,7 +27,7 @@ La scalabilità on-chain richiede modifiche al protocollo Ethereum ([rete princi Lo sharding è il processo di frammentazione di un database. Sottoinsiemi di validatori sarebbero responsabili dei singoli shard invece di tenere traccia di tutta la rete Ethereum. Un tempo destinato a essere trasferito verso il proof-of-stake prima della Fusione, lo sharding è stato per molto tempo sulla [tabella di marcia](/roadmap/) di Ethereum. Tuttavia, il rapido sviluppo dei [rollup di livello 2](#layer-2-scaling) e l'invenzione del [Dansharding](/roadmap/danksharding) (aggiunta di blob di dati di rollup ai blocchi di Ethereum che possono essere verificati in modo molto efficiente dai validatori), ha portato la community di Ethereum a preferire il ridimensionamento incentrato sui rollup piuttosto che sullo sharding. Ciò aiuterà anche a mantenere più semplice la logica del consenso di Ethereum. -## Scalabilità off-chain {#off-chain-scaling} +## Scalabilità off-chain {#offchain-scaling} Le soluzioni off-chain sono implementate separatamente dalla Rete principale di livello 1, e non richiedono alcuna modifica al protocollo Ethereum esistente. Alcune soluzioni, note come soluzioni di "livello 2", derivano la loro sicurezza direttamente dal consenso del livello 1 di Ethereum, come i [rollup ottimistici](/developers/docs/scaling/optimistic-rollups/), i [rollup a conoscenza zero](/developers/docs/scaling/zk-rollups/) o i [canali di stato](/developers/docs/scaling/state-channels/). Altre soluzioni comportano la creazione di nuove catene in varie forme, che derivano la propria sicurezza separatamente dalla Rete principale, come le [catene secondarie](#sidechains), i [validium](#validium) o le [catene Plasma](#plasma). Queste soluzioni comunicano con la Rete principale, ma derivano la loro sicurezza in modo diverso per raggiungere una serie di obiettivi. diff --git a/public/content/translations/it/developers/docs/scaling/optimistic-rollups/index.md b/public/content/translations/it/developers/docs/scaling/optimistic-rollups/index.md index 65fc1e05800..ea335814158 100644 --- a/public/content/translations/it/developers/docs/scaling/optimistic-rollups/index.md +++ b/public/content/translations/it/developers/docs/scaling/optimistic-rollups/index.md @@ -28,7 +28,7 @@ Se il batch del rollup non viene contestata (cioè, tutte le transazioni sono es ## Come interagiscono i rollup ottimistici con Ethereum? {#optimistic-rollups-and-Ethereum} -I rollup ottimistici sono [soluzioni di ridimensionamento off-chain](/developers/docs/scaling/#off-chain-scaling) create per funzionare su Ethereum. Ogni rollup ottimistico è gestito da una serie di contratti intelligenti distribuiti sulla rete di Ethereum. I rollup ottimistici elaborano le transazioni al di fuori della catena principale di Ethereum, ma pubblicano le transazioni off-chain (in batch) in un contratto di rollup on-chain. Come la blockchain di Ethereum, questo registro delle transazioni è immutabile e forma la "catena di rollup ottimistico". +I rollup ottimistici sono [soluzioni di ridimensionamento off-chain](/developers/docs/scaling/#offchain-scaling) create per funzionare su Ethereum. Ogni rollup ottimistico è gestito da una serie di contratti intelligenti distribuiti sulla rete di Ethereum. I rollup ottimistici elaborano le transazioni al di fuori della catena principale di Ethereum, ma pubblicano le transazioni off-chain (in batch) in un contratto di rollup on-chain. Come la blockchain di Ethereum, questo registro delle transazioni è immutabile e forma la "catena di rollup ottimistico". L'architettura di un optimistic rollup comprende le seguenti parti: diff --git a/public/content/translations/it/developers/docs/scaling/plasma/index.md b/public/content/translations/it/developers/docs/scaling/plasma/index.md index 67acee07f30..b89cffbde83 100644 --- a/public/content/translations/it/developers/docs/scaling/plasma/index.md +++ b/public/content/translations/it/developers/docs/scaling/plasma/index.md @@ -1,6 +1,6 @@ --- title: Catene plasma -description: Un'introduzione alle catene plasma come soluzione di scalabilità, attualmente utilizzata dalla comunità Ethereum. +description: "Un'introduzione alle catene plasma come soluzione di scalabilità, attualmente utilizzata dalla comunità Ethereum." lang: it incomplete: true sidebarDepth: 3 @@ -24,7 +24,7 @@ Le funzioni del contratto Plasma, tra le altre cose, fungono da [ponte](/develop I componenti di base del quadro Plasma sono: -### Calcolo off-chain {#off-chain-computation} +### Calcolo off-chain {#offchain-computation} La velocità di elaborazione attuale di Ethereum è limitata a circa 15-20 transazioni al secondo, riducendo la possibilità a breve termine di ridimensionamento per gestire più utenti. Questo problema esiste principalmente perché il [meccanismo di consenso](/developers/docs/consensus-mechanisms/) di Ethereum richiede molti nodi peer-to-peer per verificare ogni aggiornamento allo stato della blockchain. diff --git a/public/content/translations/it/developers/docs/scaling/validium/index.md b/public/content/translations/it/developers/docs/scaling/validium/index.md index ea548046013..e5e2f46d99c 100644 --- a/public/content/translations/it/developers/docs/scaling/validium/index.md +++ b/public/content/translations/it/developers/docs/scaling/validium/index.md @@ -1,6 +1,6 @@ --- title: Validium -description: Un'introduzione a Validium come soluzione di scalabilità, attualmente utilizzata dalla comunità Ethereum. +description: "Un'introduzione a Validium come soluzione di scalabilità, attualmente utilizzata dalla comunità Ethereum." lang: it sidebarDepth: 3 --- @@ -119,7 +119,7 @@ Alcuni team, tuttavia, stanno cercando di ottimizzare gli opcode EVM esistenti p ## Come fanno i validium a ridimensionare Ethereum? {#scaling-ethereum-with-validiums} -### 1. Archiviazione dei dati off-chain {#off-chain-data-storage} +### 1. Archiviazione dei dati off-chain {#offchain-data-storage} I progetti di ridimensionamento del livello 2, come i rollup ottimistici e a conoscenza zero, rinunciano all'infinita scalabilità dei protocolli di ridimensionamento off-chain puri (ad es. [Plasma](/developers/docs/scaling/plasma/)) in cambio della sicurezza, pubblicando alcuni dati di transazione su L1. Ma questo fa sì che le proprietà di scalabilità dei rollup sia limitata dalla larghezza di banda dei dati sulla Rete principale di Ethereum (lo [sharding dei dati](/roadmap/danksharding/) propone di migliorare la capacità di archiviazione dei dati di Ethereum per questo motivo). diff --git a/public/content/translations/it/developers/docs/scaling/zk-rollups/index.md b/public/content/translations/it/developers/docs/scaling/zk-rollups/index.md index c80610d5c15..53e0a590cd4 100644 --- a/public/content/translations/it/developers/docs/scaling/zk-rollups/index.md +++ b/public/content/translations/it/developers/docs/scaling/zk-rollups/index.md @@ -30,7 +30,7 @@ L'architettura principale del rollup ZK si compone dei seguenti componenti: 2. **Macchina virtuale (VM) off-chain**: benché il protocollo del rollup ZK risieda su Ethereum, l'esecuzione della transazione e l'archiviazione di stato si verificano su una macchina virtuale separata e indipendente dall'[EVM](/developers/docs/evm/). Questa VM off-chain è l'ambiente di esecuzione per le transazioni sul rollup ZK e serve da livello secondario o "livello 2" per il protocollo rollup ZK. Le prove di validità verificate sulla Rete principale di Ethereum garantiscono la correttezza delle transizioni di stato nella VM off-chain. -I rollup ZK sono "soluzioni di ridimensionamento ibride": protocolli off-chain che operano indipendentemente ma derivano la sicurezza da Ethereum. Nello specifico, la rete di Ethereum impone la validità degli aggiornamenti di stato sul rollup ZK e garantisce la disponibilità dei dati dietro ogni aggiornamento allo stato del rollup. Di conseguenza, i rollup ZK sono considerevolmente più sicuri delle soluzioni di ridimensionamento off-chain, come le [sidechain](/developers/docs/scaling/sidechains/), responsabili delle proprie proprietà di sicurezza, o i [validium](/developers/docs/scaling/validiums/), che pur verificando le transazioni su Ethereum con le prove di validità, memorizzano altrove i dati della transazione. +I rollup ZK sono "soluzioni di ridimensionamento ibride": protocolli off-chain che operano indipendentemente ma derivano la sicurezza da Ethereum. Nello specifico, la rete di Ethereum impone la validità degli aggiornamenti di stato sul rollup ZK e garantisce la disponibilità dei dati dietro ogni aggiornamento allo stato del rollup. Di conseguenza, i rollup ZK sono considerevolmente più sicuri delle soluzioni di ridimensionamento off-chain, come le [sidechain](/developers/docs/scaling/sidechains/), responsabili delle proprie proprietà di sicurezza, o i [validium](/developers/docs/scaling/validium/), che pur verificando le transazioni su Ethereum con le prove di validità, memorizzano altrove i dati della transazione. I rollup ZK si affidano al protocollo principale di Ethereum per quanto segue: diff --git a/public/content/translations/it/developers/docs/smart-contracts/compiling/index.md b/public/content/translations/it/developers/docs/smart-contracts/compiling/index.md index d811e9e935d..13c5b8fe609 100644 --- a/public/content/translations/it/developers/docs/smart-contracts/compiling/index.md +++ b/public/content/translations/it/developers/docs/smart-contracts/compiling/index.md @@ -1,6 +1,6 @@ --- title: Compilazione dei contratti intelligenti -description: Una spiegazione del perché devi compilare i contratti intelligenti e di cosa succede effettivamente durante la compilazione. +description: "Una spiegazione del perché devi compilare i contratti intelligenti e di cosa succede effettivamente durante la compilazione." lang: it incomplete: true --- diff --git a/public/content/translations/it/developers/docs/smart-contracts/composability/index.md b/public/content/translations/it/developers/docs/smart-contracts/composability/index.md index 794afad7d10..f3366c41acc 100644 --- a/public/content/translations/it/developers/docs/smart-contracts/composability/index.md +++ b/public/content/translations/it/developers/docs/smart-contracts/composability/index.md @@ -1,5 +1,5 @@ --- -title: Componibilità dei contratti intelligenti +title: "Componibilità dei contratti intelligenti" description: lang: it incomplete: true diff --git a/public/content/translations/it/developers/docs/smart-contracts/languages/index.md b/public/content/translations/it/developers/docs/smart-contracts/languages/index.md index 8783253b63f..3620feb806f 100644 --- a/public/content/translations/it/developers/docs/smart-contracts/languages/index.md +++ b/public/content/translations/it/developers/docs/smart-contracts/languages/index.md @@ -123,24 +123,32 @@ Per ulteriori informazioni, [consulta la logica di Vyper](https://vyper.readthed # Apertura asta # Parametri d'asta + # Il beneficiario riceve denaro dal miglior offerente + beneficiary: public(address) auctionStart: public(uint256) auctionEnd: public(uint256) # Stato attuale dell'asta + highestBidder: public(address) highestBid: public(uint256) # Imposta a true alla fine per non permettere più modifiche + ended: public(bool) # Tiene traccia delle offerte rimborsate in modo da poter seguire il modello di prelievo + pendingReturns: public(HashMap[address, uint256]) # Crea una semplice asta con `_bidding_time` + # tempo di offerta in secondi per conto + # dell'indirizzo del beneficiario `_beneficiary`. + @external def __init__(_beneficiary: address, _bidding_time: uint256): self.beneficiary = _beneficiary @@ -148,9 +156,13 @@ def __init__(_beneficiary: address, _bidding_time: uint256): self.auctionEnd = self.auctionStart + _bidding_time # Offerta sull'asta con il valore inviato + # insieme a questa transazione. + # Il valore sarà rimborsato solo se l'asta + # non viene vinta. + @external @payable def bid(): @@ -165,9 +177,13 @@ def bid(): self.highestBid = msg.value # Preleva un'offerta precedentemente rimborsata. Il modello di prelievo è + # utilizzato qui per evitare un problema di sicurezza. Se i rimborsi venissero inviati direttamente + # come parte di bid(), un contratto di offerta malevolo potrebbe bloccarli + # e quindi bloccare le nuove offerte più alte in arrivo. + @external def withdraw(): pending_amount: uint256 = self.pendingReturns[msg.sender] @@ -175,7 +191,9 @@ def withdraw(): send(msg.sender, pending_amount) # Termina l'asta e invia l'offerta più alta + # al beneficiario. + @external def endAuction(): # It is a good guideline to structure functions that interact diff --git a/public/content/translations/it/developers/docs/smart-contracts/verifying/index.md b/public/content/translations/it/developers/docs/smart-contracts/verifying/index.md index f46d2fbc5f8..bffe6042b3d 100644 --- a/public/content/translations/it/developers/docs/smart-contracts/verifying/index.md +++ b/public/content/translations/it/developers/docs/smart-contracts/verifying/index.md @@ -80,7 +80,7 @@ Etherscan è lo strumento più utilizzato per verificare i contratti. Tuttavia, [Maggiori informazioni sulla verifica dei contratti su Etherscan](https://medium.com/etherscan-blog/verifying-contracts-on-etherscan-f995ab772327). -### Sourcify {#sourcify} +### Sourcify {#blockscout} [Sourcify](https://sourcify.dev/#/verifier) è un altro strumento, open source e decentralizzato, per verificare i contratti. Non è un esploratore di blocchi e verifica i contratti soltanto su [diverse reti basate sull'EVM](https://docs.sourcify.dev/docs/chains). Agisce da infrastruttura pubblica per la costruzione di altri strumenti e mira a consentire interazioni con i contratti più intuitive, utilizzando i commenti [ABI](/developers/docs/smart-contracts/compiling/#web-applications) e [NatSpc](https://docs.soliditylang.org/en/v0.8.15/natspec-format.html) che si trovano nel file dei metadati. @@ -90,7 +90,7 @@ Inoltre, è anche possibile recuperare i file del codice sorgente via IPFS, poic [Maggiori informazioni sulla verifica dei contratti su Sourcify](https://blog.soliditylang.org/2020/06/25/sourcify-faq/). -### Tenderly {#tenderly} +### Tenderly {#sourcify} La [piattaforma Tenderly](https://tenderly.co/) consente agli sviluppatori in Web3 di creare, testare, monitorare e gestire i contratti intelligenti. Combinando strumenti di debug con osservabilità e blocchi di costruzione dell'infrastruttura, Tenderly aiuta gli sviluppatori ad accelerare lo sviluppo dei contratti intelligenti. Per abilitare appieno le funzionalità di Tenderly, gli sviluppatori devono [eseguire la verifica del codice sorgente](https://docs.tenderly.co/monitoring/contract-verification) utilizzando svariati metodi. @@ -102,6 +102,6 @@ Verificando i contratti tramite il Pannello di controllo, devi importare il file L'utilizzo del plugin Hardhat di Tenderly consente di avere maggiore controllo sul processo di verifica con minori sforzi, consentendoti di scegliere tra una verifica automatica (senza codice) e manuale (basata sul codice). -## Letture consigliate {#further-reading} +## Letture consigliate {#tenderly} - [Verificare il codice sorgente del contratto](https://programtheblockchain.com/posts/2018/01/16/verifying-contract-source-code/) diff --git a/public/content/translations/it/developers/docs/storage/index.md b/public/content/translations/it/developers/docs/storage/index.md index ef3bd169125..b67c1ceffaf 100644 --- a/public/content/translations/it/developers/docs/storage/index.md +++ b/public/content/translations/it/developers/docs/storage/index.md @@ -1,6 +1,6 @@ --- title: Archiviazione Decentralizzata -description: Panoramica di cos'è l'archiviazione decentralizzata e degli strumenti disponibili per integrarla in una dapp. +description: "Panoramica di cos'è l'archiviazione decentralizzata e degli strumenti disponibili per integrarla in una dapp." lang: it --- diff --git a/public/content/translations/it/developers/docs/transactions/index.md b/public/content/translations/it/developers/docs/transactions/index.md index 0a3ede82e33..f2d5d47562b 100644 --- a/public/content/translations/it/developers/docs/transactions/index.md +++ b/public/content/translations/it/developers/docs/transactions/index.md @@ -106,7 +106,7 @@ Con l'hash di firma, la transazione può provare crittograficamente che proviene ### Il campo di dati {#the-data-field} -La grande maggioranza delle transazioni accede a un contratto da un conto esterno. Gran parte dei contratti è scritta in Solidity e interpreta il proprio campo dei dati secondo l'[interfaccia binaria dell'applicazione (Application Binary Interface – ABI)](/glossary/#abi/). +La grande maggioranza delle transazioni accede a un contratto da un conto esterno. Gran parte dei contratti è scritta in Solidity e interpreta il proprio campo dei dati secondo l'[interfaccia binaria dell'applicazione (Application Binary Interface – ABI)](/glossary/#abi). I primi quattro byte specificano quale funzione chiamare, usando l'hash del nome e degli argomenti della funzione. Talvolta si può identificare la funzione dal selettore, usando [questo database](https://www.4byte.directory/signatures/). diff --git a/public/content/translations/it/developers/docs/wrapped-eth/index.md b/public/content/translations/it/developers/docs/wrapped-eth/index.md index f6633c6df9d..93a7afd5584 100644 --- a/public/content/translations/it/developers/docs/wrapped-eth/index.md +++ b/public/content/translations/it/developers/docs/wrapped-eth/index.md @@ -1,6 +1,6 @@ --- -title: Che cos'è il Wrapped Ether (WETH) -description: Un'introduzione al Wrapped ether (WETH)—un wrapper per ether (ETH) compatibile con ERC20. +title: "Che cos'è il Wrapped Ether (WETH)" +description: "Un'introduzione al Wrapped ether (WETH)—un wrapper per ether (ETH) compatibile con ERC20." lang: it --- @@ -35,19 +35,16 @@ Puoi "scartare" (ovvero unwrap) WETH per ETH utilizzando il contratto intelligen Devi pagare delle commissioni del gas per avvolgere o scartare ETH utilizzando il contratto WETH. - WETH è generalmente considerato sicuro perché si basa su un contratto intelligente semplice e testato sul campo. Anche il contratto WETH è stato formalmente verificato, che è lo standard di sicurezza più elevato per i contratti intelligenti su Ethereum. - Oltre all'[implementazione canonica di WETH](https://etherscan.io/token/0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2) descritta in questa pagina, ci sono altre varianti in giro. Queste possono essere token personalizzati creati dagli sviluppatori di applicazioni o versioni emesse su altre blockchain, e potrebbero comportarsi diversamente o avere proprietà di sicurezza diverse. **Ricontrolla sempre le informazioni sui token per sapere con quale implementazione di WETH stai interagendo.** - @@ -55,7 +52,6 @@ Oltre all'[implementazione canonica di WETH](https://etherscan.io/token/0xc02aaa - [Rete Principale di Ethereum](https://etherscan.io/token/0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2) - [Arbitrum](https://arbiscan.io/token/0x82af49447d8a07e3bd95bd0d56f35241523fbab1) - [Optimism](https://optimistic.etherscan.io/token/0x4200000000000000000000000000000000000006) - ## Letture consigliate {#further-reading} diff --git a/public/content/translations/it/developers/tutorials/a-developers-guide-to-ethereum-part-one/index.md b/public/content/translations/it/developers/tutorials/a-developers-guide-to-ethereum-part-one/index.md index ab9970efdcc..e755ae0d1a9 100644 --- a/public/content/translations/it/developers/tutorials/a-developers-guide-to-ethereum-part-one/index.md +++ b/public/content/translations/it/developers/tutorials/a-developers-guide-to-ethereum-part-one/index.md @@ -1,33 +1,32 @@ --- -title: Un'introduzione ad Ethereum per sviluppatori con Python, parte 1 -description: Un'introduzione allo sviluppo di Ethereum, particolarmente utile per chi conosce il linguaggio di programmazione Python +title: Introduzione a Ethereum per sviluppatori Python, parte 1 +description: Un'introduzione allo sviluppo su Ethereum, particolarmente utile per chi conosce il linguaggio di programmazione Python author: Marc Garreau lang: it -tags: - - "python" - - "web3.py" +tags: [ "python", "web3.py" ] skill: beginner published: 2020-09-08 source: Snake charmers sourceUrl: https://snakecharmers.ethereum.org/a-developers-guide-to-ethereum-pt-1/ --- -Quindi hai sentito parlare di questo Ethereum e sei pronto ad avventurarti nella tana del coniglio? Questo post coprirà rapidamente alcune basi della blockchain, portandoti a interagire con un nodo simulato di Ethereum: leggere i dati del blocco, verificare i saldi dei conti e inviare transazioni. Lungo il percorso, evidenzieremo le differenze tra metodi tradizionali di costruzione delle app e questo nuovo paradigma decentralizzato. +Quindi hai sentito parlare di questo Ethereum e sei pronto ad avventurarti nella tana del coniglio? Questo post tratterà rapidamente alcune nozioni di base sulla blockchain, per poi farti interagire con un nodo Ethereum simulato, leggendo i dati dei blocchi, controllando i saldi dei conti e inviando transazioni. Lungo il percorso, evidenzieremo le differenze tra i modi tradizionali di creare app e questo nuovo paradigma decentralizzato. -## Prerequisiti (soft) {#soft-prerequisites} +## Prerequisiti (non vincolanti) {#soft-prerequisites} -Questo post aspira ad essere accessibile ad un'ampia gamma di sviluppatori. Tireremo in ballo gli [strumenti di Python](/developers/docs/programming-languages/python/), ma sono solo un veicolo per le idee - non importa se non sei uno sviluppatore Python. Tuttavia, farò solo alcune premesse sulle basi che dovresti già avere, così da poter passare rapidamente alle parti specifiche di Ethereum. +Questo post aspira a essere accessibile a un'ampia gamma di sviluppatori. Saranno coinvolti [strumenti Python](/developers/docs/programming-languages/python/), ma sono solo un veicolo per le idee: non c'è problema se non sei uno sviluppatore Python. Tuttavia, farò solo alcune supposizioni su ciò che già sai, in modo da poter passare rapidamente alle parti specifiche di Ethereum. -Premesse: +Presupposti: - Sai muoverti in un terminale, - Hai scritto qualche riga di codice Python, -- hai la versione 3.6 o superiore di Python installata nella tua macchina (l'uso di un [ambiente virtuale](https://realpython.com/effective-python-environment/#virtual-environments) è fortemente consigliato), e -- hai usato `pip`, l'installatore di pacchetti di Python. Se alcune di queste premesse non rispondessero alla tua situazione o se non fossi interessato a riprodurre il codice in questo articolo, probabilmente puoi comunque seguirlo senza problemi. +- Python versione 3.6 o superiore è installata sul tuo computer (l'uso di un [ambiente virtuale](https://realpython.com/effective-python-environment/#virtual-environments) è fortemente incoraggiato), e +- hai usato `pip`, il programma di installazione dei pacchetti di Python. + Ancora una volta, se uno di questi presupposti non è vero, o se non hai intenzione di riprodurre il codice di questo articolo, probabilmente puoi comunque seguirlo senza problemi. ## Blockchain, in breve {#blockchains-briefly} -Ci sono molti modi per descrivere Ethereum, ma il suo fulcro è costituito dalla blockchain. Le blockchain sono composte da una serie di blocchi, quindi iniziamo da qui. In termini più semplici, ogni blocco sulla blockchain di Ethereum è semplicemente una serie di metadati e un elenco di transazioni. In formato JSON, somiglia a qualcosa del genere: +Ci sono molti modi per descrivere Ethereum, ma il suo fulcro è una blockchain. Le blockchain sono composte da una serie di blocchi, quindi iniziamo da qui. In termini più semplici, ogni blocco sulla blockchain di Ethereum è solo una serie di metadati e un elenco di transazioni. In formato JSON, ha un aspetto simile a questo: ```json { @@ -39,85 +38,85 @@ Ci sono molti modi per descrivere Ethereum, ma il suo fulcro è costituito dalla } ``` -Ogni [blocco](/developers/docs/blocks/) contiene un riferimento al blocco precedente; il `parentHash` è semplicemente l'hash del blocco precedente. +Ogni [blocco](/developers/docs/blocks/) ha un riferimento al blocco che lo precede; il `parentHash` è semplicemente l'hash del blocco precedente. -Nota: Ethereum fa uso regolare delle funzioni di hash per produrre valori di dimensioni fisse ("hash"). Gli hash giocano un ruolo importante in Ethereum, ma per il momento puoi tranquillamente vederli come ID unici. +Nota: Ethereum fa un uso regolare delle funzioni di hash per produrre valori di dimensione fissa ("hash"). Gli hash svolgono un ruolo importante in Ethereum, ma per ora puoi tranquillamente considerarli come ID univoci. -![Un diagramma raffigurante una blockchain che include i dati in ogni blocco](./blockchain-diagram.png) +![Un diagramma che raffigura una blockchain, compresi i dati all'interno di ogni blocco](./blockchain-diagram.png) -_Una blockchain è fondamentalmente un elenco collegato; ogni blocco si riferisce al precedente._ +_Una blockchain è essenzialmente una lista concatenata; ogni blocco ha un riferimento al blocco precedente._ -Questa struttura di dati non è nulla di nuovo, ma le regole (ovvero i protocolli peer-to-peer) che governano la rete lo sono. Non esiste alcuna autorità centrale; la rete di pari deve collaborare per sostenere la rete e competere per decidere quali transazioni includere nel blocco successivo. Quindi, se desideri inviare denaro a un amico, dovrai trasmettere la transazione alla rete, quindi attendere che venga inclusa in un blocco successivo. +Questa struttura dati non è una novità, ma lo sono le regole (cioè, i protocolli peer-to-peer) che governano la rete. Non c'è un'autorità centrale; la rete di peer deve collaborare per sostenere la rete e competere per decidere quali transazioni includere nel blocco successivo. Quindi, quando vuoi inviare del denaro a un amico, devi trasmettere la transazione alla rete e attendere che venga inclusa in un blocco successivo. -L'unico modo per la blockchain di verificare che il denaro sia realmente inviato da un utente all'altro è usare una valuta nativa a quella blockchain (es., creata e governata da essa). In Ethereum, questa valuta è detta ether e la blockchain di Ethereum contiene solo il registro ufficiale dei saldi dei conti. +L'unico modo per la blockchain di verificare che il denaro sia stato effettivamente inviato da un utente a un altro è usare una valuta nativa di quella blockchain (cioè creata e governata da essa). In Ethereum, questa valuta è chiamata ether e la blockchain di Ethereum contiene l'unico registro ufficiale dei saldi dei conti. ## Un nuovo paradigma {#a-new-paradigm} -Questa nuova tecnologia decentralizzata ha generato nuovi strumenti per sviluppatori. Questi esistono in molti linguaggi di programmazione, ma per il momento guarderemo attraverso la lente di Python. Per ribadire: anche se Python non è il tuo linguaggio preferito, non dovrebbe esser troppo difficile proseguire. +Questo nuovo stack tecnologico decentralizzato ha dato vita a nuovi strumenti per sviluppatori. Tali strumenti esistono in molti linguaggi di programmazione, ma noi li esamineremo attraverso la lente di Python. Per ribadire: anche se Python non è il tuo linguaggio preferito, non dovrebbe essere difficile seguirlo. -Gli sviluppatori di Python che desiderano interagire con Ethereum, probabilmente sceglieranno [Web3.py](https://web3py.readthedocs.io/). Web3.py è una libreria che semplifica notevolmente la connessione a un nodo di Ethereum e l'invio e la ricezione di dati da esso. +Gli sviluppatori Python che vogliono interagire con Ethereum probabilmente useranno [Web3.py](https://web3py.readthedocs.io/). Web3.py è una libreria che semplifica notevolmente il modo in cui ci si connette a un nodo Ethereum, per poi inviare e ricevere dati da esso. -Nota: "nodo di Ethereum" e "client di Ethereum" sono usati in modo intercambiabile. Ad ogni modo, ci riferiamo al software eseguito da un partecipante alla rete di Ethereum. Questo software può leggere i dati del blocco, ricevere aggiornamenti quando i nuovi blocchi sono aggiunti alla catena, trasmettere le nuove transazioni e tanto altro. Tecnicamente, il client è il software, il nodo è il computer che esegue il software. +Nota: "Nodo Ethereum" e "client Ethereum" sono usati in modo intercambiabile. In entrambi i casi, si riferisce al software che un partecipante esegue nella rete Ethereum. Questo software può leggere i dati dei blocchi, ricevere aggiornamenti quando nuovi blocchi vengono aggiunti alla catena, trasmettere nuove transazioni e altro ancora. Tecnicamente, il client è il software, il nodo è il computer che esegue il software. -I [client di Ethereum](/developers/docs/nodes-and-clients/) sono configurabili per esser raggiungibili da [IPC](https://wikipedia.org/wiki/Inter-process_communication), HTTP, o Websocket, quindi Web3.py dovrà rispecchiare tale configurazione. Web3.py si riferisce a queste opzioni di connessione come **provider**. Occorre scegliere uno dei tre provider per collegare l'istanza di Web3.py al tuo nodo. +I [client di Ethereum](/developers/docs/nodes-and-clients/) possono essere configurati per essere raggiungibili tramite [IPC](https://wikipedia.org/wiki/Inter-process_communication), HTTP o Websocket, quindi Web3.py dovrà rispecchiare questa configurazione. Web3.py si riferisce a queste opzioni di connessione come **provider**. Dovrai scegliere uno dei tre provider per collegare l'istanza di Web3.py con il tuo nodo. ![Un diagramma che mostra come web3.py utilizza IPC per collegare la tua applicazione a un nodo Ethereum](./web3py-and-nodes.png) -_Configura il nodo di Ethereum e Web3.py per comunicare tramite lo stesso protocollo, ad es. IPC in questo diagramma._ +_Configura il nodo Ethereum e Web3.py per comunicare tramite lo stesso protocollo, ad esempio IPC in questo diagramma._ -Una volta configurato correttamente Web3.py, puoi iniziare a interagire con la blockchain. Ecco un paio di esempi di utilizzo di Web3.py come anticipazione di ciò che vedremo tra poco: +Una volta che Web3.py è configurato correttamente, puoi iniziare a interagire con la blockchain. Ecco un paio di esempi di utilizzo di Web3.py come anteprima di ciò che sta per arrivare: ```python -# read block data: +# leggere i dati dei blocchi: w3.eth.get_block('latest') -# send a transaction: +# inviare una transazione: w3.eth.send_transaction({'from': ..., 'to': ..., 'value': ...}) ``` ## Installazione {#installation} -In questa guida, lavoreremo solo all'interno di un interprete Python. Non creeremo cartelle, file, classi o funzioni. +In questa guida, lavoreremo solo all'interno di un interprete Python. Non creeremo directory, file, classi o funzioni. -Nota: Negli esempi seguenti, i comandi che iniziano con "$" sono intesi come da eseguire nel terminale. (Non occorre digitare "$", indica solo l'inizio della riga.) +Nota: negli esempi seguenti, i comandi che iniziano con `$` devono essere eseguiti nel terminale. (Non digitare il `$`, indica solo l'inizio della riga.) -Innanzi tutto, installa [IPython](https://ipython.org/) per un ambiente user-friendly da esplorare. IPython offre il completamento delle schede, tra le altre funzionalità, facilitando notevolmente la visualizzazione di cosa è possibile in Web3.py. +Per prima cosa, installa [IPython](https://ipython.org/) per avere un ambiente intuitivo da esplorare. IPython offre, tra le altre funzionalità, il completamento automatico tramite tasto Tab, rendendo molto più facile vedere cosa è possibile fare con Web3.py. ```bash pip install ipython ``` -Web3.py è pubblicato sotto il nome `web3`. Installalo come segue: +Web3.py è pubblicato con il nome `web3`. Installalo così: ```bash pip install web3 ``` -Un'altra cosa: più avanti simuleremo una blockchain, il che richiede un paio di altre dipendenze. Puoi installarle tramite: +Ancora una cosa: più avanti simuleremo una blockchain, il che richiede un altro paio di dipendenze. Puoi installarle tramite: ```bash pip install 'web3[tester]' ``` -È tutto pronto per iniziare! +Ora è tutto pronto! -Nota: il pacchetto `web3[tester]` funziona fino a Python 3.10.xx. +Nota: il pacchetto `web3[tester]` funziona fino a Python 3.10.xx -## Aprire un sandbox {#spin-up-a-sandbox} +## Avviare una sandbox {#spin-up-a-sandbox} -Apri un nuovo ambiente di Python eseguendo `ipyton` nel tuo terminale. Ciò è comparabile ad eseguire `python`, ma con qualche fronzolo in più. +Apri un nuovo ambiente Python eseguendo `ipython` nel tuo terminale. È paragonabile all'esecuzione di `python`, ma con più funzionalità. ```bash ipython ``` -Questo produrrà una serie di informazioni sulle versioni di Python e IPython in uso, poi dovresti vedere una richiesta d'inserimento in attesa: +Questo stamperà alcune informazioni sulle versioni di Python e IPython che stai eseguendo, dopodiché dovresti vedere un prompt in attesa di input: ```python In [1]: ``` -Ciò che vedi ora è una shell interattiva di Python. In sostanza, è un recinto di sabbia in cui giocare. Se sei arrivato fin qui, è il momento di importare Web3.py: +Ora stai guardando una shell interattiva di Python. In sostanza, è una sandbox in cui sperimentare. Se sei arrivato fin qui, è il momento di importare Web3.py: ```python In [1]: from web3 import Web3 @@ -125,14 +124,14 @@ In [1]: from web3 import Web3 ## Introduzione al modulo Web3 {#introducing-the-web3-module} -Oltre all'essere un gateway per Ethereum, il modulo [Web3](https://web3py.readthedocs.io/en/stable/overview.html#base-api) offre alcune funzioni comode. Esploriamone alcune. +Oltre a essere un gateway per Ethereum, il modulo [Web3](https://web3py.readthedocs.io/en/stable/overview.html#base-api) offre alcune comode funzioni. Esploriamone un paio. -In un'applicazione di Ethereum, normalmente occorre convertire le denominazioni delle valute. Il modulo Web3 fornisce un paio di metodi di supporto appositamente per questo: [from_wei](https://web3py.readthedocs.io/en/stable/web3.main.html#web3.Web3.from_wei) e [to_wei](https://web3py.readthedocs.io/en/stable/web3.main.html#web3.Web3.to_wei). +In un'applicazione Ethereum, avrai comunemente bisogno di convertire le denominazioni di valuta. Il modulo Web3 fornisce un paio di metodi di supporto proprio per questo: [from_wei](https://web3py.readthedocs.io/en/stable/web3.main.html#web3.Web3.from_wei) e [to_wei](https://web3py.readthedocs.io/en/stable/web3.main.html#web3.Web3.to_wei). -Nota: I computer sono notoriamente inefficaci nella gestione della matematica decimale. Per aggirare ciò, gli sviluppatori archiviano spesso importi di dollari in centesimi. Per esempio, un oggetto con un prezzo di $5,99 potrebbe esser memorizzato nel database come 599. +Nota: i computer sono notoriamente scarsi nella gestione della matematica decimale. Per ovviare a questo problema, gli sviluppatori spesso memorizzano gli importi in dollari in centesimi. Ad esempio, un articolo con un prezzo di 5,99 $ può essere memorizzato nel database come 599. -Uno schema simile è usato per gestire le transazioni in ether. Tuttavia, invece di due punti decimali, ether ne ha 18! La più piccola denominazione di ether è chiamata wei, ovvero il valore specificato inviando le transazioni. +Un modello simile viene utilizzato quando si gestiscono le transazioni in ether. Tuttavia, invece di due cifre decimali, l'ether ne ha 18! La più piccola denominazione di ether si chiama wei, quindi è questo il valore specificato quando si inviano le transazioni. 1 ether = 1000000000000000000 wei @@ -140,7 +139,7 @@ Uno schema simile è usato per gestire le transazioni in ether. Tuttavia, -Prova a convertire dei valori da e verso wei. Nota che [esistono nomi per molte delle denominazioni](https://web3py.readthedocs.io/en/stable/troubleshooting.html#how-do-i-convert-currency-denominations) tra ether e wei. Una delle più note è **gwei**, spesso utilizzata per rappresentare le commissioni di transazione. +Prova a convertire alcuni valori da e verso wei. Nota che [ci sono nomi per molte delle denominazioni](https://web3py.readthedocs.io/en/stable/troubleshooting.html#how-do-i-convert-currency-denominations) tra ether e wei. Uno dei più noti tra questi è **gwei**, poiché è spesso così che vengono rappresentate le commissioni di transazione. ```python In [2]: Web3.to_wei(1, 'ether') @@ -150,49 +149,50 @@ In [3]: Web3.from_wei(500000000, 'gwei') Out[3]: Decimal('0.5') ``` -Altri metodi d'utilità sul modulo Web3 includono i convertitori di formato dei dati (ad es. [`toHex`](https://web3py.readthedocs.io/en/stable/web3.main.html#web3.Web3.toHex)), helper di indirizzo (ad es. [`isAddress`](https://web3py.readthedocs.io/en/stable/web3.main.html#web3.Web3.isAddress)) e funzioni di hash (es., [`keccak`](https://web3py.readthedocs.io/en/stable/web3.main.html#web3.Web3.keccak)). Molti di questi saranno affrontati in seguito nella serie. Per visualizzare tutti i metodi e le proprietà disponibili, usa l'autocompilazione di Python digitando `Web3` e premi il tasto tab due volte dopo il punto. +Altri metodi di utilità sul modulo Web3 includono convertitori di formato dati (ad es. [`toHex`](https://web3py.readthedocs.io/en/stable/web3.main.html#web3.Web3.toHex)), helper di indirizzi (ad es. [`isAddress`](https://web3py.readthedocs.io/en/stable/web3.main.html#web3.Web3.isAddress)) e funzioni di hash (ad es. [`keccak`](https://web3py.readthedocs.io/en/stable/web3.main.html#web3.Web3.keccak)). Molti di questi saranno trattati più avanti nella serie. Per visualizzare tutti i metodi e le proprietà disponibili, utilizza il completamento automatico di IPython digitando `Web3`. e premendo due volte il tasto tab dopo il punto. -## Comunicare con la catena {#talk-to-the-chain} +## Interagire con la blockchain {#talk-to-the-chain} -I metodi di convenienza sono fantastici, ma passiamo alla blockchain. Il prossimo passaggio è configurare Web3.py per comunicare con un nodo di Ethereum. Qui abbiamo l'opzione di usare i provider IPC, HTTP o Websocket. +I metodi di convenienza sono ottimi, ma passiamo alla blockchain. Il passo successivo è configurare Web3.py per comunicare con un nodo Ethereum. Qui abbiamo la possibilità di utilizzare i provider IPC, HTTP o Websocket. -Non percorreremo questo percorso, ma un esempio di flusso di lavoro completo usando il provider HTTP potrebbe apparire così: +Non seguiremo questa strada, ma un esempio di un flusso di lavoro completo che utilizza il provider HTTP potrebbe assomigliare a questo: -- Scarica un nodo di Ethereum, ad es. [Geth](https://geth.ethereum.org/). -- Avvia Geth in una finestra del terminale e attendi che si sincronizzi alla rete. La porta HTTP predefinita è `8545`, ma è configurabile. -- Dì a Web3.py di connettersi al nodo tramite HTTP, su `localhost:8545`. `w3 = Web3(Web3.HTTPProvider('http://127.0.0.1:8545'))` +- Scarica un nodo Ethereum, ad esempio, [Geth](https://geth.ethereum.org/). +- Avvia Geth in una finestra del terminale e attendi che si sincronizzi con la rete. La porta HTTP predefinita è `8545`, ma è configurabile. +- Indica a Web3.py di connettersi al nodo tramite HTTP, su `localhost:8545`. + `w3 = Web3(Web3.HTTPProvider('http://127.0.0.1:8545'))` - Usa l'istanza `w3` per interagire con il nodo. -Questo è uno dei modi "reali" per farlo, mentre il processo di sincronizzazione impiega ore e non è necessario se vuoi solo un ambiente di sviluppo. Web3.py espone un quarto provider per questo scopo, l'**EthereumTesterProvider**. Questo provider di prova si collega a un nodo simulato di Ethereum con autorizzazioni rilassate e valute false con cui giocare. +Anche se questo è un modo "reale" per farlo, il processo di sincronizzazione richiede ore ed è superfluo se si desidera solo un ambiente di sviluppo. Web3.py espone un quarto provider per questo scopo, l'**EthereumTesterProvider**. Questo provider di test si collega a un nodo Ethereum simulato con permessi ridotti e valuta fittizia con cui giocare. -![Un diagramma che mostra l'EthereumTesterProvider collegare la tua applicazione di web3.py a un nodo simulato di Ethereum](./ethereumtesterprovider.png) +![Un diagramma che mostra EthereumTesterProvider che collega la tua applicazione web3.py a un nodo Ethereum simulato](./ethereumtesterprovider.png) -_L'EthereumTesterProvider si connette a un nodo simulato ed è utile per gli ambienti di sviluppo rapido._ +_EthereumTesterProvider si connette a un nodo simulato ed è utile per ambienti di sviluppo rapidi._ -Quel nodo simulato è detto [eth-tester](https://github.com/ethereum/eth-tester) e lo abbiamo installato come parte del comando `pip install web3[tester]`. Configurare Web3.py per usare questo provider di prova è semplicissimo: +Quel nodo simulato si chiama [eth-tester](https://github.com/ethereum/eth-tester) e lo abbiamo installato come parte del comando `pip install web3[tester]`. Configurare Web3.py per utilizzare questo provider di test è semplice: ```python In [4]: w3 = Web3(Web3.EthereumTesterProvider()) ``` -Ora sei pronto a navigare sulla catena! In realtà non si dice così, l'ho inventato io sul momento. Facciamo un rapido tour. +Ora sei pronto a navigare sulla catena! Non è una cosa che si dice. L'ho appena inventato. Facciamo un rapido tour. ## Il tour rapido {#the-quick-tour} -Per prima cosa, un bel sanity check: +Innanzitutto, un controllo di integrità: ```python In [5]: w3.is_connected() Out[5]: True ``` -Poiché stiamo usando il provider di prova, non è un test probante, ma se dovesse fallire, c'è la possibilità che tu abbia digitato qualcosa di sbagliato per avviare un'istanza della variabile `w3`. Ricontrolla di aver incluso le parentesi interne, ad es.`Web3.EthereumTesterProvider()`. +Dato che stiamo usando il provider di test, questo non è un test molto utile, ma se fallisce, è probabile che tu abbia digitato qualcosa di sbagliato durante l'istanziazione della variabile `w3`. Verifica di aver incluso le parentesi interne, ovvero `Web3.EthereumTesterProvider()`. -## Fermata #1 del tour: [conti](/developers/docs/accounts/) {#tour-stop-1-accounts} +## Fermata del tour n. 1: [account](/developers/docs/accounts/) {#tour-stop-1-accounts} -Per comodità, il fornitore di tester ha creato alcuni account e li ha precaricati con test ether. +Per comodità, il provider di test ha creato alcuni account e li ha precaricati con ether di prova. -In primo luogo, vediamo un elenco di questi account: +Per prima cosa, vediamo un elenco di quegli account: ```python In [6]: w3.eth.accounts @@ -201,27 +201,27 @@ Out[6]: ['0x7E5F4552091A69125d5DfCb7b8C2659029395Bdf', '0x6813Eb9362372EEF6200f3b1dbC3f819671cBA69', ...] ``` -Se esegui questo comando, vedrai un elenco di dieci stringhe che iniziano per `0x`. Ciascuna di esse è un **indirizzo pubblico** ed è in qualche modo analoga al numero dell'account di verifica. Puoi fornire questo indirizzo a chiunque voglia inviarti ether. +Se esegui questo comando, dovresti vedere un elenco di dieci stringhe che iniziano con `0x`. Ciascuno è un **indirizzo pubblico** ed è, per certi versi, analogo al numero di un conto corrente. Forniresti questo indirizzo a qualcuno che volesse inviarti ether. -Come accennato, il fornitore di tester ha precaricato ciascuno di questi account con qualche test ether. Scopriamo quanto c'è nel primo account: +Come accennato, il provider di test ha precaricato ciascuno di questi account con alcuni ether di prova. Scopriamo quanto c'è nel primo account: ```python In [7]: w3.eth.get_balance(w3.eth.accounts[0]) Out[7]: 1000000000000000000000000 ``` -Sono molti zeri! Prima di correre alla velocità della luce fino alla banca finta, ricordati la lezione di poco fa sulle denominazioni della valuta. I valori dell'ether sono rappresentati nella più piccola denominazione, ovvero il wei. Convertila in ether: +Sono un sacco di zeri! Prima di andare a ridere fino alla banca finta, ricorda la lezione sulle denominazioni di valuta di prima. I valori di ether sono rappresentati nella denominazione più piccola, wei. Convertilo in ether: ```python In [8]: w3.from_wei(1000000000000000000000000, 'ether') Out[8]: Decimal('1000000') ``` -Un milione di ether di prova, comunque una cifra di tutto rispetto. +Un milione di ether di prova: non è affatto male. -## Fermata del tour #2: dati del blocco {#tour-stop-2-block-data} +## Fermata del tour n. 2: dati del blocco {#tour-stop-2-block-data} -Diamo una sbirciatina allo stato di questa blockchain simulata: +Diamo un'occhiata allo stato di questa blockchain simulata: ```python In [9]: w3.eth.get_block('latest') @@ -234,15 +234,15 @@ Out[9]: AttributeDict({ }) ``` -Vengono restituite molte informazioni su un blocco, ma qui vale la pena di sottolineare solo un paio di cose: +Vengono restituite molte informazioni su un blocco, ma ci sono solo un paio di cose da sottolineare qui: -- Il numero del blocco è zero, non importa quanto tempo fa tu abbia configurato il provider di prova. A differenza della vera rete di Ethereum, che aggiunge un nuovo blocco ogni 12 secondi, questa simulazione attenderà finché non le darai qualcosa da fare. -- `transactions` è un elenco vuoto, per lo stesso motivo: non abbiamo ancora fatto nulla. Questo primo blocco è un **blocco vuoto**, giusto per dare il via alla catena. -- Nota che il `parentHash` è solo un mucchio di byte vuoti. Questo significa che è il primo blocco nella catena, anche noto come **blocco di genesi**. +- Il numero del blocco è zero, non importa quanto tempo fa hai configurato il provider di test. A differenza della vera rete Ethereum, che aggiunge un nuovo blocco ogni 12 secondi, questa simulazione attenderà che tu le dia del lavoro da fare. +- `transactions` è un elenco vuoto, per lo stesso motivo: non abbiamo ancora fatto nulla. Questo primo blocco è un **blocco vuoto**, solo per dare il via alla catena. +- Nota che il `parentHash` è solo un mucchio di byte vuoti. Questo significa che è il primo blocco della catena, noto anche come **blocco genesi**. -## Fermata #3 del tour: [transazioni](/developers/docs/transactions/) {#tour-stop-3-transactions} +## Fermata del tour n. 3: [transazioni](/developers/docs/transactions/) {#tour-stop-3-transactions} -Siamo fermi al blocco zero finché non si verifica una transazione in sospeso, quindi diamogliene una. Invia qualche ether di prova da un account all'altro: +Siamo bloccati al blocco zero finché non c'è una transazione in sospeso, quindi creiamone una. Invia alcuni ether di prova da un account a un altro: ```python In [10]: tx_hash = w3.eth.send_transaction({ @@ -253,11 +253,14 @@ In [10]: tx_hash = w3.eth.send_transaction({ }) ``` -Questo è tipicamente il punto in cui dovresti aspettare diversi secondi affinché la tua transazione sia inclusa in un nuovo blocco. L'intero processo va più o meno come indicato sotto: +Questo è in genere il punto in cui aspetteresti diversi secondi affinché la tua transazione venga inclusa in un nuovo blocco. Il processo completo è più o meno questo: -1. Invia una transazione e mantieni l'hash della transazione. Finché il blocco contenente la transazione non viene creato e trasmesso, la transazione è "in sospeso". `tx_hash = w3.eth.send_transaction({ … })` -2. Attendi che la transazione sia inclusa in un blocco: `w3.eth.wait_for_transaction_receipt(tx_hash)` -3. Prosegui la logica dell'applicazione. Per visualizzare la transazione riuscita: `w3.eth.get_transaction(tx_hash)` +1. Invia una transazione e conserva l'hash della transazione. Finché il blocco contenente la transazione non viene creato e trasmesso, la transazione è "in sospeso". + `tx_hash = w3.eth.send_transaction({ … })` +2. Attendi che la transazione venga inclusa in un blocco: + `w3.eth.wait_for_transaction_receipt(tx_hash)` +3. Continua la logica dell'applicazione. Per visualizzare la transazione andata a buon fine: + `w3.eth.get_transaction(tx_hash)` Il nostro ambiente simulato aggiungerà la transazione in un nuovo blocco istantaneamente, quindi possiamo visualizzare immediatamente la transazione: @@ -274,9 +277,9 @@ Out[11]: AttributeDict({ }) ``` -Vedrai qualche dettaglio familiare qui: i campi `from`, `to` e `value` dovrebbero corrispondere alle immissioni della tua chiamata `send_transaction`. L'altra parte rassicurante è che questa transazione è stata inclusa come prima transazione (`'transactionIndex': 0`) nel blocco numero 1. +Qui vedrai alcuni dettagli familiari: i campi `from`, `to` e `value` dovrebbero corrispondere agli input della nostra chiamata `send_transaction`. L'altro dato rassicurante è che questa transazione è stata inclusa come prima transazione (`'transactionIndex': 0`) nel blocco numero 1. -Possiamo anche verificare facilmente il successo di questa transazione controllando i saldi dei due account coinvolti. Tre ether dovrebbero essersi spostati dal primo al secondo. +Possiamo anche verificare facilmente il successo di questa transazione controllando i saldi dei due account coinvolti. Tre ether dovrebbero essere passati da uno all'altro. ```python In [12]: w3.eth.get_balance(w3.eth.accounts[0]) @@ -286,12 +289,12 @@ In [13]: w3.eth.get_balance(w3.eth.accounts[1]) Out[13]: 1000003000000000000000000 ``` -Quest'ultima parte sembra a posto! Il saldo è passato da 1.000.000 a 1.000.003 ether. Ma cosa è successo al primo account? Sembra aver perso lievemente di più di tre ether. Ahimè, niente nella vita è gratis e per usare la rete pubblica di Ethereum occorre compensare i tuoi pari per il loro ruolo di supporto. Una piccola commissione di transazione è stata detratta dall'account che ha inviato la transazione: si tratta dell'importo di gas bruciato (21000 unità di gas per un trasferimento di ETH), moltiplicato per una commissione di base che varia a seconda dell'attività della rete, più una mancia inviata al validatore che include la transazione in un blocco. +Quest'ultimo sembra a posto! Il saldo è passato da 1.000.000 a 1.000.003 ether. Ma cosa è successo al primo account? Sembra che abbia perso poco più di tre ether. Ahimè, nulla nella vita è gratis, e l'uso della rete pubblica di Ethereum richiede che tu compensi i tuoi pari per il loro ruolo di supporto. Una piccola commissione di transazione è stata detratta dall'account che ha inviato la transazione: questa commissione è l'importo di gas bruciato (21000 unità di gas per un trasferimento di ETH) moltiplicato per una commissione di base che varia a seconda dell'attività della rete più una mancia che va al validatore che include la transazione in un blocco. Maggiori informazioni sul [gas](/developers/docs/gas/#post-london) -Nota: Sulla rete pubblica, le commissioni di transazione sono variabili in base alla domanda della rete ella rapidità con cui vorresti che una transazione fosse elaborata. Se sei interessato a una ripartizione di come sono calcolate le commissioni, vedi il mio post precedente su come sono incluse le transazioni in un blocco. +Nota: sulla rete pubblica, le commissioni di transazione sono variabili in base alla domanda della rete e alla velocità con cui si desidera che una transazione venga elaborata. Se sei interessato a un'analisi dettagliata di come vengono calcolate le commissioni, consulta il mio post precedente su come le transazioni vengono incluse in un blocco. -## E respira {#and-breathe} +## E ora, un respiro di sollievo {#and-breathe} -Ci siamo soffermati su questo argomento per un po' di tempo, quindi sembra un buon momento per prendersi una pausa. L'argomento non è esaurito e continueremo a parlarne nella seconda parte di questa serie. Alcuni concetti che affronteremo: connettersi a un nodo reale, contratti intelligenti e token. Hai domande d'approfondimento? Fammelo sapere! Il tuo feedback influenzerà il contenuto della seconda parte. Le richieste sono benvenute tramite [Twitter](https://twitter.com/wolovim). +Siamo su questo argomento da un po', quindi questo sembra un buon punto per fare una pausa. La tana del coniglio continua, e continueremo a esplorare nella seconda parte di questa serie. Alcuni concetti a venire: connessione a un nodo reale, contratti intelligenti e token. Hai altre domande? Fammelo sapere! Il tuo feedback influenzerà la direzione che prenderemo da qui. Le richieste sono benvenute tramite [Twitter](https://twitter.com/wolovim). diff --git a/public/content/translations/it/developers/tutorials/all-you-can-cache/index.md b/public/content/translations/it/developers/tutorials/all-you-can-cache/index.md index 57c7b8c3940..feceb8d43e8 100644 --- a/public/content/translations/it/developers/tutorials/all-you-can-cache/index.md +++ b/public/content/translations/it/developers/tutorials/all-you-can-cache/index.md @@ -1,34 +1,36 @@ --- title: "Salva nella cache quanto vuoi" -description: Scopri come creare e utilizzare un contratto di memorizzazione nella cache per transazioni rollup più economiche +description: "Scopri come creare e utilizzare un contratto di memorizzazione nella cache per transazioni rollup più economiche" author: Ori Pomerantz tags: - - "livello 2" - - "memorizzazione nella cache" - - "archiviazione" + [ + "livello 2", + "memorizzazione nella cache", + "archiviazione" + ] skill: intermediate published: 2022-09-15 lang: it --- -Utilizzando i rollup, il costo di un byte nella transazione è molto maggiore di quello di uno spazio d'archiviazione. Dunque, ha senso salvare nella cache quante più informazioni possibili sulla catena. +Utilizzando i rollup, il costo di un byte nella transazione è molto maggiore di quello di uno slot d'archiviazione. Dunque, ha senso salvare nella cache quante più informazioni possibili sulla catena. In questo articolo imparerai come creare e utilizzare un contratto di memorizzazione nella cache, in modo tale che il valore di ogni parametro che è probabile sia utilizzato più volte sarà salvato nella cache e disponibile all'uso (dopo la prima volta), con un numero di byte molto inferiore, e come scrivere il codice fuori catena che utilizza tale cache. -Se desideri saltare l'articolo e visualizzare soltanto il codice sorgente, [lo trovi qui](https://github.com/qbzzt/20220915-all-you-can-cache). Lo stack di sviluppo è [Foundry](https://book.getfoundry.sh/getting-started/installation). +Se vuoi saltare l'articolo e vedere solo il codice sorgente, [è qui](https://github.com/qbzzt/20220915-all-you-can-cache). Lo stack di sviluppo è [Foundry](https://getfoundry.sh/introduction/installation/). -## Design generale {#overall-design} +## Progettazione generale {#overall-design} Per semplicità supponiamo che tutti i parametri delle transazioni siano `uint256`, lunghi 32 byte. Quando riceviamo una transazione, analizziamo ogni parametro come segue: -1. Se il primo byte è `0xFF`, prendi i successivi 32 byte come valore di parametro e scrivilo nella cache. +1. Se il primo byte è `0xFF`, prendi i 32 byte successivi come valore di parametro e scrivilo nella cache. -2. Se il primo byte è `0xFE`, prendi i successivi 32 byte come valore del parametro e _non_ scriverli nella cache. +2. Se il primo byte è `0xFE`, prendi i 32 byte successivi come valore del parametro ma _non_ scriverlo nella cache. 3. Per qualsiasi altro valore, prendi i primi quattro bit come numero di byte aggiuntivi e gli ultimi quattro come i bit più significativi della chiave di cache. Ecco alcuni esempi: | Byte nei calldata | Chiave della cache | - |:----------------- | ------------------:| + | :---------------- | -----------------: | | 0x0F | 0x0F | | 0x10,0x10 | 0x10 | | 0x12,0xAC | 0x02AC | @@ -49,26 +51,26 @@ contract Cache { bytes1 public constant DONT_CACHE = 0xFE; ``` -Queste costanti sono utilizzate per interpretare i casi speciali in cui forniamo tutte le informazioni e se desideriamo scriverle o no nella cache. Scrivere nella cache richiede due operazioni [`SSTORE`](https://www.evm.codes/#55) negli spazi d'archiviazione precedentemente inutilizzati, al costo di 22100 gas l'uno, quindi lo rendiamo facoltativo. +Queste costanti sono utilizzate per interpretare i casi speciali in cui forniamo tutte le informazioni e se desideriamo scriverle o no nella cache. La scrittura nella cache richiede due operazioni [`SSTORE`](https://www.evm.codes/#55) in slot di archiviazione non utilizzati in precedenza, al costo di 22100 gas ciascuna, quindi la rendiamo facoltativa. ```solidity mapping(uint => uint) public val2key; ``` -Una [mappatura](https://www.geeksforgeeks.org/solidity-mappings/) tra i valori e le loro chiavi. Queste informazioni sono necessarie per codificare i valori prima di inviare la transazione. +Una [mappatura](https://www.geeksforgeeks.org/solidity/solidity-mappings/) tra i valori e le loro chiavi. Queste informazioni sono necessarie per codificare i valori prima di inviare la transazione. ```solidity - // Location n has the value for key n+1, because we need to preserve - // zero as "not in the cache". + // La posizione n ha il valore per la chiave n+1, perché dobbiamo preservare + // lo zero come "non nella cache". uint[] public key2val; ``` -Possiamo utilizzare un insieme per la mappatura dalle chiavi ai valori, perché assegniamo le chiavi e, per semplicità, lo facciamo sequenzialmente. +Possiamo usare un array per la mappatura da chiavi a valori perché assegniamo noi le chiavi e, per semplicità, lo facciamo in modo sequenziale. ```solidity function cacheRead(uint _key) public view returns (uint) { - require(_key <= key2val.length, "Reading uninitialize cache entry"); + require(_key <= key2val.length, "Lettura di una voce della cache non inizializzata"); return key2val[_key-1]; } // cacheRead ``` @@ -76,10 +78,10 @@ Possiamo utilizzare un insieme per la mappatura dalle chiavi ai valori, perché Legge un valore dalla cache. ```solidity - // Write a value to the cache if it's not there already - // Only public to enable the test to work + // Scrive un valore nella cache se non è già presente + // Pubblico solo per consentire il funzionamento del test function cacheWrite(uint _value) public returns (uint) { - // If the value is already in the cache, return the current key + // Se il valore è già nella cache, restituisce la chiave corrente if (val2key[_value] != 0) { return val2key[_value]; } @@ -88,18 +90,18 @@ Legge un valore dalla cache. Non ha senso mettere lo stesso valore nella cache più di una volta. Se il valore è già presente, basta restituire la chiave esistente. ```solidity - // Since 0xFE is a special case, the largest key the cache can - // hold is 0x0D followed by 15 0xFF's. If the cache length is already that - // large, fail. + // Poiché 0xFE è un caso speciale, la chiave più grande che la cache può + // contenere è 0x0D seguita da 15 0xFF. Se la lunghezza della cache è già + // così grande, l'operazione fallisce. // 1 2 3 4 5 6 7 8 9 A B C D E F require(key2val.length+1 < 0x0DFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, - "cache overflow"); + "overflow della cache"); ``` -Non penso che otterremo mai una cache così grande (approssimativamente 1,8\*1037 voci, che richiederebbero circa 1027 TB per l'archiviazione). Tuttavia, sono abbastanza anziano da ricordare che ["640 kB saranno sempre sufficienti"](https://quoteinvestigator.com/2011/09/08/640k-enough/). Questo test è molto economico. +Non penso che otterremo mai una cache così grande (approssimativamente 1,8\*1037 voci, che richiederebbero circa 1027 TB per l'archiviazione). Tuttavia, sono abbastanza vecchio da ricordare ["640kB sarebbero sempre stati sufficienti"](https://quoteinvestigator.com/2011/09/08/640k-enough/). Questo test è molto economico. ```solidity - // Write the value using the next key + // Scrivi il valore usando la chiave successiva val2key[_value] = key2val.length+1; ``` @@ -109,30 +111,30 @@ Aggiungi la ricerca inversa (dal valore alla chiave). key2val.push(_value); ``` -Aggiungi la ricerca inversa (dalla chiave al valore). Poiché assegniamo i valori sequenzialmente, possiamo semplicemente aggiungerli dopo il valore dell'ultimo insieme. +Aggiungi la ricerca diretta (dalla chiave al valore). Poiché assegniamo i valori in modo sequenziale, possiamo semplicemente aggiungerlo dopo l'ultimo valore dell'array. ```solidity return key2val.length; } // cacheWrite ``` -Restituisce la nuova lunghezza di `key2val`, la cella in cui è memorizzato il nuovo valore. +Restituisce la nuova lunghezza di `key2val`, che è la cella in cui è memorizzato il nuovo valore. ```solidity function _calldataVal(uint startByte, uint length) private pure returns (uint) ``` -Questa funzione legge un valore dai calldata di lunghezza arbitraria (fino a 32 byte, le dimensioni delle parole). +Questa funzione legge un valore dai calldata di lunghezza arbitraria (fino a 32 byte, la dimensione della parola). ```solidity { uint _retVal; require(length < 0x21, - "_calldataVal length limit is 32 bytes"); + "il limite di lunghezza di _calldataVal è 32 byte"); require(length + startByte <= msg.data.length, - "_calldataVal trying to read beyond calldatasize"); + "_calldataVal sta tentando di leggere oltre calldatasize"); ``` Questa funzione è interna, quindi se il resto del codice è scritto correttamente, questi test non sono necessari. Tuttavia, non costano molto, quindi potremmo anche averli. @@ -156,7 +158,7 @@ Non vogliamo necessariamente un valore di 32 byte. Questo elimina i byte in ecce } // _calldataVal - // Read a single parameter from the calldata, starting at _fromByte + // Legge un singolo parametro dai calldata, a partire da _fromByte function _readParam(uint _fromByte) internal returns (uint _nextByte, uint _parameterValue) { @@ -165,34 +167,34 @@ Non vogliamo necessariamente un valore di 32 byte. Questo elimina i byte in ecce Legge un singolo parametro dai calldata. Nota che dobbiamo restituire non soltanto il valore che leggiamo, ma anche la posizione di quello successivo, poiché i parametri possono andare da una lunghezza di 1 byte a 33 byte. ```solidity - // The first byte tells us how to interpret the rest + // Il primo byte ci dice come interpretare il resto uint8 _firstByte; _firstByte = uint8(_calldataVal(_fromByte, 1)); ``` -Solidity prova a ridurre il numero di bug vietando le [conversioni di tipo implicito](https://docs.soliditylang.org/en/v0.8.16/types.html#implicit-conversions) potenzialmente pericolose. Un downgrade, ad esempio da 256 bit a 8 bit, dev'essere esplicito. +Solidity cerca di ridurre il numero di bug vietando [conversioni di tipo implicite](https://docs.soliditylang.org/en/v0.8.16/types.html#implicit-conversions) potenzialmente pericolose. Un downgrade, ad esempio da 256 bit a 8 bit, dev'essere esplicito. ```solidity - // Read the value, but do not write it to the cache + // Leggi il valore, ma non scriverlo nella cache if (_firstByte == uint8(DONT_CACHE)) return(_fromByte+33, _calldataVal(_fromByte+1, 32)); - // Read the value, and write it to the cache + // Leggi il valore e scrivilo nella cache if (_firstByte == uint8(INTO_CACHE)) { uint _param = _calldataVal(_fromByte+1, 32); cacheWrite(_param); return(_fromByte+33, _param); } - // If we got here it means that we need to read from the cache + // Se siamo arrivati qui significa che dobbiamo leggere dalla cache - // Number of extra bytes to read + // Numero di byte extra da leggere uint8 _extraBytes = _firstByte / 16; ``` -Prendi un [nibble](https://en.wikipedia.org/wiki/Nibble) inferiore e combinalo con altri byte per leggere il valore dalla cache. +Prendi il [nibble](https://en.wikipedia.org/wiki/Nibble) inferiore e combinalo con gli altri byte per leggere il valore dalla cache. ```solidity uint _key = (uint256(_firstByte & 0x0F) << (8*_extraBytes)) + @@ -203,17 +205,17 @@ Prendi un [nibble](https://en.wikipedia.org/wiki/Nibble) inferiore e combinalo c } // _readParam - // Read n parameters (functions know how many parameters they expect) + // Legge n parametri (le funzioni sanno quanti parametri si aspettano) function _readParams(uint _paramNum) internal returns (uint[] memory) { ``` Potremmo ottenere il numero di parametri dagli stessi calldata, ma le funzioni che ci chiamano sanno quanti parametri sono previsti. È più facile lasciarcelo dire. ```solidity - // The parameters we read + // I parametri che leggiamo uint[] memory params = new uint[](_paramNum); - // Parameters start at byte 4, before that it's the function signature + // I parametri iniziano al byte 4, prima c'è la firma della funzione uint _atByte = 4; for(uint i=0; i<_paramNum; i++) { @@ -221,14 +223,14 @@ Potremmo ottenere il numero di parametri dagli stessi calldata, ma le funzioni c } ``` -Leggi i parametri finché non ottieni il numero desiderato. Se andiamo oltre la fine dei calldata, `_readParams` ripristinerà la chiamata. +Leggi i parametri finché non ottieni il numero desiderato. Se andiamo oltre la fine dei calldata, `_readParams` annullerà la chiamata. ```solidity return(params); } // readParams - // For testing _readParams, test reading four parameters + // Per testare _readParams, testa la lettura di quattro parametri function fourParam() public returns (uint256,uint256,uint256,uint256) { @@ -238,45 +240,45 @@ Leggi i parametri finché non ottieni il numero desiderato. Se andiamo oltre la } // fourParam ``` -Un grande vantaggio di Foundry è che consente la scrittura dei test in Solidity ([vedi Testare la cache di seguito](#testing-the-cache)). Questo semplifica molto i test unitari. Questa è una funzione che legge quattro parametri e li restituisce in modo che il test possa verificare che siano corretti. +Un grande vantaggio di Foundry è che consente di scrivere test in Solidity ([vedi Test della cache sotto](#testing-the-cache)). Questo semplifica molto i test unitari. Questa è una funzione che legge quattro parametri e li restituisce in modo che il test possa verificare che siano corretti. ```solidity - // Get a value, return bytes that will encode it (using the cache if possible) + // Ottiene un valore, restituisce i byte che lo codificheranno (usando la cache se possibile) function encodeVal(uint _val) public view returns(bytes memory) { ``` -`encodeVal` è una funzione che il codice fuori catena chiama per aiutare a creare calldata che utilizzano la cache. Riceve un singolo valore e restituisce i byte che lo codificano. Questa funzione è una `view`, quindi non richiede una transazione e quando chiamata esternamente non costa alcun gas. +`encodeVal` è una funzione che il codice offchain chiama per aiutare a creare calldata che utilizzano la cache. Riceve un singolo valore e restituisce i byte che lo codificano. Questa funzione è una `view`, quindi non richiede una transazione e se chiamata esternamente non costa gas. ```solidity uint _key = val2key[_val]; - // The value isn't in the cache yet, add it + // Il valore non è ancora nella cache, aggiungilo if (_key == 0) return bytes.concat(INTO_CACHE, bytes32(_val)); ``` -Nell'[EVM](/developers/docs/evm/) si presume che tutta l'archiviazione non inizializzata contenga zeri. Quindi se cerchiamo la chiave per un valore assente, otteniaamo uno zero. In quel caso i byte che la codificano sono `INTO_CACHE` (quindi sarà salvato nella cache la prossima volta), seguiti dal valore effettivo. +Nell'[EVM](/developers/docs/evm/) si presume che tutta l'archiviazione non inizializzata contenga zeri. Quindi se cerchiamo la chiave per un valore assente, otteniamo uno zero. In quel caso i byte che la codificano sono `INTO_CACHE` (quindi sarà salvato nella cache la prossima volta), seguiti dal valore effettivo. ```solidity - // If the key is <0x10, return it as a single byte + // Se la chiave è <0x10, la restituisce come un singolo byte if (_key < 0x10) return bytes.concat(bytes1(uint8(_key))); ``` -I byte singoli sono i più facili. Semplicemente, utilizziamo [`bytes.concat`](https://docs.soliditylang.org/en/v0.8.16/types.html#the-functions-bytes-concat-and-string-concat) per trasformare un tipo `bytes` in un insieme di byte di qualsiasi lunghezza. Nonostante il nome, funziona bene quando fornito con un solo argomento. +I byte singoli sono i più facili. Usiamo semplicemente [`bytes.concat`](https://docs.soliditylang.org/en/v0.8.16/types.html#the-functions-bytes-concat-and-string-concat) per trasformare un tipo `bytes` in un array di byte che può avere qualsiasi lunghezza. Nonostante il nome, funziona bene quando fornito con un solo argomento. ```solidity - // Two byte value, encoded as 0x1vvv + // Valore di due byte, codificato come 0x1vvv if (_key < 0x1000) return bytes.concat(bytes2(uint16(_key) | 0x1000)); ``` -Quando abbiamo una chiave inferiore a 163, possiamo esprimerla in due byte. Prima convertiamo `_key`, un valore da 256 bit, in un valore da 16 bit, quindi utilizziamo il logical o aggiungiamo il numero di byte aggiuntivi al primo byte. Quindi abbiamo un valore `bytes2` convertibile in `bytes`. +Quando abbiamo una chiave inferiore a 163, possiamo esprimerla in due byte. Prima convertiamo `_key`, un valore da 256 bit, in un valore da 16 bit, quindi utilizziamo l'OR logico o per aggiungere il numero di byte aggiuntivi al primo byte. Poi lo trasformiamo in un valore `bytes2`, che può essere convertito in `bytes`. ```solidity - // There is probably a clever way to do the following lines as a loop, - // but it's a view function so I'm optimizing for programmer time and - // simplicity. + // Probabilmente c'è un modo intelligente per eseguire le righe seguenti come un ciclo, + // ma è una funzione di visualizzazione, quindi sto ottimizzando per il tempo del programmatore e + // la semplicità. if (_key < 16*256**2) return bytes.concat(bytes3(uint24(_key) | (0x2 * 16 * 256**2))); @@ -291,14 +293,14 @@ Quando abbiamo una chiave inferiore a 163, possiamo esprimerla in due return bytes.concat(bytes16(uint128(_key) | (0xF * 16 * 256**15))); ``` -Gli altri valori (3 byte, 4 byte, ecc.) sono gestiti allo stesso modo, ma con dimensioni del campo differenti. +Gli altri valori (3 byte, 4 byte, ecc.) sono gestiti allo stesso modo, solo con dimensioni di campo differenti. ```solidity - // If we get here, something is wrong. - revert("Error in encodeVal, should not happen"); + // Se arriviamo qui, qualcosa è andato storto. + revert("Errore in encodeVal, non dovrebbe accadere"); ``` -Se arriviamo qui significa che abbiamo una chiave non inferiore a 16\*25615. Ma `cacheWrite` limita le chiavi quindi non possiamo arrivare nemmeno fino a 14\*25616 (che avrebbe un primo byte di 0xFE, quindi apparirebbe così: `DONT_CACHE`). Ma aggiungere un test nel caso in cui un programmatore futuro aggiunga un bug non ci costa molto. +Se arriviamo qui significa che abbiamo una chiave non inferiore a 16\*25615. Ma `cacheWrite` limita le chiavi quindi non possiamo arrivare nemmeno fino a 14\*25616 (che avrebbe un primo byte di 0xFE, quindi apparirebbe come `DONT_CACHE`). Ma aggiungere un test nel caso in cui un programmatore futuro aggiunga un bug non ci costa molto. ```solidity } // encodeVal @@ -306,9 +308,9 @@ Se arriviamo qui significa che abbiamo una chiave non inferiore a 16\*25615 } // Cache ``` -### Testare la cache {#testing-the-cache} +### Test della cache {#testing-the-cache} -Uno dei vantaggi di Foundry è che [ti consente di scrivere i test in Solidity](https://book.getfoundry.sh/forge/tests), semplificando la scrittura dei test unitari. I test per la classe `Cache` sono [qui](https://github.com/qbzzt/20220915-all-you-can-cache/blob/main/test/Cache.t.sol). Poiché il codice del test è ripetitivo, come tendono a essere i test, questo articolo spiega soltanto le parti interessanti. +Uno dei vantaggi di Foundry è che [ti permette di scrivere test in Solidity](https://getfoundry.sh/forge/tests/overview/), il che rende più facile scrivere test unitari. I test per la classe `Cache` sono [qui](https://github.com/qbzzt/20220915-all-you-can-cache/blob/main/test/Cache.t.sol). Poiché il codice del test è ripetitivo, come tendono a essere i test, questo articolo spiega soltanto le parti interessanti. ```solidity // SPDX-License-Identifier: UNLICENSED @@ -317,11 +319,11 @@ pragma solidity ^0.8.13; import "forge-std/Test.sol"; -// Need to run `forge test -vv` for the console. +// È necessario eseguire `forge test -vv` per la console. import "forge-std/console.sol"; ``` -Questo è solo un modello standard necessario per utilizzare il pacchetto del test e `console.log`. +Questo è solo boilerplate necessario per utilizzare il pacchetto di test e `console.log`. ```solidity import "src/Cache.sol"; @@ -344,7 +346,7 @@ La funzione `setUp` viene chiamata prima di ogni test. In questo caso, creiamo s function testCaching() public { ``` -I test sono funzioni i cui nomi iniziano per `test`. Questa funzione verifica la funzionalità di base della cache, scrivendo i valori e rileggendoli. +I test sono funzioni i cui nomi iniziano con `test`. Questa funzione verifica la funzionalità di base della cache, scrivendo i valori e rileggendoli. ```solidity for(uint i=1; i<5000; i++) { @@ -355,15 +357,15 @@ I test sono funzioni i cui nomi iniziano per `test`. Questa funzione verifica la assertEq(cache.cacheRead(i), i*i); ``` -Ecco come si esegue il test effettivo, utilizzando le funzioni [`assert...`](https://book.getfoundry.sh/reference/forge-std/std-assertions). In questo caso verifichiamo che il valore scritto sia quello che leggiamo. Possiamo scartare il risultato di `cache.cacheWrite`, poiché sappiamo che le chiavi della cache sono assegnate linearmente. +Questo è il modo in cui si esegue il test vero e proprio, utilizzando le [funzioni `assert...`](https://getfoundry.sh/reference/forge-std/std-assertions/). In questo caso verifichiamo che il valore scritto sia quello che leggiamo. Possiamo scartare il risultato di `cache.cacheWrite`, poiché sappiamo che le chiavi della cache sono assegnate linearmente. ```solidity } } // testCaching - // Cache the same value multiple times, ensure that the key stays - // the same + // Salva nella cache lo stesso valore più volte, assicurati che la chiave rimanga + // la stessa function testRepeatCaching() public { for(uint i=1; i<100; i++) { uint _key1 = cache.cacheWrite(i); @@ -382,16 +384,16 @@ Prima scriviamo ogni valore due volte nella cache e ci assicuriamo che le chiavi } // testRepeatCaching ``` -In teoria, potrebbe esserci un bug che non influenza le scritture consecutive nella cache. Quindi qui eseguiamo altre scritture non consecutive e visualizziamo i valori che non sono ancora riscritti. +In teoria, potrebbe esserci un bug che non influenza le scritture consecutive nella cache. Quindi qui eseguiamo altre scritture non consecutive e vediamo che i valori non sono ancora riscritti. ```solidity - // Read a uint from a memory buffer (to make sure we get back the parameters - // we sent out) + // Legge un uint da un buffer di memoria (per essere sicuri di riavere i parametri + // che abbiamo inviato) function toUint256(bytes memory _bytes, uint256 _start) internal pure returns (uint256) ``` -Legge una parola da 256 bit da un buffer `bytes memory`. Questa funzione di utilità ci consente di verificare che riceviamo i risultati corretti, eseguendo la chiamata a una funzione che utilizza la cache. +Legge una parola da 256 bit da un buffer `bytes memory`. Questa funzione di utilità ci consente di verificare che riceviamo i risultati corretti eseguendo una chiamata a una funzione che utilizza la cache. ```solidity { @@ -403,18 +405,18 @@ Legge una parola da 256 bit da un buffer `bytes memory`. Questa funzione di util } ``` -Yul non supporta le strutture di dati oltre `uint256`, quindi quando fai riferimento a strutture di dati più sofisticate, come il buffer di memoria `_bytes`, ne ottieni l'indirizzo. Solidity memorizza i valori di `bytes memory` come una parola da 32 byte contenente la lunghezza, seguita dai byte effettivi, quindi per ottenere il numero di byte `_start`, dobbiamo calcolare `_bytes+32+_start`. +Yul non supporta le strutture di dati oltre a `uint256`, quindi quando fai riferimento a strutture di dati più sofisticate, come il buffer di memoria `_bytes`, ne ottieni l'indirizzo. Solidity memorizza i valori `bytes memory` come una parola da 32 byte contenente la lunghezza, seguita dai byte effettivi, quindi per ottenere il numero di byte `_start`, dobbiamo calcolare `_bytes+32+_start`. ```solidity return tempUint; } // toUint256 - // Function signature for fourParams(), courtesy of + // Firma della funzione per fourParams(), per gentile concessione di // https://www.4byte.directory/signatures/?bytes4_signature=0x3edc1e6d bytes4 constant FOUR_PARAMS = 0x3edc1e6d; - // Just some constant values to see we're getting the correct values back + // Solo alcuni valori costanti per vedere se riceviamo i valori corretti uint256 constant VAL_A = 0xDEAD60A7; uint256 constant VAL_B = 0xBEEF; uint256 constant VAL_C = 0x600D; @@ -436,23 +438,23 @@ Chiama `fourParams()`, una funzione che utilizza `readParams` per testare la pos bytes memory _callOutput; ``` -Non possiamo utilizzare il normale meccanismo ABI per chiamare una funzione utilizzando la cache, quindi dobbiamo utilizzare il meccanismo di basso livello [`
.call()`](https://docs.soliditylang.org/en/v0.8.16/types.html#members-of-addresses). Tale meccanismo prende `bytes memory` come input e lo restituisce (insieme a un valore Booleano) come output. +Non possiamo utilizzare il normale meccanismo ABI per chiamare una funzione utilizzando la cache, quindi dobbiamo utilizzare il meccanismo di basso livello [`
.call()`](https://docs.soliditylang.org/en/v0.8.16/types.html#members-of-addresses). Tale meccanismo prende un `bytes memory` come input e lo restituisce (insieme a un valore booleano) come output. ```solidity - // First call, the cache is empty + // Prima chiamata, la cache è vuota _callInput = bytes.concat( FOUR_PARAMS, ``` -È utile, per lo stesso contratto, supportare sie le funzioni nella cache (per le chiamate direttamente dalle transazioni) che le funzioni non nella cache (per le chiamate da altri contratti intelligenti). Per farlo, dobbiamo continuare ad affidarci al meccanismo di Solidity per chiamare la funzione corretta, invece di mettere tutto in [una funzione di `fallback`](https://docs.soliditylang.org/en/v0.8.16/contracts.html#fallback-function). Farlo semplifica la compositività. Un singolo byte basterebbe per identificare la funzione in gran parte dei casi, quindi stiamo sprecando tre byte (16\*3=48 gas). Tuttavia, al momento della scrittura di questa guida, quei 48 di gas costano 0,07 centesimi, un costo ragionevole del codice più semplice e meno soggetto a bug. +È utile, per lo stesso contratto, supportare sia le funzioni nella cache (per le chiamate direttamente dalle transazioni) che le funzioni non nella cache (per le chiamate da altri contratti intelligenti). Per farlo, dobbiamo continuare ad affidarci al meccanismo di Solidity per chiamare la funzione corretta, invece di mettere tutto in una [funzione `fallback`](https://docs.soliditylang.org/en/v0.8.16/contracts.html#fallback-function). Farlo semplifica la componibilità. Un singolo byte basterebbe per identificare la funzione nella maggior parte dei casi, quindi stiamo sprecando tre byte (16\*3=48 gas). Tuttavia, al momento della scrittura di questa guida, quei 48 di gas costano 0,07 centesimi, un costo ragionevole per un codice più semplice e meno soggetto a bug. ```solidity - // First value, add it to the cache + // Primo valore, aggiungilo alla cache cache.INTO_CACHE(), bytes32(VAL_A), ``` -Il primo valore: un flag che dice che è un valore completo che necessita di essere scritto nella cache, seguito dai 32 byte del valore. Gli altri tre valori sono simili, ma `VAL_B` non è scritto nella cache e `VAL_C` è sia il terzo che il quarto parametro. +Il primo valore: un flag che indica che è un valore completo che deve essere scritto nella cache, seguito dai 32 byte del valore. Gli altri tre valori sono simili, tranne che `VAL_B` non è scritto nella cache e `VAL_C` è sia il terzo che il quarto parametro. ```solidity . @@ -475,7 +477,7 @@ Ci aspettiamo che la chiamata riesca. assertEq(cache.cacheRead(2), VAL_C); ``` -Iniziamo con una cache vuota e poi aggiungiamo `VAL_A`, seguito da `VAL_C`. Ci aspetteremmo che la prima abbia la chiave 1 e che la seconda abbia la chiave 2. +Iniziamo con una cache vuota e poi aggiungiamo `VAL_A` seguito da `VAL_C`. Ci aspetteremmo che il primo abbia la chiave 1 e il secondo abbia la chiave 2. ``` assertEq(toUint256(_callOutput,0), VAL_A); @@ -487,22 +489,22 @@ Iniziamo con una cache vuota e poi aggiungiamo `VAL_A`, seguito da `VAL_C`. Ci a Il risultato comprende i quattro parametri. Qui verifichiamo che sia corretto. ```solidity - // Second call, we can use the cache + // Seconda chiamata, possiamo usare la cache _callInput = bytes.concat( FOUR_PARAMS, - // First value in the Cache + // Primo valore nella cache bytes1(0x01), ``` Le chiavi della cache sotto 16 sono composte da un solo byte. ```solidity - // Second value, don't add it to the cache + // Secondo valore, non aggiungerlo alla cache cache.DONT_CACHE(), bytes32(VAL_B), - // Third and fourth values, same value + // Terzo e quarto valore, stesso valore bytes1(0x02), bytes1(0x02) ); @@ -538,23 +540,23 @@ Questa funzione è simile a `testReadParam`, ma, invece di scrivere i parametri } // testEncodeVal ``` -Il solo test aggiuntivo in `testEncodeVal()` consiste nel verificare che la lunghezza di `_callInput` sia corretta. Per la prima chiamata, è 4+33\*4. Per la seconda, dove ogni valore è già nella cache, è 4+1\*4. +L'unico test aggiuntivo in `testEncodeVal()` consiste nel verificare che la lunghezza di `_callInput` sia corretta. Per la prima chiamata, è 4+33\*4. Per la seconda, dove ogni valore è già nella cache, è 4+1\*4. ```solidity - // Test encodeVal when the key is more than a single byte - // Maximum three bytes because filling the cache to four bytes takes - // too long. + // Testa encodeVal quando la chiave è più di un singolo byte + // Massimo tre byte perché riempire la cache a quattro byte richiede + // troppo tempo. function testEncodeValBig() public { - // Put a number of values in the cache. - // To keep things simple, use key n for value n. + // Inserisce un numero di valori nella cache. + // Per semplicità, usa la chiave n per il valore n. for(uint i=1; i<0x1FFF; i++) { cache.cacheWrite(i); } ``` -La funzione `testEncodeVal` precedente scrive soltanto quattro valori nella cache, quindi [la parte della funzione che si occupa dei valori a più byte](https://github.com/qbzzt/20220915-all-you-can-cache/blob/main/src/Cache.sol#L144-L171) non è controllata. Ma quel codice è complicato e tende ad avere errori. +La funzione `testEncodeVal` di cui sopra scrive solo quattro valori nella cache, quindi la [parte della funzione che si occupa dei valori a più byte](https://github.com/qbzzt/20220915-all-you-can-cache/blob/main/src/Cache.sol#L144-L171) non è controllata. Ma quel codice è complicato e soggetto a errori. -La prima parte di questa funzione è un ciclo che scrive tutti i valori da 1 a 0x1FFF nella cache in ordine, quindi potrai codificarli e sapere cosa sta succedendo. +La prima parte di questa funzione è un ciclo che scrive tutti i valori da 1 a 0x1FFF nella cache in ordine, così saremo in grado di codificare quei valori e sapere dove stanno andando. ```solidity . @@ -563,14 +565,14 @@ La prima parte di questa funzione è un ciclo che scrive tutti i valori da 1 a 0 _callInput = bytes.concat( FOUR_PARAMS, - cache.encodeVal(0x000F), // One byte 0x0F - cache.encodeVal(0x0010), // Two bytes 0x1010 - cache.encodeVal(0x0100), // Two bytes 0x1100 - cache.encodeVal(0x1000) // Three bytes 0x201000 + cache.encodeVal(0x000F), // Un byte 0x0F + cache.encodeVal(0x0010), // Due byte 0x1010 + cache.encodeVal(0x0100), // Due byte 0x1100 + cache.encodeVal(0x1000) // Tre byte 0x201000 ); ``` -Testa valori da uno, due e tre byte. Non testiamo oltre tali valori perché ci vorrebbe troppo tempo per scrivere abbastanza elementi dello stack (almeno 0x10000000, approssimativamente, un quarto di miliardo). +Testa valori da uno, due e tre byte. Non testiamo oltre tali valori perché ci vorrebbe troppo tempo per scrivere abbastanza elementi dello stack (almeno 0x10000000, circa un quarto di miliardo). ```solidity . @@ -580,7 +582,7 @@ Testa valori da uno, due e tre byte. Non testiamo oltre tali valori perché ci v } // testEncodeValBig - // Test what with an excessively small buffer we get a revert + // Testa che con un buffer eccessivamente piccolo si ottenga un revert function testShortCalldata() public { ``` @@ -595,10 +597,10 @@ Testiamo cosa si verifica nel caso anomalo in cui non ci siano abbastanza parame } // testShortCalldata ``` -Poiché si ripristina, dovremmo ottenere `false`. +Poiché si ripristina, il risultato che dovremmo ottenere è `false`. ``` - // Call with cache keys that aren't there + // Chiama con chiavi di cache che non ci sono function testNoCacheKey() public { . . @@ -606,11 +608,11 @@ Poiché si ripristina, dovremmo ottenere `false`. _callInput = bytes.concat( FOUR_PARAMS, - // First value, add it to the cache + // Primo valore, aggiungilo alla cache cache.INTO_CACHE(), bytes32(VAL_A), - // Second value + // Secondo valore bytes1(0x0F), bytes2(0x1234), bytes11(0xA10102030405060708090A) @@ -623,35 +625,35 @@ Questa funzione ottiene quattro parametri perfettamente legittimi, ma la cache . . . - // Test what with an excessively long buffer everything works file + // Testa che con un buffer eccessivamente lungo tutto funzioni function testLongCalldata() public { address _cacheAddr = address(cache); bool _success; bytes memory _callInput; bytes memory _callOutput; - // First call, the cache is empty + // Prima chiamata, la cache è vuota _callInput = bytes.concat( FOUR_PARAMS, - // First value, add it to the cache + // Primo valore, aggiungilo alla cache cache.INTO_CACHE(), bytes32(VAL_A), - // Second value, add it to the cache + // Secondo valore, aggiungilo alla cache cache.INTO_CACHE(), bytes32(VAL_B), - // Third value, add it to the cache + // Terzo valore, aggiungilo alla cache cache.INTO_CACHE(), bytes32(VAL_C), - // Fourth value, add it to the cache + // Quarto valore, aggiungilo alla cache cache.INTO_CACHE(), bytes32(VAL_D), - // And another value for "good luck" + // E un altro valore per "buona fortuna" bytes4(0x31112233) ); ``` -Questa funzione invia cinque valori. Sappiamo che il quinto valore è ignorato perché non è un elemento della cache valido, ma avrebbe causato un ripristino se non fosse stato incluso. +Questa funzione invia cinque valori. Sappiamo che il quinto valore è ignorato perché non è un elemento della cache valido, il che avrebbe causato un ripristino se non fosse stato incluso. ```solidity (_success, _callOutput) = _cacheAddr.call(_callInput); @@ -665,13 +667,13 @@ Questa funzione invia cinque valori. Sappiamo che il quinto valore è ignorato p ``` -## Un esempio di applicazione {#a-sample-app} +## Un'applicazione di esempio {#a-sample-app} -Scrivere test in Solidity va bene, ma alla fine una dapp deve poter elaborare le richieste dall'esterno della catena per essere utile. Questo articolo dimostra come utilizzare la memorizzazione nella cache in una dapp con `WORM`, che sta per "Write Once, Read Many" (Scrivi una volta, leggi molte volte). Se una chiave non è ancora stata scritta, puoi scriverci un valore. Se la chiave è già scritta, ottieni un ripristino. +Scrivere test in Solidity va benissimo, ma alla fine una dApp deve essere in grado di elaborare richieste dall'esterno della catena per essere utile. Questo articolo dimostra come utilizzare la memorizzazione nella cache in una dApp con WORM, che sta per "Write Once, Read Many" (Scrivi una volta, leggi molte volte). Se una chiave non è ancora stata scritta, puoi scriverci un valore. Se la chiave è già scritta, ottieni un ripristino. ### Il contratto {#the-contract} -[Questo è il contratto](https://github.com/qbzzt/20220915-all-you-can-cache/blob/main/src/WORM.sol). Per lo più ripete ciò che abbiamo già fatto con `Cache` e `CacheTest`, quindi copriremo soltanto le parti interessanti. +[Questo è il contratto](https://github.com/qbzzt/20220915-all-you-can-cache/blob/main/src/WORM.sol). Per lo più ripete ciò che abbiamo già fatto con `Cache` e `CacheTest`, quindi tratteremo soltanto le parti interessanti. ```solidity import "./Cache.sol"; @@ -679,7 +681,7 @@ import "./Cache.sol"; contract WORM is Cache { ``` -Il metodo più facile per utilizzare `Cache` è ereditarlo nel proprio contratto. +Il modo più semplice per utilizzare `Cache` è ereditarlo nel proprio contratto. ```solidity function writeEntryCached() external { @@ -688,29 +690,29 @@ Il metodo più facile per utilizzare `Cache` è ereditarlo nel proprio contratto } // writeEntryCached ``` -Questa funzione è simile a `fourParam` nel precedente `CacheTest`. Poiché non seguiamo le specifiche ABI, è meglio non dichiarare alcun parametro nella funzione. +Questa funzione è simile a `fourParam` in `CacheTest` di cui sopra. Poiché non seguiamo le specifiche ABI, è meglio non dichiarare alcun parametro nella funzione. ```solidity - // Make it easier to call us - // Function signature for writeEntryCached(), courtesy of + // Rende più facile chiamarci + // Firma della funzione per writeEntryCached(), per gentile concessione di // https://www.4byte.directory/signatures/?bytes4_signature=0xe4e4f2d3 bytes4 constant public WRITE_ENTRY_CACHED = 0xe4e4f2d3; ``` Il codice esterno che chiama `writeEntryCached` dovrà creare manualmente i calldata, invece di utilizzare `worm.writeEntryCached`, poiché non seguiamo le specifiche ABI. Avere questo valore costante ne semplifica la scrittura. -Nota che anche se definiamo `WRITE_ENTRY_CACHED` come una variabile di stato, per leggerla esternamente è necessario utilizzare la sua funzione di ottenimento, `worm.WRITE_ENTRY_CACHED()`. +Nota che anche se definiamo `WRITE_ENTRY_CACHED` come una variabile di stato, per leggerla esternamente è necessario utilizzare la sua funzione getter, `worm.WRITE_ENTRY_CACHED()`. ```solidity function readEntry(uint key) public view returns (uint _value, address _writtenBy, uint _writtenAtBlock) ``` -La funzione Leggi è una `view`, quindi non richiede una transazione, né costa gas. Di conseguenza, non vi è beneficio nell'usare la cache per il parametro. Con le funzioni view, è meglio utilizzare il meccanismo standard, che è più semplice. +La funzione di lettura è una `view`, quindi non richiede una transazione e non costa gas. Di conseguenza, non vi è alcun beneficio nell'usare la cache per il parametro. Con le funzioni view, è meglio utilizzare il meccanismo standard, che è più semplice. -### Il codice di prova {#the-testing-code} +### Il codice di test {#the-testing-code} -[Questo è il codice di prova per il contratto](https://github.com/qbzzt/20220915-all-you-can-cache/blob/main/test/WORM.t.sol). Anche in questo caso ci occupiamo soltanto di ciò che ci interessa. +[Questo è il codice di test per il contratto](https://github.com/qbzzt/20220915-all-you-can-cache/blob/main/test/WORM.t.sol). Anche in questo caso ci occupiamo soltanto di ciò che ci interessa. ```solidity function testWReadWrite() public { @@ -720,27 +722,27 @@ La funzione Leggi è una `view`, quindi non richiede una transazione, né costa worm.writeEntry(0xDEAD, 0xBEEF); ``` -[Questo (`vm.expectRevert`)](https://book.getfoundry.sh/cheatcodes/expect-revert#expectrevert) è il modo in cui specifichiamo in un test Foundry che la chiamata successiva dovrebbe non riuscire e il motivo segnalato per l'errore. Questo si applica quando utilizziamo la sintassi `.()`, piuttosto che creare i calldata e chiamare il contratto utilizzando l'interfaccia di basso livello (`.call()`, etc.). +[Questo (`vm.expectRevert`)](https://book.getfoundry.sh/cheatcodes/expect-revert#expectrevert) è il modo in cui specifichiamo in un test Foundry che la chiamata successiva dovrebbe non riuscire e il motivo segnalato per l'errore. Questo si applica quando usiamo la sintassi `.()` piuttosto che creare i calldata e chiamare il contratto utilizzando l'interfaccia di basso livello (`.call()`, ecc.). ```solidity function testReadWriteCached() public { uint cacheGoat = worm.cacheWrite(0x60A7); ``` -Qui utilizziamo il fatto che `cacheWrite` restituisce la chiave della cache. Questo non è qualcosa che prevediamo di utilizzare in produzione, poiché `cacheWrite` cambia lo stato, ed è quindi chiamabile soltanto durante una transazione. Le transazioni non hanno valori restituiti, se hanno risultati, questi dovrebbero essere emessi come eventi. Quindi, il valore restituito di `cacheWrite` è accessibile soltanto dal codice sulla catena, che non necessita il salvataggio nella cache dei parametri. +Qui utilizziamo il fatto che `cacheWrite` restituisce la chiave della cache. Questo non è qualcosa che ci aspetteremmo di utilizzare in produzione, poiché `cacheWrite` cambia lo stato e quindi può essere chiamato solo durante una transazione. Le transazioni non hanno valori di ritorno; se hanno risultati, questi dovrebbero essere emessi come eventi. Quindi, il valore restituito da `cacheWrite` è accessibile soltanto dal codice onchain, e il codice onchain non necessita della memorizzazione nella cache dei parametri. ```solidity (_success,) = address(worm).call(_callInput); ``` -Questo è il modo in cui diciamo a Solidity che mentre `.call()` ha due valori restituiti, ci importa soltanto del primo. +Questo è il modo in cui diciamo a Solidity che, sebbene `.call()` abbia due valori di ritorno, ci interessa soltanto il primo. ```solidity (_success,) = address(worm).call(_callInput); assertEq(_success, false); ``` -Poiché utilizziamo la funzione di basso livello `
.call()`, non possiamo utilizzare `vm.expectRevert()` e dobbiamo guardare al valore di successo booleano, ottenuto dalla chiamata. +Poiché utilizziamo la funzione di basso livello `
.call()`, non possiamo usare `vm.expectRevert()` e dobbiamo guardare al valore booleano di successo che otteniamo dalla chiamata. ```solidity event EntryWritten(uint indexed key, uint indexed value); @@ -756,13 +758,13 @@ Poiché utilizziamo la funzione di basso livello `
.call()`, non possiam (_success,) = address(worm).call(_callInput); ``` -Così, verifichiamo che il codice [emetta un evento correttamente](https://book.getfoundry.sh/cheatcodes/expect-emit), in Foundry. +Questo è il modo in cui verifichiamo che il codice [emetta un evento correttamente](https://getfoundry.sh/reference/cheatcodes/expect-emit/) in Foundry. ### Il client {#the-client} -Una cosa che non ottieni con i test in Solidity è il codice in JavaScript che puoi tagliare e incollare nella tua applicazione. Per scrivere quel codice, ho distribuito WORM a [Optimism Goerli](https://community.optimism.io/docs/useful-tools/networks/#optimism-goerli), la nuova rete di prova di [Optimism](https://www.optimism.io/). Si trova all'indirizzo [`0xd34335b1d818cee54e3323d3246bd31d94e6a78a`](https://goerli-optimism.etherscan.io/address/0xd34335b1d818cee54e3323d3246bd31d94e6a78a). +Una cosa che non si ottiene con i test di Solidity è il codice JavaScript che si può copiare e incollare nella propria applicazione. Per scrivere quel codice ho distribuito WORM su [Optimism Goerli](https://community.optimism.io/docs/useful-tools/networks/#optimism-goerli), la nuova rete di test di [Optimism](https://www.optimism.io/). Si trova all'indirizzo [`0xd34335b1d818cee54e3323d3246bd31d94e6a78a`](https://goerli-optimism.etherscan.io/address/0xd34335b1d818cee54e3323d3246bd31d94e6a78a). -[Puoi visualizzare qui il codice in JavaScript per il client](https://github.com/qbzzt/20220915-all-you-can-cache/blob/main/javascript/index.js). Per utilizzarlo: +[Puoi vedere il codice JavaScript per il client qui](https://github.com/qbzzt/20220915-all-you-can-cache/blob/main/javascript/index.js). Per utilizzarlo: 1. Clona la repository di git: @@ -785,10 +787,10 @@ Una cosa che non ottieni con i test in Solidity è il codice in JavaScript che p 4. Modifica `.env` per la tua configurazione: - | Parametro | Valore | - | --------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | - | MNEMONIC | La frase mnemonica per un account avente abbastanza ETH da pagare per una transazione. [Puoi ottenere ETH gratuiti per la rete Goerli di Optimism qui](https://optimismfaucet.xyz/). | - | OPTIMISM_GOERLI_URL | URL per Goerli di Optimism. L'endpoint pubblico, `https://goerli.optimism.io`, è limitato ma sufficiente per ciò che ci occorre qui | + | Parametro | Valore | + | ------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | + | MNEMONIC | La frase mnemonica per un account che ha abbastanza ETH da pagare per una transazione. [Puoi ottenere ETH gratuiti per la rete Optimism Goerli qui](https://optimismfaucet.xyz/). | + | OPTIMISM_GOERLI_URL | URL di Optimism Goerli. L'endpoint pubblico, `https://goerli.optimism.io`, è a velocità limitata ma sufficiente per ciò che ci occorre qui | 5. Esegui `index.js`. @@ -798,7 +800,7 @@ Una cosa che non ottieni con i test in Solidity è il codice in JavaScript che p Questo esempio di applicazione prima scrive una voce nel WORM, mostrando i calldata e un collegamento alla transazione su Etherscan. Poi rilegge quella voce e mostra la chiave che utilizza e i valori nella voce (valore, numero del blocco e autore). -Gran parte del client è una normale Dapp in JavaScript. Quindi, ancora, analizzeremo soltanto le parti interessanti. +La maggior parte del client è normale JavaScript per dApp. Quindi, ancora, analizzeremo soltanto le parti interessanti. ```javascript . @@ -807,20 +809,20 @@ Gran parte del client è una normale Dapp in JavaScript. Quindi, ancora, analizz const main = async () => { const func = await worm.WRITE_ENTRY_CACHED() - // Need a new key every time + // Serve una nuova chiave ogni volta const key = await worm.encodeVal(Number(new Date())) ``` -Un dato spazio è scrivibile soltanto una volta, quindi utilizziamo la marca oraria per assicurarci di non riutilizzarlo. +Un dato slot può essere scritto una sola volta, quindi utilizziamo la marca temporale per assicurarci di non riutilizzare gli slot. ```javascript const val = await worm.encodeVal("0x600D") -// Write an entry +// Scrivi una voce const calldata = func + key.slice(2) + val.slice(2) ``` -Gli ether si aspettano che i dati di chiamata siano una stringa esadecimale, `0x`, seguita da un numero pari di crifre esadecimali. Poiché sia `key` che `val` iniziano con `0x`, dobbiamo rimuovere queste intestazioni. +Ethers si aspetta che i dati di chiamata siano una stringa esadecimale, `0x` seguito da un numero pari di cifre esadecimali. Poiché sia `key` che `val` iniziano con `0x`, dobbiamo rimuovere queste intestazioni. ```javascript const tx = await worm.populateTransaction.writeEntryCached() @@ -829,14 +831,14 @@ tx.data = calldata sentTx = await wallet.sendTransaction(tx) ``` -Come con il codice di test di Solidity, non possiamo chiamare normalmente una funzione. Invece, dobbiamo utilizzare un meccanismo di livello inferiore. +Come con il codice di test di Solidity, non possiamo chiamare normalmente una funzione memorizzata nella cache. Dobbiamo invece utilizzare un meccanismo di livello inferiore. ```javascript . . . - // Read the entry just written - const realKey = '0x' + key.slice(4) // remove the FF flag + // Leggi la voce appena scritta + const realKey = '0x' + key.slice(4) // rimuovi il flag FF const entryRead = await worm.readEntry(realKey) . . @@ -845,23 +847,26 @@ Come con il codice di test di Solidity, non possiamo chiamare normalmente una fu Per leggere le voci possiamo utilizzare il meccanismo normale. Non serve utilizzare il salvataggio nella cache del parametro con le funzioni `view`. -## Conclusioni {#conclusion} +## Conclusione {#conclusion} Il codice in questo articolo è una prova di concetto, lo scopo è rendere l'idea facile da comprendere. Per un sistema pronto alla produzione, potresti voler implementare delle funzionalità aggiuntive: -- Gestisce i valori diversi da `uint256`. Ad esempio, stringhe. -- Invece di una cache globale, forse, avere una mappatura tra utenti e cache. Utenti differenti utilizzano valori differenti. +- Gestire valori che non sono `uint256`. Ad esempio, stringhe. +- Invece di una cache globale, forse avere una mappatura tra utenti e cache. Utenti differenti utilizzano valori differenti. - I valori utilizzati per gli indirizzi sono distinti da quelli utilizzati per altri scopi. Potrebbe avere senso avere una cache separata soltanto per gli indirizzi. - Al momento, le chiavi della cache si basano su un algoritmo "il primo che arriva riceve la chiave più piccola". I primi sedici valori sono inviabili come un singolo byte. I 4080 valori successivi sono inviabili come due byte. Il successivo milione approssimativo di valori è in tre byte, ecc. Un sistema di produzione dovrebbe mantenere dei contatori di utilizzo sulle voci della cache e riorganizzarli così che i sedici valori _più comuni_ siano un byte, i successivi 4080 valori più comuni siano due byte, ecc. Tuttavia, questa è un'operazione potenzialmente pericolosa. Immagina la seguente sequenza di eventi: - 1. Noam Naive chiama `encodeVal` per codificare l'indirizzo a cui desidera inviare i token. Quell'indirizzo è uno dei primi utilizzati sull'applicazione, quindi il valore codificato è 0x06. Questa è una funzione `view`, non una transazione, quindi si trova tra Noam e il nodo che utilizza, e nessun altro ne è a conoscenza + 1. Noam Naive chiama `encodeVal` per codificare l'indirizzo a cui desidera inviare i token. Quell'indirizzo è uno dei primi utilizzati sull'applicazione, quindi il valore codificato è 0x06. Questa è una funzione `view`, non una transazione, quindi si trova tra Noam e il nodo che utilizza, e nessun altro ne è a conoscenza. 2. Owen Owner esegue l'operazione di riordinamento della cache. In pochissimi utilizzano realmente quell'indirizzo, quindi è ora codificato come 0x201122. Un valore differente, 1018, è assegnato a 0x06. 3. Noam Naive invia i suoi token a 0x06. I token arrivano all'indirizzo `0x0000000000000000000000000de0b6b3a7640000` e, poiché nessuno conosce la chiave privata per quell'indirizzo, restano bloccati lì. Noam _non è felice_. - Esistono dei modi per risolvere questo problema e il problema correlato delle transazioni nel mempool durante il riordino della cache, ma devi esserne consapevole. + Esistono dei modi per risolvere questo problema e il problema correlato delle transazioni nel mempool durante il riordino della cache, ma è necessario esserne consapevoli. Qui, ho dimostrato il salvataggio nella cache con Optimism, perché ne sono un dipendente ed è il rollup che conosco meglio. Ma dovrebbe funzionare con qualsiasi rollup che addebiti un costo minimo per l'elaborazione interna, così che, in confronto, scrivere i dati della transazione a L1 sia la spesa maggiore. + +[Vedi qui per altri miei lavori](https://cryptodocguy.pro/). + diff --git a/public/content/translations/it/developers/tutorials/app-plasma/index.md b/public/content/translations/it/developers/tutorials/app-plasma/index.md new file mode 100644 index 00000000000..361a452bc11 --- /dev/null +++ b/public/content/translations/it/developers/tutorials/app-plasma/index.md @@ -0,0 +1,1255 @@ +--- +title: Scrivere una plasma specifica per l'app che preserva la privacy +description: "In questa guida, creiamo una banca semi-segreta per i depositi. La banca è un componente centralizzato; conosce il saldo di ogni utente. Tuttavia, questa informazione non è archiviata sulla catena. Invece, la banca pubblica un hash dello stato. Ogni volta che si verifica una transazione, la banca pubblica il nuovo hash, insieme a una prova a conoscenza-zero che dimostra l'esistenza di una transazione firmata che cambia lo stato dell'hash in quello nuovo. Dopo aver letto questa guida, non solo capirai come usare le prove a conoscenza-zero, ma anche perché le usi e come farlo in modo sicuro." +author: Ori Pomerantz +tags: [ "conoscenza-zero", "server", "offchain", "privacy" ] +skill: advanced +lang: it +published: 2025-10-15 +--- + +## Introduzione {#introduction} + +A differenza dei [rollup](/developers/docs/scaling/zk-rollups/), le [plasma](/developers/docs/scaling/plasma) usano la rete principale di Ethereum per l'integrità, ma non per la disponibilità. In questo articolo, scriviamo un'applicazione che si comporta come una plasma, con Ethereum che garantisce l'integrità (nessuna modifica non autorizzata) ma non la disponibilità (un componente centralizzato può andare fuori servizio e disabilitare l'intero sistema). + +L'applicazione che scriviamo qui è una banca che preserva la privacy. Indirizzi diversi hanno conti con saldi, e possono inviare denaro (ETH) ad altri conti. La banca pubblica gli hash dello stato (conti e loro saldi) e delle transazioni, ma mantiene i saldi effettivi fuori dalla catena, dove possono rimanere privati. + +## Progettazione {#design} + +Questo non è un sistema pronto per la produzione, ma uno strumento didattico. Come tale, è stato scritto con diverse ipotesi semplificative. + +- Gruppo di conti fisso. C'è un numero specifico di conti, e ogni conto appartiene a un indirizzo predeterminato. Questo rende il sistema molto più semplice perché è difficile gestire strutture di dati a dimensione variabile nelle prove a conoscenza-zero. Per un sistema pronto per la produzione, possiamo usare la [radice di Merkle](/developers/tutorials/merkle-proofs-for-offline-data-integrity/) come hash di stato e fornire prove di Merkle per i saldi richiesti. + +- Archiviazione in memoria. Su un sistema di produzione, dobbiamo scrivere tutti i saldi dei conti su disco per preservarli in caso di riavvio. Qui, va bene se le informazioni vengono semplicemente perse. + +- Solo trasferimenti. Un sistema di produzione richiederebbe un modo per depositare asset nella banca e per prelevarli. Ma lo scopo qui è solo quello di illustrare il concetto, quindi questa banca è limitata ai trasferimenti. + +### Prove a conoscenza-zero {#zero-knowledge-proofs} + +A un livello fondamentale, una prova a conoscenza-zero mostra che il prover conosce alcuni dati, _Datiprivati_ tali che esiste una relazione _Relazione_ tra alcuni dati pubblici, _Datipubblici_, e _Datiprivati_. Il verificatore conosce _Relazione_ e _Datipubblici_. + +Per preservare la privacy, abbiamo bisogno che gli stati e le transazioni siano privati. Ma per garantire l'integrità, abbiamo bisogno che l'[hash crittografico](https://en.wikipedia.org/wiki/Cryptographic_hash_function) degli stati sia pubblico. Per dimostrare a chi invia le transazioni che tali transazioni sono realmente avvenute, dobbiamo anche pubblicare gli hash delle transazioni. + +Nella maggior parte dei casi, _Datiprivati_ è l'input del programma della prova a conoscenza-zero e _Datipubblici_ è l'output. + +Questi campi in _Datiprivati_: + +- _Staton_, il vecchio stato +- _Staton+1_, il nuovo stato +- _Transazione_, una transazione che cambia dal vecchio stato a quello nuovo. Questa transazione deve includere questi campi: + - _Indirizzo di destinazione_ che riceve il trasferimento + - _Importo_ trasferito + - _Nonce_ per garantire che ogni transazione possa essere elaborata una sola volta. + L'indirizzo di origine non deve essere nella transazione, perché può essere recuperato dalla firma. +- _Firma_, una firma autorizzata a eseguire la transazione. Nel nostro caso, l'unico indirizzo autorizzato a eseguire una transazione è l'indirizzo di origine. Poiché il nostro sistema a conoscenza-zero funziona in questo modo, abbiamo bisogno anche della chiave pubblica del conto, oltre alla firma di Ethereum. + +Questi sono i campi in _Datipubblici_: + +- _Hash(Staton)_ l'hash del vecchio stato +- _Hash(Staton+1)_ l'hash del nuovo stato +- _Hash(Transazione)_ l'hash della transazione che cambia lo stato da _Staton_ a _Staton+1_. + +La relazione verifica diverse condizioni: + +- Gli hash pubblici sono effettivamente gli hash corretti per i campi privati. +- La transazione, se applicata al vecchio stato, produce il nuovo stato. +- La firma proviene dall'indirizzo di origine della transazione. + +A causa delle proprietà delle funzioni di hash crittografico, la dimostrazione di queste condizioni è sufficiente a garantire l'integrità. + +### Strutture dei dati {#data-structures} + +La struttura dati principale è lo stato detenuto dal server. Per ogni conto, il server tiene traccia del saldo del conto e di un [nonce](https://en.wikipedia.org/wiki/Cryptographic_nonce), utilizzato per prevenire [attacchi di replay](https://en.wikipedia.org/wiki/Replay_attack). + +### Componenti {#components} + +Questo sistema richiede due componenti: + +- Il _server_ che riceve le transazioni, le elabora e pubblica gli hash sulla catena insieme alle prove a conoscenza-zero. +- Un _contratto intelligente_ che archivia gli hash e verifica le prove a conoscenza-zero per garantire che le transizioni di stato siano legittime. + +### Flusso di dati e di controllo {#flows} + +Questi sono i modi in cui i vari componenti comunicano per trasferire da un conto a un altro. + +1. Un browser web invia una transazione firmata che richiede un trasferimento dal conto del firmatario a un conto diverso. + +2. Il server verifica che la transazione sia valida: + + - Il firmatario ha un conto in banca con un saldo sufficiente. + - Il destinatario ha un conto in banca. + +3. Il server calcola il nuovo stato sottraendo l'importo trasferito dal saldo del firmatario e aggiungendolo al saldo del destinatario. + +4. Il server calcola una prova a conoscenza-zero che il cambio di stato è valido. + +5. Il server invia a Ethereum una transazione che include: + + - Il nuovo hash di stato + - L'hash della transazione (in modo che il mittente della transazione possa sapere che è stata elaborata) + - La prova a conoscenza-zero che dimostra che la transizione al nuovo stato è valida + +6. Il contratto intelligente verifica la prova a conoscenza-zero. + +7. Se la prova a conoscenza-zero risulta corretta, il contratto intelligente esegue queste azioni: + - Aggiorna l'hash di stato corrente con il nuovo hash di stato + - Emette una voce di registro con il nuovo hash di stato e l'hash della transazione + +### Strumenti {#tools} + +Per il codice lato client, useremo [Vite](https://vite.dev/), [React](https://react.dev/), [Viem](https://viem.sh/) e [Wagmi](https://wagmi.sh/). Questi sono strumenti standard del settore; se non li conosci, puoi usare [questa guida](/developers/tutorials/creating-a-wagmi-ui-for-your-contract/). + +La maggior parte del server è scritta in JavaScript utilizzando [Node](https://nodejs.org/en). La parte a conoscenza-zero è scritta in [Noir](https://noir-lang.org/). Abbiamo bisogno della versione `1.0.0-beta.10`, quindi dopo aver [installato Noir come indicato](https://noir-lang.org/docs/getting_started/quick_start), esegui: + +``` +noirup -v 1.0.0-beta.10 +``` + +La blockchain che usiamo è `anvil`, una blockchain di prova locale che fa parte di [Foundry](https://getfoundry.sh/introduction/installation). + +## Implementazione {#implementation} + +Dato che si tratta di un sistema complesso, lo implementeremo per fasi. + +### Fase 1 - Conoscenza-zero manuale {#stage-1} + +Per la prima fase, firmeremo una transazione nel browser e poi forniremo manualmente le informazioni alla prova a conoscenza-zero. Il codice a conoscenza-zero si aspetta di ricevere tali informazioni in `server/noir/Prover.toml` (documentato [qui](https://noir-lang.org/docs/getting_started/project_breakdown#provertoml-1)). + +Per vederlo in azione: + +1. Assicurati di aver installato [Node](https://nodejs.org/en/download) e [Noir](https://noir-lang.org/install). Preferibilmente, installali su un sistema UNIX come macOS, Linux o [WSL](https://learn.microsoft.com/en-us/windows/wsl/install). + +2. Scarica il codice della fase 1 e avvia il server web per servire il codice client. + + ```sh + git clone https://github.com/qbzzt/250911-zk-bank.git -b 01-manual-zk + cd 250911-zk-bank + cd client + npm install + npm run dev + ``` + + Il motivo per cui hai bisogno di un server web qui è che, per prevenire certi tipi di frode, molti portafogli (come MetaMask) non accettano file serviti direttamente dal disco + +3. Apri un browser con un portafoglio. + +4. Nel portafoglio, inserisci una nuova passphrase. Nota che questo cancellerà la tua passphrase esistente, quindi _assicurati di averne un backup_. + + La passphrase è `test test test test test test test test test test test junk`, la passphrase di prova predefinita per anvil. + +5. Vai al [codice lato client](http://localhost:5173/). + +6. Connettiti al portafoglio e seleziona il conto di destinazione e l'importo. + +7. Fai clic su **Firma** e firma la transazione. + +8. Sotto l'intestazione **Prover.toml**, troverai del testo. Sostituisci `server/noir/Prover.toml` con quel testo. + +9. Esegui la prova a conoscenza-zero. + + ```sh + cd ../server/noir + nargo execute + ``` + + L'output dovrebbe essere simile a + + ``` + ori@CryptoDocGuy:~/noir/250911-zk-bank/server/noir$ nargo execute + + [zkBank] Circuit witness successfully solved + [zkBank] Witness saved to target/zkBank.gz + [zkBank] Circuit output: (0x199aa62af8c1d562a6ec96e66347bf3240ab2afb5d022c895e6bf6a5e617167b, 0x0cfc0a67cb7308e4e9b254026b54204e34f6c8b041be207e64c5db77d95dd82d, 0x450cf9da6e180d6159290554ae3d8787, 0x6d8bc5a15b9037e52fb59b6b98722a85) + ``` + +10. Confronta gli ultimi due valori con l'hash che vedi sul browser web per vedere se il messaggio è stato correttamente sottoposto ad hashing. + +#### `server/noir/Prover.toml` {#server-noir-prover-toml} + +[Questo file](https://github.com/qbzzt/250911-zk-bank/blob/01-manual-zk/server/noir/Prover.toml) mostra il formato delle informazioni atteso da Noir. + +```toml +message="send 0x70997970C51812dc3A010C7d01b50e0d17dc79C8 500 finney (milliEth) 0 " +``` + +Il messaggio è in formato testo, il che lo rende facile da capire per l'utente (cosa necessaria al momento della firma) e da analizzare per il codice Noir. L'importo è quotato in finney per consentire, da un lato, trasferimenti frazionari e, dall'altro, per essere facilmente leggibile. L'ultimo numero è il [nonce](https://en.wikipedia.org/wiki/Cryptographic_nonce). + +La stringa è lunga 100 caratteri. Le prove a conoscenza-zero non gestiscono bene i dati di dimensione variabile, quindi è spesso necessario riempire i dati. + +```toml +pubKeyX=["0x83",...,"0x75"] +pubKeyY=["0x35",...,"0xa5"] +signature=["0xb1",...,"0x0d"] +``` + +Questi tre parametri sono array di byte a dimensione fissa. + +```toml +[[accounts]] +address="0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266" +balance=100_000 +nonce=0 + +[[accounts]] +address="0x70997970C51812dc3A010C7d01b50e0d17dc79C8" +balance=100_000 +nonce=0 +``` + +Questo è il modo di specificare un array di strutture. Per ogni voce, specifichiamo l'indirizzo, il saldo (in milliETH, alias [finney](https://cryptovalleyjournal.com/glossary/finney/)) e il valore nonce successivo. + +#### `client/src/Transfer.tsx` {#client-src-transfer-tsx} + +[Questo file](https://github.com/qbzzt/250911-zk-bank/blob/01-manual-zk/client/src/Transfer.tsx) implementa l'elaborazione lato client e genera il file `server/noir/Prover.toml` (quello che include i parametri a conoscenza-zero). + +Ecco la spiegazione delle parti più interessanti. + +```tsx +export default attrs => { +``` + +Questa funzione crea il componente React `Transfer`, che altri file possono importare. + +```tsx + const accounts = [ + "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", + "0x70997970C51812dc3A010C7d01b50e0d17dc79C8", + "0x3C44CdDdB6a900fa2b585dd299e03d12FA4293BC", + "0x90F79bf6EB2c4f870365E785982E1f101E93b906", + "0x15d34AAf54267DB7D7c367839AAf71A00a2C6A65", + ] +``` + +Questi sono gli indirizzi dei conti, gli indirizzi creati dalla passphrase `test ...` `test junk`. Se vuoi usare i tuoi indirizzi, basta modificare questa definizione. + +```tsx + const account = useAccount() + const wallet = createWalletClient({ + transport: custom(window.ethereum!) + }) +``` + +Questi [hook di Wagmi](https://wagmi.sh/react/api/hooks) ci consentono di accedere alla libreria [viem](https://viem.sh/) e al portafoglio. + +```tsx + const message = `send ${toAccount} ${ethAmount*1000} finney (milliEth) ${nonce}`.padEnd(100, " ") +``` + +Questo è il messaggio, riempito con spazi. Ogni volta che una delle variabili di [`useState`](https://react.dev/reference/react/useState) cambia, il componente viene ridisegnato e `message` viene aggiornato. + +```tsx + const sign = async () => { +``` + +Questa funzione viene chiamata quando l'utente fa clic sul pulsante **Firma**. Il messaggio viene aggiornato automaticamente, ma la firma richiede l'approvazione dell'utente nel portafoglio e non vogliamo chiederla se non è necessario. + +```tsx + const signature = await wallet.signMessage({ + account: fromAccount, + message, + }) +``` + +Chiedi al portafoglio di [firmare il messaggio](https://viem.sh/docs/accounts/local/signMessage). + +```tsx + const hash = hashMessage(message) +``` + +Ottieni l'hash del messaggio. È utile fornirlo all'utente per il debug (del codice Noir). + +```tsx + const pubKey = await recoverPublicKey({ + hash, + signature + }) +``` + +[Ottieni la chiave pubblica](https://viem.sh/docs/utilities/recoverPublicKey). Ciò è richiesto per la funzione [`ecrecover` di Noir](https://github.com/colinnielsen/ecrecover-noir). + +```tsx + setSignature(signature) + setHash(hash) + setPubKey(pubKey) +``` + +Imposta le variabili di stato. In questo modo si ridisegna il componente (dopo l'uscita della funzione `sign`) e si mostrano all'utente i valori aggiornati. + +```tsx + let proverToml = ` +``` + +Il testo per `Prover.toml`. + +```tsx +message="${message}" + +pubKeyX=${hexToArray(pubKey.slice(4,4+2*32))} +pubKeyY=${hexToArray(pubKey.slice(4+2*32))} +``` + +Viem ci fornisce la chiave pubblica come una stringa esadecimale di 65 byte. Il primo byte è `0x04`, un marcatore di versione. Questo è seguito da 32 byte per la `x` della chiave pubblica e poi da 32 byte per la `y` della chiave pubblica. + +Tuttavia, Noir si aspetta di ricevere queste informazioni come due array di byte, uno per `x` e uno per `y`. È più facile analizzarlo qui sul client piuttosto che come parte della prova a conoscenza-zero. + +Nota che questa è una buona pratica nella conoscenza-zero in generale. Il codice all'interno di una prova a conoscenza-zero è costoso, quindi qualsiasi elaborazione che può essere fatta al di fuori della prova a conoscenza-zero _dovrebbe_ essere fatta al di fuori della prova a conoscenza-zero. + +```tsx +signature=${hexToArray(signature.slice(2,-2))} +``` + +Anche la firma viene fornita come stringa esadecimale di 65 byte. Tuttavia, l'ultimo byte è necessario solo per recuperare la chiave pubblica. Dato che la chiave pubblica sarà già fornita al codice Noir, non ne abbiamo bisogno per verificare la firma, e il codice Noir non la richiede. + +```tsx +${accounts.map(accountInProverToml).reduce((a,b) => a+b, "")} +` +``` + +Fornisci i conti. + +```tsx + setProverToml(proverToml) + } + + return ( + <> +

Trasferimento

+``` + +Questo è il formato HTML (più precisamente, [JSX](https://react.dev/learn/writing-markup-with-jsx)) del componente. + +#### `server/noir/src/main.nr` {#server-noir-src-main-nr} + +[Questo file](https://github.com/qbzzt/250911-zk-bank/blob/01-manual-zk/server/noir/src/main.nr) è il codice effettivo a conoscenza-zero. + +``` +use std::hash::pedersen_hash; +``` + +L'[Hash di Pedersen](https://rya-sge.github.io/access-denied/2024/05/07/pedersen-hash-function/) è fornito con la [libreria standard di Noir](https://noir-lang.org/docs/noir/standard_library/cryptographic_primitives/hashes#pedersen_hash). Le prove a conoscenza-zero usano comunemente questa funzione di hash. È molto più facile da calcolare all'interno di [circuiti aritmetici](https://rareskills.io/post/arithmetic-circuit) rispetto alle funzioni di hash standard. + +``` +use keccak256::keccak256; +use dep::ecrecover; +``` + +Queste due funzioni sono librerie esterne, definite in [`Nargo.toml`](https://github.com/qbzzt/250911-zk-bank/blob/01-manual-zk/server/noir/Nargo.toml). Sono esattamente ciò per cui sono state nominate: una funzione che calcola l'[hash keccak256](https://emn178.github.io/online-tools/keccak_256.html) e una funzione che verifica le firme di Ethereum e recupera l'indirizzo Ethereum del firmatario. + +``` +global ACCOUNT_NUMBER : u32 = 5; +``` + +Noir si ispira a [Rust](https://www.rust-lang.org/). Le variabili, per impostazione predefinita, sono costanti. Questo è il modo in cui definiamo le costanti di configurazione globali. In particolare, `ACCOUNT_NUMBER` è il numero di conti che archiviamo. + +I tipi di dati denominati `u` sono quel numero di bit, senza segno. Gli unici tipi supportati sono `u8`, `u16`, `u32`, `u64` e `u128`. + +``` +global FLAT_ACCOUNT_FIELDS : u32 = 2; +``` + +Questa variabile viene utilizzata per l'hash di Pedersen dei conti, come spiegato di seguito. + +``` +global MESSAGE_LENGTH : u32 = 100; +``` + +Come spiegato sopra, la lunghezza del messaggio è fissa. È specificata qui. + +``` +global ASCII_MESSAGE_LENGTH : [u8; 3] = [0x31, 0x30, 0x30]; +global HASH_BUFFER_SIZE : u32 = 26+3+MESSAGE_LENGTH; +``` + +Le [firme EIP-191](https://eips.ethereum.org/EIPS/eip-191) richiedono un buffer con un prefisso di 26 byte, seguito dalla lunghezza del messaggio in ASCII e, infine, dal messaggio stesso. + +``` +struct Account { + balance: u128, + address: Field, + nonce: u32, +} +``` + +Le informazioni che archiviamo su un conto. [`Field`](https://noir-lang.org/docs/noir/concepts/data_types/fields) è un numero, tipicamente fino a 253 bit, che può essere usato direttamente nel [circuito aritmetico](https://rareskills.io/post/arithmetic-circuit) che implementa la prova a conoscenza-zero. Qui usiamo `Field` per archiviare un indirizzo Ethereum a 160 bit. + +``` +struct TransferTxn { + from: Field, + to: Field, + amount: u128, + nonce: u32 +} +``` + +Le informazioni che archiviamo per una transazione di trasferimento. + +``` +fn flatten_account(account: Account) -> [Field; FLAT_ACCOUNT_FIELDS] { +``` + +Una definizione di funzione. Il parametro è l'informazione `Account`. Il risultato è un array di variabili `Field`, la cui lunghezza è `FLAT_ACCOUNT_FIELDS` + +``` + let flat = [ + account.address, + ((account.balance << 32) + account.nonce.into()).into(), + ]; +``` + +Il primo valore nell'array è l'indirizzo del conto. Il secondo include sia il saldo che il nonce. Le chiamate a `.into()` cambiano un numero nel tipo di dati che deve essere. `account.nonce` è un valore `u32`, ma per aggiungerlo a `account.balance << 32`, un valore `u128`, deve essere un `u128`. Questo è il primo `.into()`. Il secondo converte il risultato `u128` in un `Field` in modo che si adatti all'array. + +``` + flat +} +``` + +In Noir, le funzioni possono restituire un valore solo alla fine (non c'è un ritorno anticipato). Per specificare il valore di ritorno, lo si valuta appena prima della parentesi di chiusura della funzione. + +``` +fn flatten_accounts(accounts: [Account; ACCOUNT_NUMBER]) -> [Field; FLAT_ACCOUNT_FIELDS*ACCOUNT_NUMBER] { +``` + +Questa funzione trasforma l'array di conti in un array di `Field`, che può essere usato come input per un Hash di Petersen. + +``` + let mut flat: [Field; FLAT_ACCOUNT_FIELDS*ACCOUNT_NUMBER] = [0; FLAT_ACCOUNT_FIELDS*ACCOUNT_NUMBER]; +``` + +Questo è il modo in cui si specifica una variabile mutabile, cioè _non_ una costante. Le variabili in Noir devono sempre avere un valore, quindi inizializziamo questa variabile a tutti zeri. + +``` + for i in 0..ACCOUNT_NUMBER { +``` + +Questo è un ciclo `for`. Nota che i limiti sono costanti. I cicli di Noir devono avere i loro limiti noti al momento della compilazione. Il motivo è che i circuiti aritmetici non supportano il controllo di flusso. Quando elabora un ciclo `for`, il compilatore semplicemente inserisce il codice al suo interno più volte, una per ogni iterazione. + +``` + let fields = flatten_account(accounts[i]); + for j in 0..FLAT_ACCOUNT_FIELDS { + flat[i*FLAT_ACCOUNT_FIELDS + j] = fields[j]; + } + } + + flat +} + +fn hash_accounts(accounts: [Account; ACCOUNT_NUMBER]) -> Field { + pedersen_hash(flatten_accounts(accounts)) +} +``` + +Finalmente, siamo arrivati alla funzione che calcola l'hash dell'array di conti. + +``` +fn find_account(accounts: [Account; ACCOUNT_NUMBER], address: Field) -> u32 { + let mut account : u32 = ACCOUNT_NUMBER; + + for i in 0..ACCOUNT_NUMBER { + if accounts[i].address == address { + account = i; + } + } +``` + +Questa funzione trova il conto con un indirizzo specifico. Questa funzione sarebbe terribilmente inefficiente nel codice standard perché itera su tutti i conti, anche dopo aver trovato l'indirizzo. + +Tuttavia, nelle prove a conoscenza-zero, non c'è controllo di flusso. Se mai avessimo bisogno di verificare una condizione, dobbiamo verificarla ogni volta. + +Una cosa simile accade con le istruzioni `if`. L'istruzione `if` nel ciclo sopra è tradotta in queste istruzioni matematiche. + +_risultatocondizione = accounts[i].address == address_ // uno se sono uguali, zero altrimenti + +_contonuovo = risultatocondizione\*i + (1-risultatocondizione)\*contovecchio_ + +```rust + assert (account < ACCOUNT_NUMBER, f"{address} non ha un conto"); + + account +} +``` + +La funzione [`assert`](https://noir-lang.org/docs/dev/noir/concepts/assert) fa sì che la prova a conoscenza-zero si blocchi se l'asserzione è falsa. In questo caso, se non riusciamo a trovare un conto con l'indirizzo pertinente. Per segnalare l'indirizzo, usiamo una [stringa di formato](https://noir-lang.org/docs/noir/concepts/data_types/strings#format-strings). + +```rust +fn apply_transfer_txn(accounts: [Account; ACCOUNT_NUMBER], txn: TransferTxn) -> [Account; ACCOUNT_NUMBER] { +``` + +Questa funzione applica una transazione di trasferimento e restituisce il nuovo array di conti. + +```rust + let from = find_account(accounts, txn.from); + let to = find_account(accounts, txn.to); + + let (txnFrom, txnAmount, txnNonce, accountNonce) = + (txn.from, txn.amount, txn.nonce, accounts[from].nonce); +``` + +Non possiamo accedere agli elementi della struttura all'interno di una stringa di formato in Noir, quindi creiamo una copia utilizzabile. + +```rust + assert (accounts[from].balance >= txn.amount, + f"{txnFrom} non ha {txnAmount} finney"); + + assert (accounts[from].nonce == txn.nonce, + f"La transazione ha nonce {txnNonce}, ma ci si aspetta che il conto usi {accountNonce}"); +``` + +Queste sono due condizioni che potrebbero rendere una transazione non valida. + +```rust + let mut newAccounts = accounts; + + newAccounts[from].balance -= txn.amount; + newAccounts[from].nonce += 1; + newAccounts[to].balance += txn.amount; + + newAccounts +} +``` + +Crea il nuovo array di conti e poi restituiscilo. + +```rust +fn readAddress(messageBytes: [u8; MESSAGE_LENGTH]) -> Field +``` + +Questa funzione legge l'indirizzo dal messaggio. + +```rust +{ + let mut result : Field = 0; + + for i in 7..47 { +``` + +L'indirizzo è sempre lungo 20 byte (alias 40 cifre esadecimali), e inizia al carattere #7. + +```rust + result *= 0x10; + if messageBytes[i] >= 48 & messageBytes[i] <= 57 { // 0-9 + result += (messageBytes[i]-48).into(); + } + if messageBytes[i] >= 65 & messageBytes[i] <= 70 { // A-F + result += (messageBytes[i]-65+10).into() + } + if messageBytes[i] >= 97 & messageBytes[i] <= 102 { // a-f + result += (messageBytes[i]-97+10).into() + } + } + + result +} + +fn readAmountAndNonce(messageBytes: [u8; MESSAGE_LENGTH]) -> (u128, u32) +``` + +Leggi l'importo e il nonce dal messaggio. + +```rust +{ + let mut amount : u128 = 0; + let mut nonce: u32 = 0; + let mut stillReadingAmount: bool = true; + let mut lookingForNonce: bool = false; + let mut stillReadingNonce: bool = false; +``` + +Nel messaggio, il primo numero dopo l'indirizzo è l'importo in finney (alias millesimo di un ETH) da trasferire. Il secondo numero è il nonce. Qualsiasi testo tra di loro viene ignorato. + +```rust + for i in 48..MESSAGE_LENGTH { + if messageBytes[i] >= 48 & messageBytes[i] <= 57 { // 0-9 + let digit = (messageBytes[i]-48); + + if stillReadingAmount { + amount = amount*10 + digit.into(); + } + + if lookingForNonce { // L'abbiamo appena trovato + stillReadingNonce = true; + lookingForNonce = false; + } + + if stillReadingNonce { + nonce = nonce*10 + digit.into(); + } + } else { + if stillReadingAmount { + stillReadingAmount = false; + lookingForNonce = true; + } + if stillReadingNonce { + stillReadingNonce = false; + } + } + } + + (amount, nonce) +} +``` + +Restituire una [tupla](https://noir-lang.org/docs/noir/concepts/data_types/tuples) è il modo di Noir per restituire più valori da una funzione. + +```rust +fn readTransferTxn(message: str) -> TransferTxn +{ + let mut txn: TransferTxn = TransferTxn { from: 0, to: 0, amount:0, nonce:0 }; + let messageBytes = message.as_bytes(); + + txn.to = readAddress(messageBytes); + let (amount, nonce) = readAmountAndNonce(messageBytes); + txn.amount = amount; + txn.nonce = nonce; + + txn +} +``` + +Questa funzione converte il messaggio in byte, quindi converte gli importi in una `TransferTxn`. + +```rust +// L'equivalente di hashMessage di Viem +// https://viem.sh/docs/utilities/hashMessage#hashmessage +fn hashMessage(message: str) -> [u8;32] { +``` + +Siamo stati in grado di utilizzare l'Hash di Pedersen per i conti perché vengono sottoposti a hashing solo all'interno della prova a conoscenza-zero. Tuttavia, in questo codice dobbiamo controllare la firma del messaggio, che viene generata dal browser. Per questo, dobbiamo seguire il formato di firma di Ethereum in [EIP 191](https://eips.ethereum.org/EIPS/eip-191). Ciò significa che dobbiamo creare un buffer combinato con un prefisso standard, la lunghezza del messaggio in ASCII e il messaggio stesso, e utilizzare lo standard Ethereum keccak256 per calcolarne l'hash. + +```rust + // Prefisso ASCII + let prefix_bytes = [ + 0x19, // \x19 + 0x45, // 'E' + 0x74, // 't' + 0x68, // 'h' + 0x65, // 'e' + 0x72, // 'r' + 0x65, // 'e' + 0x75, // 'u' + 0x6D, // 'm' + 0x20, // ' ' + 0x53, // 'S' + 0x69, // 'i' + 0x67, // 'g' + 0x6E, // 'n' + 0x65, // 'e' + 0x64, // 'd' + 0x20, // ' ' + 0x4D, // 'M' + 0x65, // 'e' + 0x73, // 's' + 0x73, // 's' + 0x61, // 'a' + 0x67, // 'g' + 0x65, // 'e' + 0x3A, // ':' + 0x0A // '\n' + ]; +``` + +Per evitare i casi in cui un'applicazione chiede all'utente di firmare un messaggio che può essere usato come transazione o per qualche altro scopo, l'EIP 191 specifica che tutti i messaggi firmati iniziano con il carattere 0x19 (non un carattere ASCII valido) seguito da `Ethereum Signed Message:` e da un a capo. + +```rust + let mut buffer: [u8; HASH_BUFFER_SIZE] = [0u8; HASH_BUFFER_SIZE]; + for i in 0..26 { + buffer[i] = prefix_bytes[i]; + } + + let messageBytes : [u8; MESSAGE_LENGTH] = message.as_bytes(); + + if MESSAGE_LENGTH <= 9 { + for i in 0..1 { + buffer[i+26] = ASCII_MESSAGE_LENGTH[i]; + } + + for i in 0..MESSAGE_LENGTH { + buffer[i+26+1] = messageBytes[i]; + } + } + + if MESSAGE_LENGTH >= 10 & MESSAGE_LENGTH <= 99 { + for i in 0..2 { + buffer[i+26] = ASCII_MESSAGE_LENGTH[i]; + } + + for i in 0..MESSAGE_LENGTH { + buffer[i+26+2] = messageBytes[i]; + } + } + + if MESSAGE_LENGTH >= 100 { + for i in 0..3 { + buffer[i+26] = ASCII_MESSAGE_LENGTH[i]; + } + + for i in 0..MESSAGE_LENGTH { + buffer[i+26+3] = messageBytes[i]; + } + } + + assert(MESSAGE_LENGTH < 1000, "I messaggi la cui lunghezza supera le tre cifre non sono supportati"); +``` + +Gestisci lunghezze di messaggio fino a 999 e fallisci se è maggiore. Ho aggiunto questo codice, anche se la lunghezza del messaggio è una costante, perché rende più facile cambiarlo. Su un sistema di produzione, probabilmente si darebbe per scontato che `MESSAGE_LENGTH` non cambi, per ottenere prestazioni migliori. + +```rust + keccak256::keccak256(buffer, HASH_BUFFER_SIZE) +} +``` + +Usa la funzione standard di Ethereum `keccak256`. + +```rust +fn signatureToAddressAndHash( + message: str, + pubKeyX: [u8; 32], + pubKeyY: [u8; 32], + signature: [u8; 64] + ) -> (Field, Field, Field) // indirizzo, primi 16 byte dell'hash, ultimi 16 byte dell'hash +{ +``` + +Questa funzione verifica la firma, che richiede l'hash del messaggio. Poi ci fornisce l'indirizzo che l'ha firmato e l'hash del messaggio. L'hash del messaggio è fornito in due valori `Field` perché sono più facili da usare nel resto del programma rispetto a un array di byte. + +Dobbiamo usare due valori `Field` perché i calcoli dei campi sono fatti [modulo](https://en.wikipedia.org/wiki/Modulo) un numero grande, ma quel numero è tipicamente inferiore a 256 bit (altrimenti sarebbe difficile eseguire quei calcoli nell'EVM). + +```rust + let hash = hashMessage(message); + + let mut (hash1, hash2) = (0,0); + + for i in 0..16 { + hash1 = hash1*256 + hash[31-i].into(); + hash2 = hash2*256 + hash[15-i].into(); + } +``` + +Specifica `hash1` e `hash2` come variabili mutabili e scrivi l'hash in esse byte per byte. + +```rust + ( + ecrecover::ecrecover(pubKeyX, pubKeyY, signature, hash), +``` + +È simile a [`ecrecover` di Solidity](https://docs.soliditylang.org/en/v0.8.30/cheatsheet.html#mathematical-and-cryptographic-functions), con due importanti differenze: + +- Se la firma non è valida, la chiamata fallisce un `assert` e il programma viene interrotto. +- Anche se la chiave pubblica può essere recuperata dalla firma e dall'hash, si tratta di un'elaborazione che può essere eseguita esternamente e, quindi, non vale la pena di eseguirla all'interno della prova a conoscenza-zero. Se qualcuno cerca di imbrogliarci qui, la verifica della firma fallirà. + +```rust + hash1, + hash2 + ) +} + +fn main( + accounts: [Account; ACCOUNT_NUMBER], + message: str, + pubKeyX: [u8; 32], + pubKeyY: [u8; 32], + signature: [u8; 64], + ) -> pub ( + Field, // Hash del vecchio array di conti + Field, // Hash del nuovo array di conti + Field, // Primi 16 byte dell'hash del messaggio + Field, // Ultimi 16 byte dell'hash del messaggio + ) +``` + +Finalmente, raggiungiamo la funzione `main`. Dobbiamo dimostrare di avere una transazione che cambia validamente l'hash dei conti dal vecchio valore a quello nuovo. Dobbiamo anche dimostrare che ha questo specifico hash di transazione, in modo che la persona che l'ha inviata sappia che la sua transazione è stata elaborata. + +```rust +{ + let mut txn = readTransferTxn(message); +``` + +Abbiamo bisogno che `txn` sia mutabile perché non leggiamo l'indirizzo di provenienza dal messaggio, lo leggiamo dalla firma. + +```rust + let (fromAddress, txnHash1, txnHash2) = signatureToAddressAndHash( + message, + pubKeyX, + pubKeyY, + signature); + + txn.from = fromAddress; + + let newAccounts = apply_transfer_txn(accounts, txn); + + ( + hash_accounts(accounts), + hash_accounts(newAccounts), + txnHash1, + txnHash2 + ) +} +``` + +### Fase 2 - Aggiunta di un server {#stage-2} + +Nella seconda fase, aggiungiamo un server che riceve e implementa le transazioni di trasferimento dal browser. + +Per vederlo in azione: + +1. Interrompi Vite se è in esecuzione. + +2. Scarica il branch che include il server e assicurati di avere tutti i moduli necessari. + + ```sh + git checkout 02-add-server + cd client + npm install + cd ../server + npm install + ``` + + Non è necessario compilare il codice Noir, è lo stesso codice che hai usato per la fase 1. + +3. Avvia il server. + + ```sh + npm run start + ``` + +4. In una finestra a riga di comando separata, esegui Vite per servire il codice del browser. + + ```sh + cd client + npm run dev + ``` + +5. Vai al codice client su [http://localhost:5173](http://localhost:5173) + +6. Prima di poter emettere una transazione, devi conoscere il nonce e l'importo che puoi inviare. Per ottenere queste informazioni, fai clic su **Aggiorna dati conto** e firma il messaggio. + + Abbiamo un dilemma qui. Da un lato, non vogliamo firmare un messaggio che possa essere riutilizzato (un [attacco di replay](https://en.wikipedia.org/wiki/Replay_attack)), motivo per cui vogliamo un nonce in primo luogo. Tuttavia, non abbiamo ancora un nonce. La soluzione è scegliere un nonce che possa essere usato una sola volta e che abbiamo già da entrambe le parti, come l'ora corrente. + + Il problema di questa soluzione è che l'ora potrebbe non essere perfettamente sincronizzata. Quindi, invece, firmiamo un valore che cambia ogni minuto. Ciò significa che la nostra finestra di vulnerabilità agli attacchi di replay è al massimo di un minuto. Considerando che in produzione la richiesta firmata sarà protetta da TLS e che l'altra parte del tunnel, il server, può già divulgare il saldo e il nonce (deve conoscerli per funzionare), questo è un rischio accettabile. + +7. Una volta che il browser riceve il saldo e il nonce, mostra il modulo di trasferimento. Seleziona l'indirizzo di destinazione e l'importo e fai clic su **Trasferisci**. Firma questa richiesta. + +8. Per vedere il trasferimento, **aggiorna i dati del conto** o guarda nella finestra in cui esegui il server. Il server registra lo stato ogni volta che cambia. + + ``` + ori@CryptoDocGuy:~/x/250911-zk-bank/server$ npm run start + + > server@1.0.0 start + > node --experimental-json-modules index.mjs + + In ascolto sulla porta 3000 + Transazione send 0x90F79bf6EB2c4f870365E785982E1f101E93b906 36000 finney (milliEth) 0 elaborata + Nuovo stato: + 0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266 ha 64000 (1) + 0x70997970C51812dc3A010C7d01b50e0d17dc79C8 ha 100000 (0) + 0x3C44CdDdB6a900fa2b585dd299e03d12FA4293BC ha 100000 (0) + 0x90F79bf6EB2c4f870365E785982E1f101E93b906 ha 136000 (0) + 0x15d34AAf54267DB7D7c367839AAf71A00a2C6A65 ha 100000 (0) + Transazione send 0x70997970C51812dc3A010C7d01b50e0d17dc79C8 7200 finney (milliEth) 1 elaborata + Nuovo stato: + 0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266 ha 56800 (2) + 0x70997970C51812dc3A010C7d01b50e0d17dc79C8 ha 107200 (0) + 0x3C44CdDdB6a900fa2b585dd299e03d12FA4293BC ha 100000 (0) + 0x90F79bf6EB2c4f870365E785982E1f101E93b906 ha 136000 (0) + 0x15d34AAf54267DB7D7c367839AAf71A00a2C6A65 ha 100000 (0) + Transazione send 0x90F79bf6EB2c4f870365E785982E1f101E93b906 3000 finney (milliEth) 2 elaborata + Nuovo stato: + 0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266 ha 53800 (3) + 0x70997970C51812dc3A010C7d01b50e0d17dc79C8 ha 107200 (0) + 0x3C44CdDdB6a900fa2b585dd299e03d12FA4293BC ha 100000 (0) + 0x90F79bf6EB2c4f870365E785982E1f101E93b906 ha 139000 (0) + 0x15d34AAf54267DB7D7c367839AAf71A00a2C6A65 ha 100000 (0) + ``` + +#### `server/index.mjs` {#server-index-mjs-1} + +[Questo file](https://github.com/qbzzt/250911-zk-bank/blob/02-add-server/server/index.mjs) contiene il processo del server e interagisce con il codice Noir in [`main.nr`](https://github.com/qbzzt/250911-zk-bank/blob/02-add-server/server/noir/src/main.nr). Ecco una spiegazione delle parti interessanti. + +```js +import { Noir } from '@noir-lang/noir_js' +``` + +La libreria [noir.js](https://www.npmjs.com/package/@noir-lang/noir_js) funge da interfaccia tra il codice JavaScript e il codice Noir. + +```js +const circuit = JSON.parse(await fs.readFile("./noir/target/zkBank.json")) +const noir = new Noir(circuit) +``` + +Carica il circuito aritmetico, il programma Noir compilato che abbiamo creato nella fase precedente, e preparati a eseguirlo. + +```js +// Forniamo le informazioni sul conto solo in risposta a una richiesta firmata +const accountInformation = async signature => { + const fromAddress = await recoverAddress({ + hash: hashMessage("Get account data " + Math.floor((new Date().getTime())/60000)), + signature + }) +``` + +Per fornire le informazioni sul conto, abbiamo bisogno solo della firma. Il motivo è che sappiamo già quale sarà il messaggio, e quindi l'hash del messaggio. + +```js +const processMessage = async (message, signature) => { +``` + +Elabora un messaggio ed esegui la transazione che codifica. + +```js + // Ottieni la chiave pubblica + const pubKey = await recoverPublicKey({ + hash, + signature + }) +``` + +Ora che eseguiamo JavaScript sul server, possiamo recuperare la chiave pubblica lì piuttosto che sul client. + +```js + let noirResult + try { + noirResult = await noir.execute({ + message, + signature: signature.slice(2,-2).match(/.{2}/g).map(x => `0x${x}`), + pubKeyX, + pubKeyY, + accounts: Accounts + }) +``` + +`noir.execute` esegue il programma Noir. I parametri sono equivalenti a quelli forniti in [`Prover.toml`](https://github.com/qbzzt/250911-zk-bank/blob/01-manual-zk/server/noir/Prover.toml). Nota che i valori lunghi vengono forniti come un array di stringhe esadecimali (`["0x60", "0xA7"]`), non come un singolo valore esadecimale (`0x60A7`), come fa Viem. + +```js + } catch (err) { + console.log(`Errore Noir: ${err}`) + throw Error("Transazione non valida, non elaborata") + } +``` + +Se c'è un errore, catturalo e poi inoltra una versione semplificata al client. + +```js + Accounts[fromAccountNumber].nonce++ + Accounts[fromAccountNumber].balance -= amount + Accounts[toAccountNumber].balance += amount +``` + +Applica la transazione. L'abbiamo già fatto nel codice Noir, ma è più facile farlo di nuovo qui piuttosto che estrarre il risultato da lì. + +```js +let Accounts = [ + { + address: "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", + balance: 5000, + nonce: 0, + }, +``` + +La struttura iniziale di `Accounts`. + +### Fase 3 - Contratti intelligenti di Ethereum {#stage-3} + +1. Interrompi i processi del server e del client. + +2. Scarica il branch con i contratti intelligenti e assicurati di avere tutti i moduli necessari. + + ```sh + git checkout 03-smart-contracts + cd client + npm install + cd ../server + npm install + ``` + +3. Esegui `anvil` in una finestra a riga di comando separata. + +4. Genera la chiave di verifica e il verificatore di solidità, quindi copia il codice del verificatore nel progetto Solidity. + + ```sh + cd noir + bb write_vk -b ./target/zkBank.json -o ./target --oracle_hash keccak + bb write_solidity_verifier -k ./target/vk -o ./target/Verifier.sol + cp target/Verifier.sol ../../smart-contracts/src + ``` + +5. Vai ai contratti intelligenti e imposta le variabili d'ambiente per usare la blockchain `anvil`. + + ```sh + cd ../../smart-contracts + export ETH_RPC_URL=http://localhost:8545 + ETH_PRIVATE_KEY=ac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80 + ``` + +6. Distribuisci `Verifier.sol` e memorizza l'indirizzo in una variabile d'ambiente. + + ```sh + VERIFIER_ADDRESS=`forge create src/Verifier.sol:HonkVerifier --private-key $ETH_PRIVATE_KEY --optimize --broadcast | awk '/Deployed to:/ {print $3}'` + echo $VERIFIER_ADDRESS + ``` + +7. Distribuisci il contratto `ZkBank`. + + ```sh + ZKBANK_ADDRESS=`forge create ZkBank --private-key $ETH_PRIVATE_KEY --broadcast --constructor-args $VERIFIER_ADDRESS 0x199aa62af8c1d562a6ec96e66347bf3240ab2afb5d022c895e6bf6a5e617167b | awk '/Deployed to:/ {print $3}'` + echo $ZKBANK_ADDRESS + ``` + + Il valore `0x199..67b` è l'hash di Pederson dello stato iniziale di `Accounts`. Se modifichi questo stato iniziale in `server/index.mjs`, puoi eseguire una transazione per vedere l'hash iniziale riportato dalla prova a conoscenza-zero. + +8. Esegui il server. + + ```sh + cd ../server + npm run start + ``` + +9. Esegui il client in una finestra a riga di comando diversa. + + ```sh + cd client + npm run dev + ``` + +10. Esegui alcune transazioni. + +11. Per verificare che lo stato sia cambiato sulla catena, riavvia il processo del server. Vedi che `ZkBank` non accetta più transazioni, perché il valore hash originale nelle transazioni differisce dal valore hash archiviato sulla catena. + + Questo è il tipo di errore previsto. + + ``` + ori@CryptoDocGuy:~/x/250911-zk-bank/server$ npm run start + + > server@1.0.0 start + > node --experimental-json-modules index.mjs + + In ascolto sulla porta 3000 + Errore di verifica: ContractFunctionExecutionError: La funzione del contratto "processTransaction" è stata ripristinata per il seguente motivo: + Hash dello stato precedente errato + + Chiamata del contratto: + address: 0xe7f1725E7734CE288F8367e1Bb143E90bb3F0512 + function: processTransaction(bytes _proof, bytes32[] _publicInputs) + args: (0x0000000000000000000000000000000000000000000000042ab5d6d1986846cf00000000000000000000000000000000000000000000000b75c020998797da7800000000000000000000000000000000000000000000000) + ``` + +#### `server/index.mjs` {#server-index-mjs-2} + +Le modifiche in questo file si riferiscono principalmente alla creazione della prova effettiva e alla sua presentazione sulla catena. + +```js +import { exec } from 'child_process' +import util from 'util' + +const execPromise = util.promisify(exec) +``` + +Dobbiamo usare [il pacchetto Barretenberg](https://github.com/AztecProtocol/aztec-packages/tree/next/barretenberg) per creare la prova effettiva da inviare sulla catena. Possiamo usare questo pacchetto sia eseguendo l'interfaccia a riga di comando (`bb`) sia usando la [libreria JavaScript, `bb.js`](https://www.npmjs.com/package/@aztec/bb.js). La libreria JavaScript è molto più lenta dell'esecuzione di codice nativo, quindi qui usiamo [`exec`](https://nodejs.org/api/child_process.html#child_processexeccommand-options-callback) per usare la riga di comando. + +Nota che se decidi di usare `bb.js`, devi usare una versione compatibile con la versione di Noir che stai usando. Al momento della stesura, l'attuale versione di Noir (1.0.0-beta.11) utilizza la versione 0.87 di `bb.js`. + +```js +const zkBankAddress = process.env.ZKBANK_ADDRESS || "0xe7f1725E7734CE288F8367e1Bb143E90bb3F0512" +``` + +L'indirizzo qui è quello che si ottiene quando si inizia con un `anvil` pulito e si seguono le indicazioni sopra. + +```js +const walletClient = createWalletClient({ + chain: anvil, + transport: http(), + account: privateKeyToAccount("0x2a871d0798f97d79848a013d4936a73bf4cc922c825d33c1cf7073dff6d409c6") +}) +``` + +Questa chiave privata è uno dei conti pre-finanziati predefiniti in `anvil`. + +```js +const generateProof = async (witness, fileID) => { +``` + +Genera una prova usando l'eseguibile `bb`. + +```js + const fname = `witness-${fileID}.gz` + await fs.writeFile(fname, witness) +``` + +Scrivi la testimonianza in un file. + +```js + await execPromise(`bb prove -b ./noir/target/zkBank.json -w ${fname} -o ${fileID} --oracle_hash keccak --output_format fields`) +``` + +Crea effettivamente la prova. Questo passaggio crea anche un file con le variabili pubbliche, ma non ne abbiamo bisogno. Abbiamo già ottenuto quelle variabili da `noir.execute`. + +```js + const proof = "0x" + JSON.parse(await fs.readFile(`./${fileID}/proof_fields.json`)).reduce((a,b) => a+b, "").replace(/0x/g, "") +``` + +La prova è un array JSON di valori `Field`, ognuno rappresentato come valore esadecimale. Tuttavia, dobbiamo inviarlo nella transazione come un singolo valore `bytes`, che Viem rappresenta con una grande stringa esadecimale. Qui cambiamo il formato concatenando tutti i valori, rimuovendo tutti gli `0x` e aggiungendone uno alla fine. + +```js + await execPromise(`rm -r ${fname} ${fileID}`) + + return proof +} +``` + +Pulisci e restituisci la prova. + +```js +const processMessage = async (message, signature) => { + . + . + . + + const publicFields = noirResult.returnValue.map(x=>'0x' + x.slice(2).padStart(64, "0")) +``` + +I campi pubblici devono essere un array di valori a 32 byte. Tuttavia, poiché abbiamo dovuto dividere l'hash della transazione tra due valori `Field`, appare come un valore a 16 byte. Qui aggiungiamo zeri in modo che Viem capisca che sono effettivamente 32 byte. + +```js + const proof = await generateProof(noirResult.witness, `${fromAddress}-${nonce}`) +``` + +Ogni indirizzo utilizza ogni nonce una sola volta, quindi possiamo utilizzare una combinazione di `fromAddress` e `nonce` come identificatore univoco per il file di testimonianza e la directory di output. + +```js + try { + await zkBank.write.processTransaction([ + proof, publicFields]) + } catch (err) { + console.log(`Errore di verifica: ${err}`) + throw Error("Impossibile verificare la transazione sulla catena") + } + . + . + . +} +``` + +Invia la transazione alla catena. + +#### `smart-contracts/src/ZkBank.sol` {#smart-contracts-src-zkbank-sol} + +Questo è il codice sulla catena che riceve la transazione. + +```solidity +// SPDX-License-Identifier: MIT + +pragma solidity >=0.8.21; + +import {HonkVerifier} from "./Verifier.sol"; + +contract ZkBank { + HonkVerifier immutable myVerifier; + bytes32 currentStateHash; + + constructor(address _verifierAddress, bytes32 _initialStateHash) { + currentStateHash = _initialStateHash; + myVerifier = HonkVerifier(_verifierAddress); + } +``` + +Il codice sulla catena deve tenere traccia di due variabili: il verificatore (un contratto separato creato da `nargo`) e l'hash dello stato corrente. + +```solidity + event TransactionProcessed( + bytes32 indexed transactionHash, + bytes32 oldStateHash, + bytes32 newStateHash + ); +``` + +Ogni volta che lo stato cambia, emettiamo un evento `TransactionProcessed`. + +```solidity + function processTransaction( + bytes calldata _proof, + bytes32[] calldata _publicFields + ) public { +``` + +Questa funzione elabora le transazioni. Ottiene la prova (come `bytes`) e gli input pubblici (come array `bytes32`), nel formato richiesto dal verificatore (per minimizzare l'elaborazione sulla catena e quindi i costi del gas). + +```solidity + require(_publicInputs[0] == currentStateHash, + "Hash dello stato precedente errato"); +``` + +La prova a conoscenza-zero deve essere che la transazione cambia dal nostro hash corrente a uno nuovo. + +```solidity + myVerifier.verify(_proof, _publicFields); +``` + +Chiama il contratto del verificatore per verificare la prova a conoscenza-zero. Questo passaggio annulla la transazione se la prova a conoscenza-zero è sbagliata. + +```solidity + currentStateHash = _publicFields[1]; + + emit TransactionProcessed( + _publicFields[2]<<128 | _publicFields[3], + _publicFields[0], + _publicFields[1] + ); + } +} +``` + +Se tutto è corretto, aggiorna l'hash di stato al nuovo valore ed emetti un evento `TransactionProcessed`. + +## Abusi da parte del componente centralizzato {#abuses} + +La sicurezza delle informazioni è composta da tre attributi: + +- _Riservatezza_, gli utenti non possono leggere informazioni che non sono autorizzati a leggere. +- _Integrità_, le informazioni non possono essere modificate se non da utenti autorizzati e in modo autorizzato. +- _Disponibilità_, gli utenti autorizzati possono usare il sistema. + +In questo sistema, l'integrità è fornita tramite prove a conoscenza-zero. La disponibilità è molto più difficile da garantire, e la riservatezza è impossibile, perché la banca deve conoscere il saldo di ogni conto e tutte le transazioni. Non c'è modo di impedire a un'entità che ha informazioni di condividerle. + +Potrebbe essere possibile creare una banca veramente confidenziale utilizzando [indirizzi stealth](https://vitalik.eth.limo/general/2023/01/20/stealth.html), ma questo va oltre lo scopo di questo articolo. + +### Informazioni false {#false-info} + +Un modo in cui il server può violare l'integrità è fornire informazioni false quando [vengono richiesti i dati](https://github.com/qbzzt/250911-zk-bank/blob/03-smart-contracts/server/index.mjs#L278-L291). + +Per risolvere questo problema, possiamo scrivere un secondo programma Noir che riceve i conti come input privato e l'indirizzo per cui si richiedono informazioni come input pubblico. L'output è il saldo e il nonce di quell'indirizzo, e l'hash dei conti. + +Naturalmente, questa prova non può essere verificata sulla catena, perché non vogliamo pubblicare nonce e saldi sulla catena. Tuttavia, può essere verificato dal codice client in esecuzione nel browser. + +### Transazioni forzate {#forced-txns} + +Il meccanismo usuale per garantire la disponibilità e prevenire la censura sugli L2 sono le [transazioni forzate](https://docs.optimism.io/stack/transactions/forced-transaction). Ma le transazioni forzate non si combinano con le prove a conoscenza-zero. Il server è l'unica entità che può verificare le transazioni. + +Possiamo modificare `smart-contracts/src/ZkBank.sol` per accettare transazioni forzate e impedire al server di cambiare lo stato finché non vengono elaborate. Tuttavia, questo ci espone a un semplice attacco di negazione del servizio. E se una transazione forzata non è valida e quindi impossibile da elaborare? + +La soluzione è avere una prova a conoscenza-zero che una transazione forzata non è valida. Questo dà al server tre opzioni: + +- Elaborare la transazione forzata, fornendo una prova a conoscenza-zero che è stata elaborata e il nuovo hash di stato. +- Rifiutare la transazione forzata e fornire una prova a conoscenza-zero al contratto che la transazione non è valida (indirizzo sconosciuto, nonce errato o saldo insufficiente). +- Ignorare la transazione forzata. Non c'è modo di forzare il server a elaborare effettivamente la transazione, ma ciò significa che l'intero sistema non è disponibile. + +#### Obbligazioni di disponibilità {#avail-bonds} + +In un'implementazione reale, ci sarebbe probabilmente una sorta di incentivo al profitto per mantenere il server in funzione. Possiamo rafforzare questo incentivo facendo sì che il server pubblichi un'obbligazione di disponibilità che chiunque può bruciare se una transazione forzata non viene elaborata entro un certo periodo. + +### Codice Noir errato {#bad-noir-code} + +Normalmente, per ottenere la fiducia delle persone in un contratto intelligente, carichiamo il codice sorgente su un [esploratore di blocchi](https://eth.blockscout.com/address/0x7D16d2c4e96BCFC8f815E15b771aC847EcbDB48b?tab=contract). Tuttavia, nel caso delle prove a conoscenza-zero, ciò è insufficiente. + +`Verifier.sol` contiene la chiave di verifica, che è una funzione del programma Noir. Tuttavia, quella chiave non ci dice quale fosse il programma Noir. Per avere effettivamente una soluzione affidabile, è necessario caricare il programma Noir (e la versione che lo ha creato). Altrimenti, le prove a conoscenza-zero potrebbero riflettere un programma diverso, uno con una backdoor. + +Finché gli esploratori di blocchi non ci permetteranno di caricare e verificare i programmi Noir, dovresti farlo da solo (preferibilmente su [IPFS](/developers/tutorials/ipfs-decentralized-ui/)). Poi gli utenti sofisticati potranno scaricare il codice sorgente, compilarlo da soli, creare `Verifier.sol` e verificare che sia identico a quello sulla catena. + +## Conclusione {#conclusion} + +Le applicazioni di tipo Plasma richiedono un componente centralizzato come archivio di informazioni. Questo apre potenziali vulnerabilità ma, in cambio, ci permette di preservare la privacy in modi non disponibili sulla blockchain stessa. Con le prove a conoscenza-zero possiamo garantire l'integrità e possibilmente rendere economicamente vantaggioso per chiunque gestisca il componente centralizzato il mantenimento della disponibilità. + +[Vedi qui per altri miei lavori](https://cryptodocguy.pro/). + +## Riconoscimenti {#acknowledgements} + +- Josh Crites ha letto una bozza di questo articolo e mi ha aiutato con un problema spinoso di Noir. + +Eventuali errori rimanenti sono di mia responsabilità. diff --git a/public/content/translations/it/developers/tutorials/calling-a-smart-contract-from-javascript/index.md b/public/content/translations/it/developers/tutorials/calling-a-smart-contract-from-javascript/index.md index 0cb3e59f136..f5770c6c5df 100644 --- a/public/content/translations/it/developers/tutorials/calling-a-smart-contract-from-javascript/index.md +++ b/public/content/translations/it/developers/tutorials/calling-a-smart-contract-from-javascript/index.md @@ -2,11 +2,7 @@ title: Chiamare un contratto intelligente da JavaScript description: Come chiamare la funzione di un contratto intelligente da JavaScript usando un esempio di token Dai author: jdourlens -tags: - - "transazioni" - - "frontend" - - "JavaScript" - - "web3.js" +tags: [ "transazioni", "frontend", "JavaScript", "web3.js" ] skill: beginner lang: it published: 2020-04-19 @@ -15,15 +11,15 @@ sourceUrl: https://ethereumdev.io/calling-a-smart-contract-from-javascript/ address: "0x19dE91Af973F404EDF5B4c093983a7c6E3EC8ccE" --- -In questo tutorial vedremo come chiamare la funzione di un [Contratto Intelligente](/developers/docs/smart-contracts/) da JavaScript. Prima, bisogna leggere lo stato di un contratto intelligente (es. il saldo di un titolare di ERC20), poi modificheremo lo stato della blockchain effettuando un trasferimento di token. Dovresti esser già familiare con la [configurazione di un ambiente JS per interagire con la blockchain](/developers/tutorials/set-up-web3js-to-use-ethereum-in-javascript/). +In questa guida vedremo come chiamare una funzione di un [contratto intelligente](/developers/docs/smart-contracts/) da JavaScript. Per prima cosa, leggeremo lo stato di un contratto intelligente (ad es. il saldo di un detentore di ERC20), dopodiché modificheremo lo stato della blockchain effettuando un trasferimento di token. Dovresti già avere familiarità con la [configurazione di un ambiente JS per interagire con la blockchain](/developers/tutorials/set-up-web3js-to-use-ethereum-in-javascript/). -Per questo esempio, avremo a che fare con il token DAI e, per scopi di testing biforcheremo la blockchain usando ganache-cli e sbloccheremo un indirizzo che contiene già molti DAI: +Per questo esempio, utilizzeremo il token DAI; a scopo di test, effettueremo una biforcazione della blockchain utilizzando ganache-cli e sbloccheremo un indirizzo che possiede già molti DAI: ```bash -ganache-cli -f https://mainnet.infura.io/v3/[YOUR INFURA KEY] -d -i 66 1 --unlock 0x4d10ae710Bd8D1C31bd7465c8CBC3add6F279E81 +ganache-cli -f https://mainnet.infura.io/v3/[LA TUA CHIAVE INFURA] -d -i 66 1 --unlock 0x4d10ae710Bd8D1C31bd7465c8CBC3add6F279E81 ``` -Per interagire con un contratto intelligente, avremo bisogno del suo indirizzo e ABI: +Per interagire con un contratto intelligente, avremo bisogno del suo indirizzo e della sua ABI: ```js const ERC20TransferABI = [ @@ -74,9 +70,9 @@ const ERC20TransferABI = [ const DAI_ADDRESS = "0x6b175474e89094c44da98b954eedeac495271d0f" ``` -Per questo progetto abbiamo ridotto l'ABI completa dell'ERC20 per mantenere solo la funzione `balancecOf` e `transfer`, ma puoi trovare l'[ABI completa dell'ERC20 qui](https://ethereumdev.io/abi-for-erc20-contract-on-ethereum/). +Per questo progetto abbiamo ridotto l'ABI ERC20 completa per mantenere solo le funzioni `balanceOf` e `transfer`, ma puoi trovare [l'ABI ERC20 completa qui](https://ethereumdev.io/abi-for-erc20-contract-on-ethereum/). -Poi dobbiamo istanziare il nostro contratto intelligente: +Dobbiamo quindi istanziare il nostro contratto intelligente: ```js const web3 = new Web3("http://localhost:8545") @@ -84,7 +80,7 @@ const web3 = new Web3("http://localhost:8545") const daiToken = new web3.eth.Contract(ERC20TransferABI, DAI_ADDRESS) ``` -Inoltre, configureremo due indirizzi: +Imposteremo anche due indirizzi: - quello che riceverà il trasferimento e - quello che abbiamo già sbloccato che lo invierà: @@ -94,42 +90,42 @@ const senderAddress = "0x4d10ae710Bd8D1C31bd7465c8CBC3add6F279E81" const receiverAddress = "0x19dE91Af973F404EDF5B4c093983a7c6E3EC8ccE" ``` -Nella prossima parte, chiameremo la funzione `balanceOf` per recuperare l'importo corrente dei token posseduti da entrambi gli indirizzi. +Nella parte successiva, chiameremo la funzione `balanceOf` per recuperare l'importo corrente di token posseduti da entrambi gli indirizzi. -## Chiamata: Leggere il valore da un contratto intelligente {#call-reading-value-from-a-smart-contract} +## Chiamata: leggere il valore da un contratto intelligente {#call-reading-value-from-a-smart-contract} -Il primo esempio chiamerà un metodo "constant" ed eseguirà il metodo del suo contratto intelligente nell'EVM, senza inviare alcuna transazione. Per questo leggeremo il saldo di ERC20 di un indirizzo. [Leggi il nostro articolo sui token ERC20](/developers/tutorials/understand-the-erc-20-token-smart-contract/). +Il primo esempio chiamerà un metodo "constant" ed eseguirà il suo metodo del contratto intelligente nell'EVM senza inviare alcuna transazione. Per questo, leggeremo il saldo ERC20 di un indirizzo. [Leggi il nostro articolo sui token ERC20](/developers/tutorials/understand-the-erc-20-token-smart-contract/). -Puoi accedere ai metodi di un contratto intelligente istanziato per cui hai fornito l'ABI come segue: `yourContract.methods.methodname`. Usando la funzione `call` riceverai il risultato dell'esecuzione della funzione. +Puoi accedere ai metodi di un contratto intelligente istanziato per il quale hai fornito l'ABI come segue: `yourContract.methods.methodname`. Utilizzando la funzione `call` riceverai il risultato dell'esecuzione della funzione. ```js daiToken.methods.balanceOf(senderAddress).call(function (err, res) { if (err) { - console.log("An error occurred", err) + console.log("Si è verificato un errore", err) return } - console.log("The balance is: ", res) + console.log("Il saldo è: ", res) }) ``` -Ricorda che l'ERC20 di DAI contiene 18 cifre decimali, il che significa che devi rimuovere 18 zeri per ottenere l'importo corretto. I valori uint256 sono restituiti come stringhe, poiché JavaScript non gestisce i grandi valori numerici. Se non sai [come gestire i grandi numeri in JS consulta il nostro tutorial su bignumber.js](https://ethereumdev.io/how-to-deal-with-big-numbers-in-javascript/). +Ricorda che DAI ERC20 ha 18 decimali, il che significa che devi rimuovere 18 zeri per ottenere l'importo corretto. I valori uint256 vengono restituiti come stringhe, poiché JavaScript non gestisce valori numerici grandi. Se non sei sicuro di [come gestire i numeri grandi in JS, consulta la nostra guida su bignumber.js](https://ethereumdev.io/how-to-deal-with-big-numbers-in-javascript/). -## Invio: Inviare una transazione alla funzione di un contratto intelligente {#send-sending-a-transaction-to-a-smart-contract-function} +## Inviare: inviare una transazione a una funzione di un contratto intelligente {#send-sending-a-transaction-to-a-smart-contract-function} -Per il secondo esempio, chiameremo la funzione di trasferimento del contratto intelligente di DAI per inviare 10 DAI al nostro secondo indirizzo. La funzione di trasferimento accetta due parametri: l'indirizzo del destinatario e l'importo di token da trasferire: +Per il secondo esempio, chiameremo la funzione di trasferimento del contratto intelligente DAI per inviare 10 DAI al nostro secondo indirizzo. La funzione di trasferimento accetta due parametri: l'indirizzo del destinatario e l'importo di token da trasferire: ```js daiToken.methods .transfer(receiverAddress, "100000000000000000000") .send({ from: senderAddress }, function (err, res) { if (err) { - console.log("An error occurred", err) + console.log("Si è verificato un errore", err) return } - console.log("Hash of the transaction: " + res) + console.log("Hash della transazione: " + res) }) ``` -La funzione di chiamata restituiscec l'hash dedlla transazione che sarà minato nella blockchain. Su Ethereum, gli hash della transazione sono prevedibili, così possiamo ottenere l'hash della transazione prima che sia eseguita ([scopri qui come sono calcolati gli hash](https://ethereum.stackexchange.com/questions/45648/how-to-calculate-the-assigned-txhash-of-a-transaction)). +La funzione di chiamata restituisce l'hash della transazione che sarà minata nella blockchain. Su Ethereum, gli hash delle transazioni sono prevedibili: è così che possiamo ottenere l'hash della transazione prima che venga eseguita ([scopri qui come vengono calcolati gli hash](https://ethereum.stackexchange.com/questions/45648/how-to-calculate-the-assigned-txhash-of-a-transaction)). -Poiché la funzione invia soltanto la transazione alla blockchain, non possiamo vedere il risultato finché non sappiamo quando è minato e incluso nella blockchain. Nel prossimo tutorial, impareremo [come attendedre l'esecuzione di una transazione, conoscendone l'hash](https://ethereumdev.io/waiting-for-a-transaction-to-be-mined-on-ethereum-with-js/). +Poiché la funzione invia solo la transazione alla blockchain, non possiamo vederne il risultato finché non viene minata e inclusa nella blockchain. Nella prossima guida impareremo [come attendere che una transazione venga eseguita sulla blockchain conoscendone l'hash](https://ethereumdev.io/waiting-for-a-transaction-to-be-mined-on-ethereum-with-js/). diff --git a/public/content/translations/it/developers/tutorials/creating-a-wagmi-ui-for-your-contract/index.md b/public/content/translations/it/developers/tutorials/creating-a-wagmi-ui-for-your-contract/index.md new file mode 100644 index 00000000000..69d15061b71 --- /dev/null +++ b/public/content/translations/it/developers/tutorials/creating-a-wagmi-ui-for-your-contract/index.md @@ -0,0 +1,585 @@ +--- +title: "Costruzione di un'interfaccia utente per il tuo contratto" +description: Utilizzando componenti moderni come TypeScript, React, Vite e Wagmi, esamineremo un'interfaccia utente moderna ma minimale e impareremo a connettere un portafoglio all'interfaccia utente, a chiamare un contratto intelligente per leggere informazioni, a inviare una transazione a un contratto intelligente e a monitorare gli eventi di un contratto intelligente per identificare le modifiche. +author: Ori Pomerantz +tags: [ "typescript", "react", "vite", "wagmi", "frontend" ] +skill: beginner +published: 2023-11-01 +lang: it +sidebarDepth: 3 +--- + +Hai trovato una funzionalità di cui abbiamo bisogno nell'ecosistema di Ethereum. Hai scritto i contratti intelligenti per implementarla e forse anche del codice correlato che viene eseguito off-chain. È fantastico! Purtroppo, senza un'interfaccia utente non avrai nessun utente e l'ultima volta che hai scritto un sito web la gente usava modem dial-up e JavaScript era una novità. + +Questo articolo è per te. Presumo che tu sappia programmare e forse un po' di JavaScript e HTML, ma che le tue competenze sull'interfaccia utente siano arrugginite e obsolete. Insieme esamineremo una semplice applicazione moderna, così vedrai come si fa al giorno d'oggi. + +## Perché è importante {#why-important} + +In teoria, potresti semplicemente fare in modo che le persone usino [Etherscan](https://holesky.etherscan.io/address/0x432d810484add7454ddb3b5311f0ac2e95cecea8#writeContract) o [Blockscout](https://eth-holesky.blockscout.com/address/0x432d810484AdD7454ddb3b5311f0Ac2E95CeceA8?tab=write_contract) per interagire con i tuoi contratti. Sarà fantastico per gli Etherean esperti. Ma stiamo cercando di servire [un altro miliardo di persone](https://blog.ethereum.org/2021/05/07/ethereum-for-the-next-billion). Ciò non accadrà senza un'ottima esperienza utente, e un'interfaccia utente intuitiva ne è una parte importante. + +## Applicazione Greeter {#greeter-app} + +C'è molta teoria dietro al funzionamento di un'interfaccia utente moderna e [molti buoni siti](https://react.dev/learn/thinking-in-react) [che la spiegano](https://wagmi.sh/core/getting-started). Invece di ripetere l'ottimo lavoro svolto da quei siti, darò per scontato che tu preferisca imparare facendo e iniziare con un'applicazione con cui puoi sperimentare. Avrai comunque bisogno della teoria per portare a termine le cose e ci arriveremo: analizzeremo semplicemente i file sorgente uno per uno e discuteremo le cose man mano che le incontriamo. + +### Installazione {#installation} + +1. Se necessario, aggiungi [la blockchain Holesky](https://chainlist.org/?search=holesky&testnets=true) al tuo portafoglio e [ottieni ETH di prova](https://www.holeskyfaucet.io/). + +2. Clona la repository di GitHub. + + ```sh + git clone https://github.com/qbzzt/20230801-modern-ui.git + ``` + +3. Installa i pacchetti necessari. + + ```sh + cd 20230801-modern-ui + pnpm install + ``` + +4. Avvia l'applicazione. + + ```sh + pnpm dev + ``` + +5. Vai all'URL mostrato dall'applicazione. Nella maggior parte dei casi, è [http://localhost:5173/](http://localhost:5173/). + +6. Puoi vedere il codice sorgente del contratto, una versione leggermente modificata del Greeter di Hardhat, [su un esploratore di blockchain](https://eth-holesky.blockscout.com/address/0x432d810484AdD7454ddb3b5311f0Ac2E95CeceA8?tab=contract). + +### Analisi dei file {#file-walk-through} + +#### `index.html` {#index-html} + +Questo file è un boilerplate HTML standard, ad eccezione di questa riga, che importa il file di script. + +```html + +``` + +#### `src/main.tsx` {#main-tsx} + +L'estensione del file ci dice che questo file è un [componente React](https://www.w3schools.com/react/react_components.asp) scritto in [TypeScript](https://www.typescriptlang.org/), un'estensione di JavaScript che supporta il [controllo dei tipi](https://en.wikipedia.org/wiki/Type_system#Type_checking). TypeScript viene compilato in JavaScript, quindi possiamo usarlo per l'esecuzione lato client. + +```tsx +import '@rainbow-me/rainbowkit/styles.css' +import { RainbowKitProvider } from '@rainbow-me/rainbowkit' +import * as React from 'react' +import * as ReactDOM from 'react-dom/client' +import { WagmiConfig } from 'wagmi' +import { chains, config } from './wagmi' +``` + +Importa il codice della libreria di cui abbiamo bisogno. + +```tsx +import { App } from './App' +``` + +Importa il componente React che implementa l'applicazione (vedi sotto). + +```tsx +ReactDOM.createRoot(document.getElementById('root')!).render( +``` + +Crea il componente React radice. Il parametro di `render` è [JSX](https://www.w3schools.com/react/react_jsx.asp), un linguaggio di estensione che utilizza sia HTML che JavaScript/TypeScript. Il punto esclamativo qui dice al componente TypeScript: "non sai che `document.getElementById('root')` sarà un parametro valido per `ReactDOM.createRoot`, ma non preoccuparti: sono io lo sviluppatore e ti dico che ci sarà". + +```tsx + +``` + +L'applicazione viene inserita in [un componente `React.StrictMode`](https://react.dev/reference/react/StrictMode). Questo componente indica alla libreria React di inserire controlli di debug aggiuntivi, utili durante lo sviluppo. + +```tsx + +``` + +L'applicazione è anche all'interno di [un componente `WagmiConfig`](https://wagmi.sh/react/api/WagmiProvider). [La libreria wagmi (we are going to make it)](https://wagmi.sh/) collega le definizioni dell'interfaccia utente di React con [la libreria viem](https://viem.sh/) per scrivere un'applicazione decentralizzata Ethereum. + +```tsx + +``` + +E infine, [un componente `RainbowKitProvider`](https://www.rainbowkit.com/). Questo componente gestisce il login e la comunicazione tra il portafoglio e l'applicazione. + +```tsx + +``` + +Ora possiamo avere il componente per l'applicazione, che implementa effettivamente l'interfaccia utente. Il `/>` alla fine del componente dice a React che questo componente non ha definizioni al suo interno, come da standard XML. + +```tsx + + + , +) +``` + +Naturalmente, dobbiamo chiudere gli altri componenti. + +#### `src/App.tsx` {#app-tsx} + +```tsx +import { ConnectButton } from '@rainbow-me/rainbowkit' +import { useAccount } from 'wagmi' +import { Greeter } from './components/Greeter' + +export function App() { +``` + +Questo è il modo standard per creare un componente React: definire una funzione che viene chiamata ogni volta che deve essere renderizzata. Questa funzione ha in genere del codice TypeScript o JavaScript all'inizio, seguito da un'istruzione `return` che restituisce il codice JSX. + +```tsx + const { isConnected } = useAccount() +``` + +Qui usiamo [`useAccount`](https://wagmi.sh/react/api/hooks/useAccount) per verificare se siamo connessi a una blockchain tramite un portafoglio o meno. + +Per convenzione, in React le funzioni chiamate `use...` sono [hook](https://www.w3schools.com/react/react_hooks.asp) che restituiscono un qualche tipo di dato. Quando si utilizzano tali hook, non solo il componente ottiene i dati, ma quando tali dati cambiano, il componente viene ri-renderizzato con le informazioni aggiornate. + +```tsx + return ( + <> +``` + +Il JSX di un componente React _deve_ restituire un solo componente. Quando abbiamo più componenti e non abbiamo nulla che li raggruppi "naturalmente", usiamo un componente vuoto (`<> ...` `) per trasformarli in un unico componente. + +```tsx +

Greeter

+ +``` + +Otteniamo [il componente `ConnectButton`](https://www.rainbowkit.com/docs/connect-button) da RainbowKit. Quando non siamo connessi, ci fornisce un pulsante `Connect Wallet` che apre una modale che spiega cosa sono i portafogli e ti permette di scegliere quale usare. Quando siamo connessi, visualizza la blockchain che usiamo, l'indirizzo del nostro conto e il nostro saldo in ETH. Possiamo usare queste visualizzazioni per cambiare rete o per disconnetterci. + +```tsx + {isConnected && ( +``` + +Quando dobbiamo inserire JavaScript effettivo (o TypeScript che sarà compilato in JavaScript) in un JSX, usiamo le parentesi graffe (`{}`). + +La sintassi `a && b` è l'abbreviazione di [`a ?` b : a`](https://www.w3schools.com/react/react_es6_ternary.asp). Cioè, se `a`è vero, restituisce`b`, altrimenti restituisce `a`(che può essere`false`, `0`, ecc.). Questo è un modo semplice per dire a React che un componente dovrebbe essere visualizzato solo se una certa condizione è soddisfatta. + +In questo caso, vogliamo mostrare all'utente `Greeter` solo se l'utente è connesso a una blockchain. + +```tsx + + )} + + ) +} +``` + +#### `src/components/Greeter.tsx` {#greeter-tsx} + +Questo file contiene la maggior parte delle funzionalità dell'interfaccia utente. Include definizioni che normalmente si troverebbero in più file, ma poiché si tratta di un tutorial, il programma è ottimizzato per essere di facile comprensione la prima volta, piuttosto che per le prestazioni o la facilità di manutenzione. + +```tsx +import { useState, ChangeEventHandler } from 'react' +import { useNetwork, + useReadContract, + usePrepareContractWrite, + useContractWrite, + useContractEvent + } from 'wagmi' +``` + +Usiamo queste funzioni di libreria. Anche in questo caso, vengono spiegate di seguito, dove vengono utilizzate. + +```tsx +import { AddressType } from 'abitype' +``` + +[La libreria `abitype`](https://abitype.dev/) ci fornisce definizioni TypeScript per vari tipi di dati di Ethereum, come [`AddressType`](https://abitype.dev/config#addresstype). + +```tsx +let greeterABI = [ + . + . + . +] as const // greeterABI +``` + +L'ABI per il contratto `Greeter`. +Se stai sviluppando i contratti e l'interfaccia utente contemporaneamente, normalmente li metteresti nella stessa repository e useresti l'ABI generata dal compilatore Solidity come file nella tua applicazione. Tuttavia, qui non è necessario perché il contratto è già stato sviluppato e non cambierà. + +```tsx +type AddressPerBlockchainType = { + [key: number]: AddressType +} +``` + +TypeScript è fortemente tipizzato. Usiamo questa definizione per specificare l'indirizzo in cui il contratto `Greeter` è distribuito su diverse catene. La chiave è un numero (il chainId) e il valore è un `AddressType` (un indirizzo). + +```tsx +const contractAddrs: AddressPerBlockchainType = { + // Holesky + 17000: '0x432d810484AdD7454ddb3b5311f0Ac2E95CeceA8', + + // Sepolia + 11155111: '0x7143d5c190F048C8d19fe325b748b081903E3BF0' +} +``` + +L'indirizzo del contratto sulle due reti supportate: [Holesky](https://eth-holesky.blockscout.com/address/0x432d810484AdD7454ddb3b5311f0Ac2E95CeceA8?tab=contact_code) e [Sepolia](https://eth-sepolia.blockscout.com/address/0x7143d5c190F048C8d19fe325b748b081903E3BF0?tab=contact_code). + +Nota: in realtà esiste una terza definizione, per Redstone Holesky, che verrà spiegata di seguito. + +```tsx +type ShowObjectAttrsType = { + name: string, + object: any +} +``` + +Questo tipo viene utilizzato come parametro per il componente `ShowObject` (spiegato più avanti). Include il nome dell'oggetto e il suo valore, che vengono visualizzati a scopo di debug. + +```tsx +type ShowGreetingAttrsType = { + greeting: string | undefined +} +``` + +In qualsiasi momento, potremmo sapere qual è il saluto (perché lo abbiamo letto dalla blockchain) o non saperlo (perché non lo abbiamo ancora ricevuto). Quindi è utile avere un tipo che possa essere una stringa o niente. + +##### Componente `Greeter` {#greeter-component} + +```tsx +const Greeter = () => { +``` + +Infine, arriviamo a definire il componente. + +```tsx + const { chain } = useNetwork() +``` + +Informazioni sulla catena che stiamo usando, per gentile concessione di [wagmi](https://wagmi.sh/react/hooks/useNetwork). +Poiché si tratta di un hook (`use...`), ogni volta che questa informazione cambia, il componente viene ridisegnato. + +```tsx + const greeterAddr = chain && contractAddrs[chain.id] +``` + +L'indirizzo del contratto Greeter, che varia a seconda della catena (e che è `undefined` se non abbiamo informazioni sulla catena o se siamo su una catena senza quel contratto). + +```tsx + const readResults = useReadContract({ + address: greeterAddr, + abi: greeterABI, + functionName: "greet" , // No arguments + watch: true + }) +``` + +[L'hook `useReadContract`](https://wagmi.sh/react/api/hooks/useReadContract) legge le informazioni da un contratto. Puoi vedere esattamente quali informazioni restituisce espandendo `readResults` nell'interfaccia utente. In questo caso, vogliamo che continui a cercare in modo da essere informati quando il saluto cambia. + +**Nota:** potremmo ascoltare gli [eventi `setGreeting`](https://eth-holesky.blockscout.com/address/0x432d810484AdD7454ddb3b5311f0Ac2E95CeceA8?tab=logs) per sapere quando il saluto cambia e aggiornare in quel modo. Tuttavia, sebbene possa essere più efficiente, non si applicherà in tutti i casi. Quando l'utente passa a una catena diversa, anche il saluto cambia, ma tale cambiamento non è accompagnato da un evento. Potremmo avere una parte del codice in ascolto degli eventi e un'altra per identificare i cambi di catena, ma sarebbe più complicato che impostare semplicemente [il parametro `watch`](https://wagmi.sh/react/api/hooks/useReadContract#watch-optional). + +```tsx + const [ newGreeting, setNewGreeting ] = useState("") +``` + +L'[hook `useState` di React](https://www.w3schools.com/react/react_usestate.asp) ci permette di specificare una variabile di stato, il cui valore persiste da un rendering all'altro del componente. Il valore iniziale è il parametro, in questo caso la stringa vuota. + +L'hook `useState` restituisce un elenco con due valori: + +1. Il valore corrente della variabile di stato. +2. Una funzione per modificare la variabile di stato quando necessario. Essendo un hook, ogni volta che viene chiamata, il componente viene renderizzato di nuovo. + +In questo caso, stiamo usando una variabile di stato per il nuovo saluto che l'utente vuole impostare. + +```tsx + const greetingChange : ChangeEventHandler = (evt) => + setNewGreeting(evt.target.value) +``` + +Questo è il gestore di eventi per quando il campo di input del nuovo saluto cambia. Il tipo, [`ChangeEventHandler`](https://react-typescript-cheatsheet.netlify.app/docs/basic/getting-started/forms_and_events/), specifica che si tratta di un gestore per una modifica del valore di un elemento di input HTML. La parte `` viene utilizzata perché si tratta di un [tipo generico](https://www.w3schools.com/typescript/typescript_basic_generics.php). + +```tsx + const preparedTx = usePrepareContractWrite({ + address: greeterAddr, + abi: greeterABI, + functionName: 'setGreeting', + args: [ newGreeting ] + }) + const workingTx = useContractWrite(preparedTx.config) +``` + +Questo è il processo per inviare una transazione blockchain dal punto di vista del client: + +1. Invia la transazione a un nodo nella blockchain usando [`eth_estimateGas`](https://docs.alchemy.com/reference/eth-estimategas). +2. Attendi una risposta dal nodo. +3. Quando la risposta viene ricevuta, chiedi all'utente di firmare la transazione tramite il portafoglio. Questo passaggio _deve_ avvenire dopo aver ricevuto la risposta del nodo, perché all'utente viene mostrato il costo del gas della transazione prima di firmarla. +4. Attendi l'approvazione dell'utente. +5. Invia di nuovo la transazione, questa volta usando [`eth_sendRawTransaction`](https://docs.alchemy.com/reference/eth-sendrawtransaction). + +Il punto 2 richiederà probabilmente una quantità di tempo percettibile, durante la quale gli utenti si chiederanno se il loro comando è stato realmente ricevuto dall'interfaccia utente e perché non gli è stato ancora chiesto di firmare la transazione. Questo crea una cattiva esperienza utente (UX). + +La soluzione è usare gli [hook di preparazione](https://wagmi.sh/react/prepare-hooks). Ogni volta che un parametro cambia, invia immediatamente al nodo la richiesta `eth_estimateGas`. Quindi, quando l'utente vuole effettivamente inviare la transazione (in questo caso premendo **Aggiorna saluto**), il costo del gas è noto e l'utente può vedere immediatamente la pagina del portafoglio. + +```tsx + return ( +``` + +Ora possiamo finalmente creare l'HTML effettivo da restituire. + +```tsx + <> +

Greeter

+ { + !readResults.isError && !readResults.isLoading && + + } +
+``` + +Crea un componente `ShowGreeting` (spiegato di seguito), ma solo se il saluto è stato letto con successo dalla blockchain. + +```tsx + +``` + +Questo è il campo di testo di input in cui l'utente può impostare un nuovo saluto. Ogni volta che l'utente preme un tasto, chiamiamo `greetingChange` che a sua volta chiama `setNewGreeting`. Poiché `setNewGreeting` proviene dall'hook `useState`, fa sì che il componente `Greeter` venga renderizzato di nuovo. Ciò significa che: + +- Dobbiamo specificare `value` per conservare il valore del nuovo saluto, altrimenti tornerebbe al valore predefinito, la stringa vuota. +- `usePrepareContractWrite` viene chiamato ogni volta che `newGreeting` cambia, il che significa che avrà sempre l'ultimo `newGreeting` nella transazione preparata. + +```tsx + +``` + +Se non c'è `workingTx.write`, allora stiamo ancora aspettando le informazioni necessarie per inviare l'aggiornamento del saluto, quindi il pulsante è disabilitato. Se c'è un valore `workingTx.write`, allora quella è la funzione da chiamare per inviare la transazione. + +```tsx +
+ + + + + ) +} +``` + +Infine, per aiutarti a vedere cosa stiamo facendo, mostriamo i tre oggetti che usiamo: + +- `readResults` +- `preparedTx` +- `workingTx` + +##### Componente `ShowGreeting` {#showgreeting-component} + +Questo componente mostra + +```tsx +const ShowGreeting = (attrs : ShowGreetingAttrsType) => { +``` + +La funzione di un componente riceve un parametro con tutti gli attributi del componente. + +```tsx + return {attrs.greeting} +} +``` + +##### Componente `ShowObject` {#showobject-component} + +A scopo informativo, usiamo il componente `ShowObject` per mostrare gli oggetti importanti (`readResults` per leggere il saluto e `preparedTx` e `workingTx` per le transazioni che creiamo). + +```tsx +const ShowObject = (attrs: ShowObjectAttrsType ) => { + const keys = Object.keys(attrs.object) + const funs = keys.filter(k => typeof attrs.object[k] == "function") + return <> +
+``` + +Non vogliamo ingombrare l'interfaccia utente con tutte le informazioni, quindi per rendere possibile visualizzarle o chiuderle, usiamo un tag [`details`](https://www.w3schools.com/tags/tag_details.asp). + +```tsx + {attrs.name} +
+        {JSON.stringify(attrs.object, null, 2)}
+```
+
+La maggior parte dei campi viene visualizzata usando [`JSON.stringify`](https://www.w3schools.com/js/js_json_stringify.asp).
+
+```tsx
+      
+ { funs.length > 0 && + <> + Funzioni: +
    +``` + +L'eccezione sono le funzioni, che non fanno parte dello [standard JSON](https://www.json.org/json-en.html), quindi devono essere visualizzate separatamente. + +```tsx + {funs.map((f, i) => +``` + +All'interno di JSX, il codice tra parentesi graffe `{` `}` viene interpretato come JavaScript. Quindi, il codice all'interno delle parentesi tonde `(` `)`, viene nuovamente interpretato come JSX. + +```tsx + (
  • {f}
  • ) + )} +``` + +React richiede che i tag nell'[albero DOM](https://www.w3schools.com/js/js_htmldom.asp) abbiano identificatori distinti. Ciò significa che gli elementi figli dello stesso tag (in questo caso, [l'elenco non ordinato](https://www.w3schools.com/tags/tag_ul.asp)), necessitano di attributi `key` diversi. + +```tsx +
+ + } +
+ +} +``` + +Termina i vari tag HTML. + +##### L'`export` finale {#the-final-export} + +```tsx +export { Greeter } +``` + +Il componente `Greeter` è quello che dobbiamo esportare per l'applicazione. + +#### `src/wagmi.ts` {#wagmi-ts} + +Infine, varie definizioni relative a WAGMI si trovano in `src/wagmi.ts`. Non spiegherò tutto qui, perché la maggior parte è boilerplate che difficilmente avrai bisogno di modificare. + +Il codice qui non è esattamente lo stesso di [quello su GitHub](https://github.com/qbzzt/20230801-modern-ui/blob/main/src/wagmi.ts) perché più avanti nell'articolo aggiungiamo un'altra catena ([Redstone Holesky](https://redstone.xyz/docs/network-info)). + +```ts +import { getDefaultWallets } from '@rainbow-me/rainbowkit' +import { configureChains, createConfig } from 'wagmi' +import { holesky, sepolia } from 'wagmi/chains' +``` + +Importa le blockchain supportate dall'applicazione. Puoi vedere l'elenco delle catene supportate [nel GitHub di viem](https://github.com/wagmi-dev/viem/tree/main/src/chains/definitions). + +```ts +import { publicProvider } from 'wagmi/providers/public' + +const walletConnectProjectId = 'c96e690bb92b6311e8e9b2a6a22df575' +``` + +Per poter utilizzare [WalletConnect](https://walletconnect.com/) è necessario un ID di progetto per la propria applicazione. Puoi ottenerlo su [cloud.walletconnect.com](https://cloud.walletconnect.com/sign-in). + +```ts +const { chains, publicClient, webSocketPublicClient } = configureChains( + [ holesky, sepolia ], + [ + publicProvider(), + ], +) + +const { connectors } = getDefaultWallets({ + appName: 'My wagmi + RainbowKit App', + chains, + projectId: walletConnectProjectId, +}) + +export const config = createConfig({ + autoConnect: true, + connectors, + publicClient, + webSocketPublicClient, +}) + +export { chains } +``` + +### Aggiungere un'altra blockchain {#add-blockchain} + +Oggigiorno ci sono molte [soluzioni di scalabilità di secondo livello](/layer-2/) e potresti volerne supportare alcune che viem non supporta ancora. Per farlo, modifica `src/wagmi.ts`. Queste istruzioni spiegano come aggiungere [Redstone Holesky](https://redstone.xyz/docs/network-info). + +1. Importa il tipo `defineChain` da viem. + + ```ts + import { defineChain } from 'viem' + ``` + +2. Aggiungi la definizione della rete. + + ```ts + const redstoneHolesky = defineChain({ + id: 17_001, + name: 'Redstone Holesky', + network: 'redstone-holesky', + nativeCurrency: { + decimals: 18, + name: 'Ether', + symbol: 'ETH', + }, + rpcUrls: { + default: { + http: ['https://rpc.holesky.redstone.xyz'], + webSocket: ['wss://rpc.holesky.redstone.xyz/ws'], + }, + public: { + http: ['https://rpc.holesky.redstone.xyz'], + webSocket: ['wss://rpc.holesky.redstone.xyz/ws'], + }, + }, + blockExplorers: { + default: { name: 'Explorer', url: 'https://explorer.holesky.redstone.xyz' }, + }, + }) + ``` + +3. Aggiungi la nuova catena alla chiamata `configureChains`. + + ```ts + const { chains, publicClient, webSocketPublicClient } = configureChains( + [ holesky, sepolia, redstoneHolesky ], + [ publicProvider(), ], + ) + ``` + +4. Assicurati che l'applicazione conosca l'indirizzo dei tuoi contratti sulla nuova rete. In questo caso, modifichiamo `src/components/Greeter.tsx`. + + ```ts + const contractAddrs : AddressPerBlockchainType = { + // Holesky + 17000: '0x432d810484AdD7454ddb3b5311f0Ac2E95CeceA8', + + // Redstone Holesky + 17001: '0x4919517f82a1B89a32392E1BF72ec827ba9986D3', + + // Sepolia + 11155111: '0x7143d5c190F048C8d19fe325b748b081903E3BF0' + } + ``` + +## Conclusione {#conclusion} + +Naturalmente, non ti interessa molto fornire un'interfaccia utente per `Greeter`. Vuoi creare un'interfaccia utente per i tuoi contratti. Per creare la tua applicazione, esegui questi passaggi: + +1. Specifica di creare un'applicazione wagmi. + + ```sh copy + pnpm create wagmi + ``` + +2. Dai un nome all'applicazione. + +3. Seleziona il framework **React**. + +4. Seleziona la variante **Vite**. + +5. Puoi [aggiungere Rainbow Kit](https://www.rainbowkit.com/docs/installation#manual-setup). + +Ora vai e rendi i tuoi contratti utilizzabili per il mondo intero. + +[Vedi qui per altri miei lavori](https://cryptodocguy.pro/). + diff --git a/public/content/translations/it/developers/tutorials/deploying-your-first-smart-contract/index.md b/public/content/translations/it/developers/tutorials/deploying-your-first-smart-contract/index.md index 7f37d8afb08..c5d530bd234 100644 --- a/public/content/translations/it/developers/tutorials/deploying-your-first-smart-contract/index.md +++ b/public/content/translations/it/developers/tutorials/deploying-your-first-smart-contract/index.md @@ -1,12 +1,14 @@ --- -title: Distribuzione del primo Smart Contract -description: Introduzione alla distribuzione del primo Smart Contract su una rete di prova Ethereum +title: Distribuzione del tuo primo smart contract +description: Un'introduzione alla distribuzione del tuo primo smart contract su una rete di test di Ethereum author: "jdourlens" tags: - - "smart contract" - - "remix" - - "Solidity" - - "distribuzione" + [ + "smart contract", + "remix", + "Solidity", + "distribuzione" + ] skill: beginner lang: it published: 2020-04-03 @@ -15,15 +17,15 @@ sourceUrl: https://ethereumdev.io/deploying-your-first-smart-contract/ address: "0x19dE91Af973F404EDF5B4c093983a7c6E3EC8ccE" --- -Sicuramente sarai entusiasta almeno quanto noi di [distribuire](/developers/docs/smart-contracts/deploying/) il tuo primo [Smart Contract](/developers/docs/smart-contracts/) e interagirvi sulla blockchain Ethereum. +Immagino che tu sia entusiasta quanto noi di [distribuire](/developers/docs/smart-contracts/deploying/) e interagire con il tuo primo [smart contract](/developers/docs/smart-contracts/) sulla blockchain di Ethereum. -Non preoccuparti, essendo il nostro primo smart contract, lo distribuiremo su una [rete locale di prova](/developers/docs/networks/) così che non ti costi nulla distribuirlo e giocarci quanto vuoi. +Non preoccuparti, essendo il nostro primo smart contract, lo distribuiremo su una [rete di test locale](/developers/docs/networks/), così non ti costerà nulla distribuirlo e giocarci quanto vuoi. -## Scrittura del contratto {#writing-our-contract} +## Scrivere il nostro contratto {#writing-our-contract} -Il primo passaggio consiste nel [visitare Remix](https://remix.ethereum.org/) e creare un nuovo file. Nella parte in alto a sinistra dell'interfaccia di Remix, aggiungi un nuovo file e inserisci il nome che preferisci. +Il primo passaggio è [visitare Remix](https://remix.ethereum.org/) e creare un nuovo file. Nella parte in alto a sinistra dell'interfaccia di Remix, aggiungi un nuovo file e inserisci il nome che preferisci. -![Aggiunta di un nuovo file all'interfaccia di Remix](./remix.png) +![Aggiunta di un nuovo file nell'interfaccia di Remix](./remix.png) Nel nuovo file, incolleremo il seguente codice. @@ -33,15 +35,15 @@ pragma solidity >=0.5.17; contract Counter { - // Public variable of type unsigned int to keep the number of counts + // Variabile pubblica di tipo intero senza segno per tenere il numero di conteggi uint256 public count = 0; - // Function that increments our counter + // Funzione che incrementa il nostro contatore function increment() public { count += 1; } - // Not necessary getter to get the count value + // Getter non necessario per ottenere il valore del conteggio function getCount() public view returns (uint256) { return count; } @@ -49,51 +51,51 @@ contract Counter { } ``` -Se sei familiare con la programmazione, puoi facilmente intuire cosa faccia questo programma. Ecco una spiegazione riga per riga: +Se hai familiarità con la programmazione, puoi intuire facilmente cosa fa questo programma. Ecco una spiegazione riga per riga: -- Riga 4: definiamo un contratto con il nome `Counter`. -- Riga 7: il nostro contratto memorizza un numero intero senza firma `count` a partire da 0. -- Riga 10: la prima funzione modificherà lo stato del contratto e incrementerà (`increment()`) la nostra variabile `count`. -- Riga 15: la seconda funzione è solo un getter per leggere il valore della variabile `count` al di fuori dello Smart Contract. Nota che, dato che abbiamo definito la variabile `count` come pubblica, questo non è necessario. Lo indichiamo come esempio. +- Riga 4: Definiamo un contratto con il nome `Counter`. +- Riga 7: Il nostro contratto memorizza un intero senza segno di nome `count`, che parte da 0. +- Riga 10: La prima funzione modificherà lo stato del contratto e incrementerà (`increment()`) la nostra variabile `count`. +- Riga 15: La seconda funzione è solo un getter per poter leggere il valore della variabile `count` al di fuori dello smart contract. Nota che, siccome abbiamo definito la nostra variabile `count` come pubblica, questo non è necessario, ma è mostrato come esempio. -Questo è tutto per il nostro primo semplice Smart Contract. Come forse saprai, somiglia un po' un linguaggio di OOP (Programmazione Orientata agli Oggetti), come Java o C++. Ora è il momento di sperimentare con il contratto. +Questo è tutto per il nostro primo, semplice smart contract. Come forse saprai, assomiglia a una classe dei linguaggi OOP (programmazione orientata agli oggetti) come Java o C++. Ora è il momento di sperimentare con il nostro contratto. -## Distribuzione del contratto {#deploying-our-contract} +## Distribuzione del nostro contratto {#deploying-our-contract} -Una volta scritto il nostro primo Smart Contract, è il momento di distribuirlo sulla blockchain per potervi interagire. +Ora che abbiamo scritto il nostro primo smart contract, lo distribuiremo sulla blockchain per poterci interagire. -[Distribuire il primo Smart Contract sulla blockchain](/developers/docs/smart-contracts/deploying/) significa semplicemente inviare una transazione contenente il codice dello Smart Contract compilato senza specificare nessun destinatario. +[Distribuire lo smart contract sulla blockchain](/developers/docs/smart-contracts/deploying/) in realtà significa solo inviare una transazione contenente il codice dello smart contract compilato, senza specificare alcun destinatario. -Dovremo per prima cosa [compilare il contratto](/developers/docs/smart-contracts/compiling/) facendo clic sull'icona di compilazione sul lato sinistro: +Per prima cosa, [compileremo il contratto](/developers/docs/smart-contracts/compiling/) cliccando sull'icona di compilazione sulla sinistra: -![L'icona compile nella toolbar di Remix](./remix-compile-button.png) +![L'icona di compilazione nella barra degli strumenti di Remix](./remix-compile-button.png) -Poi facciamo clic sul pulsante di compilazione: +Quindi, clicca sul pulsante di compilazione: -![Il pulsante compile nel compilatore Solidity di Remix](./remix-compile.png) +![Il pulsante di compilazione nel compilatore Solidity di Remix](./remix-compile.png) Puoi scegliere di selezionare l'opzione "Auto compile" in modo che il contratto venga sempre compilato quando salvi il contenuto nell'editor di testo. -Poi passa alla schermata per la distribuzione e l'esecuzione delle transazioni: +Quindi, vai alla schermata "deploy and run transactions": -![L'icona deploy nella toolbar di Remix](./remix-deploy.png) +![L'icona di distribuzione nella barra degli strumenti di Remix](./remix-deploy.png) -Una volta sulla schermata di distribuzione ed esecuzione, controlla bene che appaia il nome del tuo contratto e fai clic su Deploy. Come puoi vedere in alto nella pagina, l'ambiente corrente è "JavaScript VM", che significa che distribuiremo il nostro Smart Contract e interagiremo con esso su una blockchain di test locale per poter effettuare test in modo più veloce e senza commissioni. +Una volta sulla schermata "deploy and run transactions", controlla che il nome del tuo contratto appaia e clicca su Deploy. Come puoi vedere in cima alla pagina, l'ambiente corrente è “JavaScript VM”, il che significa che distribuiremo e interagiremo con il nostro smart contract su una blockchain di test locale, per poterlo testare più velocemente e senza commissioni. -![Il pulsante deploy nel compilatore Solidity di Remix](./remix-deploy-button.png) +![Il pulsante di distribuzione nel compilatore Solidity di Remix](./remix-deploy-button.png) -Una volta fatto clic sul pulsante "Deploy", il tuo contratto apparirà nella parte inferiore. Fai clic sulla freccia a sinistra per espanderlo, così da vederne il contenuto. Questa è la nostra variabile `counter`, la nostra funzione `increment()` e il getter `getCounter()`. +Una volta cliccato il pulsante “Deploy”, vedrai il tuo contratto apparire in basso. Clicca la freccia a sinistra per espanderlo e vedere il contenuto del nostro contratto. Questi sono la nostra variabile `counter`, la nostra funzione `increment()` e il getter `getCounter()`. -Se fai clic sul pulsante `count` o `getCount`, verrà recuperato e mostrato il contenuto della variabile `count` del contratto. Dato che non abbiamo ancora chiamato la funzione `increment`, questa dovrebbe indicare 0. +Se clicchi sul pulsante `count` o `getCount`, recupererà e mostrerà il contenuto della variabile `count` del contratto. Dato che non abbiamo ancora chiamato la funzione `increment`, dovrebbe mostrare 0. -![Il pulsante function nel compilatore Solidity di Remix](./remix-function-button.png) +![Il pulsante della funzione nel compilatore Solidity di Remix](./remix-function-button.png) -Chiamiamo ora la funzione `increment` facendo clic sul pulsante. Appariranno i log delle transazioni nella parte inferiore della finestra. Vedrai che i log sono diversi quando premi il pulsante per recuperare i dati invece del pulsante `increment`. Questo perché leggere dati sulla blockchain non richiede alcuna transazione (scrittura) o commissione. Perché una transazione è richiesta solo quando si modifica lo stato della blockchain: +Ora chiamiamo la funzione `increment` cliccando sul pulsante. Vedrai apparire i log delle transazioni effettuate in fondo alla finestra. Vedrai che i log sono diversi quando premi il pulsante per recuperare i dati invece del pulsante `increment`. Questo perché la lettura dei dati sulla blockchain non richiede transazioni (scrittura) né commissioni. Questo perché solo la modifica dello stato della blockchain richiede una transazione: -![Un log delle transazioni](./transaction-log.png) +![Un log di transazioni](./transaction-log.png) -Dopo aver scelto il pulsante increment che genererà una transazione per chiamare la funzione `increment()`, se facciamo clic di nuovo sui pulsanti count o getCount, leggiamo lo stato aggiornato del nostro Smart Contract con la variabile count maggiore di 0. +Dopo aver premuto il pulsante `increment`, che genera una transazione per chiamare la nostra funzione `increment()`, se clicchiamo di nuovo sui pulsanti `count` o `getCount`, leggeremo lo stato appena aggiornato del nostro smart contract, con la variabile `count` che sarà maggiore di 0. -![Il nuovo stato dello Smart Contract aggiornato](./updated-state.png) +![Stato dello smart contract appena aggiornato](./updated-state.png) -Nel prossimo tutorial spiegheremo [come aggiungere eventi agli Smart Contract](/developers/tutorials/logging-events-smart-contracts/). Avere un log degli eventi è un modo comodo per eseguire il debug di uno Smart Contract e per capire cosa succede quando si chiama una funzione. +Nella prossima guida, vedremo [come aggiungere eventi ai tuoi smart contract](/developers/tutorials/logging-events-smart-contracts/). La registrazione degli eventi è un modo pratico per eseguire il debug del tuo smart contract e capire cosa succede quando viene chiamata una funzione. diff --git a/public/content/translations/it/developers/tutorials/develop-and-test-dapps-with-a-multi-client-local-eth-testnet/index.md b/public/content/translations/it/developers/tutorials/develop-and-test-dapps-with-a-multi-client-local-eth-testnet/index.md new file mode 100644 index 00000000000..033734b8b5f --- /dev/null +++ b/public/content/translations/it/developers/tutorials/develop-and-test-dapps-with-a-multi-client-local-eth-testnet/index.md @@ -0,0 +1,372 @@ +--- +title: Come sviluppare e testare una dApp su una rete di test locale multi-client +description: "Questa guida ti illustrerà innanzitutto come creare un'istanza e configurare una rete di test di Ethereum locale multi-client prima di usare la rete di test per distribuire e testare una dApp." +author: "Tedi Mitiku" +tags: + [ + "client", + "nodi", + "smart contract", + "componibilità", + "livello di consenso", + "livello di esecuzione", + "test" + ] +skill: intermediate +lang: it +published: 2023-04-11 +--- + +## Introduzione {#introduction} + +Questa guida ti illustra il processo di creazione di un'istanza di una rete di test di Ethereum locale configurabile, la distribuzione di uno smart contract su di essa e l'utilizzo della rete di test per eseguire test sulla tua dApp. Questa guida è pensata per gli sviluppatori di dApp che vogliono sviluppare e testare le loro dApp localmente con diverse configurazioni di rete prima di distribuirle su una rete di test live o sulla rete principale. + +In questa guida: + +- Creare un'istanza di una rete di test di Ethereum locale con [`eth-network-package`](https://github.com/kurtosis-tech/eth-network-package) usando [Kurtosis](https://www.kurtosis.com/), +- Connettere il tuo ambiente di sviluppo dApp Hardhat alla rete di test locale per compilare, distribuire e testare una dApp, e +- Configurare la rete di test locale, inclusi parametri come il numero di nodi e specifici abbinamenti di client EL/CL, per abilitare flussi di lavoro di sviluppo e test con varie configurazioni di rete. + +### Cos'è Kurtosis? {#what-is-kurtosis} + +[Kurtosis](https://www.kurtosis.com/) è un sistema di compilazione componibile progettato per la configurazione di ambienti di test multi-container. In particolare, permette agli sviluppatori di creare ambienti riproducibili che richiedono una logica di configurazione dinamica, come le reti di test blockchain. + +In questa guida, il pacchetto eth-network-package di Kurtosis avvia una rete di test di Ethereum locale con supporto per il client del livello di esecuzione (EL) [`geth`](https://geth.ethereum.org/), nonché per i client del livello di consenso (CL) [`teku`](https://consensys.io/teku), [`lighthouse`](https://lighthouse.sigmaprime.io/) e [`lodestar`](https://lodestar.chainsafe.io/). Questo pacchetto serve come alternativa configurabile e componibile alle reti in framework come Hardhat Network, Ganache e Anvil. Kurtosis offre agli sviluppatori un maggiore controllo e flessibilità sulle reti di test che usano, che è una delle ragioni principali per cui la [Ethereum Foundation ha usato Kurtosis per testare la Fusione](https://www.kurtosis.com/blog/testing-the-ethereum-merge) e continua a usarlo per testare gli aggiornamenti della rete. + +## Configurazione di Kurtosis {#setting-up-kurtosis} + +Prima di procedere, assicurati di avere: + +- [Installato e avviato il motore Docker](https://docs.kurtosis.com/install/#i-install--start-docker) sulla tua macchina locale +- [Installato la CLI di Kurtosis](https://docs.kurtosis.com/install#ii-install-the-cli) (o aggiornata all'ultima versione, se hai già installato la CLI) +- Installato [Node.js](https://nodejs.org/en), [yarn](https://classic.yarnpkg.com/lang/en/docs/install/#mac-stable) e [npx](https://www.npmjs.com/package/npx) (per il tuo ambiente dApp) + +## Creare un'istanza di una rete di test di Ethereum locale {#instantiate-testnet} + +Per avviare una rete di test di Ethereum locale, esegui: + +```python +kurtosis --enclave local-eth-testnet run github.com/kurtosis-tech/eth-network-package +``` + +Nota: questo comando denomina la tua rete: "local-eth-testnet” usando il flag `--enclave`. + +Kurtosis stamperà i passaggi che sta eseguendo "sotto il cofano" mentre lavora per interpretare, convalidare e quindi eseguire le istruzioni. Alla fine, dovresti vedere un output che assomiglia al seguente: + +```python +INFO[2023-04-04T18:09:44-04:00] ====================================================== +INFO[2023-04-04T18:09:44-04:00] || Created enclave: local-eth-testnet || +INFO[2023-04-04T18:09:44-04:00] ====================================================== +Name: local-eth-testnet +UUID: 39372d756ae8 +Status: RUNNING +Creation Time: Tue, 04 Apr 2023 18:09:03 EDT + +========================================= Files Artifacts ========================================= +UUID Name +d4085a064230 cl-genesis-data +1c62cb792e4c el-genesis-data +bd60489b73a7 genesis-generation-config-cl +b2e593fe5228 genesis-generation-config-el +d552a54acf78 geth-prefunded-keys +5f7e661eb838 prysm-password +054e7338bb59 validator-keystore-0 + +========================================== User Services ========================================== +UUID Name Ports Status +e20f129ee0c5 cl-client-0-beacon http: 4000/tcp -> RUNNING + metrics: 5054/tcp -> + tcp-discovery: 9000/tcp -> 127.0.0.1:54263 + udp-discovery: 9000/udp -> 127.0.0.1:60470 +a8b6c926cdb4 cl-client-0-validator http: 5042/tcp -> 127.0.0.1:54267 RUNNING + metrics: 5064/tcp -> +d7b802f623e8 el-client-0 engine-rpc: 8551/tcp -> 127.0.0.1:54253 RUNNING + rpc: 8545/tcp -> 127.0.0.1:54251 + tcp-discovery: 30303/tcp -> 127.0.0.1:54254 + udp-discovery: 30303/udp -> 127.0.0.1:53834 + ws: 8546/tcp -> 127.0.0.1:54252 +514a829c0a84 prelaunch-data-generator-1680646157905431468 STOPPED +62bd62d0aa7a prelaunch-data-generator-1680646157915424301 STOPPED +05e9619e0e90 prelaunch-data-generator-1680646157922872635 STOPPED + +``` + +Congratulazioni! Hai usato Kurtosis per creare un'istanza di una rete di test di Ethereum locale, con un client CL (`lighthouse`) e un client EL (`geth`), tramite Docker. + +### Revisione {#review-instantiate-testnet} + +In questa sezione, hai eseguito un comando che ha indirizzato Kurtosis a usare il [`eth-network-package` ospitato in remoto su GitHub](https://github.com/kurtosis-tech/eth-network-package) per avviare una rete di test di Ethereum locale all'interno di una [Enclave](https://docs.kurtosis.com/advanced-concepts/enclaves/) di Kurtosis. All'interno della tua enclave, troverai sia "file artifact" che "user service". + +I [File Artifacts](https://docs.kurtosis.com/advanced-concepts/files-artifacts/) nella tua enclave includono tutti i dati generati e utilizzati per l'avvio dei client EL e CL. I dati sono stati creati utilizzando il servizio `prelaunch-data-generator` creato da questa [immagine Docker](https://github.com/ethpandaops/ethereum-genesis-generator) + +Gli "user service" mostrano tutti i servizi containerizzati in esecuzione nella tua enclave. Noterai che è stato creato un singolo nodo, con un client EL e un client CL. + +## Connetti il tuo ambiente di sviluppo dApp alla rete di test di Ethereum locale {#connect-your-dapp} + +### Impostazione dell'ambiente di sviluppo della dApp {#set-up-dapp-env} + +Ora che hai una rete di test locale in esecuzione, puoi connettere il tuo ambiente di sviluppo dApp per usare la tua rete di test locale. Il framework Hardhat sarà usato in questa guida per distribuire una dApp di blackjack sulla tua rete di test locale. + +Per impostare il tuo ambiente di sviluppo dApp, clona il repository che contiene la nostra dApp di esempio e installa le sue dipendenze, esegui: + +```python +git clone https://github.com/kurtosis-tech/awesome-kurtosis.git && cd awesome-kurtosis/smart-contract-example && yarn +``` + +La cartella [smart-contract-example](https://github.com/kurtosis-tech/awesome-kurtosis/tree/main/smart-contract-example) usata qui contiene la configurazione tipica per uno sviluppatore di dApp che usa il framework [Hardhat](https://hardhat.org/): + +- [`contracts/`](https://github.com/kurtosis-tech/awesome-kurtosis/tree/main/smart-contract-example/contracts) contiene alcuni semplici smart contract per una dApp di Blackjack +- [`scripts/`](https://github.com/kurtosis-tech/awesome-kurtosis/tree/main/smart-contract-example/scripts) contiene uno script per distribuire un contratto di token sulla tua rete di Ethereum locale +- [`test/`](https://github.com/kurtosis-tech/awesome-kurtosis/tree/main/smart-contract-example/test) contiene un semplice test .js per il tuo contratto di token per confermare che ogni giocatore nella nostra dApp di Blackjack abbia 1000 chip coniate per sé +- [`hardhat.config.ts`](https://github.com/kurtosis-tech/awesome-kurtosis/blob/main/smart-contract-example/hardhat.config.ts) configura la tua installazione di Hardhat + +### Configurare Hardhat per usare la rete di test locale {#configure-hardhat} + +Una volta impostato il tuo ambiente di sviluppo dApp, connetterai Hardhat per usare la rete di test di Ethereum locale generata con Kurtosis. Per fare ciò, sostituisci `<$YOUR_PORT>` nella struct `localnet` del tuo file di configurazione `hardhat.config.ts` con la porta dell'URI RPC restituita da qualsiasi servizio `el-client-`. In questo caso di esempio, la porta sarebbe `64248`. La tua porta sarà diversa. + +Esempio in `hardhat.config.ts`: + +```js +localnet: { +url: 'http://127.0.0.1:<$YOUR_PORT>',// TODO: SOSTITUISCI $YOUR_PORT CON LA PORTA DI UN URI DEL NODO PRODOTTO DAL PACCHETTO DI RETE ETH KURTOSIS + +// Queste sono chiavi private associate a conti di prova prefinanziati creati dal pacchetto eth-network-package +// +accounts: [ + "ef5177cd0b6b21c87db5a0bf35d4084a8a57a9d6a064f86d51ac85f2b873a4e2", + "48fcc39ae27a0e8bf0274021ae6ebd8fe4a0e12623d61464c498900b28feb567", + "7988b3a148716ff800414935b305436493e1f25237a2a03e5eebc343735e2f31", + "b3c409b6b0b3aa5e65ab2dc1930534608239a478106acf6f3d9178e9f9b00b35", + "df9bb6de5d3dc59595bcaa676397d837ff49441d211878c024eabda2cd067c9f", + "7da08f856b5956d40a72968f93396f6acff17193f013e8053f6fbb6c08c194d6", + ], +}, +``` + +Una volta salvato il file, il tuo ambiente di sviluppo dApp Hardhat è ora connesso alla tua rete di test di Ethereum locale! Puoi verificare che la tua rete di test funzioni eseguendo: + +```python +npx hardhat balances --network localnet +``` + +L'output dovrebbe essere simile a questo: + +```python +0x878705ba3f8Bc32FCf7F4CAa1A35E72AF65CF766 has balance 10000000000000000000000000 +0x4E9A3d9D1cd2A2b2371b8b3F489aE72259886f1A has balance 10000000000000000000000000 +0xdF8466f277964Bb7a0FFD819403302C34DCD530A has balance 10000000000000000000000000 +0x5c613e39Fc0Ad91AfDA24587e6f52192d75FBA50 has balance 10000000000000000000000000 +0x375ae6107f8cC4cF34842B71C6F746a362Ad8EAc has balance 10000000000000000000000000 +0x1F6298457C5d76270325B724Da5d1953923a6B88 has balance 10000000000000000000000000 +``` + +Questo conferma che Hardhat sta usando la tua rete di test locale e rileva i conti pre-finanziati creati dal `eth-network-package`. + +### Distribuire e testare la tua dApp localmente {#deploy-and-test-dapp} + +Con l'ambiente di sviluppo dApp completamente connesso alla rete di test di Ethereum locale, puoi ora eseguire flussi di lavoro di sviluppo e test sulla tua dApp usando la rete di test locale. + +Per compilare e distribuire lo smart contract `ChipToken.sol` per la prototipazione e lo sviluppo locali, esegui: + +```python +npx hardhat compile +npx hardhat run scripts/deploy.ts --network localnet +``` + +L'output dovrebbe essere simile a: + +```python +ChipToken distribuito a: 0xAb2A01BC351770D09611Ac80f1DE076D56E0487d +``` + +Ora prova a eseguire il test `simple.js` sulla tua dApp locale per confermare che ogni giocatore nella nostra dApp di Blackjack abbia 1000 chip coniate per sé: + +L'output dovrebbe essere simile a questo: + +```python +npx hardhat test --network localnet +``` + +L'output dovrebbe essere simile a questo: + +```python +ChipToken + mint + ✔ dovrebbe coniare 1000 chip per GIOCATORE UNO + + 1 superato (654ms) +``` + +### Revisione {#review-dapp-workflows} + +A questo punto, hai impostato un ambiente di sviluppo dApp, l'hai connesso a una rete Ethereum locale creata da Kurtosis, e hai compilato, distribuito ed eseguito un semplice test sulla tua dApp. + +Ora esploriamo come puoi configurare la rete sottostante per testare le nostre dApp con diverse configurazioni di rete. + +## Configurazione della rete di test di Ethereum locale {#configure-testnet} + +### Modifica delle configurazioni del client e del numero di nodi {#configure-client-config-and-num-nodes} + +La tua rete di test di Ethereum locale può essere configurata per usare diverse coppie di client EL e CL, così come un numero variabile di nodi, a seconda dello scenario e della configurazione di rete specifica che vuoi sviluppare o testare. Ciò significa che, una volta impostata, puoi avviare una rete di test locale personalizzata e usarla per eseguire gli stessi flussi di lavoro (distribuzione, test, ecc.) con varie configurazioni di rete per assicurarti che tutto funzioni come previsto. Per saperne di più sugli altri parametri che puoi modificare, visita questo link. + +Fai una prova! Puoi passare varie opzioni di configurazione al `eth-network-package` tramite un file JSON. Questo file JSON di parametri di rete fornisce le configurazioni specifiche che Kurtosis userà per impostare la rete Ethereum locale. + +Prendi il file di configurazione predefinito e modificalo per avviare tre nodi con diverse coppie EL/CL: + +- Nodo 1 con `geth`/`lighthouse` +- Nodo 2 con `geth`/`lodestar` +- Nodo 3 con `geth`/`teku` + +Questa configurazione crea una rete eterogenea di implementazioni di nodi di Ethereum per testare la tua dApp. Il tuo file di configurazione dovrebbe ora essere simile a: + +```yaml +{ + "participants": + [ + { + "el_client_type": "geth", + "el_client_image": "", + "el_client_log_level": "", + "cl_client_type": "lighthouse", + "cl_client_image": "", + "cl_client_log_level": "", + "beacon_extra_params": [], + "el_extra_params": [], + "validator_extra_params": [], + "builder_network_params": null, + }, + { + "el_client_type": "geth", + "el_client_image": "", + "el_client_log_level": "", + "cl_client_type": "lodestar", + "cl_client_image": "", + "cl_client_log_level": "", + "beacon_extra_params": [], + "el_extra_params": [], + "validator_extra_params": [], + "builder_network_params": null, + }, + { + "el_client_type": "geth", + "el_client_image": "", + "el_client_log_level": "", + "cl_client_type": "teku", + "cl_client_image": "", + "cl_client_log_level": "", + "beacon_extra_params": [], + "el_extra_params": [], + "validator_extra_params": [], + "builder_network_params": null, + }, + ], + "network_params": + { + "preregistered_validator_keys_mnemonic": "giant issue aisle success illegal bike spike question tent bar rely arctic volcano long crawl hungry vocal artwork sniff fantasy very lucky have athlete", + "num_validator_keys_per_node": 64, + "network_id": "3151908", + "deposit_contract_address": "0x4242424242424242424242424242424242424242", + "seconds_per_slot": 12, + "genesis_delay": 120, + "capella_fork_epoch": 5, + }, +} +``` + +Ogni struct `participants` corrisponde a un nodo nella rete, quindi 3 struct `participants` diranno a Kurtosis di avviare 3 nodi nella tua rete. Ogni struct `participants` ti permetterà di specificare la coppia EL e CL usata per quel nodo specifico. + +La struct `network_params` configura le impostazioni di rete usate per creare i file di genesi per ogni nodo, così come altre impostazioni come i secondi per slot della rete. + +Salva il tuo file di parametri modificato in qualsiasi directory tu voglia (nell'esempio seguente, è salvato sul desktop) e poi usalo per eseguire il tuo pacchetto Kurtosis eseguendo: + +```python +kurtosis clean -a && kurtosis run --enclave local-eth-testnet github.com/kurtosis-tech/eth-network-package "$(cat ~/eth-network-params.json)" +``` + +Nota: il comando `kurtosis clean -a` è usato qui per istruire Kurtosis a distruggere la vecchia rete di test e i suoi contenuti prima di avviarne una nuova. + +Di nuovo, Kurtosis lavorerà per un po' e stamperà i singoli passaggi che si stanno verificando. Alla fine, l'output dovrebbe essere simile a: + +```python +Starlark code successfully run. No output was returned. +INFO[2023-04-07T11:43:16-04:00] ========================================================== +INFO[2023-04-07T11:43:16-04:00] || Created enclave: local-eth-testnet || +INFO[2023-04-07T11:43:16-04:00] ========================================================== +Name: local-eth-testnet +UUID: bef8c192008e +Status: RUNNING +Creation Time: Fri, 07 Apr 2023 11:41:58 EDT + +========================================= Files Artifacts ========================================= +UUID Name +cc495a8e364a cl-genesis-data +7033fcdb5471 el-genesis-data +a3aef43fc738 genesis-generation-config-cl +8e968005fc9d genesis-generation-config-el +3182cca9d3cd geth-prefunded-keys +8421166e234f prysm-password +d9e6e8d44d99 validator-keystore-0 +23f5ba517394 validator-keystore-1 +4d28dea40b5c validator-keystore-2 + +========================================== User Services ========================================== +UUID Name Ports Status +485e6fde55ae cl-client-0-beacon http: 4000/tcp -> http://127.0.0.1:65010 RUNNING + metrics: 5054/tcp -> http://127.0.0.1:65011 + tcp-discovery: 9000/tcp -> 127.0.0.1:65012 + udp-discovery: 9000/udp -> 127.0.0.1:54455 +73739bd158b2 cl-client-0-validator http: 5042/tcp -> 127.0.0.1:65016 RUNNING + metrics: 5064/tcp -> http://127.0.0.1:65017 +1b0a233cd011 cl-client-1-beacon http: 4000/tcp -> 127.0.0.1:65021 RUNNING + metrics: 8008/tcp -> 127.0.0.1:65023 + tcp-discovery: 9000/tcp -> 127.0.0.1:65024 + udp-discovery: 9000/udp -> 127.0.0.1:56031 + validator-metrics: 5064/tcp -> 127.0.0.1:65022 +949b8220cd53 cl-client-1-validator http: 4000/tcp -> 127.0.0.1:65028 RUNNING + metrics: 8008/tcp -> 127.0.0.1:65030 + tcp-discovery: 9000/tcp -> 127.0.0.1:65031 + udp-discovery: 9000/udp -> 127.0.0.1:60784 + validator-metrics: 5064/tcp -> 127.0.0.1:65029 +c34417bea5fa cl-client-2 http: 4000/tcp -> 127.0.0.1:65037 RUNNING + metrics: 8008/tcp -> 127.0.0.1:65035 + tcp-discovery: 9000/tcp -> 127.0.0.1:65036 + udp-discovery: 9000/udp -> 127.0.0.1:63581 +e19738e6329d el-client-0 engine-rpc: 8551/tcp -> 127.0.0.1:64986 RUNNING + rpc: 8545/tcp -> 127.0.0.1:64988 + tcp-discovery: 30303/tcp -> 127.0.0.1:64987 + udp-discovery: 30303/udp -> 127.0.0.1:55706 + ws: 8546/tcp -> 127.0.0.1:64989 +e904687449d9 el-client-1 engine-rpc: 8551/tcp -> 127.0.0.1:64993 RUNNING + rpc: 8545/tcp -> 127.0.0.1:64995 + tcp-discovery: 30303/tcp -> 127.0.0.1:64994 + udp-discovery: 30303/udp -> 127.0.0.1:58096 + ws: 8546/tcp -> 127.0.0.1:64996 +ad6f401126fa el-client-2 engine-rpc: 8551/tcp -> 127.0.0.1:65003 RUNNING + rpc: 8545/tcp -> 127.0.0.1:65001 + tcp-discovery: 30303/tcp -> 127.0.0.1:65000 + udp-discovery: 30303/udp -> 127.0.0.1:57269 + ws: 8546/tcp -> 127.0.0.1:65002 +12d04a9dbb69 prelaunch-data-generator-1680882122181135513 STOPPED +5b45f9c0504b prelaunch-data-generator-1680882122192182847 STOPPED +3d4aaa75e218 prelaunch-data-generator-1680882122201668972 STOPPED +``` + +Congratulazioni! Hai configurato con successo la tua rete di test locale per avere 3 nodi invece di 1. Per eseguire gli stessi flussi di lavoro di prima sulla tua dApp (distribuzione e test), esegui le stesse operazioni che abbiamo fatto prima sostituendo `<$YOUR_PORT>` nella struct `localnet` del tuo file di configurazione `hardhat.config.ts` con la porta dell'URI RPC restituita da qualsiasi servizio `el-client-` nella tua nuova rete di test locale a 3 nodi. + +## Conclusione {#conclusion} + +E questo è tutto! Per ricapitolare questa breve guida, hai: + +- Creato una rete di test di Ethereum locale su Docker usando Kurtosis +- Connesso il tuo ambiente di sviluppo dApp locale alla rete Ethereum locale +- Distribuito una dApp ed eseguito un semplice test su di essa sulla rete Ethereum locale +- Configurato la rete Ethereum sottostante per avere 3 nodi + +Ci piacerebbe sapere cosa è andato bene per te, cosa potrebbe essere migliorato, o rispondere a qualsiasi tua domanda. Non esitare a contattarci tramite [GitHub](https://github.com/kurtosis-tech/kurtosis/issues/new/choose) o [inviaci un'email](mailto:feedback@kurtosistech.com)! + +### Altri esempi e guide {#other-examples-guides} + +Ti invitiamo a consultare la nostra [guida rapida](https://docs.kurtosis.com/quickstart) (dove creerai un database Postgres e un'API) e i nostri altri esempi nel nostro [repository awesome-kurtosis](https://github.com/kurtosis-tech/awesome-kurtosis) dove troverai alcuni ottimi esempi, inclusi pacchetti per: + +- Avviare la stessa rete di test di Ethereum locale, ma con servizi aggiuntivi connessi come uno spammer di transazioni (per simulare le transazioni), un monitor di biforcazioni e un'istanza connessa di Grafana e Prometheus +- Eseguire un test di sotto-rete sulla stessa rete Ethereum locale diff --git a/public/content/translations/it/developers/tutorials/downsizing-contracts-to-fight-the-contract-size-limit/index.md b/public/content/translations/it/developers/tutorials/downsizing-contracts-to-fight-the-contract-size-limit/index.md index 678ebb5d566..6471d20d300 100644 --- a/public/content/translations/it/developers/tutorials/downsizing-contracts-to-fight-the-contract-size-limit/index.md +++ b/public/content/translations/it/developers/tutorials/downsizing-contracts-to-fight-the-contract-size-limit/index.md @@ -1,12 +1,9 @@ --- title: "Ridimensionare i contratti per combattere i limiti di dimensioni" -description: Cosa puoi fare per impedire che i tuoi smart contract diventino troppo grandi? +description: Cosa puoi fare per impedire che i tuoi contratti intelligenti diventino troppo grandi? author: Markus Waas lang: it -tags: - - "solidity" - - "contratti intelligenti" - - "archiviazione" +tags: [ "Solidity", "smart contract", "archiviazione" ] skill: intermediate published: 2020-06-26 source: soliditydeveloper.com @@ -15,33 +12,33 @@ sourceUrl: https://soliditydeveloper.com/max-contract-size ## Perché c'è un limite? {#why-is-there-a-limit} -Il [22 Novembre 2016](https://blog.ethereum.org/2016/11/18/hard-fork-no-4-spurious-dragon/), la diramazione permanente Spurious Dragon ha introdotto [EIP-170](https://eips.ethereum.org/EIPS/eip-170), che ha aggiunto un limite di dimensioni per gli smart contract di 24.576 kb. Per gli sviluppatori in Solidity, significa che quando si aggiungono più funzionalità al contratto, a un certo punto si raggiunge il limite e, in fase di implementazione, si vedrà l'errore: +Il [22 novembre 2016](https://blog.ethereum.org/2016/11/18/hard-fork-no-4-spurious-dragon/) l'hard-fork Spurious Dragon ha introdotto l'[EIP-170](https://eips.ethereum.org/EIPS/eip-170) che ha aggiunto un limite di dimensione per i contratti intelligenti di 24.576 kb. Per te, come sviluppatore Solidity, questo significa che quando aggiungi sempre più funzionalità al tuo contratto, a un certo punto raggiungerai il limite e durante la distribuzione vedrai l'errore: -`Attenzione: La dimensione del codice del contratto eccede i 24576 byte (un limite introdotto in Spurious Dragon). This contract may not be deployable on Mainnet. Considera di abilitare l'ottimizzatore (con un valore di "esecuzioni" basso!), disattivare le stringhe di ripristino o usare le librerie.` +`Attenzione: La dimensione del codice del contratto eccede i 24576 byte (un limite introdotto in Spurious Dragon).` Questo contratto potrebbe non essere distribuibile sulla Rete Principale. `Considera di abilitare l'ottimizzatore (con un valore di "esecuzioni" basso!), disattivare le stringhe di ripristino o usare le librerie.` -Questo limite è stato introdotto per prevenire gli attacchi DOS (denial-of-service). Qualsiasi chiamata a un contratto è relativamente economica in termini di gas. Tuttavia, l'impatto della chiamata di un contratto per i nodi di Ethereum aumenta sproporzionatamente in base alla dimensione del codice del contratto chiamato (lettura del codice dal disco, pre-elaborazione del codice, aggiunta di dati alla prova di Merkle). Ogni volta che ti trovi in una situazione in cui il malintenzionato richiede poche risorse per causare molto lavoro per altri, esiste il potenziale di attacchi DOS. +Questo limite è stato introdotto per prevenire gli attacchi denial-of-service (DOS). Qualsiasi chiamata a un contratto è relativamente economica in termini di gas. Tuttavia, l'impatto della chiamata di un contratto per i nodi di Ethereum aumenta sproporzionatamente in base alla dimensione del codice del contratto chiamato (lettura del codice dal disco, pre-elaborazione del codice, aggiunta di dati alla prova di Merkle). Ogni volta che ti trovi in una situazione in cui l'aggressore richiede poche risorse per causare molto lavoro per altri, si crea il potenziale di attacchi DOS. -In origine, questo era un problema minore, dato che il limite naturale di dimensioni del contratto è il limite di gas del blocco. Ovviamente, un contratto dev'esser distribuito entro una transazione che detenga tutto il codice del byte del contratto. Se includi solo quella transazione in un blocco, puoi usare anche tutto il gas, ma non è infinito. Dall'[Aggiornamento di Londra](/ethereum-forks/#london), il limite di gas del blocco è stato capace di variare tra le 15M e le 30M unità, a seconda della domanda di rete. +In origine, questo era un problema minore, dato che il limite naturale di dimensioni del contratto è il limite del gas del blocco. Ovviamente, un contratto deve essere distribuito all'interno di una transazione che contenga tutto il bytecode del contratto. Se includi solo quella transazione in un blocco, puoi usare tutto quel gas, ma non è infinito. Dall'[Aggiornamento London](/ethereum-forks/#london), il limite del gas del blocco ha potuto variare tra 15M e 30M di unità a seconda della domanda della rete. -Di seguito, passeremo in rassegna alcuni metodi, ordinati in base al loro impatto potenziale. Pensiamo ad esempio alla perdita di peso: la strategia migliore per raggiungere il proprio peso target (nel nostro caso 24kb) consiste nel concentrarsi prima sui metodi a maggiore impatto. In gran parte dei casi è sufficiente adattare la propria dieta, mentre in altri serve qualcosa di più. Si può aggiungere un po' di esercizio fisico (impatto medio) o persino degli integratori (impatto ridotto). +Di seguito, passeremo in rassegna alcuni metodi, ordinati in base al loro impatto potenziale. Pensiamolo nei termini di perdita di peso. La strategia migliore per qualcuno per raggiungere il peso target (nel nostro caso 24kb) è concentrarsi prima sui metodi a grande impatto. Nella maggior parte dei casi, è sufficiente correggere la propria dieta, ma a volte è necessario qualcosa in più. Potresti allora aggiungere un po' di esercizio (impatto medio) o persino degli integratori (impatto ridotto). -## Impatto elevato {#big-impact} +## Grande impatto {#big-impact} ### Separa i tuoi contratti {#separate-your-contracts} -Questo dovrebbe sempre essere l'approccio preferenziale. Come fare per separare un unico contratto in diversi contratti più piccoli? Generalmente è necessario trovare un'architettura efficace per i propri contratti. I contratti più piccoli sono sempre preferibili a livello di leggibilità del codice. Per dividere i contratti, chiediti: +Questo dovrebbe sempre essere il tuo primo approccio. Come puoi separare il contratto in più contratti più piccoli? Generalmente ti costringe a pensare a una buona architettura per i tuoi contratti. I contratti più piccoli sono sempre preferibili a livello di leggibilità del codice. Per dividere i contratti, chiediti: -- Quali funzioni devono rimanere insieme? Ogni serie di funzioni potrebbe risultare più efficace in un contratto a sé stante. +- Quali funzioni devono rimanere insieme? Ogni insieme di funzioni potrebbe risultare più efficace in un contratto a sé stante. - Quali funzioni non richiedono la lettura dello stato del contratto o solo un sottoinsieme specifico dello stato? - Puoi dividere archiviazione e funzionalità? ### Librerie {#libraries} -Un modo semplice per togliere il codice di funzionalità dall'archiviazione consiste nell'utilizzare una [libreria](https://solidity.readthedocs.io/en/v0.6.10/contracts.html#libraries). Evita di dichiarare le funzioni della libreria come interne, poiché verranno [aggiunte al contratto](https://ethereum.stackexchange.com/questions/12975/are-internal-functions-in-libraries-not-covered-by-linking) direttamente durante la compilazione. Se invece usi funzioni pubbliche, queste si troveranno nel contratto di una libreria separata. Considera [using for](https://solidity.readthedocs.io/en/v0.6.10/contracts.html#using-for) per rendere l'utilizzo delle librerie più pratico. +Un modo semplice per spostare il codice delle funzionalità lontano dall'archiviazione è usare una [libreria](https://solidity.readthedocs.io/en/v0.6.10/contracts.html#libraries). Non dichiarare le funzioni della libreria come `internal` poiché verranno [aggiunte direttamente al contratto](https://ethereum.stackexchange.com/questions/12975/are-internal-functions-in-libraries-not-covered-by-linking) durante la compilazione. Ma se usi funzioni `public`, allora queste si troveranno di fatto in un contratto di libreria separato. Considera di usare [`using for`](https://solidity.readthedocs.io/en/v0.6.10/contracts.html#using-for) per rendere più comodo l'uso delle librerie. ### Proxy {#proxies} -Una strategia più avanzata è il sistema proxy. Le librerie usano `DELEGATECALL` in background, che esegue semplicemente la funzione di un altro contratto con lo stato del contratto chiamante. Dai un'occhiata a [questo post del blog](https://hackernoon.com/how-to-make-smart-contracts-upgradable-2612e771d5a2) per scoprire di più sui sistemi proxy. Offono maggiore funzionalità, ad es. consentono l'aggiornabilità ma aggiungono anche una notevole complessità. Non li aggiungerei solo per ridurre le dimensioni del contratto, a meno che non sia la sola opzione per qualche motivo. +Una strategia più avanzata sarebbe un sistema proxy. Le librerie usano `DELEGATECALL` dietro le quinte, che esegue semplicemente la funzione di un altro contratto con lo stato del contratto chiamante. Consulta [questo post del blog](https://hackernoon.com/how-to-make-smart-contracts-upgradable-2612e771d5a2) per saperne di più sui sistemi proxy. Offrono più funzionalità, ad esempio, abilitano l'aggiornabilità, ma aggiungono anche molta complessità. Non li aggiungerei solo per ridurre le dimensioni del contratto, a meno che non sia la sola opzione per qualche motivo. ## Impatto medio {#medium-impact} @@ -49,12 +46,10 @@ Una strategia più avanzata è il sistema proxy. Le librerie usano `DELEGATECALL Questo punto dovrebbe essere ovvio. Le funzioni aumentano di un bel po' le dimensioni di un contratto. -- **Esterne**: talvolta aggiungiamo molte funzioni di visualizzazione per motivi di comodità, il che va perfettamente bene finché non si supera il limite di dimensioni. A quel punto si potrebbe seriamente pensare di rimuovere tutte le funzioni tranne quelle essenziali. -- **Interne**: puoi rimuovere anche le funzioni interne/private e limitarti a mettere il codice in linea, a condizione che la funzione venga chiamata solo una volta. +- **Esterne**: spesso aggiungiamo molte funzioni `view` per motivi di comodità. Va benissimo finché non raggiungi il limite di dimensione. A quel punto potresti voler davvero pensare di rimuovere tutte quelle non assolutamente essenziali. +- **Interne**: puoi anche rimuovere le funzioni `internal`/`private` e semplicemente mettere il codice in linea, a patto che la funzione sia chiamata solo una volta. -### Evita le variabili aggiuntive {#avoid-additional-variables} - -Una semplice modifica come questa: +### Evita variabili aggiuntive {#avoid-additional-variables} ```solidity function get(uint id) returns (address,address) { @@ -69,15 +64,14 @@ function get(uint id) returns (address,address) { } ``` -crea una differenza di **0,28kb**. È facile incontrare numerose situazioni simili nei propri contratti, con il rischio che si sommino fino a raggiungere volumi significativi. +Un semplice cambiamento come questo fa una differenza di **0,28kb**. È probabile che tu possa trovare molte situazioni simili nei tuoi contratti, e queste possono davvero sommarsi fino a raggiungere importi significativi. -### Abbrevia i messaggi d'errore {#shorten-error-message} +### Accorcia i messaggi di errore {#shorten-error-message} -I messaggi di ripristino lunghi e, in particolare, la presenza di numerosi messaggi diversi possono fare espandere il contratto. Invece, è meglio usare brevi codici d'errore e decodificali nel contratto. In questo modo è possibile rendere brevi i messaggi più lunghi: +I lunghi messaggi di ripristino e, in particolare, molti messaggi di ripristino diversi, possono gonfiare il contratto. Usa invece codici di errore brevi e decodificali nel tuo contratto. Un messaggio lungo potrebbe diventare molto più corto: ```solidity -require(msg.sender == owner, "Only the owner of this contract can call this function"); - +require(msg.sender == owner, "Solo il proprietario di questo contratto può chiamare questa funzione"); ``` ```solidity @@ -86,7 +80,7 @@ require(msg.sender == owner, "OW1"); ### Utilizza gli errori personalizzati invece dei messaggi d'errore -Gli errori personalizzati sono stati introdotti in [Solidity 0.8.4](https://blog.soliditylang.org/2021/04/21/custom-errors/). Sono ottimi modi per ridurre le dimensioni dei tuoi contratti, poiché sono codificati in ABI come selettori (proprio come le funzioni). +Gli errori personalizzati sono stati introdotti in [Solidity 0.8.4](https://blog.soliditylang.org/2021/04/21/custom-errors/). Sono un ottimo modo per ridurre le dimensioni dei tuoi contratti, perché sono codificati in ABI come selettori (proprio come le funzioni). ```solidity error Unauthorized(); @@ -96,15 +90,15 @@ if (msg.sender != owner) { } ``` -### Considera un valore d'esecuzione basso nell'ottimizzatore {#consider-a-low-run-value-in-the-optimizer} +### Considera un valore di esecuzione basso nell'ottimizzatore {#consider-a-low-run-value-in-the-optimizer} -Puoi anche cambiare le impostazioni dell'ottimizzatore. Il valore predefinito di 200 significa che sta provando a ottimizzare il bytecode come se una funzione fosse chiamata 200 volte. Se lo modifichi a 1, fondamentalmente dici all'ottimizzatore di ottimizzare nel caso dell'esecuzione di ogni funzione una sola volta. Una funzione ottimizzata per essere eseguita solo una volta è ottimizzata per la distribuzione stessa. Sappi che **ciò aumenta i [costi del gas](/developers/docs/gas/) per l'esecuzione delle funzioni**, quindi meglio non farlo. +Puoi anche cambiare le impostazioni dell'ottimizzatore. Il valore predefinito di 200 significa che sta provando a ottimizzare il bytecode come se una funzione fosse chiamata 200 volte. Se lo modifichi a 1, fondamentalmente dici all'ottimizzatore di ottimizzare nel caso dell'esecuzione di ogni funzione una sola volta. Una funzione ottimizzata per essere eseguita solo una volta significa che è ottimizzata per la distribuzione stessa. Sappi che **questo aumenta i [costi del gas](/developers/docs/gas/) per l'esecuzione delle funzioni**, quindi potresti non volerlo fare. -## Piccolo impatto {#small-impact} +## Impatto ridotto {#small-impact} -### Evita il passaggio di struct alle funzioni {#avoid-passing-structs-to-functions} +### Evita di passare struct alle funzioni {#avoid-passing-structs-to-functions} -Se utilizzi l'[ABIEncoderV2](https://solidity.readthedocs.io/en/v0.6.10/layout-of-source-files.html#abiencoderv2), può essere utile evitare il passaggio di struct a una funzione. Anziché passare il parametro come struct... +Se usi l'[ABIEncoderV2](https://solidity.readthedocs.io/en/v0.6.10/layout-of-source-files.html#abiencoderv2), può essere d'aiuto non passare `struct` a una funzione. Invece di passare il parametro come una `struct`, passa direttamente i parametri richiesti. In questo esempio abbiamo risparmiato altri **0,1kb**. ```solidity function get(uint id) returns (address,address) { @@ -126,12 +120,10 @@ function _get(address addr1, address addr2) private view returns(address,address } ``` -... passa direttamente i parametri richiesti. In questo esempio abbiamo risparmiato altri **0,1kb**. - ### Dichiara la visibilità corretta per funzioni e variabili {#declare-correct-visibility-for-functions-and-variables} -- Funzioni o variabili chiamate solo dall'esterno? Dichiarale come `external` anziché `public`. -- Funzioni o variabili chiamate dall'interno del contratto? Dichiarale come `private` o `internal` anziché `public`. +- Funzioni o variabili chiamate solo dall'esterno? Dichiarale come `external` invece che `public`. +- Funzioni o variabili chiamate dall'interno del contratto? Dichiarale come `private` o `internal` invece che `public`. ### Rimuovi i modificatori {#remove-modifiers} diff --git a/public/content/translations/it/developers/tutorials/eip-1271-smart-contract-signatures/index.md b/public/content/translations/it/developers/tutorials/eip-1271-smart-contract-signatures/index.md index a2fc674b14f..3a4bd8f0038 100644 --- a/public/content/translations/it/developers/tutorials/eip-1271-smart-contract-signatures/index.md +++ b/public/content/translations/it/developers/tutorials/eip-1271-smart-contract-signatures/index.md @@ -3,18 +3,14 @@ title: "EIP-1271: firmare e verificare le firme dei contratti intelligenti" description: Una panoramica della generazione e della verifica delle firme dei contratti intelligenti con EIP-1271. Rivediamo anche l'implementazione di EIP-1271 utilizzata in Safe (precedentemente Gnosis Safe) per fornire un esempio concreto agli sviluppatori di contratti intelligenti su cui costruire. author: Nathan H. Leung lang: it -tags: - - "eip-1271" - - "contratti intelligenti" - - "verifica" - - "firma" +tags: [ "eip-1271", "Smart Contract", "verifica", "firma" ] skill: intermediate published: 2023-01-12 --- -Lo standard [EIP-1271](https://eips.ethereum.org/EIPS/eip-1271) permette ai contratti intelligenti di verificare le firme. +Lo standard [EIP-1271](https://eips.ethereum.org/EIPS/eip-1271) consente ai contratti intelligenti di verificare le firme. -In questo tutorial diamo una panoramica delle firme digitali, conoscenze di base su EIP-1271 e l'implementazione specifica di EIP-1271 utilizzata da [Safe](https://safe.global/) (precedentemente Gnosis Safe). Tutto ciò può servire come punto di partenza per implementare EIP-1271 nei tuoi contratti. +In questa guida, forniamo una panoramica delle firme digitali, del contesto di EIP-1271 e dell'implementazione specifica di EIP-1271 usata da [Safe](https://safe.global/) (precedentemente Gnosis Safe). Tutto ciò può servire come punto di partenza per implementare EIP-1271 nei tuoi contratti. ## Che cos'è una firma? @@ -24,7 +20,7 @@ Ad esempio, una firma digitale potrebbe essere così: 1. Messaggio: "Voglio accedere a questo sito web con il mio portafoglio di Ethereum." 2. Firmatario: Il mio indirizzo è `0x000…` -3. Prova: Qui c'è una prova che io, `0x000…`, ho effettivamente creato questo intero messaggio (questo di solito è qualcosa di crittografico). +3. Prova: ecco una prova che io, `0x000…`, ho effettivamente creato questo intero messaggio (di solito è qualcosa di crittografico). È importante notare che una firma digitale include sia un "messaggio" che una "firma". @@ -36,11 +32,11 @@ Allo stesso modo una firma digitale non significa nulla senza un messaggio a ess Per creare una firma digitale che possa essere utilizzata su una blockchain basata su Ethereum, in linea generale si ha bisogno di una chiave privata che nessun altro conosca. Questo è ciò che rende tua la tua firma (nessun altro può creare la stessa firma senza sapere la chiave segreta). -Il tuo conto di Ethereum (ovvero il tuo conto posseduto esternamente/EOA) ha una chiave privata associata, e questa è la chiave privata che tipicamente viene utilizzata quando un sito web o una dApp chiede la tua firma (ad es. per "Accedi con Ethereum"). +Il tuo account Ethereum (ossia, il tuo account di proprietà esterna/EOA) ha una chiave privata associata, e questa è la chiave privata che viene tipicamente usata quando un sito web o una dApp ti chiede una firma (ad es., per "Accedi con Ethereum"). -Un'app può [verificare una firma](https://docs.alchemy.com/docs/how-to-verify-a-message-signature-on-ethereum) creata usando una libreria esterna come ether.js [senza conoscere la tua chiave privata](https://en.wikipedia.org/wiki/Public-key_cryptography) ed essere sicura che _tu_ sia la persona che ha generato la firma. +Un'app può [verificare una firma](https://www.alchemy.com/docs/how-to-verify-a-message-signature-on-ethereum) che crei usando una libreria di terze parti come ethers.js [senza conoscere la tua chiave privata](https://en.wikipedia.org/wiki/Public-key_cryptography) ed essere sicura che sia stato proprio _tu_ a creare la firma. -> Infatti siccome le firme digitali degli EOA utilizzano una crittografia a chiave pubblica, possono essere generate e verificate **fuori dalla catena**! Così funziona la votazione senza gas nelle DAO: invece di inviare voti sulla catena, le firme digitali possono creare e verificare fuori dalla catena utilizzando librerie crittografiche. +> Infatti, poiché le firme digitali EOA usano la crittografia a chiave pubblica, possono essere generate e verificate **fuori dalla catena**! Ecco come funziona il voto DAO senza gas: invece di inviare i voti sulla catena, le firme digitali possono essere create e verificate fuori dalla catena usando librerie crittografiche. Mentre i conti EOA hanno una chiave privata, i conti dei contratti intelligenti non hanno alcun tipo di chiave privata o segreta (quindi "Accedi con Ethereum", e simili non possono funzionare nativamente con i conti dei contratti intelligenti). @@ -50,17 +46,17 @@ Il problema che EIP-1271 si pone di risolvere: come possiamo essere sicuri che l I contratti intelligenti non hanno chiavi private che possano essere usate per firmare i messaggi. Quindi come possiamo sapere se una firma è autentica? -Un'idea è che possiamo semplicemente _chiedere_ al contratto intelligente se una firma è autentica! +Beh, un'idea è che possiamo semplicemente _chiedere_ al contratto intelligente se una firma è autentica! Quello che fa EIP-1271 è standardizzare l'idea di "chiedere" a un contratto intelligente se una data firma sia valida. -Un contratto che implementa EIP-1271 deve avere una funzione chiamata `isValidSignature` che accetti un messaggio e una firma. Il contratto può quindi eseguire qualche logica di validazione (le specifiche non impongono nulla di specifico qui) e restituire un valore che indica se la firma sia valida o meno. +Un contratto che implementa EIP-1271 deve avere una funzione chiamata `isValidSignature` che accetta un messaggio e una firma. Il contratto può quindi eseguire qualche logica di validazione (le specifiche non impongono nulla di specifico qui) e restituire un valore che indica se la firma sia valida o meno. -Se `isValidSignature` restituisce un risultato valido, significa che il contratto sta dicendo "sì, approvo questa firma + messaggio!" +Se `isValidSignature` restituisce un risultato valido, è come se il contratto dicesse "sì, approvo questa firma + messaggio!" ### Interfaccia -Ecco l'interfaccia esatta presente nelle specifiche EIP-1271 (parleremo del parametro `_hash` più avanti, ma per adesso, puoi pensarlo come il messaggio che viene verificato): +Ecco l'interfaccia esatta nelle specifiche EIP-1271 (parleremo del parametro `_hash` più avanti, ma per ora, consideralo come il messaggio che viene verificato): ```jsx pragma solidity ^0.5.0; @@ -71,13 +67,13 @@ contract ERC1271 { bytes4 constant internal MAGICVALUE = 0x1626ba7e; /** - * @dev Should return whether the signature provided is valid for the provided hash - * @param _hash Hash of the data to be signed - * @param _signature Signature byte array associated with _hash + * @dev Dovrebbe restituire se la firma fornita è valida per l'hash fornito + * @param _hash Hash dei dati da firmare + * @param _signature Array di byte della firma associato a _hash * - * MUST return the bytes4 magic value 0x1626ba7e when function passes. - * MUST NOT modify state (using STATICCALL for solc < 0.5, view modifier for solc > 0.5) - * MUST allow external calls + * DEVE restituire il valore magico bytes4 0x1626ba7e quando la funzione passa. + * NON DEVE modificare lo stato (usando STATICCALL per solc < 0.5, modificatore view per solc > 0.5) + * DEVE consentire chiamate esterne */ function isValidSignature( bytes32 _hash, @@ -90,28 +86,28 @@ contract ERC1271 { ## Esempio di implementazione di EIP-1271: Safe -I contratti possono implementare `isValidSignature` in diversi modi, le specifiche da sole non dicono molto riguardo l'esatta implementazione. +I contratti possono implementare `isValidSignature` in molti modi: la specifica non dice molto sull'implementazione esatta. Un contratto degno di nota che implementa EIP-1271 è Safe (precedentemente Gnosis Safe). -Nel codice di Safe, `isValidSignature` [è implementata](https://github.com/safe-global/safe-contracts/blob/main/contracts/handler/CompatibilityFallbackHandler.sol) in modo che le firme possano essere create e verificate in [due modi](https://ethereum.stackexchange.com/questions/122635/signing-messages-as-a-gnosis-safe-eip1271-support): +Nel codice di Safe, `isValidSignature` [è implementato](https://github.com/safe-global/safe-contracts/blob/main/contracts/handler/CompatibilityFallbackHandler.sol) in modo che le firme possano essere create e verificate in [due modi](https://ethereum.stackexchange.com/questions/122635/signing-messages-as-a-gnosis-safe-eip1271-support): -1. Messaggi on-chain - 1. Creazione: un proprietario sicuro crea una nuova transazione sicura per "firmare" il messaggio, passando il messaggio come dati nella transazione. Quando un numero sufficiente di proprietari firma la transazione per raggiungere la soglia multifirma, la transazione è trasmessa ed eseguita. Nella transazione viene chiamata una funzione sicura che aggiunge il messaggio all'elenco di messaggi "approvati". - 2. Verifica: chiama `isValidSignature` sul contratto di Safe, passando il messaggio da verificare come parametro messaggio e [un valore vuoto per il parametro firma](https://github.com/safe-global/safe-contracts/blob/main/contracts/handler/CompatibilityFallbackHandler.sol#L32) (ossia `0x`). Safe vedrà che il parametro firma è vuoto e invece di verificare in maniera crittografica la firma, saprà di dover andare avanti e controllare se il messaggio si trova nell'elenco di messaggi "approvati". -2. Messaggi off-chain: - 1. Creazione: un proprietario sicuro crea un messaggio off-chain, poi fa in modo che altri proprietari sicuri firmino il messaggio, ognuno individualmente, finché ci sono abbastanza firme per superare la soglia di approvazione multifirma. +1. Messaggi sulla catena + 1. Creazione: un proprietario sicuro crea una nuova transazione sicura per "firmare" il messaggio, passando il messaggio come dati nella transazione. Quando un numero sufficiente di proprietari firma la transazione per raggiungere la soglia multifirma, la transazione è trasmessa ed eseguita. Nella transazione, viene chiamata una funzione di Safe (`signMessage(bytes calldata _data)`) che aggiunge il messaggio a una lista di messaggi "approvati". + 2. Verifica: chiama `isValidSignature` sul contratto Safe e passa il messaggio da verificare come parametro del messaggio e [un valore vuoto per il parametro della firma](https://github.com/safe-global/safe-contracts/blob/main/contracts/handler/CompatibilityFallbackHandler.sol#L32) (ossia, `0x`). Safe vedrà che il parametro firma è vuoto e invece di verificare in maniera crittografica la firma, saprà di dover andare avanti e controllare se il messaggio si trova nell'elenco di messaggi "approvati". +2. Messaggi fuori dalla catena: + 1. Creazione: un proprietario di Safe crea un messaggio fuori dalla catena, poi fa in modo che altri proprietari di Safe firmino il messaggio individualmente finché non ci sono abbastanza firme per superare la soglia di approvazione multisig. 2. Verifica: chiama `isValidSignature`. Nel parametro messaggio, passa il messaggio da verificare. Nel parametro firma, passa ognuna delle firme dei proprietari sicure tutte concatenate, una dietro l'altra. Safe controllerà che ci siano abbastanza firme per raggiungere la soglia **e** che ogni firma sia valida. Se è così, restituirà un valore che indica che la firma è stata verificata con successo. ## Che cos'è esattamente il parametro `_hash`? Perché non passiamo l'intero messaggio? -Potresti aver notato che la funzione `isValidSignature` nell'[interfaccia EIP-1271](https://eips.ethereum.org/EIPS/eip-1271) non prende il messaggio stesso bensì un parametro `_hash`. Questo significa che invece che passare l'intero messaggio di lunghezza arbitraria a `isValidSignature`, passiamo invece un hash di 32-byte del messaggio (generalmente keccak256). +Potresti aver notato che la funzione `isValidSignature` nell'[interfaccia EIP-1271](https://eips.ethereum.org/EIPS/eip-1271) non accetta il messaggio stesso, ma un parametro `_hash`. Questo significa che invece di passare l'intero messaggio di lunghezza arbitraria a `isValidSignature`, passiamo un hash di 32 byte del messaggio (generalmente keccak256). -Ogni byte di calldata – ovvero dati dei parametri della funzione passati a una funzione del contratto intelligente – [costa 16 unità di gas (4 unità di gas se sono zero byte)](https://eips.ethereum.org/EIPS/eip-2028), quindi in questo modo si può risparmiare molto gas se il messaggio è lungo. +Ogni byte di calldata — ossia, i dati dei parametri di funzione passati a una funzione di un contratto intelligente — [costa 16 gas (4 gas se è un byte zero)](https://eips.ethereum.org/EIPS/eip-2028), quindi questo può far risparmiare molto gas se un messaggio è lungo. ### Specifiche precedenti di EIP-1271 -Esistono specifiche di EIP-1271 che hanno la funzione `isValidSignature` con un primo parametro di tipo `bytes` (di lunghezza arbitraria invece che di lunghezza fissa `bytes32`) e un parametro nome `message`. Questa è una [versione precedente](https://github.com/safe-global/safe-contracts/issues/391#issuecomment-1075427206) dello standard EIP-1271. +Esistono in circolazione specifiche EIP-1271 che hanno una funzione `isValidSignature` con un primo parametro di tipo `bytes` (a lunghezza arbitraria, invece di `bytes32` a lunghezza fissa) e con `message` come nome del parametro. Questa è una [versione precedente](https://github.com/safe-global/safe-contracts/issues/391#issuecomment-1075427206) dello standard EIP-1271. ## Come dovrei implementare EIP-1271 nei miei contratti? @@ -122,6 +118,6 @@ La specifica è molto flessibile in merito. L'implementazione di Safe ha alcune Alla fine, dipende da te, in quanto sviluppatore del contratto! -## Conclusioni +## Conclusione [EIP-1271](https://eips.ethereum.org/EIPS/eip-1271) è uno standard versatile che consente ai contratti intelligenti di verificare le firme. Apre la porta perché i contratti intelligenti agiscano in modo più simile agli EOA - ad esempio fornendo un modo per far funzionare "Accedi con Ethereum" con i contratti intelligenti - e può essere implementato in molti modi (Safe ha un'implementazione non banale e interessante da considerare). diff --git a/public/content/translations/it/developers/tutorials/erc-721-vyper-annotated-code/index.md b/public/content/translations/it/developers/tutorials/erc-721-vyper-annotated-code/index.md index 1aa4513316d..ab5aaac02e6 100644 --- a/public/content/translations/it/developers/tutorials/erc-721-vyper-annotated-code/index.md +++ b/public/content/translations/it/developers/tutorials/erc-721-vyper-annotated-code/index.md @@ -1,31 +1,35 @@ --- -title: "Guisa sul Contratto ERC-721 Vyper" +title: "Analisi dettagliata del contratto ERC-721 in Vyper" description: Il contratto ERC-721 di Ryuya Nakamura e come funziona author: Ori Pomerantz lang: it -tags: - - "vyper" - - "erc-721" - - "python" +tags: [ "vyper", "erc-721", "python" ] skill: beginner published: 2021-04-01 --- ## Introduzione {#introduction} -Lo standard [ERC-721](/developers/docs/standards/tokens/erc-721/) è utilizzato per determinare la proprietà di un Token Non Fungibile (NFT). I token [ERC-20](/developers/docs/standards/tokens/erc-20/) si comportano come una commodity, perché non c'è differenza tra i token individuali. Al contrario, i token ERC-721 sono progettati per risorse simili ma non identiche, come diversi [cat cartoon](https://www.cryptokitties.co/) o titoli di diverse proprietà immobiliari. +Lo standard [ERC-721](/developers/docs/standards/tokens/erc-721/) è usato per detenere la proprietà di Token Non Fungibili (NFT). +I token [ERC-20](/developers/docs/standards/tokens/erc-20/) si comportano come una commodity, perché non c'è differenza tra i singoli token. +Al contrario, i token ERC-721 sono progettati per asset simili ma non identici, come diversi cartoni +di gatti o titoli di diverse proprietà immobiliari. -In questo articolo analizzeremo [il contratto ERC-721 di Ryuya Nakamura](https://github.com/vyperlang/vyper/blob/master/examples/tokens/ERC721.vy). Questo contratto è scritto in [Vyper](https://vyper.readthedocs.io/en/latest/index.html), un linguaggio per contratti simile a Python, pensato per rendere più difficile scrivere codice non sicuro rispetto a Solidity. +In questo articolo analizzeremo il [contratto ERC-721 di Ryuya Nakamura](https://github.com/vyperlang/vyper/blob/master/examples/tokens/ERC721.vy). +Questo contratto è scritto in [Vyper](https://vyper.readthedocs.io/en/latest/index.html), un linguaggio per contratti simile a Python, progettato per rendere +più difficile scrivere codice insicuro di quanto lo sia in Solidity. -## Il contratto {#contract} +## Il Contratto {#contract} ```python -# @dev Implementation of ERC-721 non-fungible token standard. +# @dev Implementazione dello standard dei token non fungibili ERC-721. # @author Ryuya Nakamura (@nrryuya) -# Modified from: https://github.com/vyperlang/vyper/blob/de74722bf2d8718cca46902be165f9fe0e3641dd/examples/tokens/ERC721.vy +# Modificato da: https://github.com/vyperlang/vyper/blob/de74722bf2d8718cca46902be165f9fe0e3641dd/examples/tokens/ERC721.vy ``` -I commenti in Vyper, come in Python, iniziano con un hash (`#`) e continuano fino alla fine della riga. I commenti che includono `@` sono usati da [NatSpec](https://vyper.readthedocs.io/en/latest/natspec.html) per produrre una documentazione leggibile. +I commenti in Vyper, come in Python, iniziano con un hash (`#`) e continuano fino alla fine della riga. I commenti che includono +`@` sono utilizzati da [NatSpec](https://vyper.readthedocs.io/en/latest/natspec.html) per produrre documentazione +leggibile. ```python from vyper.interfaces import ERC721 @@ -33,22 +37,28 @@ from vyper.interfaces import ERC721 implements: ERC721 ``` -L'interfaccia ERC-721 è creata nel linguaggio Vyper. [Puoi vedere qui la definizione del codice](https://github.com/vyperlang/vyper/blob/master/vyper/builtin_interfaces/ERC721.py). La definizione dell'interfaccia è scritta in Python, anziché in Vyper, perché le interfacce non sono usate solo nella blockchain, ma anche quando si invia una transazione alla blockchain da un client esterno, che potrebbe esser scritto in Python. +L'interfaccia ERC-721 è integrata nel linguaggio Vyper. +[Puoi vedere la definizione del codice qui](https://github.com/vyperlang/vyper/blob/master/vyper/builtin_interfaces/ERC721.py). +La definizione dell'interfaccia è scritta in Python, anziché in Vyper, perché le interfacce non sono usate solo nella blockchain, ma anche quando si invia una transazione alla blockchain da un client esterno, che potrebbe esser scritto in +Python. La prima riga importa l'interfaccia, la seconda specifica che la stiamo implementando qui. ### L'interfaccia ERC721Receiver {#receiver-interface} ```python -# Interface for the contract called by safeTransferFrom() +# Interfaccia per il contratto chiamato da safeTransferFrom() interface ERC721Receiver: def onERC721Received( ``` -ERC-721 supporta due tipi di trasferimento: +L'ERC-721 supporta due tipi di trasferimento: -- `transferFrom`, che consente al mittente di specificare qualsiasi indirizzo di destinazione e pone sul mittente la responsabilità del trasferimento. Ciò significa che puoi trasferire a un indirizzo non valido, nel qual caso l'NFT è perso definitivamente. -- `safeTransferFrom`, che controlla se l'indirizzo di destinazione è un contratto. In tal caso, il contratto ERC-721 chiede al contratto ricevente se vuole ricevere l’NFT. +- `transferFrom`, che consente al mittente di specificare qualsiasi indirizzo di destinazione e attribuisce la responsabilità + del trasferimento al mittente. Ciò significa che puoi trasferire a un indirizzo non valido, nel qual caso + l'NFT è perso per sempre. +- `safeTransferFrom`, che controlla se l'indirizzo di destinazione è un contratto. In tal caso, il contratto ERC-721 + chiede al contratto ricevente se vuole ricevere l’NFT. Per rispondere alle richieste `safeTransferFrom`, un contratto ricevente deve implementare `ERC721Receiver`. @@ -57,13 +67,15 @@ Per rispondere alle richieste `safeTransferFrom`, un contratto ricevente deve im _from: address, ``` -L'indirizzo `_from` è il proprietario corrente del token. L'indirizzo `_operator` è quello che ha richiesto il trasferimento (i due potrebbero non corrispondere, a causa delle indennità). +L'indirizzo `_from` è il proprietario corrente del token. L'indirizzo `_operator` è quello che +ha richiesto il trasferimento (i due potrebbero non essere gli stessi, a causa delle autorizzazioni). ```python _tokenId: uint256, ``` -Gli ID del token ERC-721 sono a 256 bit. Solitamente sono creati mediante hashing di una descrizione di qualsiasi token rappresenti. +Gli ID dei token ERC-721 sono a 256 bit. Generalmente, sono creati tramite l'hashing di una descrizione di ciò che +il token rappresenta. ```python _data: Bytes[1024] @@ -75,113 +87,141 @@ La richiesta può avere fino a 1024 byte di dati utente. ) -> bytes32: view ``` -Per impedire casi la possibilità che un contratto accetti accidentalmente un trasferimento, il valore restituito non è booleano, ma 256 bit con un valore specifico. +Per evitare i casi in cui un contratto accetti accidentalmente un trasferimento, il valore restituito non è un booleano, +ma 256 bit con un valore specifico. Questa funzione è una `view`, ovvero può leggere lo stato della blockchain, ma non modificarlo. ### Eventi {#events} -Gli [eventi](https://media.consensys.net/technical-introduction-to-events-and-logs-in-ethereum-a074d65dd61e) sono emessi per informare gli utenti e i server al di fuori della blockchain degli eventi. Nota che il contenuto degli eventi non è disponibile per i contratti sulla blockchain. +Gli [Eventi](https://media.consensys.net/technical-introduction-to-events-and-logs-in-ethereum-a074d65dd61e) +sono emessi per informare gli utenti e i server al di fuori della blockchain degli eventi. Nota che il contenuto degli eventi +non è disponibile per i contratti sulla blockchain. ```python -# @dev Emits when ownership of any NFT changes by any mechanism. This event emits when NFTs are -# created (`from` == 0) and destroyed (`to` == 0). Exception: during contract creation, any -# number of NFTs may be created and assigned without emitting Transfer. At the time of any -# transfer, the approved address for that NFT (if any) is reset to none. -# @param _from Sender of NFT (if address is zero address it indicates token creation). -# @param _to Receiver of NFT (if address is zero address it indicates token destruction). -# @param _tokenId The NFT that got transferred. +# @dev Emette quando la proprietà di un qualsiasi NFT cambia con qualsiasi meccanismo. Questo evento viene emesso quando gli NFT sono +# creati (`from` == 0) e distrutti (`to` == 0). Eccezione: durante la creazione del contratto, un qualsiasi +# numero di NFT può essere creato e assegnato senza emettere un evento Transfer. Al momento di ogni +# trasferimento, l'indirizzo approvato per quell'NFT (se presente) viene reimpostato su nessuno. +# @param _from Mittente dell'NFT (se l'indirizzo è l'indirizzo zero, indica la creazione del token). +# @param _to Destinatario dell'NFT (se l'indirizzo è l'indirizzo zero, indica la distruzione del token). +# @param _tokenId L'NFT che è stato trasferito. event Transfer: sender: indexed(address) receiver: indexed(address) tokenId: indexed(uint256) ``` -Questo è simile all'evento di Trasferimento dell'ERC-20, tranne per il fatto che segnaliamo un `tokenId` anziché un importo. Nessuno possiede l'indirizzo zero, quindi per convenzione lo usiamo per segnalare la creazione e distruzione dei token. +Questo è simile all'evento di trasferimento dell'ERC-20, con la differenza che viene segnalato un `tokenId` invece di un importo. +Nessuno possiede l'indirizzo zero, quindi per convenzione lo usiamo per segnalare la creazione e distruzione dei token. ```python -# @dev This emits when the approved address for an NFT is changed or reaffirmed. The zero -# address indicates there is no approved address. When a Transfer event emits, this also -# indicates that the approved address for that NFT (if any) is reset to none. -# @param _owner Owner of NFT. -# @param _approved Address that we are approving. -# @param _tokenId NFT which we are approving. +# @dev Viene emesso quando l'indirizzo approvato per un NFT viene modificato o riconfermato. L'indirizzo +# zero indica che non c'è nessun indirizzo approvato. Quando un evento Transfer viene emesso, questo +# indica anche che l'indirizzo approvato per quell'NFT (se presente) viene reimpostato su nessuno. +# @param _owner Proprietario dell'NFT. +# @param _approved Indirizzo che stiamo approvando. +# @param _tokenId NFT che stiamo approvando. event Approval: owner: indexed(address) approved: indexed(address) tokenId: indexed(uint256) ``` -L'approvazione di un ERC-721 è simile a un'indennità dell'ERC-20. Un indirizzo specifico può trasferire un token specifico. Questo offre ai contratti un meccanismo per rispondere quando accettano un token. I contratti non possono ascoltare gli eventi, quindi se semplicemente trasferisci loro il token, non lo "sanno". In questo modo, il proprietario invia prima un'approvazione e poi una richiesta al contratto: "Ho approvato il tuo trasferimento del token X, sei pregato di...". +Un'approvazione ERC-721 è simile a un'autorizzazione ERC-20. A un indirizzo specifico è consentito trasferire uno specifico +token. Questo offre ai contratti un meccanismo per rispondere quando accettano un token. I contratti non possono +rimanere in ascolto degli eventi, quindi se si trasferisce loro semplicemente il token non ne vengono a "conoscenza". In questo modo il +proprietario prima invia un'approvazione e poi una richiesta al contratto: "Ti ho approvato per trasferire il token +X, procedi pure...". -Si tratta di una scelta di progettazione per rendere lo standard ERC-721 simile allo standard ERC-20. Poiché i token di ERC-721 non sono fungibili, un contratto può capire di aver ricevuto un token specifico anche guardando alle sue proprietà. +Si tratta di una scelta di progettazione per rendere lo standard ERC-721 simile allo standard ERC-20. Poiché +i token ERC-721 non sono fungibili, un contratto può anche identificare di aver ricevuto un token specifico +controllando la proprietà del token. ```python -# @dev This emits when an operator is enabled or disabled for an owner. The operator can manage -# all NFTs of the owner. -# @param _owner Owner of NFT. -# @param _operator Address to which we are setting operator rights. -# @param _approved Status of operator rights(true if operator rights are given and false if -# revoked). +# @dev Emette quando un operatore è abilitato o disabilitato per un proprietario. L'operatore può gestire +# tutti gli NFT del proprietario. +# @param _owner Proprietario dell'NFT. +# @param _operator Indirizzo al quale stiamo impostando i diritti di operatore. +# @param _approved Stato dei diritti di operatore (true se i diritti di operatore sono concessi e false se +# revocati). event ApprovalForAll: owner: indexed(address) operator: indexed(address) approved: bool ``` -Talvolta, è utile avere un _operatore_, che possa gestire tutti i token di un conto di un tipo specifico (quelli gestiti da un contratto specifico), similmente a una delega. Ad esempio, potrei voler dare a un contratto una delega per verificare se non l'ho contattato per sei mesi e, in questo caso, distribuisce le mie risorse ai miei eredi (se uno di loro lo richiede, i contratti non possono fare niente senza esser chiamati da una transazione). In ERC-20 possiamo solo dare un'indennità elevata a un contratto di ereditarietà, ma questo non funziona per ERC-721 perché i token non sono fungibili. Questo è l'equivalente. +A volte è utile avere un _operatore_ che possa gestire tutti i token di un account di un tipo specifico (quelli gestiti da +un contratto specifico), in modo simile a una procura. Ad esempio, potrei voler dare tale potere a un contratto che controlli se +non l'ho contattato per sei mesi e, in tal caso, distribuisca i miei asset ai miei eredi (se uno di loro lo richiede, i contratti +non possono fare nulla senza essere chiamati da una transazione). In ERC-20 possiamo semplicemente dare un'elevata autorizzazione a un contratto di successione, +ma ciò non funziona per ERC-721 perché i token non sono fungibili. Questo è l'equivalente. -Il valore `approved` ci comunica se l'evento è per un'approvazione, o la revoca di un'approvazione. +Il valore `approved` ci dice se l'evento è per un'approvazione o per la revoca di un'approvazione. -### Variabili di stato {#state-vars} +### Variabili di Stato {#state-vars} -Queste variabili contengono lo stato corrente dei token: quali sono disponibili e chi li possiede. Gran parte di questi sono oggetti di `HashMap`, [mappature unidirezionali che esistono tra due tipi](https://vyper.readthedocs.io/en/latest/types.html#mappings). +Queste variabili contengono lo stato corrente dei token: quali sono disponibili e chi li possiede. La maggior parte di queste +sono oggetti `HashMap`, [mappature unidirezionali che esistono tra due tipi](https://vyper.readthedocs.io/en/latest/types.html#mappings). ```python -# @dev Mapping from NFT ID to the address that owns it. +# @dev Mappatura dall'ID dell'NFT all'indirizzo che lo possiede. idToOwner: HashMap[uint256, address] -# @dev Mapping from NFT ID to approved address. +# @dev Mappatura dall'ID dell'NFT all'indirizzo approvato. idToApprovals: HashMap[uint256, address] ``` -Le identità dell'utente e del contratto su Ethereum sono rappresentate da indirizzi a 160 bit. Queste due variabili mappano gli ID dei token con i loro proprietari e quelli approvati per trasferirli (a un massimo di uno ciascuno). In Ethereum, i dati non inizializzati sono sempre zero, quindi se non c'è alcun proprietario o trasferente approvato, il valore per quel token è zero. +Le identità dell'utente e del contratto su Ethereum sono rappresentate da indirizzi a 160 bit. Queste due variabili mappano +dagli ID dei token ai loro proprietari e a coloro approvati a trasferirli (per un massimo di uno per ciascuno). In Ethereum, +i dati non inizializzati sono sempre zero, quindi se non c'è alcun proprietario o trasferitore approvato, il valore per quel token +è zero. ```python -# @dev Mapping from owner address to count of his tokens. +# @dev Mappatura dall'indirizzo del proprietario al conteggio dei suoi token. ownerToNFTokenCount: HashMap[address, uint256] ``` -Questa variabile tiene conto dei token per ogni proprietario. Non c'è alcuna mappatura dai proprietari ai token, quindi l'unico modo per identificare i token che un proprietario specifico possiede è guardare alla cronologia di eventi della blockchain e vedere gli eventi di `trasferimento` appropriati. Possiamo usare questa variabile per sapere quando abbiamo tutti gli NFT e non dobbiamo guardare oltre nel tempo. +Questa variabile contiene il conteggio dei token per ogni proprietario. Non esiste una mappatura dai proprietari ai token, quindi +l'unico modo per identificare i token posseduti da un proprietario specifico è guardare indietro nella cronologia degli eventi della blockchain +e vedere gli eventi `Transfer` appropriati. Possiamo usare questa variabile per sapere quando abbiamo tutti gli NFT e non +abbiamo bisogno di guardare ancora più indietro nel tempo. -Questo algoritmo funziona solo per le interfacce utente e i server esterni. Il codice in esecuzione sulla blockchain stessa non può leggere gli eventi passati. +Nota che questo algoritmo funziona solo per le interfacce utente e i server esterni. Il codice in esecuzione sulla blockchain +stessa non può leggere gli eventi passati. ```python -# @dev Mapping from owner address to mapping of operator addresses. +# @dev Mappatura dall'indirizzo del proprietario alla mappatura degli indirizzi degli operatori. ownerToOperators: HashMap[address, HashMap[address, bool]] ``` -Un conto potrebbe avere più di un singolo operatore. Un semplice `HashMap` è insufficiente per tenerne traccia, perché ogni chiave conduce a un valore singolo. Invece, puoi usare `HashMap[address, bool]` come valore. Di default, il valore per ogni indirizzo è `False`, che significa che non è un operatore. Puoi impostare i valori a `True` se necessario. +Un account può avere più di un singolo operatore. Un semplice `HashMap` è insufficiente per +tenerne traccia, perché ogni chiave porta a un singolo valore. Invece, è possibile utilizzare +`HashMap[address, bool]` come valore. Per impostazione predefinita, il valore per ogni indirizzo è `False`, il che significa che +non è un operatore. È possibile impostare i valori su `True` secondo necessità. ```python -# @dev Address of minter, who can mint a token +# @dev Indirizzo del minter, che può coniare un token minter: address ``` -I nuovi token devono in qualche modo esser creati. In questo contratto, esiste solo un'entità che può farlo, il `coniatore`. Questo sarà probabilmente sufficiente per un gioco, ad esempio. Per altri scopi, potrebbe esser necessario creare una logica di business più complicata. +I nuovi token devono essere creati in qualche modo. In questo contratto c'è una sola entità autorizzata a farlo, il +`minter`. Questo è probabilmente sufficiente per un gioco, ad esempio. Per altri scopi, potrebbe essere necessario +creare una logica di business più complicata. ```python -# @dev Mapping of interface id to bool about whether or not it's supported +# @dev Mappatura dell'ID dell'interfaccia a un valore booleano che indica se è supportata o meno supportedInterfaces: HashMap[bytes32, bool] -# @dev ERC165 interface ID of ERC165 +# @dev ID dell'interfaccia ERC165 di ERC165 ERC165_INTERFACE_ID: constant(bytes32) = 0x0000000000000000000000000000000000000000000000000000000001ffc9a7 -# @dev ERC165 interface ID of ERC721 +# @dev ID dell'interfaccia ERC165 di ERC721 ERC721_INTERFACE_ID: constant(bytes32) = 0x0000000000000000000000000000000000000000000000000000000080ac58cd ``` -[ERC-165](https://eips.ethereum.org/EIPS/eip-165) specifica un meccanismo con cui un contratto può rivelare come le applicazioni possono comunicare con esso, a quali ERC è conforme. In questo caso, il contratto è conforme a ERC-165 ed ERC-721. +[ERC-165](https://eips.ethereum.org/EIPS/eip-165) specifica un meccanismo con cui un contratto può rivelare come le applicazioni +possono comunicare con esso, a quali ERC è conforme. In questo caso, il contratto è conforme a ERC-165 ed ERC-721. ### Funzioni {#functions} @@ -198,11 +238,13 @@ In Vyper, come in Python, la funzione del costruttore è chiamata `__init__`. ```python """ - @dev Contract constructor. + @dev Costruttore del contratto. """ ``` -Su Python e su Vyper, puoi anche creare un commento specificando una stringa su più righe (che inizia e termina per `"""`), senza usarla in alcun modo. Questi commenti possono anche includere [NatSpec](https://vyper.readthedocs.io/en/latest/natspec.html). +In Python, e in Vyper, è possibile anche creare un commento specificando una stringa su più righe (che inizia e finisce +con `"""`), e non utilizzandola in alcun modo. Questi commenti possono anche includere +[NatSpec](https://vyper.readthedocs.io/en/latest/natspec.html). ```python self.supportedInterfaces[ERC165_INTERFACE_ID] = True @@ -210,40 +252,47 @@ Su Python e su Vyper, puoi anche creare un commento specificando una stringa su self.minter = msg.sender ``` -Per accedere alle variabili di stato, si usa `self.` (di nuovo, come in Python). +Per accedere alle variabili di stato si usa `self.` (di nuovo, come in Python). #### Funzioni di visualizzazione {#views} -Sono funzioni che non modificano lo stato della blockchain e dunque sono eseguibili liberamente se chiamate esternamente. Se le funzioni di visualizzazione sono chiamate da un contratto, devono comunque esser eseguite su ogni nodo e, dunque, costano gas. +Queste sono funzioni che non modificano lo stato della blockchain e che quindi possono essere eseguite gratuitamente +se chiamate esternamente. Se le funzioni di visualizzazione sono chiamate da un contratto, devono comunque essere eseguite su +ogni nodo e, di conseguenza, costano gas. ```python @view @external ``` -Queste parole chiave prima della definizione di una funzione che inizia con un segno (`@`) sono dette _decorazioni_. Specificano le circostanze in cui una funzione è chiamabile. +Queste parole chiave prima di una definizione di funzione che iniziano con una chiocciola (`@`) sono chiamate _decorazioni_. Specificano +le circostanze in cui una funzione può essere chiamata. -- `@view` specifica che questa funzione è una visualizzazione. -- `@external` specifica che questa particolare funzione è chiamabile dalle transazioni o da altri contratti. +- `@view` specifica che questa funzione è una vista. +- `@external` specifica che questa particolare funzione può essere chiamata da transazioni e da altri contratti. ```python def supportsInterface(_interfaceID: bytes32) -> bool: ``` -A differenza di Python, Vyper è un [linguaggio tipizzato statico](https://wikipedia.org/wiki/Type_system#Static_type_checking). Non puoi dichiarare una variabile, o il parametro di una funzione, senza indicare il [tipo di dato](https://vyper.readthedocs.io/en/latest/types.html). In questo caso, il parametro inserito è `bytes32`, un valore a 256 bit (256 bit è la dimensione nativa della word della [Macchina Virtuale di Ethereum](/developers/docs/evm/)). L'output è un valore booleano. Per convenzione, i nomi dei parametri della funzione iniziano con un trattino basso (`_`). +A differenza di Python, Vyper è un [linguaggio a tipizzazione statica](https://wikipedia.org/wiki/Type_system#Static_type_checking). +Non è possibile dichiarare una variabile, o un parametro di funzione, senza identificarne il [tipo di dato](https://vyper.readthedocs.io/en/latest/types.html). In questo caso il parametro di input è `bytes32`, un valore a 256 bit +(256 bit è la dimensione nativa della parola della [Ethereum Virtual Machine](/developers/docs/evm/)). L'output è un valore booleano +. Per convenzione, i nomi dei parametri della funzione iniziano con un trattino basso (`_`). ```python """ - @dev Interface identification is specified in ERC-165. - @param _interfaceID Id of the interface + @dev L'identificazione dell'interfaccia è specificata in ERC-165. + @param _interfaceID Id dell'interfaccia """ return self.supportedInterfaces[_interfaceID] ``` -Restituisce il valore dall'HashMap `self-supportedInterfaces`, che è impostata nel costruttore (`__init__`). +Restituisce il valore dall'HashMap `self.supportedInterfaces`, che è impostato nel costruttore (`__init__`). ```python -### VIEW FUNCTIONS ### +### FUNZIONI DI VISUALIZZAZIONE ### + ``` Queste sono le funzioni di visualizzazione che rendono le informazioni sui token disponibili a utenti e altri contratti. @@ -253,14 +302,15 @@ Queste sono le funzioni di visualizzazione che rendono le informazioni sui token @external def balanceOf(_owner: address) -> uint256: """ - @dev Returns the number of NFTs owned by `_owner`. - Throws if `_owner` is the zero address. NFTs assigned to the zero address are considered invalid. - @param _owner Address for whom to query the balance. + @dev Restituisce il numero di NFT posseduti da `_owner`. + Genera un'eccezione se `_owner` è l'indirizzo zero. Gli NFT assegnati all'indirizzo zero sono considerati non validi. + @param _owner Indirizzo per il quale interrogare il saldo. """ assert _owner != ZERO_ADDRESS ``` -Questa riga [afferma](https://vyper.readthedocs.io/en/latest/statements.html#assert) che `_owner` non è zero. Se lo è, c'è un errore e l'operazione è annullata. +Questa riga [afferma](https://vyper.readthedocs.io/en/latest/statements.html#assert) che `_owner` non è +zero. Se lo è, si verifica un errore e l'operazione viene annullata. ```python return self.ownerToNFTokenCount[_owner] @@ -269,70 +319,75 @@ Questa riga [afferma](https://vyper.readthedocs.io/en/latest/statements.html#ass @external def ownerOf(_tokenId: uint256) -> address: """ - @dev Returns the address of the owner of the NFT. - Throws if `_tokenId` is not a valid NFT. - @param _tokenId The identifier for an NFT. + @dev Restituisce l'indirizzo del proprietario dell'NFT. + Genera un'eccezione se `_tokenId` non è un NFT valido. + @param _tokenId L'identificatore di un NFT. """ owner: address = self.idToOwner[_tokenId] - # Throws if `_tokenId` is not a valid NFT + # Genera un'eccezione se `_tokenId` non è un NFT valido assert owner != ZERO_ADDRESS return owner ``` -Nella Macchina Virtuale di Ethereum (EVM), ogni memoria senza un valore memorizzato è zero. Se non esiste alcun token a `_tokenId`, allora il valore di `self.idToOwner[_tokenId]` è zero. In quel caso la funzione si annulla. +Nella Ethereum Virtual Machine (EVM), qualsiasi spazio di archiviazione che non ha un valore memorizzato è zero. +Se non esiste alcun token in `_tokenId`, il valore di `self.idToOwner[_tokenId]` è zero. In tal +caso la funzione viene annullata. ```python @view @external def getApproved(_tokenId: uint256) -> address: """ - @dev Get the approved address for a single NFT. - Throws if `_tokenId` is not a valid NFT. - @param _tokenId ID of the NFT to query the approval of. + @dev Ottiene l'indirizzo approvato per un singolo NFT. + Genera un'eccezione se `_tokenId` non è un NFT valido. + @param _tokenId ID dell'NFT di cui interrogare l'approvazione. """ - # Throws if `_tokenId` is not a valid NFT + # Genera un'eccezione se `_tokenId` non è un NFT valido assert self.idToOwner[_tokenId] != ZERO_ADDRESS return self.idToApprovals[_tokenId] ``` -Nota che `getApproved` _può_ restituire zero. Se il token è valido, restituisce `self.idToApprovals[_tokenId]`. Se non c'è alcun approvatore, quel valore è zero. +Nota che `getApproved` _può_ restituire zero. Se il token è valido, restituisce `self.idToApprovals[_tokenId]`. +Se non c'è alcun approvatore, quel valore è zero. ```python @view @external def isApprovedForAll(_owner: address, _operator: address) -> bool: """ - @dev Checks if `_operator` is an approved operator for `_owner`. - @param _owner The address that owns the NFTs. - @param _operator The address that acts on behalf of the owner. + @dev Controlla se `_operator` è un operatore approvato per `_owner`. + @param _owner L'indirizzo che possiede gli NFT. + @param _operator L'indirizzo che agisce per conto del proprietario. """ return (self.ownerToOperators[_owner])[_operator] ``` -Questa funzione verifica se `_operator` può gestire tutti i token del `_owner` in questo contratto. Poiché possono esserci diversi operatori, si tratta di un HashMap a due livelli. +Questa funzione controlla se `_operator` è autorizzato a gestire tutti i token di `_owner` in questo contratto. +Poiché possono esserci più operatori, si tratta di un HashMap a due livelli. -#### Funzioni d'aiuto al trasferimento {#transfer-helpers} +#### Funzioni di supporto per il trasferimento {#transfer-helpers} Queste funzioni implementano operazioni che fanno parte del trasferimento o della gestione dei token. ```python -### TRANSFER FUNCTION HELPERS ### +### FUNZIONI DI SUPPORTO PER IL TRASFERIMENTO ### @view @internal ``` -Questa decorazione, `@internal`, significa che la funzione è accessibile solo da altre funzioni nello stesso contratto. Per convenzione, questi nomi di funzione iniziano anch'essi con un trattino basso (`_`). +Questa decorazione, `@internal`, significa che la funzione è accessibile solo da altre funzioni all'interno dello +stesso contratto. Per convenzione, anche i nomi di queste funzioni iniziano con un trattino basso (`_`). ```python def _isApprovedOrOwner(_spender: address, _tokenId: uint256) -> bool: """ - @dev Returns whether the given spender can transfer a given token ID - @param spender address of the spender to query - @param tokenId uint256 ID of the token to be transferred - @return bool whether the msg.sender is approved for the given token ID, - is an operator of the owner, or is the owner of the token + @dev Restituisce se lo spender specificato può trasferire un determinato ID di token + @param spender indirizzo dello spender da interrogare + @param tokenId uint256 ID del token da trasferire + @return bool se msg.sender è approvato per l'ID di token dato, + è un operatore del proprietario, o è il proprietario del token """ owner: address = self.idToOwner[_tokenId] spenderIsOwner: bool = owner == _spender @@ -341,117 +396,123 @@ def _isApprovedOrOwner(_spender: address, _tokenId: uint256) -> bool: return (spenderIsOwner or spenderIsApproved) or spenderIsApprovedForAll ``` -Esistono tre modi in cui a un indirizzo è consentito trasferire un token: +Ci sono tre modi in cui un indirizzo può essere autorizzato a trasferire un token: 1. L'indirizzo è il proprietario del token -2. L'indirizzo è autorizzato a spendere quel token +2. L'indirizzo è approvato per spendere quel token 3. L'indirizzo è un operatore per il proprietario del token -La funzione che precedere può essere una visualizzazione, perché non modifica lo stato. Per ridurre i costi operativi, ogni funzione che _può_ essere una visualizzazione, _dovrebbe_ esserlo. +La funzione di cui sopra può essere una vista perché non cambia lo stato. Per ridurre i costi operativi, qualsiasi +funzione che _può_ essere una vista _dovrebbe_ essere una vista. ```python @internal def _addTokenTo(_to: address, _tokenId: uint256): """ - @dev Add a NFT to a given address - Throws if `_tokenId` is owned by someone. + @dev Aggiunge un NFT a un dato indirizzo + Genera un'eccezione se `_tokenId` è di proprietà di qualcuno. """ - # Throws if `_tokenId` is owned by someone + # Genera un'eccezione se `_tokenId` è di proprietà di qualcuno assert self.idToOwner[_tokenId] == ZERO_ADDRESS - # Change the owner + # Cambia il proprietario self.idToOwner[_tokenId] = _to - # Change count tracking + # Cambia il tracciamento del conteggio self.ownerToNFTokenCount[_to] += 1 @internal def _removeTokenFrom(_from: address, _tokenId: uint256): """ - @dev Remove a NFT from a given address - Throws if `_from` is not the current owner. + @dev Rimuove un NFT da un dato indirizzo + Genera un'eccezione se `_from` non è il proprietario corrente. """ - # Throws if `_from` is not the current owner + # Genera un'eccezione se `_from` non è il proprietario corrente assert self.idToOwner[_tokenId] == _from - # Change the owner + # Cambia il proprietario self.idToOwner[_tokenId] = ZERO_ADDRESS - # Change count tracking + # Cambia il tracciamento del conteggio self.ownerToNFTokenCount[_from] -= 1 ``` -Quando c'è un problema con un trasferimento, anulliamo la chiamata. +Quando c'è un problema con un trasferimento, annulliamo la chiamata. ```python @internal def _clearApproval(_owner: address, _tokenId: uint256): """ - @dev Clear an approval of a given address - Throws if `_owner` is not the current owner. + @dev Cancella un'approvazione di un dato indirizzo + Genera un'eccezione se `_owner` non è il proprietario corrente. """ - # Throws if `_owner` is not the current owner + # Genera un'eccezione se `_owner` non è il proprietario corrente assert self.idToOwner[_tokenId] == _owner if self.idToApprovals[_tokenId] != ZERO_ADDRESS: - # Reset approvals + # Reimposta le approvazioni self.idToApprovals[_tokenId] = ZERO_ADDRESS ``` -Cambia il valore solo se necessario. Le variabili di stato risiedono nella memoria. La scrittura all'archiviazione è una delle operazioni più costose che l'EVM (Macchina Virtuale di Ethereum) effettua (in termini di [gas](/developers/docs/gas/)). Dunque, è bene mantenerla al minimo, anche scrivere il valore esistente ha un costo elevato. +Cambiare il valore solo se necessario. Le variabili di stato risiedono nello spazio di archiviazione. La scrittura nello spazio di archiviazione è +una delle operazioni più costose che l'EVM (Ethereum Virtual Machine) esegue (in termini di +[gas](/developers/docs/gas/)). Pertanto, è una buona idea ridurla al minimo, anche la scrittura del +valore esistente ha un costo elevato. ```python @internal def _transferFrom(_from: address, _to: address, _tokenId: uint256, _sender: address): """ - @dev Execute transfer of a NFT. - Throws unless `msg.sender` is the current owner, an authorized operator, or the approved - address for this NFT. (NOTE: `msg.sender` not allowed in private function so pass `_sender`.) - Throws if `_to` is the zero address. - Throws if `_from` is not the current owner. - Throws if `_tokenId` is not a valid NFT. + @dev Esegue il trasferimento di un NFT. + Genera un'eccezione a meno che `msg.sender` non sia il proprietario corrente, un operatore autorizzato o l'indirizzo approvato + per questo NFT. (NOTA: `msg.sender` non è consentito in una funzione privata, quindi passa `_sender`.) + Genera un'eccezione se `_to` è l'indirizzo zero. + Genera un'eccezione se `_from` non è il proprietario corrente. + Genera un'eccezione se `_tokenId` non è un NFT valido. """ ``` -Abbiamo questa funzione interna perché esistono due modi per trasferire i token (regolare e sicuro), ma vogliamo una sola posizione nel codice dove farlo, per semplificare il controllo. +Abbiamo questa funzione interna perché ci sono due modi per trasferire i token (regolare e sicuro), ma +vogliamo solo un unico punto nel codice in cui lo facciamo per facilitare il controllo. ```python - # Check requirements + # Controlla i requisiti assert self._isApprovedOrOwner(_sender, _tokenId) - # Throws if `_to` is the zero address + # Genera un'eccezione se `_to` è l'indirizzo zero assert _to != ZERO_ADDRESS - # Clear approval. Throws if `_from` is not the current owner + # Cancella l'approvazione. Genera un'eccezione se `_from` non è il proprietario corrente self._clearApproval(_from, _tokenId) - # Remove NFT. Throws if `_tokenId` is not a valid NFT + # Rimuovi l'NFT. Genera un'eccezione se `_tokenId` non è un NFT valido self._removeTokenFrom(_from, _tokenId) - # Add NFT + # Aggiungi l'NFT self._addTokenTo(_to, _tokenId) - # Log the transfer + # Registra il trasferimento log Transfer(_from, _to, _tokenId) ``` -Per emettere un evento su Vyper, si usa una dichiarazione di `log` ([vedi qui per ulteriori dettagli](https://vyper.readthedocs.io/en/latest/event-logging.html#event-logging)). +Per emettere un evento in Vyper si usa un'istruzione `log` ([vedi qui per maggiori dettagli](https://vyper.readthedocs.io/en/latest/event-logging.html#event-logging)). #### Funzioni di trasferimento {#transfer-funs} ```python -### TRANSFER FUNCTIONS ### +### FUNZIONI DI TRASFERIMENTO ### @external def transferFrom(_from: address, _to: address, _tokenId: uint256): """ - @dev Throws unless `msg.sender` is the current owner, an authorized operator, or the approved - address for this NFT. - Throws if `_from` is not the current owner. - Throws if `_to` is the zero address. - Throws if `_tokenId` is not a valid NFT. - @notice The caller is responsible to confirm that `_to` is capable of receiving NFTs or else - they maybe be permanently lost. - @param _from The current owner of the NFT. - @param _to The new owner. - @param _tokenId The NFT to transfer. + @dev Genera un'eccezione a meno che `msg.sender` non sia il proprietario corrente, un operatore autorizzato o l'indirizzo approvato + per questo NFT. + Genera un'eccezione se `_from` non è il proprietario corrente. + Genera un'eccezione se `_to` è l'indirizzo zero. + Genera un'eccezione se `_tokenId` non è un NFT valido. + @notice Il chiamante è responsabile di confermare che `_to` è in grado di ricevere NFT, altrimenti + potrebbero essere persi in modo permanente. + @param _from Il proprietario attuale dell'NFT. + @param _to Il nuovo proprietario. + @param _tokenId L'NFT da trasferire. """ self._transferFrom(_from, _to, _tokenId, msg.sender) ``` -Questa funzione ti consente di trasferire a un indirizzo arbitrario. A meno che l'indirizzo non sia un utente o un contratto che sa come trasferire i token, ogni token che trasferisci sarà bloccato in quell'indirizzo e inutile. +Questa funzione permette di trasferire a un indirizzo arbitrario. A meno che l'indirizzo non sia un utente o un contratto che +sa come trasferire i token, qualsiasi token trasferito rimarrà bloccato in quell'indirizzo e sarà inutilizzabile. ```python @external @@ -462,30 +523,34 @@ def safeTransferFrom( _data: Bytes[1024]=b"" ): """ - @dev Transfers the ownership of an NFT from one address to another address. - Throws unless `msg.sender` is the current owner, an authorized operator, or the - approved address for this NFT. - Throws if `_from` is not the current owner. - Throws if `_to` is the zero address. - Throws if `_tokenId` is not a valid NFT. - If `_to` is a smart contract, it calls `onERC721Received` on `_to` and throws if - the return value is not `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))`. - NOTE: bytes4 is represented by bytes32 with padding - @param _from The current owner of the NFT. - @param _to The new owner. - @param _tokenId The NFT to transfer. - @param _data Additional data with no specified format, sent in call to `_to`. + @dev Trasferisce la proprietà di un NFT da un indirizzo a un altro. + Genera un'eccezione a meno che `msg.sender` non sia il proprietario corrente, un operatore autorizzato o + l'indirizzo approvato per questo NFT. + Genera un'eccezione se `_from` non è il proprietario corrente. + Genera un'eccezione se `_to` è l'indirizzo zero. + Genera un'eccezione se `_tokenId` non è un NFT valido. + Se `_to` è uno smart contract, chiama `onERC721Received` su `_to` e genera un'eccezione se + il valore restituito non è `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))`. + NOTA: bytes4 è rappresentato da bytes32 con riempimento + @param _from Il proprietario attuale dell'NFT. + @param _to Il nuovo proprietario. + @param _tokenId L'NFT da trasferire. + @param _data Dati aggiuntivi senza formato specificato, inviati nella chiamata a `_to`. """ self._transferFrom(_from, _to, _tokenId, msg.sender) ``` -Va bene effettuare prima il trasferimento perché se c'è un problema, ripristineremo comunque, quindi tutto ciò che è fatto nella chiamata sarà annullato. +Va bene effettuare prima il trasferimento perché se c'è un problema, l'operazione verrà comunque annullata, +quindi tutto ciò che è stato fatto nella chiamata sarà annullato. ```python - if _to.is_contract: # check if `_to` is a contract address + if _to.is_contract: # controlla se `_to` è un indirizzo di contratto ``` -Prima controlla per vedere se l'indirizzo è un contratto (se ha il codice). Altrimenti, presumi che sia un indirizzo utente e che l'utente possa usare o trasferire il token. Ma non abbandonarti a un falso senso di sicurezza. Puoi infatti perdere i token, anche con `safeTransferFrom`, se li trasferisci a un indirizzo di cui nessuno conosce la chiave privata. +Prima controlla se l'indirizzo è un contratto (se ha del codice). In caso contrario, si presume che sia un indirizzo +di utente e che l'utente sarà in grado di utilizzare il token o di trasferirlo. Ma non lasciarti cullare +in un falso senso di sicurezza. Puoi perdere i token, anche con `safeTransferFrom`, se li trasferisci +a un indirizzo di cui nessuno conosce la chiave privata. ```python returnValue: bytes32 = ERC721Receiver(_to).onERC721Received(msg.sender, _from, _tokenId, _data) @@ -494,43 +559,44 @@ Prima controlla per vedere se l'indirizzo è un contratto (se ha il codice). Alt Chiama il contratto di destinazione per vedere se può ricevere i token ERC-721. ```python - # Throws if transfer destination is a contract which does not implement 'onERC721Received' + # Genera un'eccezione se la destinazione del trasferimento è un contratto che non implementa 'onERC721Received' assert returnValue == method_id("onERC721Received(address,address,uint256,bytes)", output_type=bytes32) ``` -Se la destinazione è un contratto, ma un contratto che non accetta i token ERC-721 (o che ha deciso di non accettare questo specifico trasferimento), annulla. +Se la destinazione è un contratto, ma uno che non accetta token ERC-721 (o che ha deciso di non accettare questo +particolare trasferimento), annulla. ```python @external def approve(_approved: address, _tokenId: uint256): """ - @dev Set or reaffirm the approved address for an NFT. The zero address indicates there is no approved address. - Throws unless `msg.sender` is the current NFT owner, or an authorized operator of the current owner. - Throws if `_tokenId` is not a valid NFT. (NOTE: This is not written the EIP) - Throws if `_approved` is the current owner. (NOTE: This is not written the EIP) - @param _approved Address to be approved for the given NFT ID. - @param _tokenId ID of the token to be approved. + @dev Imposta o riconferma l'indirizzo approvato per un NFT. L'indirizzo zero indica che non c'è nessun indirizzo approvato. + Genera un'eccezione a meno che `msg.sender` non sia il proprietario corrente dell'NFT, o un operatore autorizzato del proprietario corrente. + Genera un'eccezione se `_tokenId` non è un NFT valido. (NOTA: questo non è scritto nell'EIP) + Genera un'eccezione se `_approved` è il proprietario corrente. (NOTA: questo non è scritto nell'EIP) + @param _approved Indirizzo da approvare per il dato ID NFT. + @param _tokenId ID del token da approvare. """ owner: address = self.idToOwner[_tokenId] - # Throws if `_tokenId` is not a valid NFT + # Genera un'eccezione se `_tokenId` non è un NFT valido assert owner != ZERO_ADDRESS - # Throws if `_approved` is the current owner + # Genera un'eccezione se `_approved` è il proprietario corrente assert _approved != owner ``` -Per convenzione, se non vuoi avere un approvatore, nomini l'indirizzo zero, non te stesso. +Per convenzione, se non si desidera avere un approvatore, si nomina l'indirizzo zero, non se stessi. ```python - # Check requirements + # Controlla i requisiti senderIsOwner: bool = self.idToOwner[_tokenId] == msg.sender senderIsApprovedForAll: bool = (self.ownerToOperators[owner])[msg.sender] assert (senderIsOwner or senderIsApprovedForAll) ``` -Per impostare un'approvazione, puoi essere il proprietario o un operatore autorizzato dal proprietario. +Per impostare un'approvazione puoi essere il proprietario o un operatore autorizzato dal proprietario. ```python - # Set the approval + # Imposta l'approvazione self.idToApprovals[_tokenId] = _approved log Approval(owner, _approved, _tokenId) @@ -538,95 +604,111 @@ Per impostare un'approvazione, puoi essere il proprietario o un operatore autori @external def setApprovalForAll(_operator: address, _approved: bool): """ - @dev Enables or disables approval for a third party ("operator") to manage all of - `msg.sender`'s assets. It also emits the ApprovalForAll event. - Throws if `_operator` is the `msg.sender`. (NOTE: This is not written the EIP) - @notice This works even if sender doesn't own any tokens at the time. - @param _operator Address to add to the set of authorized operators. - @param _approved True if the operators is approved, false to revoke approval. + @dev Abilita o disabilita l'approvazione per una terza parte ("operatore") per la gestione di tutte le + risorse di `msg.sender`. Emette anche l'evento ApprovalForAll. + Genera un'eccezione se `_operator` è il `msg.sender`. (NOTA: questo non è scritto nell'EIP) + @notice Funziona anche se il mittente non possiede alcun token al momento. + @param _operator Indirizzo da aggiungere al set di operatori autorizzati. + @param _approved True se l'operatore è approvato, false per revocare l'approvazione. """ - # Throws if `_operator` is the `msg.sender` + # Genera un'eccezione se `_operator` è il `msg.sender` assert _operator != msg.sender self.ownerToOperators[msg.sender][_operator] = _approved log ApprovalForAll(msg.sender, _operator, _approved) ``` -#### Conia nuovi token e distruggi token esistenti {#mint-burn} +#### Conia nuovi token e distruggi quelli esistenti {#mint-burn} -Il conto che ha creato il contratto è il `minter`, il super utente autorizzato a coniare nuovi NFT. Tuttavia, nemmeno lui è autorizzato a bruciare i token esistenti. Può farlo solo il proprietario, o un'entità da autorizzata dal proprietario. +L'account che ha creato il contratto è il `minter`, il super utente autorizzato a coniare +nuovi NFT. Tuttavia, anche a lui non è permesso bruciare i token esistenti. Solo il proprietario, o un'entità +autorizzata dal proprietario, può farlo. ```python -### MINT & BURN FUNCTIONS ### +### FUNZIONI DI CONIO E BRUCIATURA ### @external def mint(_to: address, _tokenId: uint256) -> bool: ``` -Questa funzione restituisce sempre `True`, perché se l'operazione fallisce è ripristinata. +Questa funzione restituisce sempre `True`, perché se l'operazione fallisce, viene annullata. ```python """ - @dev Function to mint tokens - Throws if `msg.sender` is not the minter. - Throws if `_to` is zero address. - Throws if `_tokenId` is owned by someone. - @param _to The address that will receive the minted tokens. - @param _tokenId The token id to mint. - @return A boolean that indicates if the operation was successful. + @dev Funzione per coniare token + Genera un'eccezione se `msg.sender` non è il minter. + Genera un'eccezione se `_to` è l'indirizzo zero. + Genera un'eccezione se `_tokenId` è di proprietà di qualcuno. + @param _to L'indirizzo che riceverà i token coniati. + @param _tokenId L'id del token da coniare. + @return Un booleano che indica se l'operazione è andata a buon fine. """ - # Throws if `msg.sender` is not the minter + # Genera un'eccezione se `msg.sender` non è il minter assert msg.sender == self.minter ``` -Solo il coniatore (il conto che ha creato il contratto ERC-721) può coniare nuovi token. Questo può essere un problema in futuro se si vuole cambiare l'identità del coniatore. In un contratto di produzione, potresti volere una funzione che consenta al coniatore di trasferire i propri privilegi a qualcun altro. +Solo il minter (l'account che ha creato il contratto ERC-721) può coniare nuovi token. Questo potrebbe essere un +problema in futuro se volessimo cambiare l'identità del minter. In +un contratto di produzione, probabilmente vorresti una funzione che permetta al minter di trasferire +i privilegi di minter a qualcun altro. ```python - # Throws if `_to` is zero address + # Genera un'eccezione se `_to` è l'indirizzo zero assert _to != ZERO_ADDRESS - # Add NFT. Throws if `_tokenId` is owned by someone + # Aggiungi NFT. Genera un'eccezione se `_tokenId` è di proprietà di qualcuno self._addTokenTo(_to, _tokenId) log Transfer(ZERO_ADDRESS, _to, _tokenId) return True ``` -Per convenzione, coniare i nuovi token conta come un trasferimento all'indirizzo zero. +Per convenzione, il conio di nuovi token conta come un trasferimento dall'indirizzo zero. ```python @external def burn(_tokenId: uint256): """ - @dev Burns a specific ERC721 token. - Throws unless `msg.sender` is the current owner, an authorized operator, or the approved - address for this NFT. - Throws if `_tokenId` is not a valid NFT. - @param _tokenId uint256 id of the ERC721 token to be burned. + @dev Brucia uno specifico token ERC721. + Genera un'eccezione a meno che `msg.sender` non sia il proprietario corrente, un operatore autorizzato o l'indirizzo approvato + per questo NFT. + Genera un'eccezione se `_tokenId` non è un NFT valido. + @param _tokenId uint256 id del token ERC721 da bruciare. """ - # Check requirements + # Controlla i requisiti assert self._isApprovedOrOwner(msg.sender, _tokenId) owner: address = self.idToOwner[_tokenId] - # Throws if `_tokenId` is not a valid NFT + # Genera un'eccezione se `_tokenId` non è un NFT valido assert owner != ZERO_ADDRESS self._clearApproval(owner, _tokenId) self._removeTokenFrom(owner, _tokenId) log Transfer(owner, ZERO_ADDRESS, _tokenId) ``` -Chiunque è autorizzato a trasferire un token, può bruciarlo. Anche se bruciare un token appare equivalente a trasferirlo all'indirizzo zero, l'indirizzo zero non riceve realmente il token. Ciò ci consente di liberare tutta l'archiviazione usata per il token, riducendo il costo del gas della transazione. +Chiunque sia autorizzato a trasferire un token è autorizzato a bruciarlo. Anche se una bruciatura appare equivalente a un +trasferimento all'indirizzo zero, l'indirizzo zero non riceve effettivamente il token. Questo ci permette di +liberare tutto lo spazio di archiviazione utilizzato per il token, il che può ridurre il costo del gas della transazione. -## Usare questo contratto {#using-contract} +## Utilizzo di questo contratto {#using-contract} -A differenza di Solidity, Vyper non ha un ereditarietà. Si tratta di una scelta progettuale deliberata per rendere il codice più chiaro e quindi più facile da proteggere. Quindi, per creare il tuo contratto ERC-721 in Vyper, prendi [questo contratto](https://github.com/vyperlang/vyper/blob/master/examples/tokens/ERC721.vy) e lo modifichi per implementare la logica di business che desideri. +A differenza di Solidity, Vyper non ha ereditarietà. Si tratta di una scelta progettuale deliberata per rendere il codice +più chiaro e quindi più facile da proteggere. Quindi, per creare il tuo contratto ERC-721 in Vyper, prendi questo +contratto e lo modifichi +per implementare la logica di business che desideri. -### Conclusione {#conclusion} +## Conclusione {#conclusion} -Per ripasso presentiamo alcune delle idee più importanti in questo contratto: +Per un ripasso, ecco alcune delle idee più importanti in questo contratto: -- Per ricevere i token ERC-721 con un trasferimento sicuro, i contratti devono implementare l'interfaccia di `ERC721Receiver`. -- Anche se usi il trasferimento sicuro, i token possono comunque rimanere bloccati se li invii a un indirizzo la cui chiave privata è sconosciuta. -- Quando c'è un problema con un'operazione, è una buona idea eseguire il `revert` della chiamata, piuttosto che restituire semplicemente un valore d'errore. +- Per ricevere i token ERC-721 con un trasferimento sicuro, i contratti devono implementare l'interfaccia `ERC721Receiver`. +- Anche se si utilizza il trasferimento sicuro, i token possono comunque rimanere bloccati se li si invia a un indirizzo la cui chiave privata + è sconosciuta. +- Quando si verifica un problema con un'operazione, è una buona idea `annullare` la chiamata, piuttosto che restituire semplicemente + un valore di fallimento. - I token ERC-721 esistono quando hanno un proprietario. -- Esistono tre modi per essere autorizzati a trasferire un NFT. Puoi essere il proprietario, essere approvato per un token specifico o essere un operatore per tutti i token del proprietario. -- Gli eventi passati sono visibili solo al di fuori della blockchain. Il codice eseguito nella blockchain non può vederli. +- Ci sono tre modi per essere autorizzati a trasferire un NFT. Puoi essere il proprietario, essere approvato per un token specifico, + o essere un operatore per tutti i token del proprietario. +- Gli eventi passati sono visibili solo al di fuori della blockchain. Il codice in esecuzione all'interno della blockchain non può visualizzarli. + +Ora vai e implementa contratti sicuri in Vyper. + +[Vedi qui per altri miei lavori](https://cryptodocguy.pro/). -Ora puoi andare a implementare contratti sicuri in Vyper. diff --git a/public/content/translations/it/developers/tutorials/erc20-annotated-code/index.md b/public/content/translations/it/developers/tutorials/erc20-annotated-code/index.md index 77d28e8c2a6..57e00e002af 100644 --- a/public/content/translations/it/developers/tutorials/erc20-annotated-code/index.md +++ b/public/content/translations/it/developers/tutorials/erc20-annotated-code/index.md @@ -1,30 +1,33 @@ --- title: "Guida dettagliata al contratto ERC-20" -description: Cosa c'è nel contratto ERC-20 di OpenZeppelin e a cosa serve? +description: "Cosa c'è nel contratto ERC-20 di OpenZeppelin e perché?" author: Ori Pomerantz lang: it -tags: - - "solidity" - - "erc-20" +tags: [ "Solidity", "erc-20" ] skill: beginner published: 2021-03-09 --- ## Introduzione {#introduction} -Uno degli utilizzi più comuni di Ethereum è quello di permettere a un gruppo di persone di creare un token scambiabile, che potremmo definire la loro valuta. In genere questi token seguono uno standard, l'[ERC-20](/developers/docs/standards/tokens/erc-20/). Questo standard permette di scrivere gli strumenti, come pool di liquidità e wallet, compatibili con tutti i token ERC-20. In questo articolo analizzeremo l'[Implementazione di ERC20 in Solidity su OpenZeppelin](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC20/ERC20.sol), nonché la [definizione dell'interfaccia](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC20/IERC20.sol). +Uno degli utilizzi più comuni di Ethereum è quello di permettere a un gruppo di persone di creare un token scambiabile, che potremmo definire la loro valuta. Questi token seguono in genere uno standard, +[ERC-20](/developers/docs/standards/tokens/erc-20/). Questo standard permette di scrivere strumenti, come pool di liquidità e portafogli, compatibili con tutti i token ERC-20. In questo articolo analizzeremo l'[implementazione ERC20 di OpenZeppelin in Solidity](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC20/ERC20.sol), nonché la [definizione dell'interfaccia](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC20/IERC20.sol). -Qui parliamo del codice sorgente annotato. Se vuoi implementare ERC-20, [leggi questo tutorial](https://docs.openzeppelin.com/contracts/2.x/erc20-supply). +Questo è un codice sorgente annotato. Se vuoi implementare l'ERC-20, +[leggi questa guida](https://docs.openzeppelin.com/contracts/2.x/erc20-supply). ## L'interfaccia {#the-interface} -Lo scopo di uno standard come ERC-20 è quello di consentire molte implementazioni di token che siano interoperabili tra le varie applicazioni, quali wallet e scambi decentralizzati. A tale scopo, creiamo un'[interfaccia](https://www.geeksforgeeks.org/solidity-basics-of-interface/). Ogni codice che necessita di usare il contratto del token può avvalersi delle stesse definizioni nell'interfaccia ed essere compatibile con tutti i contratti del token che la usano, che si tratti di un portafoglio come MetaMask, una dApp come etherscan.io o un contratto diverso, come un pool di liquidità. +Lo scopo di uno standard come l'ERC-20 è di consentire molte implementazioni di token che siano interoperabili tra le varie applicazioni, quali portafogli ed exchange decentralizzati. Per raggiungere questo obiettivo, creiamo un'[interfaccia](https://www.geeksforgeeks.org/solidity/solidity-basics-of-interface/). Qualsiasi codice che debba usare il contratto del token +può usare le stesse definizioni nell'interfaccia ed essere compatibile con tutti i contratti di token che la usano, che si tratti di un portafoglio come +MetaMask, una dApp come etherscan.io o un contratto diverso come un pool di liquidità. -![Illustrazione dell'interfaccia di ERC-20](erc20_interface.png) +![Illustrazione dell'interfaccia ERC-20](erc20_interface.png) -Se sei un programmatore esperto, probabilmente ricorderai di aver visto costrutti simili in [Java](https://www.w3schools.com/java/java_interface.asp) o persino nei [file d'intestazione in C](https://gcc.gnu.org/onlinedocs/cpp/Header-Files.html). +Se sei un programmatore esperto, probabilmente ricorderai di aver visto costrutti simili in [Java](https://www.w3schools.com/java/java_interface.asp) o persino nei [file header C](https://gcc.gnu.org/onlinedocs/cpp/Header-Files.html). -Questa è una definizione dell'[Interfaccia di ERC-20](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC20/IERC20.sol) da OpenZeppelin. È una traduzione dello [standard leggibile umano](https://eips.ethereum.org/EIPS/eip-20) nel codice di Solidity. Ovviamente, l'interfaccia di per sé non definisce _come_ fare qualcosa. Ciò è spiegato nel codice sorgente del contratto di seguito. +Questa è una definizione dell'[Interfaccia ERC-20](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC20/IERC20.sol) di OpenZeppelin. È una traduzione dello [standard leggibile dall'uomo](https://eips.ethereum.org/EIPS/eip-20) in codice Solidity. Naturalmente, l'interfaccia +stessa non definisce _come_ fare nulla. Questo è spiegato nel codice sorgente del contratto qui sotto.   @@ -32,7 +35,8 @@ Questa è una definizione dell'[Interfaccia di ERC-20](https://github.com/OpenZe // SPDX-License-Identifier: MIT ``` -I file di Solidity dovrebbero includere un'identificativo della licenza. [Puoi vedere qui l'elenco di licenze](https://spdx.org/licenses/). Se hai bisogno di una licenza diversa, basta spiegarlo nei commenti. +I file Solidity dovrebbero includere un identificatore di licenza. [Puoi vedere l'elenco delle licenze qui](https://spdx.org/licenses/). Se hai bisogno di una licenza diversa, +puoi semplicemente spiegarlo nei commenti.   @@ -40,17 +44,20 @@ I file di Solidity dovrebbero includere un'identificativo della licenza. [Puoi v pragma solidity >=0.6.0 <0.8.0; ``` -Il linguaggio Solidity si sta ancora evolvendo rapidamente e le nuove versioni potrebbero non essere compatibili con il vecchio codice ([vedi qui](https://docs.soliditylang.org/en/v0.7.0/070-breaking-changes.html)). Dunque, è una buona idea specificare non solo una versione minima del linguaggio, ma anche una versione massima, l'ultima con cui hai testato il codice. +Il linguaggio Solidity si sta ancora evolvendo rapidamente e le nuove versioni potrebbero non essere compatibili con il codice obsoleto +([vedi qui](https://docs.soliditylang.org/en/v0.7.0/070-breaking-changes.html)). Pertanto, è una buona idea specificare non solo una versione minima +del linguaggio, ma anche una versione massima, l'ultima con cui hai testato il codice.   ```solidity /** - * @dev Interface of the ERC20 standard as defined in the EIP. + * @dev Interfaccia dello standard ERC20 come definito nell'EIP. */ ``` -Il `@dev` nel commento è parte del [formato NatSpec](https://docs.soliditylang.org/en/develop/natspec-format.html), usato per produrre la documentazione dal codice sorgente. +Il `@dev` nel commento fa parte del [formato NatSpec](https://docs.soliditylang.org/en/develop/natspec-format.html), usato per produrre +la documentazione dal codice sorgente.   @@ -58,135 +65,162 @@ Il `@dev` nel commento è parte del [formato NatSpec](https://docs.soliditylang. interface IERC20 { ``` -Per convenzione, i nomi dell'interfaccia iniziano per `I`. +Per convenzione, i nomi delle interfacce iniziano con `I`.   ```solidity /** - * @dev Returns the amount of tokens in existence. + * @dev Restituisce la quantità di token esistenti. */ function totalSupply() external view returns (uint256); ``` -Questa funzione è `external`, a significare che [può essere chiamata solo dal di fuori del contratto](https://docs.soliditylang.org/en/v0.7.0/cheatsheet.html#index-2). Restituisce la fornitura totale di token nel contratto. Questo valore è restituito usando il tipo più comune in Ethereum, ovvero 256 bit non firmati (256 bit è la dimensione nativa della parola dell'EVM). Questa funzione è anche una `view`, il che significa che non cambia stato, quindi è eseguibile su un nodo singolo invece di farla eseguire da ciascun nodo nella blockchain. Questo tipo di funzione non genera una transazione e non costa [gas](/developers/docs/gas/). +Questa funzione è `external`, il che significa che [può essere chiamata solo dall'esterno del contratto](https://docs.soliditylang.org/en/v0.7.0/cheatsheet.html#index-2). +Restituisce la fornitura totale di token nel contratto. Questo valore è restituito usando il tipo più comune in Ethereum, 256 bit senza segno (256 bit è la dimensione +nativa della parola dell'EVM). Questa funzione è anche una `view`, il che significa che non modifica lo stato, quindi può essere eseguita su un singolo nodo anziché da ogni nodo della blockchain. Questo tipo di funzione non genera una transazione e non costa [gas](/developers/docs/gas/). -**Nota:** In teoria, si potrebbe pensare che il creatore del contratto possa imbrogliare restituendo una fornitura totale inferiore al valore reale, facendo apparire ogni token come più prezioso di quanto sia realmente. Tuttavia, tale timore ignora la vera natura della blockchain. Tutto ciò che succede sulla blockchain è verificabile da ogni nodo. A tale scopo, il codice del linguaggio della macchina e la memoria di ciascun contratto sono disponibili su tutti i nodi. Benché non sia obbligatorio pubblicare il codice di Solidity per il tuo contratto, nessuno ti prenderebbe sul serio se non pubblicassi il codice sorgente e la versione di Solidity con cui lo hai compilato, così da renderlo verificabile rispetto al codice del linguaggio della macchina che hai indicato. Vediamo ad esempio [questo contratto](https://etherscan.io/address/0xa530F85085C6FE2f866E7FdB716849714a89f4CD#code). +**Nota:** in teoria, potrebbe sembrare che un creatore di un contratto possa imbrogliare restituendo una fornitura totale inferiore al valore reale, facendo apparire ogni token +più prezioso di quanto non sia in realtà. Tuttavia, questo timore ignora la vera natura della blockchain. Tutto ciò che accade sulla blockchain può essere verificato da +ogni nodo. Per raggiungere questo obiettivo, il codice in linguaggio macchina e lo spazio di archiviazione di ogni contratto sono disponibili su ogni nodo. Sebbene non sia obbligatorio pubblicare il codice Solidity +per il tuo contratto, nessuno ti prenderebbe sul serio se non pubblicassi il codice sorgente e la versione di Solidity con cui è stato compilato, in modo che possa +essere verificato rispetto al codice in linguaggio macchina fornito. +Ad esempio, vedi [questo contratto](https://eth.blockscout.com/address/0xa530F85085C6FE2f866E7FdB716849714a89f4CD?tab=contract).   ```solidity /** - * @dev Returns the amount of tokens owned by `account`. + * @dev Restituisce la quantità di token posseduti da `account`. */ function balanceOf(address account) external view returns (uint256); ``` -Come dice il nome `balanceOf` restituisce il saldo di un conto. I conti di Ethereum sono identificati in Solidity usando il tipo `address`, contenente 160 bit. È anche `external` e `view`. +Come suggerisce il nome, `balanceOf` restituisce il saldo di un account. Gli account Ethereum sono identificati in Solidity tramite il tipo `address`, che contiene 160 bit. +È anche `external` e `view`.   ```solidity /** - * @dev Moves `amount` tokens from the caller's account to `recipient`. + * @dev Sposta una quantità `amount` di token dall'account del chiamante al `recipient`. * - * Returns a boolean value indicating whether the operation succeeded. + * Restituisce un valore booleano che indica se l'operazione è riuscita. * - * Emits a {Transfer} event. + * Emette un evento {Transfer}. */ function transfer(address recipient, uint256 amount) external returns (bool); ``` -La funzione `transfer` trasferisce i token dal chiamante a un indirizzo diverso. Ciò implica un cambio di stato, quindi non è una `view`. Quando un utente chiama questa funzione, crea una transazione e consuma del gas. Inoltre viene emesso un evento, `Transfer`, per informare tutti sulla blockchain dell'evento. +La funzione `transfer` trasferisce dei token dal chiamante a un indirizzo diverso. Ciò implica una modifica di stato, quindi non è una `view`. +Quando un utente chiama questa funzione, crea una transazione e consuma del gas. Emette anche un evento, `Transfer`, per informare tutti +sulla blockchain dell'evento. La funzione ha due tipi di output per due diversi tipi di chiamanti: -- Gli utenti che chiamano la funzione direttamente da un'interfaccia utente. In genere l'utente invia una transazione e non attende una risposta, il che potrebbe richiedere un tempo indefinito. L'utente può vedere cosa è successo cercando la ricevuta della transazione (identificata dall'hash della transazione) o cercando l'evento `Transfer`. -- Altri contratti, che chiamano la funzione nell'ambito di una transazione complessiva. Questi ottengono il risultato immediatamente, perché sono eseguiti nella transazione stessa, così da poter usare il valore di ritorno della funzione. +- Utenti che chiamano la funzione direttamente da un'interfaccia utente. In genere, l'utente invia una transazione + e non attende una risposta, il che potrebbe richiedere un tempo indefinito. L'utente può vedere cosa è successo + cercando la ricevuta della transazione (identificata dall'hash della transazione) o l'evento + `Transfer`. +- Altri contratti, che chiamano la funzione come parte di una transazione complessiva. Questi contratti ottengono il risultato immediatamente, + perché vengono eseguiti nella stessa transazione, quindi possono usare il valore di ritorno della funzione. -Lo stesso tipo di output è creato da altre funzioni che cambiano lo stato del contratto. +Lo stesso tipo di output è creato dalle altre funzioni che modificano lo stato del contratto.   -Le indennità permettono a un conto di spendere dei token appartenenti a un altro proprietario. Ciò è utile, ad esempio, per i contratti che fungono da venditori. I contratti non possono monitorare gli eventi, quindi se un acquirente dovesse trasferire token al contratto del venditore direttamente, quel contratto non saprebbe di aver ricevuto il pagamento. Invece, l'acquirente permette al contratto del venditore di spendere un certo importo e il venditore trasferisce quell'importo. Questo avviene tramite un funzione chiamata dal contratto del venditore, in modo tale che il contratto del venditore possa sapere se è andata a buon fine. +Le autorizzazioni consentono a un account di spendere alcuni token che appartengono a un proprietario diverso. +Questo è utile, ad esempio, per i contratti che fungono da venditori. I contratti non possono +monitorare gli eventi, quindi se un acquirente trasferisse token al contratto del venditore +direttamente, quel contratto non saprebbe di essere stato pagato. Invece, l'acquirente autorizza il contratto +del venditore a spendere un certo importo, e il venditore trasferisce tale importo. +Ciò avviene tramite una funzione chiamata dal contratto del venditore, in modo che il contratto del venditore +possa sapere se la chiamata ha avuto successo. ```solidity /** - * @dev Returns the remaining number of tokens that `spender` will be - * allowed to spend on behalf of `owner` through {transferFrom}. This is - * zero by default. + * @dev Restituisce il numero residuo di token che `spender` potrà + * spendere per conto di `owner` tramite {transferFrom}. Il valore predefinito + * è zero. * - * This value changes when {approve} or {transferFrom} are called. + * Questo valore cambia quando vengono chiamate {approve} o {transferFrom}. */ function allowance(address owner, address spender) external view returns (uint256); ``` -La funzione `allowance` consente a chiunque di richiedere di vedere quale sia il margine di tolleranza che un indirizzo (`owner`) permette all'altro indirizzo (`spender`) di spendere. +La funzione `allowance` consente a chiunque di interrogare per vedere qual è l'autorizzazione che un +indirizzo (`owner`) concede a un altro indirizzo (`spender`) per la spesa.   ```solidity /** - * @dev Sets `amount` as the allowance of `spender` over the caller's tokens. + * @dev Imposta `amount` come autorizzazione di `spender` sui token del chiamante. * - * Returns a boolean value indicating whether the operation succeeded. + * Restituisce un valore booleano che indica se l'operazione è riuscita. * - * IMPORTANT: Beware that changing an allowance with this method brings the risk - * that someone may use both the old and the new allowance by unfortunate - * transaction ordering. One possible solution to mitigate this race - * condition is to first reduce the spender's allowance to 0 and set the - * desired value afterwards: + * IMPORTANTE: fai attenzione al fatto che la modifica di un'autorizzazione con questo metodo comporta il rischio + * che qualcuno possa utilizzare sia la vecchia che la nuova autorizzazione a causa di un + * sfortunato ordine delle transazioni. Una possibile soluzione per mitigare questa race + * condition è ridurre prima l'autorizzazione dello spender a 0 e impostare il + * valore desiderato in seguito: * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 * - * Emits an {Approval} event. + * Emette un evento {Approval}. */ function approve(address spender, uint256 amount) external returns (bool); ``` -La funzione `approve` crea una tolleranza. Assicurati di leggere il messaggio sui rischi di utilizzo improprio. In Ethereum puoi controllare l'ordine delle tue transazioni, ma non puoi controllare l'ordine con cui le transazioni altrui saranno eseguite, a meno che tu tenga in sospeso la tua transazione finché non vedi che la transazione dell'altro lato ha avuto luogo. +La funzione `approve` crea un'autorizzazione. Assicurati di leggere il messaggio sui +rischi di utilizzo improprio. In Ethereum controlli l'ordine delle tue transazioni, +ma non puoi controllare l'ordine in cui verranno eseguite le transazioni di altre persone, +a meno che non invii la tua transazione solo dopo aver visto che la transazione +dell'altra parte è avvenuta.   ```solidity /** - * @dev Moves `amount` tokens from `sender` to `recipient` using the - * allowance mechanism. `amount` is then deducted from the caller's - * allowance. + * @dev Sposta una quantità `amount` di token da `sender` a `recipient` usando il + * meccanismo di autorizzazione. L'importo `amount` viene quindi dedotto dall'autorizzazione + * del chiamante. * - * Returns a boolean value indicating whether the operation succeeded. + * Restituisce un valore booleano che indica se l'operazione è riuscita. * - * Emits a {Transfer} event. + * Emette un evento {Transfer}. */ function transferFrom(address sender, address recipient, uint256 amount) external returns (bool); ``` -Infine, `transferFrom` è usata dallo spender per spendere concretamente il margine di tolleranza. +Infine, `transferFrom` viene utilizzato dallo spender per spendere effettivamente l'autorizzazione.   ```solidity /** - * @dev Emitted when `value` tokens are moved from one account (`from`) to - * another (`to`). + * @dev Emesso quando i token `value` vengono spostati da un account (`from`) a + * un altro (`to`). * - * Note that `value` may be zero. + * Nota che `value` può essere zero. */ event Transfer(address indexed from, address indexed to, uint256 value); /** - * @dev Emitted when the allowance of a `spender` for an `owner` is set by - * a call to {approve}. `value` is the new allowance. + * @dev Emesso quando l'autorizzazione di uno `spender` per un `owner` è impostata da + * una chiamata a {approve}. `value` è la nuova autorizzazione. */ event Approval(address indexed owner, address indexed spender, uint256 value); } ``` -Questi eventi sono emessi quando lo stato del contratto ERC-20 cambia. +Questi eventi vengono emessi quando lo stato del contratto ERC-20 cambia. -## Il Contratto effettivo {#the-actual-contract} +## Il contratto effettivo {#the-actual-contract} -Si tratta del contratto vero e proprio che implementa lo standard ERC-20, [preso da qui](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC20/ERC20.sol). Non è destinato a essere utilizzato così com'è, ma puoi [ereditare](https://www.tutorialspoint.com/solidity/solidity_inheritance.htm) la sua struttura ed estenderla per ottenere un qualcosa di utilizzabile. +Questo è il contratto effettivo che implementa lo standard ERC-20, +[tratto da qui](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC20/ERC20.sol). +Non è destinato a essere usato così com'è, ma puoi [ereditare](https://www.tutorialspoint.com/solidity/solidity_inheritance.htm) da esso per estenderlo a qualcosa di utilizzabile. ```solidity // SPDX-License-Identifier: MIT @@ -195,9 +229,9 @@ pragma solidity >=0.6.0 <0.8.0;   -### Dichiarazioni relative all'importazione {#import-statements} +### Dichiarazioni di importazione {#import-statements} -Oltre alle definizioni d'interfaccia summenzionate, la definizione del contratto importa altri due file: +Oltre alle definizioni di interfaccia di cui sopra, la definizione del contratto importa altri due file: ```solidity @@ -206,8 +240,8 @@ import "./IERC20.sol"; import "../../math/SafeMath.sol"; ``` -- `GSN/Context.sol` è la definizione necessaria per usare [OpenGSN](https://www.opengsn.org/), un sistema che consente agli utenti senza ether di usare la blockchain. Tieni conto che questa è una versione obsoleta. Se vuoi integrare con OpenGSN [usa questo tutorial](https://docs.opengsn.org/javascript-client/tutorial.html). -- [La libreria SafeMath](https://ethereumdev.io/using-safe-math-library-to-prevent-from-overflows/), usata per effettuare addizioni e sottrazioni senza sovraflussi. È necessaria perché altrimenti una persona potrebbe in qualche modo avere un token, spenderne due e poi ritrovarsi con 2^256-1. +- `GSN/Context.sol` contiene le definizioni necessarie per utilizzare [OpenGSN](https://www.opengsn.org/), un sistema che permette agli utenti senza ether di usare la blockchain. Si noti che questa è una versione obsoleta; se si desidera integrare con OpenGSN, [utilizzare questa guida](https://docs.opengsn.org/javascript-client/tutorial.html). +- [La libreria SafeMath](https://ethereumdev.io/using-safe-math-library-to-prevent-from-overflows/), che previene gli overflow/underflow aritmetici per le versioni di Solidity **<0.8.0**. In Solidity ≥0.8.0, le operazioni aritmetiche eseguono automaticamente il revert in caso di overflow/underflow, rendendo SafeMath non necessaria. Questo contratto usa SafeMath per la retrocompatibilità con le versioni precedenti del compilatore.   @@ -215,33 +249,32 @@ Questo commento spiega lo scopo del contratto. ```solidity /** - * @dev Implementation of the {IERC20} interface. + * @dev Implementazione dell'interfaccia {IERC20}. * - * This implementation is agnostic to the way tokens are created. This means - * that a supply mechanism has to be added in a derived contract using {_mint}. - * For a generic mechanism see {ERC20PresetMinterPauser}. + * Questa implementazione è agnostica al modo in cui vengono creati i token. Ciò significa + * che un meccanismo di fornitura deve essere aggiunto in un contratto derivato usando {_mint}. + * Per un meccanismo generico, vedere {ERC20PresetMinterPauser}. * - * TIP: For a detailed writeup see our guide - * https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How - * to implement supply mechanisms]. + * SUGGERIMENTO: per una descrizione dettagliata, vedere la nostra guida + * https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[Come + * implementare i meccanismi di fornitura]. * - * We have followed general OpenZeppelin guidelines: functions revert instead - * of returning `false` on failure. This behavior is nonetheless conventional - * and does not conflict with the expectations of ERC20 applications. + * Abbiamo seguito le linee guida generali di OpenZeppelin: le funzioni eseguono il revert invece + * di restituire 'false' in caso di fallimento. Questo comportamento è comunque convenzionale + * e non è in conflitto con le aspettative delle applicazioni ERC20. * - * Additionally, an {Approval} event is emitted on calls to {transferFrom}. - * This allows applications to reconstruct the allowance for all accounts just - * by listening to said events. Other implementations of the EIP may not emit - * these events, as it isn't required by the specification. + * Inoltre, un evento {Approval} viene emesso sulle chiamate a {transferFrom}. + * Ciò consente alle applicazioni di ricostruire l'autorizzazione (allowance) per tutti i conti semplicemente + * rimanendo in ascolto di tali eventi. Altre implementazioni dell'EIP potrebbero non emettere + * questi eventi, poiché non è richiesto dalla specifica. * - * Finally, the non-standard {decreaseAllowance} and {increaseAllowance} - * functions have been added to mitigate the well-known issues around setting - * allowances. See {IERC20-approve}. + * Infine, sono state aggiunte le funzioni non standard {decreaseAllowance} e {increaseAllowance} + * per mitigare i noti problemi relativi all'impostazione + * delle autorizzazioni (allowance). Vedere {IERC20-approve}. */ - ``` -### Composizione del contratto {#contract-definition} +### Definizione del contratto {#contract-definition} ```solidity contract ERC20 is Context, IERC20 { @@ -257,19 +290,19 @@ Questa riga specifica l'eredità, in questo caso da `IERC20` da sopra e `Context ``` -Questa riga allega la libreria `SafeMath` al tipo `uint256`. Puoi trovare questa libreria [qui](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/utils/math/SafeMath.sol). +Questa riga associa la libreria `SafeMath` al tipo `uint256`. È possibile trovare questa libreria [qui](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/utils/math/SafeMath.sol). ### Definizioni delle variabili {#variable-definitions} -Queste definizioni specificano le variabili di stato del contratto. Queste variabili sono dichiarate come `private`, ma ciò significa solo che gli altri contratti sulla blockchain non possono leggerle. _Non ci sono segreti sulla blockchain_, il software su ogni nodo ha lo stato di ciascun contratto in ogni blocco. Per convenzione, le variabili di stato sono denominate `_`. +Queste definizioni specificano le variabili di stato del contratto. Queste variabili sono dichiarate `private`, ma ciò significa solo che altri contratti sulla blockchain non possono leggerle. _Non ci sono segreti sulla blockchain_, il software su ogni nodo ha lo stato di ogni contratto in ogni blocco. Per convenzione, le variabili di stato sono denominate `_`. -Le prime due variabili sono di [mappatura](https://www.tutorialspoint.com/solidity/solidity_mappings.htm), il che significa che si comportano più o meno come [insiemi associativi](https://wikipedia.org/wiki/Associative_array), se con la differenza che le chiavi sono valori numerici. La memoria è allocata solo per le voci che hanno valori differenti dal default (zero). +Le prime due variabili sono [mapping](https://www.tutorialspoint.com/solidity/solidity_mappings.htm), il che significa che si comportano all'incirca come [array associativi](https://wikipedia.org/wiki/Associative_array), con la differenza che le chiavi sono valori numerici. Lo spazio di archiviazione viene allocato solo per le voci con valori diversi da quello predefinito (zero). ```solidity mapping (address => uint256) private _balances; ``` -La prima mappatura, `_balances` è composta da indirizzi e dai rispettivi saldi di questo token. Per accedere al saldo, usa questa sintassi: `_balances[
]`. +Il primo mapping, `_balances`, associa gli indirizzi ai rispettivi saldi di questo token. Per accedere al saldo, utilizzare la seguente sintassi: `_balances[
]`.   @@ -277,7 +310,7 @@ La prima mappatura, `_balances` è composta da indirizzi e dai rispettivi saldi mapping (address => mapping (address => uint256)) private _allowances; ``` -Questa variabile, `_allowances`, memorizza i margini di tolleranza spiegati in precedenza. Il primo indice è il proprietario dei token e il secondo è il contratto con il margine di tolleranza. Per accedere all'importo che l'indirizzo A può spendere dal conto dell'indirizzo B, usa `_allowances[B][A]`. +Questa variabile, `_allowances`, memorizza le autorizzazioni (allowance) spiegate in precedenza. Il primo indice è il proprietario dei token e il secondo è il contratto con l'autorizzazione (allowance). Per accedere all'importo che l'indirizzo A può spendere dal conto dell'indirizzo B, usare `_allowances[B][A]`.   @@ -297,25 +330,27 @@ Come suggerisce il nome, questa variabile tiene traccia della fornitura totale d Queste tre variabili sono usate per migliorare la leggibilità. Le prime due sono autoesplicative, ma `_decimals` no. -Da un lato, Ethereum non ha un numero in virgola mobile o variabili frazionali. Dall'altro, gli esseri vogliono la libertà di dividere i token. Un motivo per cui è stato scelto l'oro per gli scambi era la difficoltà di dare il resto quando qualcuno voleva comprare una quantità di mucca equivalente a un'anatra. +Da un lato, Ethereum non dispone di variabili in virgola mobile o frazionarie. D'altro canto, alle persone piace poter dividere i token. Un motivo per cui è stato scelto l'oro per gli scambi era la difficoltà di dare il resto quando qualcuno voleva comprare una quantità di mucca equivalente a un'anatra. -La soluzione è tenere traccia degli interi e, al posto del token reale, contare un token frazionale, quasi privo di valore. Nel caso dell'ether, il token frazionale è detto wei e 10^18 wei sono pari a un ETH. Mentre scriviamo questo articolo, 10.000.000.000.000 wei corrispondono a circa un centesimo di dollaro americano o di euro. +La soluzione è tenere traccia dei numeri interi, ma contare, invece del token reale, un token frazionario che è quasi senza valore. Nel caso dell'ether, il token frazionario è detto wei e 10^18 wei equivalgono a un ETH. Al momento della stesura di questo articolo, 10.000.000.000.000 di wei corrispondono a circa un centesimo di dollaro statunitense o di euro. -Le applicazioni devono sapere come mostrare il saldo di token. Se un utente ha 3.141.000.000.000.000.000 wei, vuol dire che ha in mano 3,14 ETH? O forse 31,41 ETH? O magari 3.141 ETH? Nel caso dell'ether, è definito a 10^18 wei per ETH, ma per il tuo token, puoi selezionare un valore differente. Se dividere il token non ha senso, puoi usare un valore `_decimals` di zero. Se vuoi usare lo stesso standard come ETH, usa il valore **18**. +Le applicazioni devono sapere come visualizzare il saldo del token. Se un utente ha 3.141.000.000.000.000.000 di wei, corrispondono a 3,14 ETH? 31,41 ETH? 3.141 ETH? Nel caso dell'ether, è definito che 10^18 wei corrispondono a un ETH, ma per il proprio token è possibile selezionare un valore diverso. Se dividere il token non ha senso, si può usare un valore di `_decimals` pari a zero. Se si desidera utilizzare lo stesso standard di ETH, usare il valore **18**. ### Il costruttore {#the-constructor} ```solidity /** - * @dev Sets the values for {name} and {symbol}, initializes {decimals} with - * a default value of 18. + * @dev Imposta i valori per {name} e {symbol}, inizializza {decimals} con + * un valore predefinito di 18. * - * To select a different value for {decimals}, use {_setupDecimals}. + * Per selezionare un valore diverso per {decimals}, usare {_setupDecimals}. * - * All three of these values are immutable: they can only be set once during - * construction. + * Tutti e tre questi valori sono immutabili: possono essere impostati solo una volta durante + * la costruzione. */ constructor (string memory name_, string memory symbol_) public { + // In Solidity ≥0.7.0, 'public' è implicito e può essere omesso. + _name = name_; _symbol = symbol_; _decimals = 18; @@ -328,57 +363,55 @@ Il costruttore viene chiamato alla prima creazione del contratto. Per convenzion ```solidity /** - * @dev Returns the name of the token. + * @dev Restituisce il nome del token. */ function name() public view returns (string memory) { return _name; } /** - * @dev Returns the symbol of the token, usually a shorter version of the - * name. + * @dev Restituisce il simbolo del token, di solito una versione più breve del nome. */ function symbol() public view returns (string memory) { return _symbol; } /** - * @dev Returns the number of decimals used to get its user representation. - * For example, if `decimals` equals `2`, a balance of `505` tokens should - * be displayed to a user as `5,05` (`505 / 10 ** 2`). + * @dev Restituisce il numero di decimali usati per ottenere la sua rappresentazione utente. + * Ad esempio, se `decimals` è uguale a `2`, un saldo di `505` token dovrebbe + * essere visualizzato a un utente come `5,05` (`505 / 10 ** 2`). * - * Tokens usually opt for a value of 18, imitating the relationship between - * ether and wei. This is the value {ERC20} uses, unless {_setupDecimals} is - * called. + * I token di solito optano per un valore di 18, imitando la relazione tra + * ether e wei. Questo è il valore che {ERC20} usa, a meno che non venga chiamato {_setupDecimals}. * - * NOTE: This information is only used for _display_ purposes: it in - * no way affects any of the arithmetic of the contract, including - * {IERC20-balanceOf} and {IERC20-transfer}. + * NOTA: questa informazione è usata solo a scopo di _visualizzazione_: non + * influenza in alcun modo l'aritmetica del contratto, inclusi + * {IERC20-balanceOf} e {IERC20-transfer}. */ function decimals() public view returns (uint8) { return _decimals; } ``` -Queste funzioni, `name`, `symbol`, e `decimals` aiutano le interfacce utente a conoscere il tuo contratto, in modo da visualizzarlo correttamente. +Queste funzioni, `name`, `symbol` e `decimals`, aiutano le interfacce utente a ottenere informazioni sul contratto, in modo da poterlo visualizzare correttamente. -Il tipo di restituzione è `string memory`, a significare che la restituzione è una stringa archiviata in memoria. Le variabili, come le stringhe, sono memorizzabili in tre posizioni: +Il tipo di ritorno è `string memory`, il che significa che viene restituita una stringa memorizzata in memoria. Le variabili, come le stringhe, possono essere memorizzate in tre posizioni: -| | Durata | Accesso al contratto | Costo del Gas | -| ------------- | ----------------------- | -------------------- | ---------------------------------------------------------------------------------- | -| Memoria | Chiamata della funzione | Lettura/Scrittura | Decine o centinaia (maggiori per maggiori posizioni) | -| Calldata | Chiamata della funzione | Sola Lettura | Inutilizzabile come tipo di restituzione, solo un tipo di parametro della funzione | -| Archiviazione | Fino alla modifica | Lettura/Scrittura | Elevato (800 per la lettura, 20.000 per la scrittura) | +| | Durata | Accesso al contratto | Costo del gas | +| -------- | ----------------------- | -------------------- | ------------------------------------------------------------------------------------------------------- | +| Memoria | Chiamata della funzione | Lettura/Scrittura | Decine o centinaia (superiore per posizioni superiori) | +| Calldata | Chiamata della funzione | Sola Lettura | Non può essere usato come tipo di ritorno, solo come tipo di parametro di una funzione. | +| Storage | Fino alla modifica | Lettura/Scrittura | Elevato (800 per la lettura, 20.000 per la scrittura) | In questo caso, `memory` è la scelta migliore. -### Informazioni di lettura del token {#read-token-information} +### Lettura delle informazioni sul token {#read-token-information} -Queste sono funzioni che forniscono informazioni sul token, la fornitura totale o il saldo di un conto. +Queste sono funzioni che forniscono informazioni sul token, sulla fornitura totale o sul saldo di un conto. ```solidity /** - * @dev See {IERC20-totalSupply}. + * @dev Vedere {IERC20-totalSupply}. */ function totalSupply() public view override returns (uint256) { return _totalSupply; @@ -391,30 +424,30 @@ La funzione `totalSupply` restituisce la fornitura totale di token. ```solidity /** - * @dev See {IERC20-balanceOf}. + * @dev Vedere {IERC20-balanceOf}. */ function balanceOf(address account) public view override returns (uint256) { return _balances[account]; } ``` -Leggi il saldo di un conto. Nota che chiunque può ottenere il saldo del conto di qualcun altro. Non ha senso provare a nascondere queste informazioni, perché sono comunque disponibili su ogni nodo. _Non ci sono segreti sulla blockchain._ +Legge il saldo di un conto. Si noti che chiunque è autorizzato a ottenere il saldo del conto di chiunque altro. Non ha senso provare a nascondere queste informazioni, perché sono comunque disponibili su ogni nodo. _Non ci sono segreti sulla blockchain._ -### Trasferire token {#transfer-tokens} +### Trasferimento di token {#transfer-tokens} ```solidity /** - * @dev See {IERC20-transfer}. + * @dev Vedere {IERC20-transfer}. * - * Requirements: + * Requisiti: * - * - `recipient` cannot be the zero address. - * - the caller must have a balance of at least `amount`. + * - `recipient` non può essere l'indirizzo zero. + * - il chiamante deve avere un saldo di almeno `amount`. */ function transfer(address recipient, uint256 amount) public virtual override returns (bool) { ``` -La funzione `transfer` è chiamata per trasferire i token dal conto del mittente a un altro. Nota che anche se viene restituito un valore booleano, quel valore è sempre **true**. Se il trasferimento fallisce, il contratto ripristina la chiamata. +La funzione `transfer` è chiamata per trasferire i token dal conto del mittente a un altro. Si noti che, anche se restituisce un valore booleano, tale valore è sempre **true**. Se il trasferimento fallisce, il contratto esegue il revert della chiamata.   @@ -424,44 +457,44 @@ La funzione `transfer` è chiamata per trasferire i token dal conto del mittente } ``` -La funzione `_transfer` fa il lavoro effettivo. È una funzione privata, chiamabile solo da altre funzioni del contratto. Per convenzione le funzioni private sono denominate `_`, come le variabili di stato. +La funzione `_transfer` esegue il lavoro vero e proprio. È una funzione privata, che può essere chiamata solo da altre funzioni del contratto. Per convenzione, le funzioni private sono denominate `_`, come le variabili di stato. -Normalmente, in Solidity usiamo `msg.sender` per il mittente del messaggio. Tuttavia, ciò corrompe [OpenGSN](http://opengsn.org/). Se vogliamo consentire transazioni senza ether con il nostro token, dobbiamo usare `_msgSender()`. Restituisce `msg.sender` per le transazioni normali, ma per quelle senza ether restituisce il firmatario originale e non il contratto che ha trasmesso il messaggio. +Normalmente in Solidity si usa `msg.sender` per il mittente del messaggio. Tuttavia, questo non è compatibile con [OpenGSN](http://opengsn.org/). Se si desidera consentire transazioni senza ether con il proprio token, è necessario utilizzare `_msgSender()`. Restituisce `msg.sender` per le transazioni normali, ma per quelle senza ether restituisce il firmatario originale e non il contratto che ha inoltrato il messaggio. -### Funzioni di tolleranza {#allowance-functions} +### Funzioni di autorizzazione (allowance) {#allowance-functions} -Sono le funzioni che implementano il margine di tolleranza: `allowance`, `approve`, `transferFrom` e `_approve`. Inoltre, l'implementazione di OpenZeppelin va oltre lo standard di base e include alcune funzionalità che migliorano la sicurezza: `increaseAllowance` e `decreaseAllowance`. +Queste sono le funzioni che implementano la funzionalità di autorizzazione (allowance): `allowance`, `approve`, `transferFrom` e `_approve`. Inoltre, l'implementazione di OpenZeppelin va oltre lo standard di base e include alcune funzionalità che migliorano la sicurezza: `increaseAllowance` e `decreaseAllowance`. -#### La funzione di tolleranza {#allowance} +#### La funzione allowance {#allowance} ```solidity /** - * @dev See {IERC20-allowance}. + * @dev Vedere {IERC20-allowance}. */ function allowance(address owner, address spender) public view virtual override returns (uint256) { return _allowances[owner][spender]; } ``` -La funzione `allowance` consente a chiunque di verificare qualsiasi margine di tolleranza. +La funzione `allowance` permette a chiunque di controllare qualsiasi autorizzazione (allowance). -#### La funzione di approvazione {#approve} +#### La funzione approve {#approve} ```solidity /** - * @dev See {IERC20-approve}. + * @dev Vedere {IERC20-approve}. * - * Requirements: + * Requisiti: * - * - `spender` cannot be the zero address. + * - `spender` non può essere l'indirizzo zero. */ function approve(address spender, uint256 amount) public virtual override returns (bool) { ``` -Questa funzione viene chiamata per creare un margine di tolleranza. È simile alla suddetta funzione `transfer`: +Questa funzione viene chiamata per creare un'autorizzazione (allowance). È simile alla funzione `transfer` di cui sopra: -- La funzione chiama semplicemente una funzione interna (in questo caso, `_approve`), che fa il lavoro vero e proprio. -- La funzione restituisce `true` (se va a buon fine), altrimenti si ripristina. +- La funzione si limita a chiamare una funzione interna (in questo caso, `_approve`) che esegue il lavoro vero e proprio. +- La funzione restituisce `true` (in caso di successo) o esegue il revert (in caso contrario).   @@ -471,24 +504,24 @@ Questa funzione viene chiamata per creare un margine di tolleranza. È simile al } ``` -Usiamo le funzioni interne per minimizzre il numero di posti in cui si verificano cambi di stato. _Qualsiasi_ funzione che cambia stato costituisce un potenziale rischio di sicurezza, che va controllato per sicurezza. Così facendo riduciamo il rischio di conseguenze negative. +Usiamo le funzioni interne per ridurre al minimo il numero di punti in cui avvengono le modifiche di stato. _Qualsiasi_ funzione che modifica lo stato è un potenziale rischio per la sicurezza che deve essere controllato. In questo modo abbiamo meno possibilità di sbagliare. #### La funzione transferFrom {#transferFrom} -È la funzione chiamata dallo spender per spendere un margine di tolleranza. Richiede due operazioni: trasferire l'importo speso e ridurre il margine di tolleranza in misura pari allo stesso importo. +Questa è la funzione che uno spender chiama per utilizzare un'autorizzazione (allowance). Ciò richiede due operazioni: trasferire l'importo speso e ridurre l'autorizzazione (allowance) di tale importo. ```solidity /** - * @dev See {IERC20-transferFrom}. + * @dev Vedere {IERC20-transferFrom}. * - * Emits an {Approval} event indicating the updated allowance. This is not - * required by the EIP. See the note at the beginning of {ERC20}. + * Emette un evento {Approval} che indica l'autorizzazione (allowance) aggiornata. Questo non + * è richiesto dall'EIP. Vedere la nota all'inizio di {ERC20}. * - * Requirements: + * Requisiti: * - * - `sender` and `recipient` cannot be the zero address. - * - `sender` must have a balance of at least `amount`. - * - the caller must have allowance for ``sender``'s tokens of at least + * - `sender` e `recipient` non possono essere l'indirizzo zero. + * - `sender` deve avere un saldo di almeno `amount`. + * - il chiamante deve disporre di un'autorizzazione (allowance) per i token di ``sender`` di almeno * `amount`. */ function transferFrom(address sender, address recipient, uint256 amount) public virtual @@ -498,59 +531,66 @@ Usiamo le funzioni interne per minimizzre il numero di posti in cui si verifican   -La funzione `a.sub(b, "message")` produce due azioni. Innanzi tutto calcola `a-b`, ovvero il nuovo margine di tolleranza (allowance). Quindi controlla che tale risultato non sia negativo. Se lo è, la chiamata si ripristina con il messaggio fornito. Occorre notare che, in caso di ripristino, qualsiasi elaborazione effettuata in precedenza durante tale chiamata viene ignorata, così da evitare di dover annullare il `_transfer`. +La chiamata di funzione `a.sub(b, "messaggio")` esegue due operazioni. Innanzitutto, calcola `a-b`, che è la nuova autorizzazione (allowance). +In secondo luogo, controlla che il risultato non sia negativo. Se è negativo, la chiamata esegue il revert con il messaggio fornito. Si noti che quando una chiamata esegue il revert, qualsiasi elaborazione eseguita in precedenza durante tale chiamata viene ignorata, quindi non è necessario annullare il `_transfer`. ```solidity _approve(sender, _msgSender(), _allowances[sender][_msgSender()].sub(amount, - "ERC20: transfer amount exceeds allowance")); + "ERC20: l'importo del trasferimento supera l'autorizzazione (allowance)")); return true; } ``` #### Aggiunte di sicurezza di OpenZeppelin {#openzeppelin-safety-additions} -È pericoloso impostare un margine di tolleranza diverso da zero su un altro valore diverso da zero, perché puoi controllare solo l'ordine delle tue transazioni, ma non di quelle altrui. Immagina che ci siano due utenti: Alice, una ragazza ingenua, e Bill, un uomo disonesto. Alice vuole ricevere da Bill un servizio che secondo lei costa cinque token, quindi concede a Bill un margine di tolleranza di cinque token. +È pericoloso impostare un'autorizzazione (allowance) non nulla su un altro valore non nullo, perché si può controllare solo l'ordine delle proprie transazioni, non quello degli altri. Immaginiamo due utenti: Alice, che è ingenua, e Bill, che è disonesto. Alice vuole un servizio da Bill, che pensa costi cinque token, quindi dà a Bill un'autorizzazione (allowance) di cinque token. -Poi qualcosa cambia e il prezzo di Bill aumenta a dieci token. Alice, che è ancora interessata a ricevere il servizio, invia una transazione che imposta il margine di tolleranza di Bill a dieci. Quando Bill vede questa nuova transazione nel pool della transazione, invia una transazione che spende cinque token di Alice e ha un prezzo del gas molto maggiore, così che sarà minata più rapidamente. In questo modo Bill può spendere prima i cinque token e poi, una volta minato il nuovo margine di tolleranza di Alice, spenderne altri dieci per un prezzo complessivo di quindici token, più di quanto Alice volesse autorizzare. Questa tecnica è detta [front-running](https://consensysdiligence.github.io/smart-contract-best-practices/attacks/#front-running) +Poi qualcosa cambia e il prezzo di Bill sale a dieci token. Alice, che vuole ancora il servizio, invia una transazione che imposta l'autorizzazione (allowance) di Bill a dieci. Nel momento in cui Bill vede questa nuova transazione nel pool di transazioni, ne invia una che spende i cinque token di Alice e ha un prezzo del gas molto più alto, in modo che venga minata più velocemente. In questo modo Bill può spendere prima cinque token e poi, +una volta minata la nuova autorizzazione di Alice, spenderne altri dieci per un prezzo totale di quindici token, più di quanto +Alice intendesse autorizzare. Questa tecnica è chiamata +[front-running](https://consensysdiligence.github.io/smart-contract-best-practices/attacks/#front-running) -| Transazione di Alice | Nonce di Alice | Transazione di Bill | Nonce di Bill | Tolleranza di Bill | Entrate totali di Bill da Alice | -| -------------------- | -------------- | ----------------------------- | ------------- | ------------------ | ------------------------------- | -| approve(Bill, 5) | 10 | | | 5 | 0 | -| | | transferFrom(Alice, Bill, 5) | 10,123 | 0 | 5 | -| approve(Bill, 10) | 11 | | | 10 | 5 | -| | | transferFrom(Alice, Bill, 10) | 10,124 | 0 | 15 | +| Transazione di Alice | Nonce di Alice | Transazione di Bill | Nonce di Bill | Autorizzazione di Bill | Guadagno totale di Bill da Alice | +| ------------------------------------ | -------------- | ------------------------------------------------ | ---------------------- | ---------------------- | -------------------------------- | +| approve(Bill, 5) | 10 | | | 5 | 0 | +| | | transferFrom(Alice, Bill, 5) | 10.123 | 0 | 5 | +| approve(Bill, 10) | 11 | | | 10 | 5 | +| | | transferFrom(Alice, Bill, 10) | 10.124 | 0 | 15 | -Per evitare questo problema, queste due funzioni (`increaseAllowance` e `decreaseAllowance`) ti consentono di modificare il margine di tolleranza di un importo specifico. Quindi, se Bill avesse già speso cinque token, potrà spenderne solo altri cinque. A seconda delle tempistiche, esistono due modi in cui questo può funzionare, entrambi terminano con Bill che riceve solo dieci token: +Per evitare questo problema, queste due funzioni (`increaseAllowance` e `decreaseAllowance`) ti consentono +di modificare l'autorizzazione di un importo specifico. Quindi, se Bill avesse già speso cinque token, potrà +spenderne solo altri cinque. A seconda della tempistica, ci sono due modi in cui questo può funzionare, entrambi +terminano con Bill che riceve solo dieci token: A: -| Transazione di Alice | Nonce di Alice | Transazione di Bill | Nonce di Bill | Tolleranza di Bill | Entrate totali di Bill da Alice | -| -------------------------- | --------------:| ---------------------------- | -------------:| ------------------:| ------------------------------- | -| approve(Bill, 5) | 10 | | | 5 | 0 | -| | | transferFrom(Alice, Bill, 5) | 10,123 | 0 | 5 | -| increaseAllowance(Bill, 5) | 11 | | | 0+5 = 5 | 5 | -| | | transferFrom(Alice, Bill, 5) | 10,124 | 0 | 10 | +| Transazione di Alice | Nonce di Alice | Transazione di Bill | Nonce di Bill | Autorizzazione di Bill | Guadagno totale di Bill da Alice | +| --------------------------------------------- | -------------: | ----------------------------------------------- | ---------------------: | ---------------------: | -------------------------------- | +| approve(Bill, 5) | 10 | | | 5 | 0 | +| | | transferFrom(Alice, Bill, 5) | 10.123 | 0 | 5 | +| increaseAllowance(Bill, 5) | 11 | | | 0+5 = 5 | 5 | +| | | transferFrom(Alice, Bill, 5) | 10.124 | 0 | 10 | B: -| Transazione di Alice | Nonce di Alice | Transazione di Bill | Nonce di Bill | Tolleranza di Bill | Entrate totali di Bill da Alice | -| -------------------------- | --------------:| ----------------------------- | -------------:| ------------------:| -------------------------------:| -| approve(Bill, 5) | 10 | | | 5 | 0 | -| increaseAllowance(Bill, 5) | 11 | | | 5+5 = 10 | 0 | -| | | transferFrom(Alice, Bill, 10) | 10,124 | 0 | 10 | +| Transazione di Alice | Nonce di Alice | Transazione di Bill | Nonce di Bill | Autorizzazione di Bill | Guadagno totale di Bill da Alice | +| --------------------------------------------- | -------------: | ------------------------------------------------ | ---------------------: | ---------------------: | -------------------------------: | +| approve(Bill, 5) | 10 | | | 5 | 0 | +| increaseAllowance(Bill, 5) | 11 | | | 5+5 = 10 | 0 | +| | | transferFrom(Alice, Bill, 10) | 10.124 | 0 | 10 | ```solidity /** - * @dev Atomically increases the allowance granted to `spender` by the caller. + * @dev Aumenta atomicamente l'autorizzazione concessa a `spender` dal chiamante. * - * This is an alternative to {approve} that can be used as a mitigation for - * problems described in {IERC20-approve}. + * Questa è un'alternativa a {approve} che può essere usata per mitigare i + * problemi descritti in {IERC20-approve}. * - * Emits an {Approval} event indicating the updated allowance. + * Emette un evento {Approval} che indica l'autorizzazione aggiornata. * - * Requirements: + * Requisiti: * - * - `spender` cannot be the zero address. + * - `spender` non può essere l'indirizzo zero. */ function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) { _approve(_msgSender(), spender, _allowances[_msgSender()][spender].add(addedValue)); @@ -558,22 +598,23 @@ B: } ``` -La funzione `a.add(b)` è un'aggiunta sicura. Nell'improbabile caso in cui `a`+`b`>=`2^256`, non ha luogo il mormale avvolgimento come avviene con l'addizione normale. +La funzione `a.add(b)` è un'addizione sicura. Nel caso improbabile in cui `a`+`b`>=`2^256`, non si verifica il wrap-around +come nell'addizione normale. ```solidity /** - * @dev Atomically decreases the allowance granted to `spender` by the caller. + * @dev Diminuisce atomicamente l'autorizzazione concessa a `spender` dal chiamante. * - * This is an alternative to {approve} that can be used as a mitigation for - * problems described in {IERC20-approve}. + * Questa è un'alternativa a {approve} che può essere usata come mitigazione per i + * problemi descritti in {IERC20-approve}. * - * Emits an {Approval} event indicating the updated allowance. + * Emette un evento {Approval} che indica l'autorizzazione aggiornata. * - * Requirements: + * Requisiti: * - * - `spender` cannot be the zero address. - * - `spender` must have allowance for the caller of at least + * - `spender` non può essere l'indirizzo zero. + * - `spender` deve avere un'autorizzazione per il chiamante di almeno * `subtractedValue`. */ function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) { @@ -583,31 +624,33 @@ La funzione `a.add(b)` è un'aggiunta sicura. Nell'improbabile caso in cui `a`+` } ``` -### Funzioni che modificano le informazioni del token {#functions-that-modify-token-information} +### Funzioni che modificano le informazioni sui token {#functions-that-modify-token-information} -Queste sono le quattro funzioni che effettuano il lavoro effettivo: `_transfer`, `_mint`, `_burn` e `_approve`. +Queste sono le quattro funzioni che svolgono il lavoro vero e proprio: `_transfer`, `_mint`, `_burn` e `_approve`. -#### La funzione \_transfer {#_transfer} +#### La funzione `_transfer` {#_transfer} ```solidity /** - * @dev Moves tokens `amount` from `sender` to `recipient`. + * @dev Sposta una quantità `amount` di token da `sender` a `recipient`. * - * This is internal function is equivalent to {transfer}, and can be used to - * e.g., implement automatic token fees, slashing mechanisms, etc. + * Questa funzione interna è equivalente a {transfer} e può essere usata per + * implementare, ad esempio, commissioni automatiche sui token, meccanismi di slashing, ecc. * - * Emits a {Transfer} event. + * Emette un evento {Transfer}. * - * Requirements: + * Requisiti: * - * - `sender` cannot be the zero address. - * - `recipient` cannot be the zero address. - * - `sender` must have a balance of at least `amount`. + * - `sender` non può essere l'indirizzo zero. + * - `recipient` non può essere l'indirizzo zero. + * - `sender` deve avere un saldo di almeno `amount`. */ function _transfer(address sender, address recipient, uint256 amount) internal virtual { ``` -Questa funzione, `_transfer`, trasferisce i token da un conto all'altro. È chiamata sia da `transfer` (per i trasferimenti dal conto del mittente) che da `transferFrom` (per usare le indennità per trasferire dal conto di qualcun altro). +Questa funzione, `_transfer`, trasferisce token da un account a un altro. Viene chiamata sia da +`transfer` (per trasferimenti dall'account del mittente) sia da `transferFrom` (per usare le autorizzazioni +per trasferire dall'account di qualcun altro).   @@ -616,7 +659,9 @@ Questa funzione, `_transfer`, trasferisce i token da un conto all'altro. È chia require(recipient != address(0), "ERC20: transfer to the zero address"); ``` -Nessuno possiedere realmente l'indirizzo zero in Ethereum (ciò significa che nessuno conosce una chiave privata la cui chiave pubblica corrispondente è trasformata all'indirizzo zero). Quando si usa quell'indirizzo, in genere si tratta di un bug del software, quindi falliamo se usiamo l'indirizzo zero come mittente o destinatario. +Nessuno possiede effettivamente l'indirizzo zero in Ethereum (cioè, nessuno conosce una chiave privata la cui chiave pubblica corrispondente +si trasforma nell'indirizzo zero). Quando le persone usano quell'indirizzo, di solito si tratta di un bug del software, quindi la chiamata +fallisce se l'indirizzo zero viene usato come mittente o destinatario.   @@ -625,14 +670,17 @@ Nessuno possiedere realmente l'indirizzo zero in Ethereum (ciò significa che ne ``` -Esistono due modi per usare questo contratto: +Ci sono due modi per usare questo contratto: 1. Usarlo come modello per il proprio codice -1. [Ereditare da esso](https://www.bitdegree.org/learn/solidity-inheritance) e sovrascrivere solo le funzioni da modificare +2. [Ereditarlo](https://www.bitdegree.org/learn/solidity-inheritance) e sovrascrivere solo le funzioni che devi modificare -Il secondo metodo è di gran lunga migliore perché il codice ERC-20 di OpenZeppelin è stato già controllato e mostrato come sicuro. Quando si usa l'eredità, le funzioni da modificare sono note e, per fidarsi del tuo contratto, gli altri devono controllare solo quelle funzioni specifiche. +Il secondo metodo è molto meglio perché il codice ERC-20 di OpenZeppelin è già stato verificato e dimostrato sicuro. Quando si usa l'ereditarietà, +è chiaro quali sono le funzioni che si modificano e, per fidarsi del tuo contratto, le persone devono solo verificare quelle funzioni specifiche. -Spesso è utile eseguire una funzione ogni volta che i token passano di mano. Tuttavia, `_transfer` è una funzione davvero importante ed esiste il rischio di scriverla in modo non sicuro (vedi sotto), quindi è meglio non sovrascriverla. La soluzione è `_beforeTokenTransfer`, una [funzione hook](https://wikipedia.org/wiki/Hooking). Puoi sovrascrivere questa funzione, che verrà quindi richiamata a ogni trasferimento. +È spesso utile eseguire una funzione ogni volta che i token cambiano di mano. Tuttavia,`_transfer` è una funzione molto importante ed è +possibile scriverla in modo non sicuro (vedi sotto), quindi è meglio non sovrascriverla. La soluzione è `_beforeTokenTransfer`, una +[funzione hook](https://wikipedia.org/wiki/Hooking). Puoi sovrascrivere questa funzione e verrà chiamata a ogni trasferimento.   @@ -641,7 +689,10 @@ Spesso è utile eseguire una funzione ogni volta che i token passano di mano. Tu _balances[recipient] = _balances[recipient].add(amount); ``` -Queste sono le righe che effettuano concretamente il trasferimento. Nota che non c'è **nulla** tra di esse e che sottraiamo l'importo trasferito dal mittente prima di aggiungerlo al destinatario. Questo passaggio è importante perché, se ci fosse una chiamata a un contratto diverso nel mezzo, potrebbe essere utilizzata per barare su questo contratto. Questo metodo di trasferimento è atomico, in quanto nulla può verificarsi mentre è in corso. +Queste sono le righe che eseguono effettivamente il trasferimento. Nota che non c'è **nulla** tra di loro e che sottraiamo +l'importo trasferito dal mittente prima di aggiungerlo al destinatario. Questo è importante perché se ci fosse una +chiamata a un contratto diverso nel mezzo, potrebbe essere usata per imbrogliare questo contratto. In questo modo il trasferimento +è atomico, nulla può accadere nel mezzo.   @@ -650,23 +701,32 @@ Queste sono le righe che effettuano concretamente il trasferimento. Nota che non } ``` -Infine, emetti un evento `Transfer`. Gli eventi non sono accessibili agli smart contract, ma il codice eseguito al di fuori della blockchain può ascoltarli e reagire a essi. Ad esempio, un portafoglio può tracciare la ricezione di altri token da parte del proprietario. +Infine, emetti un evento `Transfer`. Gli eventi non sono accessibili agli smart contract, ma il codice in esecuzione al di fuori della blockchain +può ascoltare gli eventi e reagire ad essi. Ad esempio, un portafoglio può tenere traccia di quando il proprietario riceve più token. -#### Le funzioni \_mint e \_burn {#_mint-and-_burn} +#### Le funzioni `_mint` e `_burn` {#_mint-and-_burn} -Queste due funzioni (`_mint` e `_burn`) modificano la fornitura totale di token. Sono interne e non esiste alcuna funzione che le chiami in questo contratto, quindi sono utili solo se erediti dal contratto e aggiungi la tua logica per decidere a quali condizioni coniare nuovi token o bruciare quelli esistenti. +Queste due funzioni (`_mint` e `_burn`) modificano la fornitura totale di token. +Sono interne e non c'è nessuna funzione che le chiami in questo contratto, +quindi sono utili solo se erediti dal contratto e aggiungi la tua +logica per decidere in quali condizioni coniare nuovi token o bruciare quelli +esistenti. -**NOTA:** Ogni token ERC-20 ha la propria logica commerciale che detta la gestione del token. Ad esempio, un contratto di fornitura fissa potrebbe chiamare solo `_mint` nel costruttore e mai `_burn`. Un contratto che vende token chiamerà `_mint` quando è pagato e chiamerà presumibilmente `_burn` a un certo punto per evitare l'inflazione incontrollata. +**NOTA:** ogni token ERC-20 ha la propria logica di business che ne detta la gestione. +Ad esempio, un contratto a fornitura fissa potrebbe chiamare `_mint` +solo nel costruttore e non chiamare mai `_burn`. Un contratto che vende token +chiamerà `_mint` quando viene pagato e presumibilmente chiamerà `_burn` a un certo punto +per evitare un'inflazione galoppante. ```solidity - /** @dev Creates `amount` tokens and assigns them to `account`, increasing - * the total supply. + /** @dev Crea un `amount` di token e li assegna a un `account`, aumentando + * la fornitura totale. * - * Emits a {Transfer} event with `from` set to the zero address. + * Emette un evento {Transfer} con `from` impostato sull'indirizzo zero. * - * Requirements: + * Requisiti: * - * - `to` cannot be the zero address. + * - `to` non può essere l'indirizzo zero. */ function _mint(address account, uint256 amount) internal virtual { require(account != address(0), "ERC20: mint to the zero address"); @@ -681,17 +741,17 @@ Assicurati di aggiornare `_totalSupply` quando il numero totale di token cambia.   -``` +```solidity /** - * @dev Destroys `amount` tokens from `account`, reducing the - * total supply. + * @dev Distrugge `amount` token da `account`, riducendo la + * fornitura totale. * - * Emits a {Transfer} event with `to` set to the zero address. + * Emette un evento {Transfer} con `to` impostato sull'indirizzo zero. * - * Requirements: + * Requisiti: * - * - `account` cannot be the zero address. - * - `account` must have at least `amount` tokens. + * - `account` non può essere l'indirizzo zero. + * - `account` deve avere almeno `amount` token. */ function _burn(address account, uint256 amount) internal virtual { require(account != address(0), "ERC20: burn from the zero address"); @@ -704,25 +764,27 @@ Assicurati di aggiornare `_totalSupply` quando il numero totale di token cambia. } ``` -La funzione `_burn` è quasi identica a `_mint`, con la differenza che va in senso opposto. +La funzione `_burn` è quasi identica a `_mint`, tranne per il fatto che va nella direzione opposta. -#### La funzione \_approve {#_approve} +#### La funzione `_approve` {#_approve} -Questa è la funzione che specifica concretamente i margini di tolleranza. Nota che consente a un proprietario di specificare una tolleranza superiore al saldo corrente del proprietario. Questo non è un problema, poiché il saldo è controllato al momento del trasferimento, quando potrebbe differire dal saldo alla creazione del margine di tolleranza. +Questa è la funzione che specifica effettivamente le autorizzazioni. Nota che permette a un proprietario di specificare +un'autorizzazione superiore al saldo corrente del proprietario. Questo va bene perché il saldo viene +controllato al momento del trasferimento, quando potrebbe essere diverso dal saldo al momento della creazione dell'autorizzazione. ```solidity /** - * @dev Sets `amount` as the allowance of `spender` over the caller's tokens. + * @dev Imposta `amount` come autorizzazione di `spender` sui token di `owner`. * - * This internal function is equivalent to `approve`, and can be used to - * e.g., set automatic allowances for certain subsystems, etc. + * Questa funzione interna è equivalente ad `approve` e può essere usata per + * impostare, ad esempio, autorizzazioni automatiche per alcuni sottosistemi, ecc. * - * Emits an {Approval} event. + * Emette un evento {Approval}. * - * Requirements: + * Requisiti: * - * - `owner` cannot be the zero address. - * - `spender` cannot be the zero address. + * - `owner` non può essere l'indirizzo zero. + * - `spender` non può essere l'indirizzo zero. */ function _approve(address owner, address spender, uint256 amount) internal virtual { require(owner != address(0), "ERC20: approve from the zero address"); @@ -733,7 +795,8 @@ Questa è la funzione che specifica concretamente i margini di tolleranza. Nota   -Emette un evento `Approval`. In base a come è scritta l'applicazione, il contratto dello spender può essere informato dell'approvazione dal proprietario o da un server che monitora questi eventi. +Emetti un evento `Approval`. A seconda di come è scritta l'applicazione, il contratto dello spender può essere informato dell'approvazione +dal proprietario o da un server che ascolta questi eventi. ```solidity emit Approval(owner, spender, amount); @@ -747,51 +810,68 @@ Emette un evento `Approval`. In base a come è scritta l'applicazione, il contra /** - * @dev Sets {decimals} to a value other than the default one of 18. + * @dev Imposta {decimals} su un valore diverso da quello predefinito di 18. * - * WARNING: This function should only be called from the constructor. Most - * applications that interact with token contracts will not expect - * {decimals} to ever change, and may work incorrectly if it does. + * ATTENZIONE: questa funzione dovrebbe essere chiamata solo dal costruttore. La maggior parte delle + * applicazioni che interagiscono con i contratti di token non si aspettano + * che {decimals} cambi mai e potrebbero funzionare in modo errato se lo fa. */ function _setupDecimals(uint8 decimals_) internal { _decimals = decimals_; } ``` -Questa funzione modifica la variabile `_decimals`, usata per indicare alle interfacce utente come interpretare l'importo. Suggeriamo di chiamarla dal costruttore. Sarebbe disonesto chiamarla in qualsiasi punto successivo e le applicazioni non sono progettate per gestirla. +Questa funzione modifica la variabile `_decimals`, che viene utilizzata per indicare alle interfacce utente come interpretare l'importo. +Dovresti chiamarla dal costruttore. Sarebbe disonesto chiamarla in qualsiasi momento successivo e le applicazioni +non sono progettate per gestirlo. ### Hook {#hooks} ```solidity /** - * @dev Hook that is called before any transfer of tokens. This includes - * minting and burning. + * @dev Hook che viene chiamato prima di ogni trasferimento di token. Ciò include + * il conio e la distruzione. * - * Calling conditions: + * Condizioni di chiamata: * - * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens - * will be to transferred to `to`. - * - when `from` is zero, `amount` tokens will be minted for `to`. - * - when `to` is zero, `amount` of ``from``'s tokens will be burned. - * - `from` and `to` are never both zero. + * - quando `from` e `to` sono entrambi diversi da zero, un `amount` di token di `from` + * verrà trasferito a `to`. + * - quando `from` è zero, un `amount` di token verrà coniato per `to`. + * - quando `to` è zero, un `amount` di token di `from` verrà bruciato. + * - `from` e `to` non sono mai entrambi zero. * - * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks]. + * Per saperne di più sugli hook, vai a xref:ROOT:extending-contracts.adoc#using-hooks[Uso degli hook]. */ function _beforeTokenTransfer(address from, address to, uint256 amount) internal virtual { } } ``` -Questa è la funzione hook da chiamare durante i trasferimenti. Qui è vuota, ma se hai bisogno di fare qualcosa, basta sovrascriverla. +Questa è la funzione hook da chiamare durante i trasferimenti. Qui è vuota, ma se hai bisogno +che faccia qualcosa, devi solo sovrascriverla. + +## Conclusione {#conclusion} -## Conclusioni {#conclusion} +A titolo di ripasso, ecco alcune delle idee più importanti di questo contratto (secondo me, la tua opinione potrebbe essere diversa): -A titolo di ripasso, ecco alcune delle idee più importanti in questo contrato (a mio parere, probabilmente il tuo sarà diverso): +- _Non ci sono segreti sulla blockchain_. Qualsiasi informazione a cui uno smart contract può accedere + è disponibile al mondo intero. +- Puoi controllare l'ordine delle tue transazioni, ma non quando avvengono le transazioni + di altre persone. Questo è il motivo per cui modificare un'autorizzazione può essere pericoloso, perché permette + allo spender di spendere la somma di entrambe le autorizzazioni. +- I valori di tipo `uint256` si riavvolgono (wrap around). In altre parole, _0-1=2^256-1_. Se questo non è il comportamento desiderato, + devi controllarlo (o usare la libreria SafeMath che lo fa per te). Nota che questo è cambiato in + [Solidity 0.8.0](https://docs.soliditylang.org/en/breaking/080-breaking-changes.html). +- Esegui tutte le modifiche di stato di un tipo specifico in un punto specifico, perché rende più facile la verifica. + Questo è il motivo per cui abbiamo, ad esempio, `_approve`, che è chiamato da `approve`, `transferFrom`, + `increaseAllowance` e `decreaseAllowance` +- Le modifiche di stato dovrebbero essere atomiche, senza nessun'altra azione nel mezzo (come puoi vedere + in `_transfer`). Questo perché durante la modifica di stato si ha uno stato incoerente. Ad esempio, + tra il momento in cui si detrae dal saldo del mittente e il momento in cui si aggiunge al saldo del + destinatario, esistono meno token di quanti dovrebbero essercene. Si potrebbe potenzialmente abusare di ciò se ci + sono operazioni tra di loro, specialmente chiamate a un contratto diverso. -- _Non ci sono segreti sulla blockchain_. Ogni informazione accessibile a uno smart contract è disponibile per il mondo intero. -- Puoi controllare l'ordine delle tue transazioni, ma non come si verificano quelle altrui. Per questo modificare un'indennità può esser pericoloso, perché consente allo spender di spendere la somma di entrambi i margini di tolleranza. -- I valori di tipo `uint256` si avvolgono o, in altre parole, _0-1=2^256-1_. Se questo non è il comportamento desiderato, devi verificarlo (o usare la libreria SafeMath più adatta alle tue esigenze). Nota che ciò è cambiato in [Solidity 0.8.0](https://docs.soliditylang.org/en/breaking/080-breaking-changes.html). -- Effettua tutte le modifiche di un tipo specifico in un luogo specifico, così da semplificare i controlli. Per questo abbiamo, ad esempio, `_approve`, chiamata da `approve`, `transferFrom`, `increaseAllowance` e `decreaseAllowance` -- I cambi di stato dovrebbero essere atomici, senza altre azioni nel mezzo (come si può vedere in `_transfer`). Questo perché durante il cambio di stato hai uno stato incoerente. Ad esempio, tra il momento in cui detrai dal saldo del mittente e il momento in cui aggiungi al saldo del destinatario, esistono meno token di quanti dovrebbero essercene. Questa condizione potrebbe essere esposta ad abusi se vengono effettuate operazioni tra di essi, specialmente nel caso di chiamate a un contratto differente. +Ora che hai visto come è scritto il contratto ERC-20 di OpenZeppelin, e soprattutto come è +reso più sicuro, vai e scrivi i tuoi contratti e le tue applicazioni sicure. -Ora che hai visto come è scritto il contratto ERC-20 di OpenZeppelin e specialmente come viene reso più sicuro, vai a scrivere i tuoi contratti sicuri e le tue applicazioni. +[Vedi qui per altri miei lavori](https://cryptodocguy.pro/). diff --git a/public/content/translations/it/developers/tutorials/erc20-with-safety-rails/index.md b/public/content/translations/it/developers/tutorials/erc20-with-safety-rails/index.md index 1ac9a9e0eed..58cfe0b563d 100644 --- a/public/content/translations/it/developers/tutorials/erc20-with-safety-rails/index.md +++ b/public/content/translations/it/developers/tutorials/erc20-with-safety-rails/index.md @@ -3,60 +3,62 @@ title: ERC-20 con barriere di sicurezza description: Come aiutare le persone a evitare errori banali author: Ori Pomerantz lang: it -tags: - - "erc-20" +tags: [ "erc-20" ] skill: beginner published: 2022-08-15 --- ## Introduzione {#introduction} -Una delle cose fantastiche su Ethereum è che non esiste un'autorità centrale che possa modificare o annullare le tue transazioni. Uno dei suoi grandi problemi è che non c'è un'autorità centrale con il potere di annullare gli errori o le transazioni illecite degli utenti. In questo articolo imparerai alcuni dei comuni errori che gli utenti commettono con i token [ERC-20](/developers/docs/standards/tokens/erc-20/), nonché come creare dei contratti ERC-20 che aiutano gli utenti a evitarli, o danno poteri a un'autorità centrale (ad esempio, congelare gli account). +Una delle cose fantastiche di Ethereum è che non esiste un'autorità centrale che possa modificare o annullare le tue transazioni. Uno dei grandi problemi di Ethereum è che non esiste un'autorità centrale con il potere di annullare gli errori degli utenti o le transazioni illecite. In questo articolo imparerai alcuni degli errori comuni che gli utenti commettono con i token [ERC-20](/developers/docs/standards/tokens/erc-20/), nonché come creare contratti ERC-20 che aiutino gli utenti a evitare quegli errori, o che diano a un'autorità centrale un certo potere (ad esempio per congelare gli account). -Nota che, mentre utilizzeremo il [contratto del token ERC-20 di OpenZeppelin](https://github.com/OpenZeppelin/openzeppelin-contracts/tree/master/contracts/token/ERC20), questo articolo non lo spiega nel dettaglio. Puoi trovare queste informazioni [qui](/developers/tutorials/erc20-annotated-code). +Nota che, sebbene useremo il [contratto di token ERC-20 di OpenZeppelin](https://github.com/OpenZeppelin/openzeppelin-contracts/tree/master/contracts/token/ERC20), questo articolo non lo spiega nel dettaglio. Puoi trovare queste informazioni [qui](/developers/tutorials/erc20-annotated-code). -Se desideri visualizzare il codice sorgente completo: +Se vuoi vedere il codice sorgente completo: -1. Apri l'[IDE di Remix](https://remix.ethereum.org/). -2. Clicca l'icona di clonazione di GitHub (![clone github icon](icon-clone.png)). +1. Apri [Remix IDE](https://remix.ethereum.org/). +2. Fai clic sull'icona per clonare da github (![icona per clonare da github](icon-clone.png)). 3. Clona la repository di GitHub `https://github.com/qbzzt/20220815-erc20-safety-rails`. -4. Apri **contratti > erc20-safety-rails.sol**. +4. Apri **contracts > erc20-safety-rails.sol**. -## Creare un contratto ERC-20 {#creating-an-erc-20-contract} +## Creazione di un contratto ERC-20 {#creating-an-erc-20-contract} -Prima di poter aggiungere la funzionalità della barriera di sicurezza, ci occorre un contratto ERC-20. In questo articolo utilizzeremo [la procedura guidata dei contratti di OpenZeppelin](https://docs.openzeppelin.com/contracts/5.x/wizard). Aprila in un altro browser e segui queste istruzioni: +Prima di poter aggiungere la funzionalità della barriera di sicurezza, abbiamo bisogno di un contratto ERC-20. In questo articolo useremo [OpenZeppelin Contracts Wizard](https://docs.openzeppelin.com/contracts/5.x/wizard). Aprilo in un altro browser e segui queste istruzioni: 1. Seleziona **ERC20**. + 2. Inserisci queste impostazioni: | Parametro | Valore | | --------------- | ---------------- | | Nome | SafetyRailsToken | - | Symbol | SAFE | + | Simbolo | SAFE | | Premint | 1000 | | Caratteristiche | Nessuno | | Access Control | Ownable | | Upgradability | Nessuno | -3. Scorri in alto e clicca su **Apri su Remix** (per Remix) o su **Scarica** per utilizzare un ambiente differente. Supporrò che tu stia utilizzando Remix, altrimenti, effettua le modifiche appropriate. -4. Ora, abbiamo un contratto ERC-20 pienamente funzionante. Puoi espandere `.deps` > `npm` per visualizzare il codice importato. -5. Compila, distribuisci e gioca con il contratto, per scoprire che funziona come un contratto ERC-20. Se devi apprendere come funziona Remix, [utilizza questo tutorial](https://remix.ethereum.org/?#activate=udapp,solidity,LearnEth). +3. Scorri verso l'alto e fai clic su **Open in Remix** (per Remix) o **Download** per usare un ambiente diverso. Darò per scontato che tu stia usando Remix, se usi qualcos'altro apporta le modifiche appropriate. + +4. Ora abbiamo un contratto ERC-20 perfettamente funzionante. Puoi espandere `.deps` > `npm` per vedere il codice importato. + +5. Compila, distribuisci e interagisci con il contratto per vedere che funziona come un contratto ERC-20. Se hai bisogno di imparare a usare Remix, [usa questa guida](https://remix.ethereum.org/?#activate=udapp,solidity,LearnEth). ## Errori comuni {#common-mistakes} ### Gli errori {#the-mistakes} -Gli utenti, talvolta, inviano dei token all'indirizzo errato. Anche se non possiamo leggere la loro mente per sapere cosa intendevano fare, ci sono due tipi di errore che capitano spesso e sono facili da rilevare: +A volte gli utenti inviano token all'indirizzo sbagliato. Anche se non possiamo leggere loro nel pensiero per sapere cosa intendevano fare, ci sono due tipi di errore che si verificano spesso e sono facili da individuare: -1. Inviare i token all'indirizzo del contratto. Ad esempio, il [token OP di Optimism](https://optimism.mirror.xyz/qvd0WfuLKnePm1Gxb9dpGchPf5uDz5NSMEFdgirDS4c) è riuscito ad accumulare [oltre 120.000](https://optimistic.etherscan.io/address/0x4200000000000000000000000000000000000042#tokentxns) token OP in meno di due mesi. Questo rappresenta una significativa quantità di ricchezza che, presumibilmente, è semplicemente stata persa dalle persone. +1. Inviare i token all'indirizzo del contratto stesso. Ad esempio, il [token OP di Optimism](https://optimism.mirror.xyz/qvd0WfuLKnePm1Gxb9dpGchPf5uDz5NSMEFdgirDS4c) è riuscito ad accumulare [oltre 120.000](https://optimism.blockscout.com/address/0x4200000000000000000000000000000000000042) token OP in meno di due mesi. Questo rappresenta una quantità significativa di ricchezza che presumibilmente le persone hanno semplicemente perso. -2. Inviare i token a un indirizzo vuoto, non corrispondente a un [conto posseduto esternamente](/developers/docs/accounts/#externally-owned-accounts-and-key-pairs) o a un [contratto intelligente](/developers/docs/smart-contracts). Sebbene non siano disponibili le statistiche su quanto spesso si verifichi, [un incidente potrebbe costare fino a 20.000.000 token](https://gov.optimism.io/t/message-to-optimism-community-from-wintermute/2595). +2. Inviare i token a un indirizzo vuoto, uno che non corrisponde a un [conto posseduto esternamente](/developers/docs/accounts/#externally-owned-accounts-and-key-pairs) o a un [contratto intelligente](/developers/docs/smart-contracts). Anche se non ho statistiche sulla frequenza con cui ciò accade, [un incidente sarebbe potuto costare 20.000.000 di token](https://gov.optimism.io/t/message-to-optimism-community-from-wintermute/2595). ### Prevenire i trasferimenti {#preventing-transfers} -Il contratto ERC-20 di OpenZeppelin include [un hook, `_beforeTokenTransfer`](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC20/ERC20.sol#L364-L368), chiamato prima del trasferimento di un token. Per impostazione predefinita, questo hook non fa nulla, ma possiamo allegarci la nostra funzionalità, come controlli che ripristinano la transazione se si verifica un problema. +Il contratto ERC-20 di OpenZeppelin include [un hook, `_beforeTokenTransfer`](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC20/ERC20.sol#L364-L368), che viene chiamato prima che un token venga trasferito. Per impostazione predefinita questo hook non fa nulla, ma possiamo agganciarvi la nostra funzionalità, come dei controlli che eseguono il revert della transazione se c'è un problema. -Per utilizzare l'hook, aggiungi questa funzione dopo il costruttore: +Per usare l'hook, aggiungi questa funzione dopo il costruttore: ```solidity function _beforeTokenTransfer(address from, address to, uint256 amount) @@ -67,42 +69,42 @@ Per utilizzare l'hook, aggiungi questa funzione dopo il costruttore: } ``` -Alcune parti di questa funzione potrebbero essere nuove, se non hai familiarità con Solidity: +Alcune parti di questa funzione potrebbero esserti nuove se non hai molta familiarità con Solidity: ```solidity internal virtual ``` -La parola chiave `virtual` signiica che appena abbiamo ereditato la funzionalità da `ERC20` e sovrascritto questa funzione, gli altri contratti possono ereditare da noi e sovrascriverla. +La parola chiave `virtual` significa che, proprio come noi abbiamo ereditato la funzionalità da `ERC20` e sovrascritto questa funzione, altri contratti possono ereditare da noi e sovrascrivere questa funzione. ```solidity override(ERC20) ``` -Dobbiamo specificare esplicitamente che stiamo [sovrascrivendo](https://docs.soliditylang.org/en/v0.8.15/contracts.html#function-overriding) la definizione del token ERC20 di `_beforeTokenTransfer`. In generale, le definizioni esplicite sono molto migliori, dal punto di vista della sicurezza, rispetto a quelle implicite: non puoi dimenticare di aver fatto qualcosa se ce l'hai davanti. Questo è anche il motivo per cui dobbiamo specificare il `_beforeTokenTransfer` di quale superclasse stiamo sovrascrivendo. +Dobbiamo specificare esplicitamente che stiamo [sovrascrivendo](https://docs.soliditylang.org/en/v0.8.15/contracts.html#function-overriding) la definizione del token ERC20 di `_beforeTokenTransfer`. In generale, le definizioni esplicite sono molto meglio, dal punto di vista della sicurezza, di quelle implicite: non puoi dimenticare di aver fatto qualcosa se ce l'hai proprio di fronte. Questo è anche il motivo per cui dobbiamo specificare quale `_beforeTokenTransfer` della superclasse stiamo sovrascrivendo. ```solidity super._beforeTokenTransfer(from, to, amount); ``` -Questa riga chiama la funzione `_beforeTokenTransfer` del contratto o dei contratti da cui abbiamo ereditato o che la contengono. In qusto caso, è solo `ERC20`, `Ownable` non contiene questo hook. Sebbene correntemente `ERC20._beforeTokenTransfer` non faccia nulla, lo chiamiamo nel caso in cui la funzionalità sia aggiunta in futuro (e, quindi, decidiamo di ridistribuire il contratto, poiché i contratti non cambiano dopo la distribuzione). +Questa riga chiama la funzione `_beforeTokenTransfer` del contratto (o dei contratti) da cui ereditiamo e che la possiede. In questo caso, si tratta solo di `ERC20`, `Ownable` non ha questo hook. Anche se attualmente `ERC20._beforeTokenTransfer` non fa nulla, lo chiamiamo nel caso in cui una funzionalità venga aggiunta in futuro (e decidiamo quindi di ridistribuire il contratto, perché i contratti non cambiano dopo la distribuzione). ### Codifica dei requisiti {#coding-the-requirements} Vogliamo aggiungere questi requisiti alla funzione: -- L'indirizzo `to` non può equivalere ad `address(this)`, l'indirizzo dello stesso contratto ERC-20. -- L'indirizzo `to` non può essere vuoto, dev'essere: - - Account posseduti esternamente (EOA). Non possiamo verificare se un indirizzo è un EOA direttamente, ma possiamo verificare il saldo di ETH di un indirizzo. Gli EOA contengono quasi sempre un saldo, anche se non sono più utilizzati; è difficile ripulirli fino all'ultimo wei. - - Un contratto intelligente. Testare se un indirizzo è un contratto intelligente è più difficile. Esiste un codice operativo che controlla la lunghezza del codice esterno, chiamato [`EXTCODESIZE`](https://www.evm.codes/#3b), ma non è direttamente disponibile in Solidity. Dobbiamo utilizzare [Yul](https://docs.soliditylang.org/en/v0.8.15/yul.html), un assemblaggio dell'EVM, per farlo. Esistono altri valori che potremmo utilizzare da Solidity ([`
.code` e `
.codehash`](https://docs.soliditylang.org/en/v0.8.15/units-and-global-variables.html#members-of-address-types)), ma costano di più. +- L'indirizzo `to` non può essere uguale a `address(this)`, l'indirizzo del contratto ERC-20 stesso. +- L'indirizzo `to` non può essere vuoto, deve essere: + - Un conto posseduto esternamente (EOA). Non possiamo verificare direttamente se un indirizzo è un EOA, ma possiamo controllare il saldo ETH di un indirizzo. Gli EOA hanno quasi sempre un saldo, anche se non sono più utilizzati: è difficile svuotarli fino all'ultimo wei. + - Un contratto intelligente. Verificare se un indirizzo è un contratto intelligente è un po' più difficile. Esiste un opcode che controlla la lunghezza del codice esterno, chiamato [`EXTCODESIZE`](https://www.evm.codes/#3b), ma non è disponibile direttamente in Solidity. Dobbiamo usare [Yul](https://docs.soliditylang.org/en/v0.8.15/yul.html), che è l'assembly della EVM, per farlo. Ci sono altri valori che potremmo usare da Solidity ([`
.code` e `
.codehash`](https://docs.soliditylang.org/en/v0.8.15/units-and-global-variables.html#members-of-address-types)), ma costano di più. -Analizziamo il codice, riga per riga: +Analizziamo il nuovo codice riga per riga: ```solidity - require(to != address(this), "Can't send tokens to the contract address"); + require(to != address(this), "Impossibile inviare token all'indirizzo del contratto"); ``` -Questo è il primo requisito, controlla che `to` `this(address)` non siano la stessa cosa. +Questo è il primo requisito, verificare che `to` e `address(this)` non siano la stessa cosa. ```solidity bool isToContract; @@ -111,53 +113,53 @@ Questo è il primo requisito, controlla che `to` `this(address)` non siano la st } ``` -È così che controlliamo se un indirizzo è un contratto. Non possiamo ricevere direttamente il risultato da Yul, quindi, invece, definiamo una variabile che detenga il risultato (`isToContract` in questo caso). Yul funziona così: ogni codice operativo è considerato come una funzione. Quindi, prima chiamiamo [`EXTCODESIZE`](https://www.evm.codes/#3b) per ottenere le dimensioni del contratto, quindi utilizziamo [`GT`](https://www.evm.codes/#11) per verificare che non sia zero (stiamo avendo a che fare con interi non firmati, quindi, ovviamente, non possono essere negativi). Poi, dobbiamo scrivere il risultato in `isToContract`. +Questo è il modo in cui verifichiamo se un indirizzo è un contratto. Non possiamo ricevere l'output direttamente da Yul, quindi definiamo una variabile per contenere il risultato (`isToContract` in questo caso). Il modo in cui Yul funziona è che ogni opcode è considerato una funzione. Quindi, prima chiamiamo [`EXTCODESIZE`](https://www.evm.codes/#3b) per ottenere la dimensione del contratto, e poi usiamo [`GT`](https://www.evm.codes/#11) per verificare che non sia zero (stiamo trattando con interi senza segno, quindi ovviamente non può essere negativo). Quindi scriviamo il risultato in `isToContract`. ```solidity - require(to.balance != 0 || isToContract, "Can't send tokens to an empty address"); + require(to.balance != 0 || isToContract, "Impossibile inviare token a un indirizzo vuoto"); ``` -E, infine, abbiamo il controllo effettivo per gli indirizzi vuoti. +E infine, abbiamo il controllo effettivo per gli indirizzi vuoti. ## Accesso amministrativo {#admin-access} -Talvolta è utile avere un amministratore che possa annullare gli errori. Per ridurre il potenziale di abusi, questo può essere una [multifirma](https://blog.logrocket.com/security-choices-multi-signature-wallets/), quindi più persone devono approvare un'azione. In questo articolo abbiamo due funzionalità amministrative: +A volte è utile avere un amministratore che possa annullare gli errori. Per ridurre il potenziale di abuso, questo amministratore può essere un [multisig](https://blog.logrocket.com/security-choices-multi-signature-wallets/) in modo che più persone debbano concordare un'azione. In questo articolo avremo due funzioni amministrative: -1. Congelamento e scongelamento degli account. Utile, ad esempio, quando un account potrebbe essere compromesso. -2. Pulizia della risorsa. +1. Congelamento e scongelamento dei conti. Può essere utile, ad esempio, quando un account potrebbe essere compromesso. +2. Pulizia degli asset. - Talvolta, i truffatori inviano token fraudolenti al contratto del token reale, per ottenere legittimità. Ad esempio, [vedi qui](https://optimistic.etherscan.io/token/0x2348b1a1228ddcd2db668c3d30207c3e1852fbbe?a=0x4200000000000000000000000000000000000042). Il contratto ERC-20 legittimo è [0x4200....0042](https://optimistic.etherscan.io/address/0x4200000000000000000000000000000000000042). La truffa che pretende di essere tale contratto è [0x234....bbe](https://optimistic.etherscan.io/address/0x2348b1a1228ddcd2db668c3d30207c3e1852fbbe). + A volte i truffatori inviano token fraudolenti al contratto del token reale per ottenere legittimità. Ad esempio, [vedi qui](https://optimism.blockscout.com/token/0x2348B1a1228DDCd2dB668c3d30207c3E1852fBbe?tab=holders). Il contratto ERC-20 legittimo è [0x4200....0042](https://optimism.blockscout.com/token/0x4200000000000000000000000000000000000042). La truffa che finge di essere tale è [0x234....bbe](https://optimism.blockscout.com/token/0x2348B1a1228DDCd2dB668c3d30207c3E1852fBbe). - Inoltre, è possibile che le persone inviino token ERC-20 legittimi al nostro contratto per errore, un altro motivo per cui vogliamo avere un modo per farli uscire. + È anche possibile che le persone inviino per errore token ERC-20 legittimi al nostro contratto, che è un altro motivo per cui avere un modo per recuperarli. -OpenZeppelin fornisce due meccanismi per consentire l'accesso amministrativo: +OpenZeppelin fornisce due meccanismi per abilitare l'accesso amministrativo: -- I contratti [`Ownable`](https://docs.openzeppelin.com/contracts/5.x/access-control#ownership-and-ownable) hanno un singolo proprietario. Le funzioni aventi il [modificatore](https://www.tutorialspoint.com/solidity/solidity_function_modifiers.htm) `onlyOwner` possono essere chiamate soltanto dal proprietario. I proprietari possono trasferire la proprietà a qualcun altro o rinunciarvi completamente. I diritti di tutti gli altri account sono solitamente identici. -- I contratti [`AccessControl`](https://docs.openzeppelin.com/contracts/5.x/access-control#role-based-access-control) hanno il [controllo d'accesso basato sul ruolo (RBAC)](https://en.wikipedia.org/wiki/Role-based_access_control). +- I contratti [`Ownable`](https://docs.openzeppelin.com/contracts/5.x/access-control#ownership-and-ownable) hanno un unico proprietario. Le funzioni che hanno il [modificatore](https://www.tutorialspoint.com/solidity/solidity_function_modifiers.htm) `onlyOwner` possono essere chiamate solo da quel proprietario. I proprietari possono trasferire la proprietà a qualcun altro o rinunciarvi completamente. I diritti di tutti gli altri conti sono in genere identici. +- I contratti [`AccessControl`](https://docs.openzeppelin.com/contracts/5.x/access-control#role-based-access-control) hanno il [controllo degli accessi basato sui ruoli (RBAC)](https://en.wikipedia.org/wiki/Role-based_access_control). -Per semplicità, in questo articolo utilizzeremo `Ownable`. +Per semplicità, in questo articolo usiamo `Ownable`. ### Congelare e scongelare i contratti {#freezing-and-thawing-contracts} Congelare e scongelare i contratti richiede diverse modifiche: -- Una [mappatura](https://www.tutorialspoint.com/solidity/solidity_mappings.htm) dagli indirizzi a [booleani](https://en.wikipedia.org/wiki/Boolean_data_type) per tenere traccia di quali indirizzi siano congelati. Tutti i valori sono inizialmente pari a zero, che per i valori booleani è interpretato come falso. Questo è ciò che vogliamo perché gli account non sono congelati per impostazione predefinita. +- Una [mappa](https://www.tutorialspoint.com/solidity/solidity_mappings.htm) da indirizzi a [booleani](https://en.wikipedia.org/wiki/Boolean_data_type) per tenere traccia di quali indirizzi sono congelati. Tutti i valori sono inizialmente zero, che per i valori booleani è interpretato come falso. Questo è ciò che vogliamo perché per impostazione predefinita i conti non sono congelati. ```solidity mapping(address => bool) public frozenAccounts; ``` -- [Eventi](https://www.tutorialspoint.com/solidity/solidity_events.htm) per informare chiunque sia interessato quando un account è congelato o scongelato. Tecnicamente parlando, gli eventi non sono necessari per tali azioni, ma aiutano il codice esterno alla catena a essere capace di ascoltare tali eventi e sapere che sta succedendo. È considerata buona pratica, per un contratto intelligente, di emetterli quando si verifica qualcosa che potrebbe essere rilevante per qualcuno. +- Gli [eventi](https://www.tutorialspoint.com/solidity/solidity_events.htm) servono per informare chiunque sia interessato quando un conto viene congelato o scongelato. Tecnicamente parlando, gli eventi non sono necessari per queste azioni, ma aiutano il codice off-chain a essere in grado di ascoltare questi eventi e sapere cosa sta succedendo. È considerata buona norma per un contratto intelligente emetterli quando accade qualcosa che potrebbe essere rilevante per qualcun altro. - Gli eventi sono indicizzati, quindi sarà possibile cercarli tutte le volte che un account è stato congelato o scongelato. + Gli eventi sono indicizzati, quindi sarà possibile cercare tutte le volte che un conto è stato congelato o scongelato. ```solidity - // When accounts are frozen or unfrozen + // Quando i conti vengono congelati o scongelati event AccountFrozen(address indexed _addr); event AccountThawed(address indexed _addr); ``` -- Funzioni per congelare e scongelare gli account. Queste due funzioni sono quasi identiche, quindi analizzeremo soltanto la funzione di congelamento. +- Funzioni per congelare e scongelare gli account. Queste due funzioni sono quasi identiche, quindi esamineremo solo la funzione di congelamento. ```solidity function freezeAccount(address addr) @@ -165,27 +167,27 @@ Congelare e scongelare i contratti richiede diverse modifiche: onlyOwner ``` - Le funzioni contrassegnate come [`public`](https://www.tutorialspoint.com/solidity/solidity_contracts.htm), possono essere chiamate da altri contratti intelligenti o direttamente da una transazione. + Le funzioni contrassegnate come [`public`](https://www.tutorialspoint.com/solidity/solidity_contracts.htm) possono essere chiamate da altri contratti intelligenti o direttamente da una transazione. ```solidity { - require(!frozenAccounts[addr], "Account already frozen"); + require(!frozenAccounts[addr], "Conto già congelato"); frozenAccounts[addr] = true; emit AccountFrozen(addr); } // freezeAccount ``` - Se l'account è già congelato, si ripristina. Altrimenti, lo congela ed emette (`emit`) un evento. + Se il conto è già congelato, si esegue il revert. Altrimenti, lo si congela e si `emit` un evento. -- Modificare `_beforeTokenTransfer` per impedire che il denaro sia spostato da un account congelato. Nota che il denaro è ancora trasferibile in un account congelato. +- Modifica `_beforeTokenTransfer` per impedire che il denaro venga spostato da un conto congelato. Nota che il denaro può ancora essere trasferito nel conto congelato. ```solidity - require(!frozenAccounts[from], "The account is frozen"); + require(!frozenAccounts[from], "Il conto è congelato"); ``` -### Pulizia della risorsa {#asset-cleanup} +### Pulizia degli asset {#asset-cleanup} -Per rilasciare i token ERC-20 detenuti da questo contratto, dobbiamo chiamare una funzione sul contratto del token cui aappartengono, [`transfer`](https://eips.ethereum.org/EIPS/eip-20#transfer) o [`approve`](https://eips.ethereum.org/EIPS/eip-20#approve). Non ha senso, in questo caso, sprecare gas sulle indennità, potremmo anche trasferirle direttamente. +Per rilasciare i token ERC-20 detenuti da questo contratto, dobbiamo chiamare una funzione sul contratto del token a cui appartengono, o [`transfer`](https://eips.ethereum.org/EIPS/eip-20#transfer) o [`approve`](https://eips.ethereum.org/EIPS/eip-20#approve). Non ha senso sprecare gas in questo caso per le autorizzazioni, tanto vale trasferire direttamente. ```solidity function cleanupERC20( @@ -198,7 +200,7 @@ Per rilasciare i token ERC-20 detenuti da questo contratto, dobbiamo chiamare un IERC20 token = IERC20(erc20); ``` -Questa è la sintassi per creare un oggetto per un contratto quando riceviamo l'indirizzo. Possiamo farlo perché abbiamo la definizione per i token ERC20 come parte del codice sorgente (vedi riga 4) e tale file include [la definizione per IERC20](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC20/IERC20.sol), l'interfaccia per un contratto ERC-20 di OpenZeppelin. +Questa è la sintassi per creare un oggetto per un contratto quando riceviamo l'indirizzo. Possiamo farlo perché abbiamo la definizione per i token ERC20 come parte del codice sorgente (vedi riga 4), e quel file include [la definizione per IERC20](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC20/IERC20.sol), l'interfaccia per un contratto ERC-20 di OpenZeppelin. ```solidity uint balance = token.balanceOf(address(this)); @@ -206,8 +208,10 @@ Questa è la sintassi per creare un oggetto per un contratto quando riceviamo l' } ``` -Questa è una funzione di pulizia, quindi, presumibilmente, non vogliamo lasciare alcun token. Invece di ottenere manualmente il saldo dall'utente, potremmo automatizzare anche questo processo. +Questa è una funzione di pulizia, quindi presumibilmente non vogliamo lasciare alcun token. Invece di ottenere manualmente il saldo dall'utente, potremmo anche automatizzare il processo. + +## Conclusione {#conclusion} -## Conclusioni {#conclusion} +Questa non è una soluzione perfetta: non esiste una soluzione perfetta per il problema "l'utente ha commesso un errore". Tuttavia, l'uso di questo tipo di controlli può almeno prevenire alcuni errori. La capacità di congelare i conti, sebbene pericolosa, può essere utilizzata per limitare i danni di alcuni hack negando all'hacker i fondi rubati. -Questa non è una soluzione perfetta, non esiste una soluzione perfetta al problema "un utente ha commesso un errore". Tuttavia, utilizzando questi tipi di controlli, alcuni errori possono almeno essere prevenuti. L'abilità di congelare gli account, sebbene pericolosa, è utilizzabile per limitare i danni di certi attacchi, negando all'hacker i fondi rubati. +[Vedi qui per altri miei lavori](https://cryptodocguy.pro/). diff --git a/public/content/translations/it/developers/tutorials/ethereum-for-web2-auth/index.md b/public/content/translations/it/developers/tutorials/ethereum-for-web2-auth/index.md new file mode 100644 index 00000000000..8993f5619b3 --- /dev/null +++ b/public/content/translations/it/developers/tutorials/ethereum-for-web2-auth/index.md @@ -0,0 +1,886 @@ +--- +title: Uso di Ethereum per l'autenticazione web2 +description: "Dopo aver letto questa guida, uno sviluppatore sarà in grado di integrare il login di Ethereum (web3) con il login SAML, uno standard utilizzato nel web2 per fornire il single sign-on e altri servizi correlati. Ciò consente di autenticare l'accesso alle risorse web2 attraverso le firme di Ethereum, con gli attributi dell'utente provenienti da attestazioni." +author: Ori Pomerantz +tags: [ "web2", "autenticazione", "eas" ] +skill: beginner +lang: it +published: 2025-04-30 +--- + +## Introduzione + +[SAML](https://www.onelogin.com/learn/saml) è uno standard utilizzato su web2 per consentire a un [fornitore di identità (IdP)](https://en.wikipedia.org/wiki/Identity_provider#SAML_identity_provider) di fornire informazioni sull'utente per [i fornitori di servizi (SP)](https://en.wikipedia.org/wiki/Service_provider_\(SAML\)). + +In questa guida imparerai come integrare le firme di Ethereum con SAML per consentire agli utenti di usare i loro portafogli Ethereum per autenticarsi ai servizi web2 che non supportano ancora Ethereum in modo nativo. + +Nota che questa guida è scritta per due pubblici separati: + +- Utenti di Ethereum che conoscono Ethereum e hanno bisogno di imparare SAML +- Utenti Web2 che conoscono SAML e l'autenticazione web2 e hanno bisogno di imparare Ethereum + +Di conseguenza, conterrà molto materiale introduttivo che già conosci. Sentiti libero di saltarlo. + +### SAML per gli utenti di Ethereum + +SAML è un protocollo centralizzato. Un fornitore di servizi (SP) accetta asserzioni (come "questo è il mio utente John, dovrebbe avere i permessi per fare A, B e C") da un fornitore di identità (IdP) solo se ha una relazione di fiducia preesistente con esso, o con l'[autorità di certificazione](https://www.ssl.com/article/what-is-a-certificate-authority-ca/) che ha firmato il certificato di quell'IdP. + +Ad esempio, l'SP può essere un'agenzia di viaggi che fornisce servizi di viaggio alle aziende e l'IdP può essere il sito web interno di un'azienda. Quando i dipendenti devono prenotare viaggi di lavoro, l'agenzia di viaggi li invia per l'autenticazione da parte dell'azienda prima di permettere loro di prenotare effettivamente il viaggio. + +![Processo SAML passo dopo passo](./fig-01-saml.png) + +Questo è il modo in cui le tre entità, il browser, l'SP e l'IdP, negoziano l'accesso. L'SP non ha bisogno di sapere nulla in anticipo sull'utente che usa il browser, gli basta fidarsi dell'IdP. + +### Ethereum per gli utenti SAML + +Ethereum è un sistema decentralizzato. + +![Accesso a Ethereum](./fig-02-eth-logon.png) + +Gli utenti hanno una chiave privata (solitamente conservata in un'estensione del browser). Dalla chiave privata è possibile derivare una chiave pubblica, e da questa un indirizzo a 20 byte. Quando gli utenti devono accedere a un sistema, viene loro richiesto di firmare un messaggio con un nonce (un valore monouso). Il server può verificare che la firma è stata creata da quell'indirizzo. + +![Ottenere dati aggiuntivi dalle attestazioni](./fig-03-eas-data.png) + +La firma verifica solo l'indirizzo Ethereum. Per ottenere altri attributi dell'utente, solitamente si usano le [attestazioni](https://attest.org/). Un'attestazione ha in genere questi campi: + +- **Attestatore**, l'indirizzo che ha effettuato l'attestazione +- **Destinatario**, l'indirizzo a cui si applica l'attestazione +- **Dati**, i dati oggetto di attestazione, come nome, permessi, ecc. +- **Schema**, l'ID dello schema utilizzato per interpretare i dati. + +A causa della natura decentralizzata di Ethereum, qualsiasi utente può fare attestazioni. L'identità dell'attestatore è importante per identificare quali attestazioni consideriamo affidabili. + +## Configurazione + +Il primo passo è fare in modo che un SP SAML e un IdP SAML comunichino tra loro. + +1. Scarica il software. Il software di esempio per questo articolo è [su GitHub](https://github.com/qbzzt/250420-saml-ethereum). Le diverse fasi sono memorizzate in diversi rami, per questa fase è necessario `saml-only` + + ```sh + git clone https://github.com/qbzzt/250420-saml-ethereum -b saml-only + cd 250420-saml-ethereum + pnpm install + ``` + +2. Crea chiavi con certificati autofirmati. Ciò significa che la chiave è la propria autorità di certificazione e deve essere importata manualmente nel fornitore di servizi. Consulta [la documentazione di OpenSSL](https://docs.openssl.org/master/man1/openssl-req/) per maggiori informazioni. + + ```sh + mkdir keys + cd keys + openssl req -new -x509 -days 365 -nodes -sha256 -out saml-sp.crt -keyout saml-sp.pem -subj /CN=sp/ + openssl req -new -x509 -days 365 -nodes -sha256 -out saml-idp.crt -keyout saml-idp.pem -subj /CN=idp/ + cd .. + ``` + +3. Avvia i server (sia SP che IdP) + + ```sh + pnpm start + ``` + +4. Naviga fino all'SP all'URL [http://localhost:3000/](http://localhost:3000/) e fai clic sul pulsante per essere reindirizzato all'IdP (porta 3001). + +5. Fornisci all'IdP il tuo indirizzo email e fai clic su **Login al fornitore di servizi**. Verifica di essere reindirizzato al fornitore di servizi (porta 3000) e che ti riconosca tramite il tuo indirizzo email. + +### Spiegazione dettagliata + +Ecco cosa succede, passo dopo passo: + +![Accesso SAML normale senza Ethereum](./fig-04-saml-no-eth.png) + +#### src/config.mts + +Questo file contiene la configurazione sia per l'Identity Provider che per il Service Provider. Normalmente queste due sarebbero entità differenti, ma qui possiamo condividere il codice per semplicità. + +```typescript +const fs = await import("fs") + +const protocol="http" +``` + +Per ora stiamo solo testando, quindi va bene usare HTTP. + +```typescript +export const spCert = fs.readFileSync("keys/saml-sp.crt").toString() +export const idpCert = fs.readFileSync("keys/saml-idp.crt").toString() +``` + +Leggi le chiavi pubbliche, che normalmente sono disponibili per entrambi i componenti (e sono affidabili direttamente o firmate da un'autorità di certificazione fidata). + +```typescript +export const spPort = 3000 +export const spHostname = "localhost" +export const spDir = "sp" + +export const idpPort = 3001 +export const idpHostname = "localhost" +export const idpDir = "idp" + +export const spUrl = `${protocol}://${spHostname}:${spPort}/${spDir}` +export const idpUrl = `${protocol}://${idpHostname}:${idpPort}/${idpDir}` +``` + +Gli URL per entrambi i componenti. + +```typescript +export const spPublicData = { +``` + +I dati pubblici per il fornitore di servizi. + +```typescript + entityID: `${spUrl}/metadata`, +``` + +Per convenzione, in SAML `entityID` è l'URL in cui sono disponibili i metadati dell'entità. Questi metadati corrispondono ai dati pubblici qui, tranne per il fatto che sono in formato XML. + +```typescript + wantAssertionsSigned: true, + authnRequestsSigned: false, + signingCert: spCert, + allowCreate: true, + assertionConsumerService: [{ + Binding: 'urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST', + Location: `${spUrl}/assertion`, + }] + } +``` + +La definizione più importante per i nostri scopi è `assertionConsumerServer`. Significa che per asserire qualcosa (ad esempio, "l'utente che ti invia queste informazioni è somebody@example.com") al fornitore di servizi, dobbiamo usare [HTTP POST](https://www.w3schools.com/tags/ref_httpmethods.asp) all'URL `http://localhost:3000/sp/assertion`. + +```typescript +export const idpPublicData = { + entityID: `${idpUrl}/metadata`, + signingCert: idpCert, + wantAuthnRequestsSigned: false, + singleSignOnService: [{ + Binding: "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST", + Location: `${idpUrl}/login` + }], + singleLogoutService: [{ + Binding: "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST", + Location: `${idpUrl}/logout` + }], + } +``` + +I dati pubblici del fornitore di identità sono simili. Specifica che per far accedere un utente devi fare una richiesta POST a `http://localhost:3001/idp/login` e per disconnetterlo devi fare una richiesta POST a `http://localhost:3001/idp/logout`. + +#### src/sp.mts + +Questo è il codice che implementa un fornitore di servizi. + +```typescript +import * as config from "./config.mts" +const fs = await import("fs") +const saml = await import("samlify") +``` + +Usiamo la libreria [`samlify`](https://www.npmjs.com/package/samlify) per implementare SAML. + +```typescript +import * as validator from "@authenio/samlify-node-xmllint" +saml.setSchemaValidator(validator) +``` + +La libreria `samlify` si aspetta di avere un pacchetto che convalidi che l'XML sia corretto, firmato con la chiave pubblica prevista, ecc. A tale scopo, usiamo [`@authenio/samlify-node-xmllint`](https://www.npmjs.com/package/@authenio/samlify-node-xmllint). + +```typescript +const express = (await import("express")).default +const spRouter = express.Router() +const app = express() +``` + +Un [`Router`](https://expressjs.com/en/5x/api.html#router) di [`express`](https://expressjs.com/) è un "mini sito web" che può essere montato all'interno di un sito web. In questo caso, lo usiamo per raggruppare tutte le definizioni del fornitore di servizi. + +```typescript +const spPrivateKey = fs.readFileSync("keys/saml-sp.pem").toString() + +const sp = saml.ServiceProvider({ + privateKey: spPrivateKey, + ...config.spPublicData +}) +``` + +La rappresentazione che il fornitore di servizi ha di se stesso comprende tutti i dati pubblici e la chiave privata che usa per firmare le informazioni. + +```typescript +const idp = saml.IdentityProvider(config.idpPublicData); +``` + +I dati pubblici contengono tutto ciò che il fornitore di servizi deve sapere sul fornitore di identità. + +```typescript +spRouter.get(`/metadata`, + (req, res) => res.header("Content-Type", "text/xml").send(sp.getMetadata()) +) +``` + +Per consentire l'interoperabilità con altri componenti SAML, i fornitori di servizi e di identità dovrebbero avere i loro dati pubblici (chiamati metadati) disponibili in formato XML in `/metadata`. + +```typescript +spRouter.post(`/assertion`, +``` + +Questa è la pagina a cui accede il browser per identificarsi. L'asserzione include l'identificatore dell'utente (qui usiamo l'indirizzo email) e può includere attributi aggiuntivi. Questo è il gestore per il passaggio 7 nel diagramma di sequenza sopra. + +```typescript + async (req, res) => { + // console.log(`SAML response:\n${Buffer.from(req.body.SAMLResponse, 'base64').toString('utf-8')}`) +``` + +È possibile usare il comando commentato per visualizzare i dati XML forniti nell'asserzione. È [codificato in base64](https://en.wikipedia.org/wiki/Base64). + +```typescript + try { + const loginResponse = await sp.parseLoginResponse(idp, 'post', req); +``` + +Analizza la richiesta di accesso dal server di identità. + +```typescript + res.send(` + + +

Hello ${loginResponse.extract.nameID}

+ + + `) + res.send(); +``` + +Invia una risposta HTML, solo per mostrare all'utente che abbiamo ricevuto l'accesso. + +```typescript + } catch (err) { + console.error('Error processing SAML response:', err); + res.status(400).send('SAML authentication failed'); + } + } +) +``` + +Informa l'utente in caso di errore. + +```typescript +spRouter.get('/login', +``` + +Crea una richiesta di accesso quando il browser tenta di ottenere questa pagina. Questo è il gestore per il passaggio 1 nel diagramma di sequenza sopra. + +```typescript + async (req, res) => { + const loginRequest = await sp.createLoginRequest(idp, "post") +``` + +Ottieni le informazioni per inviare una richiesta di accesso. + +```typescript + res.send(` + + + +``` + +Questa pagina invia il modulo (vedi sotto) automaticamente. In questo modo l'utente non deve fare nulla per essere reindirizzato. Questo è il passaggio 2 nel diagramma di sequenza sopra. + +```typescript +
+``` + +Invia a `loginRequest.entityEndpoint` (l'URL dell'endpoint del fornitore di identità). + +```typescript + +``` + +Il nome dell'input è `loginRequest.type` (`SAMLRequest`). Il contenuto di quel campo è `loginRequest.context`, che è di nuovo XML codificato in base64. + +```typescript +
+ + + `) + } +) + +app.use(express.urlencoded({extended: true})) +``` + +[Questo middleware](https://expressjs.com/en/5x/api.html#express.urlencoded) legge il corpo della [richiesta HTTP](https://www.tutorialspoint.com/http/http_requests.htm). Per impostazione predefinita, express lo ignora, perché la maggior parte delle richieste non lo richiede. Ne abbiamo bisogno perché POST usa il corpo. + +```typescript +app.use(`/${config.spDir}`, spRouter) +``` + +Monta il router nella directory del fornitore di servizi (`/sp`). + +```typescript +app.get("/", (req, res) => { + res.send(` + + + + + + `) +}) +``` + +Se un browser tenta di accedere alla directory principale, forniscigli un link alla pagina di accesso. + +```typescript +app.listen(config.spPort, () => { + console.log(`il fornitore di servizi è in esecuzione su http://${config.spHostname}:${config.spPort}`) +}) +``` + +Ascolta la `spPort` con questa applicazione express. + +#### src/idp.mts + +Questo è il fornitore di identità. È molto simile al fornitore di servizi, le spiegazioni seguenti riguardano le parti che sono differenti. + +```typescript +const xmlParser = new (await import("fast-xml-parser")).XMLParser( + { + ignoreAttributes: false, // Conserva gli attributi + attributeNamePrefix: "@_", // Prefisso per gli attributi + } +) +``` + +Dobbiamo leggere e comprendere la richiesta XML che riceviamo dal fornitore di servizi. + +```typescript +const getLoginPage = requestId => ` +``` + +Questa funzione crea la pagina con il modulo inviato automaticamente che viene restituito nel passaggio 4 del diagramma di sequenza sopra. + +```typescript + + + Pagina di accesso + + +

Pagina di accesso

+
+ + Indirizzo email: +
+ +``` + +Ci sono due campi che inviamo al fornitore di servizi: + +1. Il `requestId` a cui stiamo rispondendo. +2. L'identificatore dell'utente (per ora usiamo l'indirizzo email fornito dall'utente). + +```typescript +
+ + + +const idpRouter = express.Router() + +idpRouter.post("/loginSubmitted", async (req, res) => { + const loginResponse = await idp.createLoginResponse( +``` + +Questo è il gestore per il passaggio 5 nel diagramma di sequenza sopra. [`idp.createLoginResponse`](https://github.com/tngan/samlify/blob/master/src/entity-idp.ts#L73-L125) crea la risposta di accesso. + +```typescript + sp, + { + authnContextClassRef: 'urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport', + audience: sp.entityID, +``` + +Il pubblico è il fornitore di servizi. + +```typescript + extract: { + request: { + id: req.body.requestId + } + }, +``` + +Informazioni estratte dalla richiesta. L'unico parametro che ci interessa nella richiesta è il requestId, che consente al fornitore di servizi di abbinare le richieste e le loro risposte. + +```typescript + signingKey: { privateKey: idpPrivateKey, publicKey: config.idpCert } // Assicura la firma +``` + +Abbiamo bisogno di `signingKey` per avere i dati per firmare la risposta. Il fornitore di servizi non si fida delle richieste non firmate. + +```typescript + }, + "post", + { + email: req.body.email +``` + +Questo è il campo con le informazioni dell'utente che inviamo al fornitore di servizi. + +```typescript + } + ); + + res.send(` + + + + +
+ +
+ + + `) +}) +``` + +Di nuovo, usa un modulo inviato automaticamente. Questo è il passaggio 6 del diagramma di sequenza sopra. + +```typescript + +// Endpoint IdP per le richieste di accesso +idpRouter.post(`/login`, +``` + +Questo è l'endpoint che riceve una richiesta di accesso dal fornitore di servizi. Questo è il gestore per il passaggio 3 del diagramma di sequenza sopra. + +```typescript + async (req, res) => { + try { + // Soluzione alternativa perché non sono riuscito a far funzionare parseLoginRequest. + // const loginRequest = await idp.parseLoginRequest(sp, 'post', req) + const samlRequest = xmlParser.parse(Buffer.from(req.body.SAMLRequest, 'base64').toString('utf-8')) + res.send(getLoginPage(samlRequest["samlp:AuthnRequest"]["@_ID"])) +``` + +Dovremmo essere in grado di usare [`idp.parseLoginRequest`](https://github.com/tngan/samlify/blob/master/src/entity-idp.ts#L127-L144) per leggere l'ID della richiesta di autenticazione. Tuttavia, non sono riuscito a farlo funzionare e non valeva la pena spenderci molto tempo, quindi ho usato un [parser XML generico](https://www.npmjs.com/package/fast-xml-parser). L'informazione di cui abbiamo bisogno è l'attributo `ID` all'interno del tag ``, che si trova al livello più alto dell'XML. + +## Uso delle firme di Ethereum + +Ora che possiamo inviare un'identità utente al fornitore di servizi, il passo successivo è ottenere l'identità utente in modo affidabile. Viem ci permette di chiedere semplicemente al portafoglio l'indirizzo dell'utente, ma questo significa chiedere l'informazione al browser. Non controlliamo il browser, quindi non possiamo fidarci automaticamente della risposta che riceviamo da esso. + +Invece, l'IdP invierà al browser una stringa da firmare. Se il portafoglio nel browser firma questa stringa, significa che è davvero quell'indirizzo (cioè, conosce la chiave privata che corrisponde all'indirizzo). + +Per vederlo in azione, ferma l'IdP e l'SP esistenti ed esegui questi comandi: + +```sh +git checkout eth-signatures +pnpm install +pnpm start +``` + +Quindi naviga [all'SP](http://localhost:3000) e segui le indicazioni. + +Nota che a questo punto non sappiamo come ottenere l'indirizzo email dall'indirizzo Ethereum, quindi, invece, segnaliamo `@bad.email.address` all'SP. + +### Spiegazione dettagliata + +Le modifiche sono nei passaggi 4-5 del diagramma precedente. + +![SAML con una firma di Ethereum](./fig-05-saml-w-signature.png) + +L'unico file che abbiamo modificato è `idp.mts`. Ecco le parti modificate. + +```typescript +import { v4 as uuidv4 } from 'uuid' +import { verifyMessage } from 'viem' +``` + +Abbiamo bisogno di queste due librerie aggiuntive. Usiamo [`uuid`](https://www.npmjs.com/package/uuid) per creare il valore [nonce](https://en.wikipedia.org/wiki/Cryptographic_nonce). Il valore in sé non ha importanza, solo il fatto che venga usato una sola volta. + +La libreria [`viem`](https://viem.sh/) ci permette di usare le definizioni di Ethereum. Qui ne abbiamo bisogno per verificare che la firma sia effettivamente valida. + +```typescript +const loginPrompt = "Per accedere al fornitore di servizi, firma questo nonce: " +``` + +Il portafoglio chiede all'utente il permesso di firmare il messaggio. Un messaggio che è solo un nonce potrebbe confondere gli utenti, quindi includiamo questo prompt. + +```typescript +// Conserva i requestId qui +let nonces = {} +``` + +Abbiamo bisogno delle informazioni della richiesta per poter rispondere. Potremmo inviarle con la richiesta (passaggio 4) e riceverle indietro (passaggio 5). Tuttavia, non possiamo fidarci delle informazioni che otteniamo dal browser, che è sotto il controllo di un utente potenzialmente ostile. Quindi è meglio memorizzarle qui, con il nonce come chiave. + +Nota che lo stiamo facendo qui come variabile per semplicità. Tuttavia, questo ha diversi svantaggi: + +- Siamo vulnerabili a un attacco di negazione del servizio. Un utente malevolo potrebbe tentare di accedere più volte, riempiendo la nostra memoria. +- Se il processo IdP deve essere riavviato, perdiamo i valori esistenti. +- Non possiamo bilanciare il carico su più processi, perché ognuno avrebbe la propria variabile. + +Su un sistema di produzione useremmo un database e implementeremmo un qualche tipo di meccanismo di scadenza. + +```typescript +const getSignaturePage = requestId => { + const nonce = uuidv4() + nonces[nonce] = requestId +``` + +Crea un nonce e memorizza il `requestId` per un uso futuro. + +```typescript + return ` + + + + + +

Per favore, firma

+ +
+ + + +` +} +``` + +Il resto è solo HTML standard. + +```typescript +idpRouter.get("/signature/:nonce/:account/:signature", async (req, res) => { +``` + +Questo è il gestore per il passaggio 5 nel diagramma di sequenza. + +```typescript + const requestId = nonces[req.params.nonce] + if (requestId === undefined) { + res.send("Nonce errato") + return ; + } + + nonces[req.params.nonce] = undefined +``` + +Ottieni l'ID della richiesta ed elimina il nonce da `nonces` per assicurarti che non possa essere riutilizzato. + +```typescript + try { +``` + +Poiché ci sono tanti modi in cui la firma può essere non valida, avvolgiamo questo in un blocco `try ...` blocco `catch` per catturare eventuali errori lanciati. + +```typescript + const validSignature = await verifyMessage({ + address: req.params.account, + message: `${loginPrompt}${req.params.nonce}`, + signature: req.params.signature + }) +``` + +Usa [`verifyMessage`](https://viem.sh/docs/actions/public/verifyMessage#verifymessage) per implementare il passaggio 5.5 nel diagramma di sequenza. + +```typescript + if (!validSignature) + throw("Firma errata") + } catch (err) { + res.send("Errore:" + err) + return ; + } +``` + +Il resto del gestore è equivalente a ciò che abbiamo fatto in precedenza nel gestore `/loginSubmitted`, tranne per una piccola modifica. + +```typescript + const loginResponse = await idp.createLoginResponse( + . + . + . + { + email: req.params.account + "@bad.email.address" + } + ); +``` + +Non abbiamo l'indirizzo email effettivo (lo otterremo nella prossima sezione), quindi per ora restituiamo l'indirizzo Ethereum e lo contrassegniamo chiaramente come non un indirizzo email. + +```typescript +// Endpoint IdP per le richieste di accesso +idpRouter.post(`/login`, + async (req, res) => { + try { + // Soluzione alternativa perché non sono riuscito a far funzionare parseLoginRequest. + // const loginRequest = await idp.parseLoginRequest(sp, 'post', req) + const samlRequest = xmlParser.parse(Buffer.from(req.body.SAMLRequest, 'base64').toString('utf-8')) + res.send(getSignaturePage(samlRequest["samlp:AuthnRequest"]["@_ID"])) + } catch (err) { + console.error('Errore nell'elaborazione della risposta SAML:', err); + res.status(400).send('Autenticazione SAML fallita'); + } + } +) +``` + +Invece di `getLoginPage`, ora usa `getSignaturePage` nel gestore del passaggio 3. + +## Ottenere l'indirizzo email + +Il passo successivo è ottenere l'indirizzo email, l'identificatore richiesto dal fornitore di servizi. Per farlo, usiamo [Ethereum Attestation Service (EAS)](https://attest.org/). + +Il modo più semplice per ottenere le attestazioni è usare l'[API GraphQL](https://docs.attest.org/docs/developer-tools/api). Usiamo questa query: + +``` +query GetAttestationsByRecipient { + attestations( + where: { + recipient: { equals: "${getAddress(ethAddr)}" } + schemaId: { equals: "0xfa2eff59a916e3cc3246f9aec5e0ca00874ae9d09e4678e5016006f07622f977" } + } + take: 1 + ) { + data + id + attester + } +} +``` + +Questo [`schemaId`](https://optimism.easscan.org/schema/view/0xfa2eff59a916e3cc3246f9aec5e0ca00874ae9d09e4678e5016006f07622f977) include solo un indirizzo e-mail. Questa query richiede le attestazioni di questo schema. Il soggetto dell'attestazione è chiamato `destinatario`. È sempre un indirizzo Ethereum. + +Attenzione: il modo in cui stiamo ottenendo le attestazioni qui presenta due problemi di sicurezza. + +- Stiamo andando all'endpoint API, `https://optimism.easscan.org/graphql`, che è un componente centralizzato. Possiamo ottenere l'attributo `id` e quindi fare una ricerca sulla catena per verificare che un'attestazione sia reale, ma l'endpoint dell'API può ancora censurare le attestazioni non informandoci della loro esistenza. + + Questo problema non è impossibile da risolvere, potremmo eseguire il nostro endpoint GraphQL e ottenere le attestazioni dai registri della catena, ma questo è eccessivo per i nostri scopi. + +- Non guardiamo l'identità dell'attestatore. Chiunque può fornirci informazioni false. In un'implementazione reale, avremmo un set di attestatori fidati e guarderemmo solo le loro attestazioni. + +Per vederlo in azione, ferma l'IdP e l'SP esistenti ed esegui questi comandi: + +```sh +git checkout email-address +pnpm install +pnpm start +``` + +Quindi fornisci il tuo indirizzo e-mail. Hai due modi per farlo: + +- Importa un portafoglio usando una chiave privata e usa la chiave privata di prova `0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80`. + +- Aggiungi un'attestazione per il tuo indirizzo e-mail: + + 1. Naviga [allo schema nell'esploratore di attestazioni](https://optimism.easscan.org/schema/view/0xfa2eff59a916e3cc3246f9aec5e0ca00874ae9d09e4678e5016006f07622f977). + + 2. Fai clic su **Attesta con Schema**. + + 3. Inserisci il tuo indirizzo Ethereum come destinatario, il tuo indirizzo e-mail come indirizzo email e seleziona **Sulla catena**. Quindi fai clic su **Crea Attestazione**. + + 4. Approva la transazione nel tuo portafoglio. Avrai bisogno di un po' di ETH sulla [Blockchain di Optimism](https://app.optimism.io/bridge/deposit) per pagare il gas. + +In ogni caso, dopo aver fatto questo, naviga su [http://localhost:3000](http://localhost:3000) e segui le indicazioni. Se hai importato la chiave privata di prova, l'e-mail che ricevi è `test_addr_0@example.com`. Se hai usato il tuo indirizzo, dovrebbe essere quello che hai attestato. + +### Spiegazione dettagliata + +![Ottenere l'e-mail dall'indirizzo Ethereum](./fig-06-saml-sig-n-email.png) + +I nuovi passaggi sono la comunicazione GraphQL, i passaggi 5.6 e 5.7. + +Di nuovo, ecco le parti modificate di `idp.mts`. + +```typescript +import { GraphQLClient } from 'graphql-request' +import { SchemaEncoder } from '@ethereum-attestation-service/eas-sdk' +``` + +Importa le librerie di cui abbiamo bisogno. + +```typescript +const graphqlEndpointUrl = "https://optimism.easscan.org/graphql" +``` + +C'è [un endpoint separato per ogni blockchain](https://docs.attest.org/docs/developer-tools/api). + +```typescript +const graphqlClient = new GraphQLClient(graphqlEndpointUrl, { fetch }) +``` + +Crea un nuovo client `GraphQLClient` che possiamo usare per interrogare l'endpoint. + +```typescript +const graphqlSchema = 'string emailAddress' +const graphqlEncoder = new SchemaEncoder(graphqlSchema) +``` + +GraphQL ci fornisce solo un oggetto dati opaco con byte. Per capirlo abbiamo bisogno dello schema. + +```typescript +const ethereumAddressToEmail = async ethAddr => { +``` + +Una funzione per passare da un indirizzo Ethereum a un indirizzo e-mail. + +```typescript + const query = ` + query GetAttestationsByRecipient { +``` + +Questa è una query GraphQL. + +```typescript + attestazioni( +``` + +Stiamo cercando attestazioni. + +```typescript + where: { + recipient: { equals: "${getAddress(ethAddr)}" } + schemaId: { equals: "0xfa2eff59a916e3cc3246f9aec5e0ca00874ae9d09e4678e5016006f07622f977" } + } +``` + +Le attestazioni che vogliamo sono quelle nel nostro schema, in cui il destinatario è `getAddress(ethAddr)`. La funzione [`getAddress`](https://viem.sh/docs/utilities/getAddress#getaddress) si assicura che il nostro indirizzo abbia il [checksum](https://github.com/ethereum/ercs/blob/master/ERCS/erc-55.md) corretto. Questo è necessario perché GraphQL è sensibile alle maiuscole/minuscole. "0xBAD060A7", "0xBad060A7" e "0xbad060a7" sono valori diversi. + +```typescript + take: 1 +``` + +Indipendentemente da quante attestazioni troviamo, vogliamo solo la prima. + +```typescript + ) { + data + id + attester + } + }` +``` + +I campi che vogliamo ricevere. + +- `attestatore`: l'indirizzo che ha inviato l'attestazione. Normalmente questo viene usato per decidere se fidarsi o meno dell'attestazione. +- `id`: L'ID dell'attestazione. Puoi usare questo valore per [leggere l'attestazione sulla catena](https://optimism.blockscout.com/address/0x4200000000000000000000000000000000000021?tab=read_proxy&source_address=0x4E0275Ea5a89e7a3c1B58411379D1a0eDdc5b088#0xa3112a64) per verificare che le informazioni della query GraphQL siano corrette. +- `data`: i dati dello schema (in questo caso, l'indirizzo e-mail). + +```typescript + const queryResult = await graphqlClient.request(query) + + if (queryResult.attestations.length == 0) + return "no_address@available.is" +``` + +Se non c'è un'attestazione, restituisce un valore che è ovviamente errato, ma che apparirebbe valido al fornitore di servizi. + +```typescript + const attestationDataFields = graphqlEncoder.decodeData(queryResult.attestations[0].data) + return attestationDataFields[0].value.value +} +``` + +Se c'è un valore, usa `decodeData` per decodificare i dati. Non abbiamo bisogno dei metadati che fornisce, solo del valore stesso. + +```typescript + const loginResponse = await idp.createLoginResponse( + sp, + { + . + . + . + }, + "post", + { + email: await ethereumAddressToEmail(req.params.account) + } + ); +``` + +Usa la nuova funzione per ottenere l'indirizzo e-mail. + +## E la decentralizzazione? + +In questa configurazione gli utenti non possono fingere di essere qualcuno che non sono, a condizione che ci affidiamo ad attestatori affidabili per la mappatura dell'indirizzo Ethereum all'indirizzo e-mail. Tuttavia, il nostro fornitore di identità è ancora un componente centralizzato. Chiunque abbia la chiave privata del fornitore di identità può inviare informazioni false al fornitore di servizi. + +Potrebbe esserci una soluzione che utilizza il [calcolo multi-parte (MPC)](https://en.wikipedia.org/wiki/Secure_multi-party_computation). Spero di scriverne in una guida futura. + +## Conclusione + +L'adozione di uno standard di accesso, come le firme di Ethereum, si scontra con il problema dell'uovo e della gallina. I fornitori di servizi vogliono rivolgersi al mercato più ampio possibile. Gli utenti vogliono poter accedere ai servizi senza doversi preoccupare di supportare il loro standard di accesso. +La creazione di adattatori, come un IdP Ethereum, può aiutarci a superare questo ostacolo. + +[Vedi qui per altri miei lavori](https://cryptodocguy.pro/). diff --git a/public/content/translations/it/developers/tutorials/getting-started-with-ethereum-development-using-alchemy/index.md b/public/content/translations/it/developers/tutorials/getting-started-with-ethereum-development-using-alchemy/index.md index 4530e734b93..33d8103469d 100644 --- a/public/content/translations/it/developers/tutorials/getting-started-with-ethereum-development-using-alchemy/index.md +++ b/public/content/translations/it/developers/tutorials/getting-started-with-ethereum-development-using-alchemy/index.md @@ -1,58 +1,60 @@ --- title: Primi passi con lo sviluppo di Ethereum -description: "Questa è una guida per principianti per iniziare con lo sviluppo di Ethereum. Ti guideremo dal lancio di un endpoint API alla formulazione di una richiesta da riga di comando, fino alla scrittura del tuo primo script web3! Non è necessaria alcuna esperienza di sviluppo con le blockchain!" +description: "Questa è una guida per principianti per iniziare con lo sviluppo di Ethereum. Ti guideremo dal lancio di un endpoint API alla formulazione di una richiesta da riga di comando, fino alla scrittura del tuo primo script web3! Non è necessaria alcuna esperienza di sviluppo con la blockchain." author: "Elan Halpern" tags: - - "javascript" - - "ethers.js" - - "nodi" - - "query" - - "alchemy" + [ + "javascript", + "ethers.js", + "nodi", + "query", + "alchemy" + ] skill: beginner lang: it published: 2020-10-30 -source: Medio +source: Medium sourceUrl: https://medium.com/alchemy-api/getting-started-with-ethereum-development-using-alchemy-c3d6a45c567f --- -![Loghi Ethereum e Alchemy](./ethereum-alchemy.png) +![Loghi di Ethereum e Alchemy](./ethereum-alchemy.png) -Questa è una guida per principianti per muovere i primi passi con lo sviluppo di Ethereum. Per questo tutorial useremo [Alchemy](https://alchemyapi.io/), la piattaforma principale per sviluppatori della blockchain con milioni di utenti dal 70% delle migliori app della blockchain, tra cui Maker, 0x, MyEtherWallet, Dharma e Kyber. Alchemy ci darà accesso all'endpoint di un'API sulla catena di Ethereum, così da permetterci di leggere e scrivere le transazioni. +Questa è una guida per principianti per muovere i primi passi con lo sviluppo di Ethereum. Per questo tutorial useremo [Alchemy](https://alchemyapi.io/), la piattaforma di sviluppo blockchain leader che alimenta milioni di utenti dal 70% delle migliori app blockchain, tra cui Maker, 0x, MyEtherWallet, Dharma e Kyber. Alchemy ci darà accesso all'endpoint di un'API sulla catena di Ethereum, così da permetterci di leggere e scrivere le transazioni. -Inizieremo dalla registrazione ad Alchemy e passeremo alla scrittura del tuo primo script web3! Non è necessaria alcuna esperienza di sviluppo con blockchain. +Inizieremo dalla registrazione ad Alchemy e passeremo alla scrittura del tuo primo script web3! Non è necessaria alcuna esperienza di sviluppo con la blockchain. -## 1. Registrati per un Conto Gratuito di Alchemy {#sign-up-for-a-free-alchemy-account} +## 1. Registrati per un account Alchemy gratuito {#sign-up-for-a-free-alchemy-account} -Creare un conto di Alchemy è facile, [registrati gratuitamente qui](https://auth.alchemyapi.io/signup). +Creare un account con Alchemy è facile, [registrati gratuitamente qui](https://auth.alchemy.com/). -## 2. Crea un'app con Alchemy {#create-an-alchemy-app} +## 2. Crea un'app Alchemy {#create-an-alchemy-app} -Per comunicare con la catena Ethereum e per utilizzare i prodotti di Alchemy, è necessaria una chiave API per autenticare le richieste. +Per comunicare con la catena di Ethereum e per utilizzare i prodotti di Alchemy, è necessaria una chiave API per autenticare le richieste. -Puoi [creare chiavi API dalla dashboard](http://dashboard.alchemyapi.io/). Per creare una nuova chiave, vai a "Create App" come mostrato sotto: +Puoi [creare chiavi API dalla dashboard](https://dashboard.alchemy.com/). Per creare una nuova chiave, vai a "Crea App" come mostrato sotto: -Ringraziamenti speciali a [_ShapeShift_](https://shapeshift.com/) _per averci permesso di mostrare la sua dashboard!_ +Un ringraziamento speciale a [_ShapeShift_](https://shapeshift.com/) _per averci permesso di mostrare la loro dashboard!_ ![Dashboard di Alchemy](./alchemy-dashboard.png) -Compila i dettagli sotto "Create App" per ottenere la tua nuova chiave. Qui puoi anche vedere le app create in precedenza e quelle create dal tuo team. Preleva le chiavi esistenti facendo clic su "View Key" per qualsiasi app. +Compila i dettagli sotto "Crea App" per ottenere la tua nuova chiave. Qui puoi anche vedere le app create in precedenza e quelle create dal tuo team. Recupera le chiavi esistenti facendo clic su "View Key" per qualsiasi app. -![Crea l'app con gli screenshot di Alchemy](./create-app.png) +![Screenshot della creazione di un'app con Alchemy](./create-app.png) -Puoi anche prelevare chiavi API esistenti passando con il mouse su "Apps" e selezionandone una. Puoi scegliere "View Key" o "Edit App" per consentire domini specifici, vedere diversi strumenti da sviluppatore e visualizzare i dati analitici. +Puoi anche recuperare chiavi API esistenti passando il mouse su "App" e selezionandone una. Qui puoi usare "View Key" e "Edit App" per aggiungere domini specifici alla whitelist, vedere diversi strumenti per sviluppatori e visualizzare i dati analitici. -![Gif che mostra a un utente come estrarre le chiavi API](./pull-api-keys.gif) +![GIF che mostra a un utente come recuperare le chiavi API](./pull-api-keys.gif) ## 3. Effettua una richiesta dalla riga di comando {#make-a-request-from-the-command-line} -Interagisci con la blockchain Ethereum tramite Alchemy usando JSON-RPC e curl. +Interagisci con la blockchain di Ethereum tramite Alchemy usando JSON-RPC e curl. -Per le richieste manuali, consigliamo di interagire con `JSON-RPC` tramite richieste `POST`. Passa semplicemente nell'intestazione `Content-Type: application/json` la tua query sotto forma di corpo `POST` con i seguenti campi: +Per le richieste manuali, consigliamo di interagire con il `JSON-RPC` tramite richieste `POST`. Basta passare l'header `Content-Type: application/json` e la query come corpo `POST` con i seguenti campi: -- `jsonrpc`: versione JSON-RPC. Attualmente è supportata solo la `2.0`. -- `method`: metodo dell'API ETH. [Vedi il riferimento all'API.](https://docs.alchemyapi.io/documentation/alchemy-api-reference/json-rpc) -- `params`: elenco di parametri da passare al metodo. -- `id`: ID della richiesta. Sarà restituita dalla risposta, e potrai controllare sempre a quale richiesta appartiene la risposta. +- `jsonrpc`: la versione di JSON-RPC; attualmente, è supportato solo `2.0`. +- `method`: il metodo dell'API ETH. [Vedi il riferimento API.](https://docs.alchemyapi.io/documentation/alchemy-api-reference/json-rpc) +- `params`: un elenco di parametri da passare al metodo. +- `id`: l'ID della tua richiesta. Sarà restituito dalla risposta, così potrai tenere traccia a quale richiesta corrisponde una risposta. Ecco un esempio che puoi eseguire dalla riga di comando per recuperare il prezzo corrente del gas: @@ -63,7 +65,7 @@ curl https://eth-mainnet.alchemyapi.io/v2/demo \ -d '{"jsonrpc":"2.0","method":"eth_gasPrice","params":[],"id":73}' ``` -_**NOTA:** Sostituisci [https://eth-mainnet.alchemyapi.io/v2/demo](https://eth-mainnet.alchemyapi.io/jsonrpc/demo) con la tua chiave API `https://eth-mainnet.alchemyapi.io/v2/**your-api-key`._ +_**NOTA:** Sostituisci [https://eth-mainnet.alchemyapi.io/v2/demo](https://eth-mainnet.alchemyapi.io/jsonrpc/demo) con la tua chiave API: `https://eth-mainnet.alchemyapi.io/v2/**your-api-key`._ **Risultati:** @@ -71,13 +73,13 @@ _**NOTA:** Sostituisci [https://eth-mainnet.alchemyapi.io/v2/demo](https://eth-m { "id": 73,"jsonrpc": "2.0","result": "0x09184e72a000" // 10000000000000 } ``` -## 4. Configura il client Web3 {#set-up-your-web3-client} +## 4. Configura il tuo client Web3 {#set-up-your-web3-client} -**Se hai già un client,** cambia l'URL del provider del nodo corrente inserendo un URL Alchemy con la tua chiave API: `"https://eth-mainnet.alchemyapi.io/v2/your-api-key"` +**Se hai già un client,** cambia l'URL del provider del tuo nodo corrente con un URL di Alchemy con la tua chiave API: `“https://eth-mainnet.alchemyapi.io/v2/your-api-key"` -**_NOTA:_** gli script qui sotto devono essere eseguiti in un **contesto node** o **salvati in un file**, non devono essere eseguiti dalla riga di comando. Se non hai installato Node o npm, dai un'occhiata a questa [guida di configurazione per Mac](https://app.gitbook.com/@alchemyapi/s/alchemy/guides/alchemy-for-macs). +**_NOTA:_** Gli script qui sotto devono essere eseguiti in un **contesto node** o **salvati in un file**, non eseguiti dalla riga di comando. Se non hai già installato Node o npm, consulta questa rapida [guida alla configurazione per Mac](https://app.gitbook.com/@alchemyapi/s/alchemy/guides/alchemy-for-macs). -Ci sono tantissime [librerie Web3](https://docs.alchemyapi.io/guides/getting-started#other-web3-libraries) che puoi integrare con Alchemy, tuttavia, consigliamo di usare [Alchemy Web3](https://docs.alchemy.com/reference/api-overview), un sostituto di web3.js, creato e configurato per funzionare senza problemi con Alchemy. Fornisce diversi vantaggi, come tentativi automatici e supporto affidabile per WebSocket. +Esistono tantissime [librerie Web3](https://docs.alchemyapi.io/guides/getting-started#other-web3-libraries) che puoi integrare con Alchemy, tuttavia, ti consigliamo di usare [Alchemy Web3](https://docs.alchemy.com/reference/api-overview), un sostituto pronto all'uso per web3.js, creato e configurato per funzionare senza problemi con Alchemy. Ciò fornisce diversi vantaggi, come tentativi automatici e un solido supporto WebSocket. Per installare AlchemyWeb3.js, **passa alla directory del tuo progetto** ed esegui: @@ -93,7 +95,7 @@ yarn add @alch/alchemy-web3 npm install @alch/alchemy-web3 ``` -Per interagire con l'infrastruttura del nodo di Alchemy, esegui NodeJS o aggiungi il codice seguente a un file JavaScript: +Per interagire con l'infrastruttura dei nodi di Alchemy, esegui il codice in NodeJS o aggiungilo a un file JavaScript: ```js const { createAlchemyWeb3 } = require("@alch/alchemy-web3") @@ -104,36 +106,36 @@ const web3 = createAlchemyWeb3( ## 5. Scrivi il tuo primo script Web3! {#write-your-first-web3-script} -Ora per sporcarci un po' le mani con la programmazione web3 scriveremo uno script semplice che riporta il numero dell'ultimo blocco della rete principale Ethereum. +Ora per sporcarci un po' le mani con la programmazione web3 scriveremo uno script semplice che stampa il numero dell'ultimo blocco della Rete Principale di Ethereum. -**1. Se non lo hai già fatto, nel terminale crea una nuova directory del progetto passa ad essa (cd):** +**1. Se non l'hai già fatto, nel terminale crea una nuova directory di progetto e accedi con cd:** ``` mkdir web3-example cd web3-example ``` -**2. Se non lo hai già fatto, installa la dipendenza Alchemy Web3 (o web3 di altro tipo) nel progetto:** +**2. Installa la dipendenza Alchemy web3 (o qualsiasi web3) nel tuo progetto se non l'hai già fatto:** ``` npm install @alch/alchemy-web3 ``` -**3. Crea un file denominato `index.js` e aggiungi i seguenti contenuti:** +**3. Crea un file di nome `index.js` e aggiungi i seguenti contenuti:** -> Devi sostituire `demo` con la tua chiave API HTTP di Alchemy. +> Infine, dovrai sostituire `demo` con la tua chiave API HTTP di Alchemy. ```js async function main() { const { createAlchemyWeb3 } = require("@alch/alchemy-web3") const web3 = createAlchemyWeb3("https://eth-mainnet.alchemyapi.io/v2/demo") const blockNumber = await web3.eth.getBlockNumber() - console.log("The latest block number is " + blockNumber) + console.log("Il numero di blocco più recente è " + blockNumber) } main() ``` -Non hai famigliarità con la programmazione asincrona? Dai un'occhiata a questo [post di Medium](https://medium.com/better-programming/understanding-async-await-in-javascript-1d81bb079b2c). +Non hai famigliarità con la programmazione asincrona? Dai un'occhiata a questo [post su Medium](https://medium.com/better-programming/understanding-async-await-in-javascript-1d81bb079b2c). **4. Eseguilo nel terminale usando node** @@ -141,14 +143,14 @@ Non hai famigliarità con la programmazione asincrona? Dai un'occhiata a questo node index.js ``` -**5. A questo punto dovresti vedere l'output con il numero dell'ultimo blocco nella console!** +**5. A questo punto dovresti vedere il numero di blocco più recente nella tua console!** ``` -The latest block number is 11043912 +Il numero di blocco più recente è 11043912 ``` -**Wow! Congratulazioni! Hai appena scritto il tuo primo script web3 usando Alchemy** +**Woo!** Congratulazioni! Hai appena scritto il tuo primo script web3 usando Alchemy 🎉\*\* -Non sai come proseguire? Prova a distribuire il tuo primo smart contract e fai qualche prova pratica di programmazione in Solidity nella nostra [Guida agli smart contract Hello World](https://docs.alchemyapi.io/tutorials/hello-world-smart-contract) o testa la tua conoscenza della Dashboard con l'[_App Demo della Dashboard_](https://docs.alchemyapi.io/tutorials/demo-app)! +Non sai come proseguire? Prova a distribuire il tuo primo contratto intelligente e cimentati con un po' di programmazione in Solidity nella nostra [Guida al contratto intelligente Hello World](https://www.alchemy.com/docs/hello-world-smart-contract), o metti alla prova la tua conoscenza della dashboard con la [App Demo della Dashboard](https://docs.alchemyapi.io/tutorials/demo-app)! -_[Iscriviti gratis ad Alchemy](https://auth.alchemyapi.io/signup), dai un'occhiata alla nostra [documentazione](https://docs.alchemyapi.io/) e, per le ultime notizie, seguici su [Twitter](https://twitter.com/AlchemyPlatform)_. +_[Registrati gratuitamente su Alchemy](https://auth.alchemy.com/), consulta la nostra [documentazione](https://www.alchemy.com/docs/) e, per le ultime notizie, seguici su [Twitter](https://twitter.com/AlchemyPlatform)_. diff --git a/public/content/translations/it/developers/tutorials/guide-to-smart-contract-security-tools/index.md b/public/content/translations/it/developers/tutorials/guide-to-smart-contract-security-tools/index.md index cbc0ab8e3a8..f48e5433366 100644 --- a/public/content/translations/it/developers/tutorials/guide-to-smart-contract-security-tools/index.md +++ b/public/content/translations/it/developers/tutorials/guide-to-smart-contract-security-tools/index.md @@ -1,35 +1,32 @@ --- title: Una guida agli strumenti di sicurezza per gli smart contract -description: Una panoramica di tre differenti tecniche di test e analisi del programma +description: Una panoramica di tre diverse tecniche di test e analisi del programma author: "Trailofbits" lang: it -tags: - - "solidity" - - "contratti intelligenti" - - "sicurezza" +tags: [ "Solidity", "smart contract", "sicurezza" ] skill: intermediate published: 2020-09-07 -source: Creare contratti sicuri +source: Building secure contracts sourceUrl: https://github.com/crytic/building-secure-contracts/tree/master/program-analysis --- -Utilizziremo tre distinte tecniche di test e analisi del programma: +Utilizzeremo tre distinte tecniche di test e analisi del programma: -- **Analisi statica con [Slither](/developers/tutorials/how-to-use-slither-to-find-smart-contract-bugs/).** Tutti i percorsi del programma sono approssimati e analizzati simultaneamente, tramite diverse presentazioni del programma (es. diagramma di flusso di controllo) -- **Fuzzing con [Echidna](/developers/tutorials/how-to-use-echidna-to-test-smart-contracts/).** Il codice è eseguito con una generazione pseudo-casuale di transazioni. Il fuzzer proverà a trovare una sequenza di transazioni per violare una data proprietà. -- **Esecuzione simbolica con [Manticore](/developers/tutorials/how-to-use-manticore-to-find-smart-contract-bugs/).** Una tecnica di verifica formale che traduce ogni percorso d'esecuzione in una formula matematica, su cui possono essere controllati i vincoli massimi. +- **Analisi statica con [Slither](/developers/tutorials/how-to-use-slither-to-find-smart-contract-bugs/).** Tutti i percorsi del programma sono approssimati e analizzati contemporaneamente, tramite diverse rappresentazioni del programma (ad es., diagramma di flusso di controllo) +- **Fuzzing con [Echidna](/developers/tutorials/how-to-use-echidna-to-test-smart-contracts/).** Il codice viene eseguito con una generazione pseudo-casuale di transazioni. Il fuzzer proverà a trovare una sequenza di transazioni per violare una data proprietà. +- **Esecuzione simbolica con [Manticore](/developers/tutorials/how-to-use-manticore-to-find-smart-contract-bugs/).** Una tecnica di verifica formale, che traduce ogni percorso di esecuzione in una formula matematica, sulla quale è possibile verificare dei vincoli. -Ogni tecnica ha vantaggi e svantaggi ed è utile in [casi specifici](#determining-security-properties): +Ogni tecnica ha vantaggi e svantaggi e sarà utile in [casi specifici](#determining-security-properties): | Tecnica | Strumento | Uso | Velocità | Bug mancati | Falsi allarmi | | -------------------- | --------- | ------------------------------ | -------- | ----------- | ------------- | | Analisi statica | Slither | CLI e script | secondi | moderati | bassi | | Fuzzing | Echidna | Proprietà di Solidity | minuti | bassi | nessuno | -| Esecuzione simbolica | Manticore | Proprietà di Solidity e script | ore | nessuno\* | nessuno | +| Esecuzione simbolica | Manticore | Proprietà di Solidity e script | ore | nessuno\* | nessuno | \* se tutti i percorsi sono esplorati senza timeout -**Slither** analizza i contratti in pochi secondi, tuttavia, l'analisi statica potrebbe condurre a falsi allarmi e sarà meno idonea per i controlli complessi (es. controlli aritmetici). Esegui Slither tramite l'API per l'accesso ai pulsanti per i rilevatori integrati o tramite l'API per i controlli definiti dall'utente. +**Slither** analizza i contratti in pochi secondi, tuttavia, l'analisi statica potrebbe portare a falsi allarmi e sarà meno adatta per controlli complessi (ad es., controlli aritmetici). Esegui Slither tramite l'API per un accesso facilitato ai rilevatori integrati o tramite l'API per i controlli definiti dall'utente. **Echidna** deve essere eseguito per diversi minuti e produrrà solo veri positivi. Echidna controlla le proprietà di sicurezza fornite dall'utente, scritte in Solidity. Potrebbe tralasciare dei bug, essendo basato sull'esplorazione casuale. @@ -37,25 +34,25 @@ Ogni tecnica ha vantaggi e svantaggi ed è utile in [casi specifici](#determinin ## Flusso di lavoro suggerito {#suggested-workflow} -Inizia con i rilevatori integrati di Slither per assicurarti che non siano presenti bug semplici ora o che non saranno introdotti in seguito. Usa Slither per controllare le proprietà correlate all'eredità, le dipendenze della variabile e i problemi strutturali. Al crescere della base di codice, usa Echidna per testare proprietà più complesse della macchina di stato. Rivisita Slither per sviluppare controlli personalizzati per protezioni non disponibili con Solidity, come la protezione contro una funzione in sovrascrizione. Infine, usa Manticore per eseguire la verifica mirata di proprietà di sicurezza critiche, ad es. operazioni aritmetiche. +Inizia con i rilevatori integrati di Slither per assicurarti che non siano presenti bug semplici ora o che non saranno introdotti in seguito. Usa Slither per controllare le proprietà correlate all'ereditarietà, alle dipendenze delle variabili e ai problemi strutturali. Al crescere della base di codice, usa Echidna per testare le proprietà più complesse della macchina a stati. Rivisita Slither per sviluppare controlli personalizzati per protezioni non disponibili in Solidity, come la protezione dalla sovrascrittura di una funzione. Infine, usa Manticore per eseguire la verifica mirata di proprietà di sicurezza critiche, ad es., operazioni aritmetiche. - Usa la CLI di Slither per individuare problemi comuni -- Usa Echidna per testare le proprietà di sicurezza d'alto livello del tuo contratto +- Usa Echidna per testare le proprietà di sicurezza di alto livello del tuo contratto - Usa Slither per scrivere controlli statici personalizzati -- Usa Manticore quando desideri un'assicurazione approfondita delle proprietà di sicurezza critiche +- Usa Manticore quando desideri una garanzia approfondita delle proprietà di sicurezza critiche -**Una nota sui test unitari**. I testi unitari servono necessariamente per creare software di alta qualità. Tuttavia, queste tecniche non sono le più adatte a trovare difetti di sicurezza. Sono tipicamente usati per testare i comportamenti positivi del codice (ad es. il codice funziona come previsto nel contesto normale), mentre i difetti di sicurezza tendono a risiedere in casi al limite che gli sviluppatori non hanno considerato. Nel nostro studio di dozzine di revisioni di sicurezza di contratti intelligenti, la [copertura dei test unitari non ha avuto alcun effetto sul numero o sulla gravità dei difetti di sicurezza](https://blog.trailofbits.com/2019/08/08/246-findings-from-our-smart-contract-audits-an-executive-summary/) trovati nel codice del nostro client. +**Una nota sui test unitari**. I test unitari sono necessari per creare software di alta qualità. Tuttavia, queste tecniche non sono le più adatte a trovare difetti di sicurezza. Sono tipicamente usati per testare i comportamenti positivi del codice (cioè, il codice funziona come previsto nel contesto normale), mentre i difetti di sicurezza tendono a risiedere in casi limite che gli sviluppatori non hanno considerato. Nel nostro studio di dozzine di revisioni di sicurezza di contratti intelligenti, la [copertura dei test unitari non ha avuto alcun effetto sul numero o sulla gravità dei difetti di sicurezza](https://blog.trailofbits.com/2019/08/08/246-findings-from-our-smart-contract-audits-an-executive-summary/) che abbiamo trovato nel codice del nostro client. ## Determinare le proprietà di sicurezza {#determining-security-properties} -Per testare e verificare efficacemente il tuo codice, devi identificare le aree che richiedono attenzione. Poiché le risorse impiegate per la sicurezza sono limitate, è importante sfruttare le parti deboli o d'alto valore della tua base di codice per ottimizzare lo sforzo. La modellazione della minaccia può essere utile. Puoi consultare: +Per testare e verificare efficacemente il tuo codice, devi identificare le aree che richiedono attenzione. Poiché le tue risorse dedicate alla sicurezza sono limitate, è importante delimitare le parti deboli o di alto valore della tua base di codice per ottimizzare i tuoi sforzi. La modellazione delle minacce può essere d'aiuto. Considera di consultare: -- [Valutazione rapida del rischio](https://infosec.mozilla.org/guidelines/risk/rapid_risk_assessment.html) (il nostro approccio preferito quando c'è poco tempo a disposizione) -- [Guide to Data-Centric System Threat Modeling](https://csrc.nist.gov/publications/detail/sp/800-154/draft) (o NIST 800-154) -- [Modellazione delle minacce Shostack](https://www.amazon.com/Threat-Modeling-Designing-Adam-Shostack/dp/1118809998) -- [STRIDE](https://wikipedia.org/wiki/STRIDE_(security)) / [DREAD](https://wikipedia.org/wiki/DREAD_(risk_assessment_model)) +- [Valutazioni rapide del rischio (Rapid Risk Assessments)](https://infosec.mozilla.org/guidelines/risk/rapid_risk_assessment.html) (il nostro approccio preferito quando il tempo è poco) +- [Guida alla modellazione delle minacce dei sistemi incentrati sui dati (Guide to Data-Centric System Threat Modeling)](https://csrc.nist.gov/pubs/sp/800/154/ipd) (anche nota come NIST 800-154) +- [Modellazione delle minacce di Shostack (Shostack threat modeling)](https://www.amazon.com/Threat-Modeling-Designing-Adam-Shostack/dp/1118809998) +- [STRIDE](https://wikipedia.org/wiki/STRIDE_\(security\)) / [DREAD](https://wikipedia.org/wiki/DREAD_\(risk_assessment_model\)) - [PASTA](https://wikipedia.org/wiki/Threat_model#P.A.S.T.A.) -- [Uso delle asserzioni](https://blog.regehr.org/archives/1091) +- [Uso delle asserzioni (Use of Assertions)](https://blog.regehr.org/archives/1091) ### Componenti {#components} @@ -63,39 +60,39 @@ Sapere cosa vuoi controllare ti aiuterà anche a selezionare lo strumento più a Tra le grandi aree spesso pertinenti per gli smart contract troviamo: -- **Macchina di stato.** Gran parte dei contratti è rappresentabile come una macchina di stato. Considera di controllare che: (1) nessuno stato invalido sia raggiungibile, (2) se uno stato è valido, che sia raggiungibile e (3) nessuno stato intrappoli il contratto. +- **Macchina a stati.** La maggior parte dei contratti può essere rappresentata come una macchina a stati. Considera di controllare che: (1) nessuno stato invalido sia raggiungibile, (2) se uno stato è valido, che sia raggiungibile e (3) nessuno stato intrappoli il contratto. - - Echidna e Manticore sono gli strumenti da preferire per testare le specifiche della macchina di stato. + - Echidna e Manticore sono gli strumenti da preferire per testare le specifiche della macchina a stati. -- **Controlli d'accesso.** Se il tuo sistema ha degli utenti privilegiati (ad es. un proprietario, controllori...) devi assicurarti che (1) ogni utente possa eseguire solo le azioni autorizzate e (2) nessun utente possa bloccare le azioni da un utente più privilegiato. +- **Controlli di accesso.** Se il tuo sistema ha utenti privilegiati (ad es., un proprietario, dei controller, ...) devi assicurarti che (1) ogni utente possa eseguire solo le azioni autorizzate e (2) nessun utente possa bloccare le azioni di un utente più privilegiato. - - Slither, Echidna e Manticore possono controllare i controlli d'accesso corretti. Ad esempio, Slither può controllare che solo alle funzioni incluse nella white list manchi il modificatore onlyOwner. Echidna e Manticore sono utili per un controllo d'accesso più complesso, come un permesso dato solo se il contratto raggiunge un particolare stato. + - Slither, Echidna e Manticore possono verificare la correttezza dei controlli di accesso. Ad esempio, Slither può controllare che solo le funzioni in lista bianca non abbiano il modificatore onlyOwner. Echidna e Manticore sono utili per un controllo d'accesso più complesso, come un permesso dato solo se il contratto raggiunge un particolare stato. -- **Operazioni aritmetiche.** Controllare la solidità delle operazioni aritmetiche è fondamentale. Usare `SafeMath` ovunque è un buon passo per prevenire overflow e underflow, ma occorre comunque considerare altri difetti aritmetici, tra cui i problemi d'arrotondamento e i difetti che intrappolano il contratto. +- **Operazioni aritmetiche.** Controllare la solidità delle operazioni aritmetiche è fondamentale. Usare `SafeMath` ovunque è un buon passo per prevenire sovraflusso/sottoflusso, tuttavia, devi considerare anche altri difetti aritmetici, tra cui problemi di arrotondamento e difetti che intrappolano il contratto. - - Manticore è la migliore scelta a questo scopo. Echidna è utilizzabile se l'aritmetica è esclusa dall'ambito del risolutore SMT. + - Manticore è la scelta migliore in questo caso. Echidna può essere utilizzato se l'aritmetica non rientra nell'ambito del risolutore SMT. -- **Correttezza dell'eredità.** I contratti di Solidity fanno ampio affidamento sull'eredità multipla. Sono facilmente introducibili errori quali funzioni di shadowing prive di chiamata `super` e ordini di linearizzazione c3 interpretati erroneamente. +- **Correttezza dell'ereditarietà.** I contratti Solidity si basano molto sull'ereditarietà multipla. Sono facilmente introducibili errori quali funzioni di shadowing prive di chiamata `super` e ordini di linearizzazione c3 interpretati erroneamente. - - Slither è lo strumento giusto per assicurare il rilevamento di tali problemi. + - Slither è lo strumento che garantisce il rilevamento di questi problemi. -- **Interazioni esterne.** I contratti interagiscono tra loro, ragion per cui non ci si dovrebbe fidare di alcuni contratti esterni. Ad esempio, se il tuo contratto si basa su oracoli esterni, rimarrà sicuro se metà degli oracoli disponibili sono compromessi? +- **Interazioni esterne.** I contratti interagiscono tra loro, e non ci si dovrebbe fidare di alcuni contratti esterni. Ad esempio, se il tuo contratto si basa su oracoli esterni, rimarrà sicuro se metà degli oracoli disponibili sono compromessi? - - Manticore ed Echidna sono la scelta migliore per testare le interazioni esterne coi tuoi contratti. Manticore ha un meccanismo integrato per troncare i contratti esterni. + - Manticore ed Echidna sono la scelta migliore per testare le interazioni esterne con i tuoi contratti. Manticore ha un meccanismo integrato per creare stub di contratti esterni. -- **Conformità standard.** Gli standard di Ethereum (es. ERC20) sono noti per i difetti a livello di progettazione. Sii consapevole delle limitazioni dello standard su cui stai costruendo. +- **Conformità standard.** Gli standard di Ethereum (ad es. ERC20) sono noti per i difetti a livello di progettazione. Sii consapevole delle limitazioni dello standard su cui stai costruendo. - Slither, Echidna e Manticore ti aiuteranno a rilevare le deviazioni da un dato standard. -### Tabella riepilogativa per la selezione degli strumenti {#tool-selection-cheatsheet} +### Guida rapida alla selezione degli strumenti {#tool-selection-cheatsheet} -| Componente | Strumenti | Esempi | -| ------------------------ | --------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| Macchina di stato | Echidna, Manticore | | -| Controllo d'accesso | Slither, Echidna, Manticore | [Esercizio di Slither 2](https://github.com/crytic/slither/blob/7f54c8b948c34fb35e1d61adaa1bd568ca733253/docs/src/tutorials/exercise2.md), [Esercizio di Echidna 2](https://github.com/crytic/building-secure-contracts/blob/master/program-analysis/echidna/exercises/Exercise-2.md) | -| Operazioni aritmetiche | Manticore, Echidna | [Esercizio di Echidna 1](https://github.com/crytic/building-secure-contracts/blob/master/program-analysis/echidna/exercises/Exercise-1.md), [Esercizi di Manticore 1 - 3](https://github.com/crytic/building-secure-contracts/tree/master/program-analysis/manticore/exercises) | -| Correttezza d'eredità | Slither | [Esercizio di Slither 1](https://github.com/crytic/slither/blob/7f54c8b948c34fb35e1d61adaa1bd568ca733253/docs/src/tutorials/exercise1.md) | -| Interazioni esterne | Manticore, Echidna | | -| Conformità agli standard | Slither, Echidna, Manticore | [`slither-erc`](https://github.com/crytic/slither/wiki/ERC-Conformance) | +| Componente | Strumenti | Esempi | +| ----------------------------- | --------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| Macchina a stati | Echidna, Manticore | | +| Controllo di accesso | Slither, Echidna, Manticore | [Esercizio 2 di Slither](https://github.com/crytic/slither/blob/7f54c8b948c34fb35e1d61adaa1bd568ca733253/docs/src/tutorials/exercise2.md), [Esercizio 2 di Echidna](https://github.com/crytic/building-secure-contracts/blob/master/program-analysis/echidna/exercises/Exercise-2.md) | +| Operazioni aritmetiche | Manticore, Echidna | [Esercizio 1 di Echidna](https://github.com/crytic/building-secure-contracts/blob/master/program-analysis/echidna/exercises/Exercise-1.md), [Esercizi 1 - 3 di Manticore](https://github.com/crytic/building-secure-contracts/tree/master/program-analysis/manticore/exercises) | +| Correttezza dell'ereditarietà | Slither | [Esercizio 1 di Slither](https://github.com/crytic/slither/blob/7f54c8b948c34fb35e1d61adaa1bd568ca733253/docs/src/tutorials/exercise1.md) | +| Interazioni esterne | Manticore, Echidna | | +| Conformità agli standard | Slither, Echidna, Manticore | [`slither-erc`](https://github.com/crytic/slither/wiki/ERC-Conformance) | Occorrerà controllare altri aspetti a seconda degli obiettivi, ma queste macro aree di attenzione sono un buon inizio per qualunque sistema di smart contract. diff --git a/public/content/translations/it/developers/tutorials/hello-world-smart-contract-fullstack/index.md b/public/content/translations/it/developers/tutorials/hello-world-smart-contract-fullstack/index.md index 0a417e53d75..95997d9fb35 100644 --- a/public/content/translations/it/developers/tutorials/hello-world-smart-contract-fullstack/index.md +++ b/public/content/translations/it/developers/tutorials/hello-world-smart-contract-fullstack/index.md @@ -1,94 +1,97 @@ --- -title: Contratto intelligente "Hello World" per principianti - full stack +title: Contratto intelligente "Hello World" per principianti - Full stack description: Tutorial introduttivo su come scrivere e distribuire un semplice smart contract su Ethereum. author: "nstrike2" tags: - - "solidity" - - "hardhat" - - "alchemy" - - "contratti intelligenti" - - "distribuzione" - - "blockexplorer" - - "frontend" - - "transazioni" + [ + "Solidity", + "hardhat", + "alchemy", + "smart contract", + "distribuzione", + "esploratore di blocchi", + "frontend", + "transazioni" + ] skill: beginner lang: it published: 2021-10-25 --- -Questa guida fa per te se hai appena iniziato con lo sviluppo sulla blockchain e non sai da dove cominciare o come distribuire e interagire con i contratti intelligenti. Esamineremo la creazione e la distribuzione di un semplice contratto intelligente sulla rete di prova di Goerli, utilizzando [MetaMask](https://metamask.io), [Solidity](https://docs.soliditylang.org/en/v0.8.0/), [Hardhat](https://hardhat.org) e [Alchemy](https://alchemyapi.io/eth). +Questa guida fa per te se hai appena iniziato con lo sviluppo sulla blockchain e non sai da dove cominciare o come distribuire e interagire con i contratti intelligenti. Analizzeremo passo passo la creazione e la distribuzione di un semplice contratto intelligente sulla rete di test Goerli usando [MetaMask](https://metamask.io), [Solidity](https://docs.soliditylang.org/en/v0.8.0/), [Hardhat](https://hardhat.org) e [Alchemy](https://alchemy.com/eth). -Per completare questo tutorial avrai bisogno di un conto di Alchemy. [Registrati per un conto gratuito](https://www.alchemy.com/). +Per completare questo tutorial avrai bisogno di un account Alchemy. [Registrati per un account gratuito](https://www.alchemy.com/). -Se in qualsiasi momento hai domande, non esitare a contattarci nel [Discord di Alchemy](https://discord.gg/gWuC7zB)! +Se hai domande in qualsiasi momento, non esitare a contattarci sul [Discord di Alchemy](https://discord.gg/gWuC7zB)! -## Parte 1- Crea e distribuisci il tuo contratto intelligente usando Hardhat {#part-1} +## Parte 1 - Crea e distribuisci il tuo contratto intelligente usando Hardhat {#part-1} -### Connettersi alla rete di Ethereum {#connect-to-the-ethereum-network} +### Connettiti alla rete Ethereum {#connect-to-the-ethereum-network} -Esistono molti modi per effettuare richieste alla catena di Ethereum. Per semplicità, ci serviremo di un conto gratuito su Alchemy, una piattaforma per sviluppatori di blockchain e API che ci consentirà di comunicare con la catena di Ethereum senza dover eseguire noi stessi un nodo. Alchemy offre anche strumenti di monitoraggio e analisi per gli sviluppatori di cui ci serviremo in questo tutorial per comprendere al meglio l'andamento della distribuzione del nostro contratto intelligente. +Esistono molti modi per effettuare richieste alla catena di Ethereum. Per semplicità, useremo un account gratuito su Alchemy, una piattaforma per sviluppatori di blockchain e API che ci consentirà di comunicare con la catena di Ethereum senza dover eseguire noi stessi un nodo. Alchemy offre anche strumenti di monitoraggio e analisi per gli sviluppatori, di cui ci serviremo in questo tutorial per comprendere al meglio cosa succede dietro le quinte nella distribuzione del nostro contratto intelligente. -### Crea la tua app e la chiave API {#create-your-app-and-api-key} +### Crea la tua app e la tua chiave API {#create-your-app-and-api-key} -Una volta creato un conto di Alchemy, puoi generare una chiave API creando un'app. Questo ti consentirà di effettuare richieste alla rete di prova di Goerli. Se non hai familiarità con le reti di prova puoi [leggere la guida di Alchemy alla scelta di una rete](https://docs.alchemyapi.io/guides/choosing-a-network). +Una volta creato un account Alchemy, puoi generare una chiave API creando un'app. Questo ti consentirà di effettuare richieste alla rete di test Goerli. Se non hai familiarità con le reti di test, puoi [leggere la guida di Alchemy sulla scelta di una rete](https://www.alchemy.com/docs/choosing-a-web3-network). -Sul pannello di controllo di Alchemy, trova il menu a discesa delle **App** nella barra di navigazione e fai clic su su **Crea App**. +Sulla dashboard di Alchemy, trova il menu a discesa **App** nella barra di navigazione e fai clic su **Crea App**. -![Creare l'app Hello world](./hello-world-create-app.png) +![Crea app Hello world](./hello-world-create-app.png) -Nomina la tua app '_Hello World_' e scrivi una breve descrizione. Seleziona **Staging** come tuo ambiente e **Goerli** come tua rete. +Assegna alla tua app il nome '_Hello World_' e scrivi una breve descrizione. Seleziona **Staging** come ambiente e **Goerli** come rete. -![Vista della creazione dell'app Hello world](./create-app-view-hello-world.png) +![visualizzazione crea app hello world](./create-app-view-hello-world.png) _Nota: assicurati di selezionare **Goerli**, altrimenti questo tutorial non funzionerà._ -Fa i clic su **Crea app**. La tua app apparirà nella tabella sottostante. +Fai clic su **Crea app**. La tua app apparirà nella tabella sottostante. -### Crea un conto di Ethereum {#create-an-ethereum-account} +### Crea un account Ethereum {#create-an-ethereum-account} -Per inviare e ricevere transazioni, hai bisogno di un account di Ethereum. Useremo MetaMask, un portafoglio virtuale nel browser che permette agli utenti di gestire l'indirizzo del proprio conto di Ethereum. +Per inviare e ricevere transazioni, hai bisogno di un account Ethereum. Useremo MetaMask, un portafoglio virtuale nel browser che consente agli utenti di gestire l'indirizzo del proprio account Ethereum. -Puoi scaricare e creare gratuitamente un conto di MetaMask [qui](https://metamask.io/download). Quando crei un account, o se ne possiedi già uno, assicurati di passare alla "rete di prova di Goerli" in alto a destra (così da non avere a che fare con denaro reale). +Puoi scaricare e creare un account MetaMask gratuitamente [qui](https://metamask.io/download). Quando crei un account, o se ne hai già uno, assicurati di passare alla “Rete di test Goerli” in alto a destra (in modo da non usare soldi veri). -### Fase 4: aggiungi ether da un Faucet {#step-4-add-ether-from-a-faucet} +### Fase 4: Aggiungi ether da un Faucet {#step-4-add-ether-from-a-faucet} -Per distribuire il tuo contratto intelligente sulla rete di prova, avrai bisogno di alcuni ETH finti. Per ottenere ETH sulla rete di Goerli, vai ad un faucet di Goerli e immetti l'indirizzo del tuo conto di Goerli. Nota che, di recente, i faucet di Goerli possono essere un po' inaffidabili; consulta la [pagina delle reti di prova](/developers/docs/networks/#goerli) per un elenco di opzioni da provare: +Per distribuire il tuo contratto intelligente sulla rete di test, avrai bisogno di ETH finti. Per ottenere ETH sulla rete Goerli, vai a un faucet Goerli e inserisci l'indirizzo del tuo account Goerli. Nota che i faucet Goerli possono essere un po' inaffidabili di recente - consulta la [pagina delle reti di test](/developers/docs/networks/#goerli) per un elenco di opzioni da provare: -_Nota: a causa della congestione della rete, questa operazione potrebbe richiedere del tempo_ `` +_Nota: a causa della congestione della rete, l'operazione potrebbe richiedere un po' di tempo._ +`` -### Fase 5: controlla il saldo {#step-5-check-your-balance} +### Passaggio 5: Controlla il tuo saldo {#step-5-check-your-balance} -Per ricontrollare che gli ETH siano nel tuo portafoglio, facciamo una richiesta [eth_getBalance](https://docs.alchemyapi.io/alchemy/documentation/alchemy-api-reference/json-rpc#eth_getbalance) usando lo [strumento compositore di Alchemy](https://composer.alchemyapi.io/?composer_state=%7B%22network%22%3A0%2C%22methodName%22%3A%22eth_getBalance%22%2C%22paramValues%22%3A%5B%22%22%2C%22latest%22%5D%7D). Questo restituirà l'importo di ETH nel nostro portafoglio. Per saperne di più consultate [il breve tutorial di Alchemy su come usare lo strumento compositore](https://youtu.be/r6sjRxBZJuU). +Per verificare che gli ETH siano nel tuo portafoglio, effettuiamo una richiesta [eth_getBalance](https://docs.alchemyapi.io/alchemy/documentation/alchemy-api-reference/json-rpc#eth_getbalance) utilizzando lo [strumento compositore di Alchemy](https://composer.alchemyapi.io/?composer_state=%7B%22network%22%3A0%2C%22methodName%22%3A%22eth_getBalance%22%2C%22paramValues%22%3A%5B%22%22%2C%22latest%22%5D%7D). Questo restituirà l'importo di ETH nel nostro portafoglio. Per saperne di più, guarda il [breve tutorial di Alchemy su come usare lo strumento compositore](https://youtu.be/r6sjRxBZJuU). -Inserisci l'indirizzo del tuo conto di MetaMask e fai clic su **Invia richiesta**. Vedrai una risposta simile al pezzetto di codice qui sotto. +Inserisci l'indirizzo del tuo account MetaMask e fai clic su **Invia richiesta**. Vedrai una risposta che assomiglia allo snippet di codice sottostante. ```json { "jsonrpc": "2.0", "id": 0, "result": "0x2B5E3AF16B1880000" } ``` -> _Nota: questo risultato è in wei, non in ETH. Wei è usato come taglio più piccolo dell'ether._ +> _Nota: questo risultato è in wei, non in ETH._ _Il wei è usato come la più piccola denominazione di ether._ Meno male! I nostri soldi finti ci sono tutti. -### Fase 6: inizializza il progetto {#step-6-initialize-our-project} +### Passaggio 6: Inizializza il nostro progetto {#step-6-initialize-our-project} -Per prima cosa dobbiamo creare una cartella per il nostro progetto. Passa alla tua riga di comando e inserisci quanto segue. +Per prima cosa, dovremo creare una cartella per il nostro progetto. Vai alla tua riga di comando e inserisci quanto segue. ``` mkdir hello-world cd hello-world ``` -Ora che siamo nella cartella del nostro progetto, useremo `npm init` per inizializzare il progetto. +Ora che siamo all'interno della nostra cartella del progetto, useremo `npm init` per inizializzare il progetto. -> Se non hai ancora installato npm, segui [queste istruzioni su come installare Node.js e npm](https://docs.alchemyapi.io/alchemy/guides/alchemy-for-macs#1-install-nodejs-and-npm). +> Se non hai ancora installato npm, segui [queste istruzioni per installare Node.js e npm](https://docs.alchemyapi.io/alchemy/guides/alchemy-for-macs#1-install-nodejs-and-npm). -Ai fini di questo tutorial, non ha importanza a come rispondi alle domande di inizializzazione. Per tuo riferimento, ecco come abbiamo fatto: +Ai fini di questo tutorial, non importa come rispondi alle domande di inizializzazione. Ecco come abbiamo fatto, come riferimento: ``` package name: (hello-world) version: (1.0.0) -description: hello world smart contract +description: contratto intelligente hello world entry point: (index.js) test command: git repository: @@ -96,12 +99,12 @@ keywords: author: license: (ISC) -About to write to /Users/.../.../.../hello-world/package.json: +Sto per scrivere su /Users/.../.../.../hello-world/package.json: { "name": "hello-world", "version": "1.0.0", - "description": "hello world smart contract", + "description": "contratto intelligente hello world", "main": "index.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1" @@ -111,23 +114,23 @@ About to write to /Users/.../.../.../hello-world/package.json: } ``` -Approva il package.json e siamo pronti! +Approva il file package.json e siamo pronti a partire! -### Passo 7: scarica Hardhat {#step-7-download-hardhat} +### Passaggio 7: Scarica Hardhat {#step-7-download-hardhat} Hardhat è un ambiente di sviluppo per compilare, distribuire, testare ed effettuare il debug del tuo software di Ethereum. Aiuta gli sviluppatori nella costruzione di contratti intelligenti e dapp localmente, prima di distribuirli alla catena. -Nel nostro progetto `hello-world` esegui: +All'interno del nostro progetto `hello-world`, esegui: ``` npm install --save-dev hardhat ``` -Dai un'occhiata a questa pagina per ulteriori dettagli sulle [istruzioni d'installazione](https://hardhat.org/getting-started/#overview). +Consulta questa pagina per maggiori dettagli sulle [istruzioni di installazione](https://hardhat.org/getting-started/#overview). -### Fase 8: crea un progetto Hardhat {#step-8-create-hardhat-project} +### Passaggio 8: Crea il progetto Hardhat {#step-8-create-hardhat-project} -All'interno della cartella di progetto `hello-world` esegui: +All'interno della nostra cartella di progetto `hello-world`, esegui: ``` npx hardhat @@ -145,65 +148,65 @@ Dovresti poi vedere un messaggio di benvenuto e l'opzione per selezionare cosa d 888 888 888 888 888 Y88b 888 888 888 888 888 Y88b. 888 888 "Y888888 888 "Y88888 888 888 "Y888888 "Y888 -👷 Welcome to Hardhat v2.0.11 👷‍ +👷 Benvenuto in Hardhat v2.0.11 👷‍ -What do you want to do? … -Create a sample project -❯ Create an empty hardhat.config.js -Quit +Cosa vuoi fare? … +Crea un progetto di esempio +❯ Crea un file hardhat.config.js vuoto +Esci ``` -Questo genererà un file `hardhat.config.js` nel progetto. Lo utilizzeremo più avanti nel tutorial per specificare la configurazione del nostro progetto. +Questo genererà un file `hardhat.config.js` nel progetto. Lo useremo più avanti nel tutorial per specificare la configurazione del nostro progetto. -### Fase 9: aggiungi le cartelle del progetto {#step-9-add-project-folders} +### Passaggio 9: Aggiungi cartelle di progetto {#step-9-add-project-folders} -Per mantenere organizzato il nostro progetto, creiamo due nuove cartelle. Nella riga di comando, vai alla cartella di root del tuo progetto `hello-world` e digita: +Per mantenere il progetto organizzato, creiamo due nuove cartelle. Nella riga di comando, vai alla directory principale del tuo progetto `hello-world` e digita: ``` mkdir contracts mkdir scripts ``` -- `contracts/` è dove manterremo il file del codice del nostro smart contract hello world -- `scripts/` è dove manterremo gli script per distribuire e interagire con il nostro contratto +- `contracts/` è dove conserveremo il file del codice del nostro smart contract hello world +- `scripts/` è dove conserveremo gli script per distribuire e interagire con il nostro contratto -### Fase 10: compila il nostro contratto {#step-10-write-our-contract} +### Passaggio 10: Scrivi il nostro contratto {#step-10-write-our-contract} -Potresti chiederti: quando scriveremo del codice? È arrivato il momento! +Forse ti starai chiedendo: quando scriveremo del codice? È il momento! -Apri il progetto hello-world nel tuo editor preferito. La maggior parte dei contratti intelligenti è scritta in Solidity, che useremo per scrivere il nostro contratto intelligente +Apri il progetto hello-world nel tuo editor preferito. I contratti intelligenti sono scritti più comunemente in Solidity, che useremo per scrivere il nostro contratto intelligente.‌ 1. Vai alla cartella `contracts` e crea un nuovo file chiamato `HelloWorld.sol` -2. Di seguito, un esempio del contratto intelligente Hello World che utilizzeremo per questo tutorial. Copia il contenuto seguente in un file `HelloWorld.sol`. +2. Di seguito è riportato un esempio di contratto intelligente Hello World che useremo per questo tutorial. Copia il contenuto qui sotto nel file `HelloWorld.sol`. -_Nota: assicurati di leggere i commenti per comprendere cosa fa questo contratto._ +_Nota: assicurati di leggere i commenti per capire cosa fa questo contratto._ ``` -// Specifica la versione di Solidity, utilizzando il controllo delle versioni semantico. -// Learn more: https://solidity.readthedocs.io/en/v0.5.10/layout-of-source-files.html#pragma +// Specifica la versione di Solidity, usando il versioning semantico. +// Per saperne di più: https://solidity.readthedocs.io/en/v0.5.10/layout-of-source-files.html#pragma pragma solidity >=0.7.3; -// Defines a contract named `HelloWorld`. -// Un contratto è una raccolta di funzioni e dati (il suo stato). Once deployed, a contract resides at a specific address on the Ethereum blockchain. Learn more: https://solidity.readthedocs.io/en/v0.5.10/structure-of-a-contract.html +// Definisce un contratto chiamato `HelloWorld`. +// Un contratto è una raccolta di funzioni e dati (il suo stato). Una volta distribuito, un contratto risiede a un indirizzo specifico sulla blockchain di Ethereum. Per saperne di più: https://solidity.readthedocs.io/en/v0.5.10/structure-of-a-contract.html contract HelloWorld { - //Emitted when update function is called - //Smart contract events are a way for your contract to communicate that something happened on the blockchain to your app front-end, which can be 'listening' for certain events and take action when they happen. + //Emesso quando viene chiamata la funzione di aggiornamento + //Gli eventi dei contratti intelligenti sono un modo per il tuo contratto di comunicare che qualcosa è accaduto sulla blockchain alla tua app front-end, che può essere 'in ascolto' di determinati eventi e agire di conseguenza. event UpdatedMessages(string oldStr, string newStr); - // Declares a state variable `message` of type `string`. - // Le variabili di stato sono variabili con valori memorizzati in modo permanente nello spazio di archiviazione (storage) del contratto. The keyword `public` makes variables accessible from outside a contract and creates a function that other contracts or clients can call to access the value. + // Dichiara una variabile di stato `message` di tipo `string`. + // Le variabili di stato sono variabili i cui valori sono memorizzati in modo permanente nella memoria del contratto. La parola chiave `public` rende le variabili accessibili dall'esterno di un contratto e crea una funzione che altri contratti o client possono chiamare per accedere al valore. string public message; - // Similar to many class-based object-oriented languages, a constructor is a special function that is only executed upon contract creation. - // I costruttori sono utilizzati per inizializzare i dati del contratto. Learn more:https://solidity.readthedocs.io/en/v0.5.10/contracts.html#constructors + // Simile a molti linguaggi orientati agli oggetti basati su classi, un costruttore è una funzione speciale che viene eseguita solo alla creazione del contratto. + // I costruttori sono usati per inizializzare i dati del contratto. Per saperne di più:https://solidity.readthedocs.io/en/v0.5.10/contracts.html#constructors constructor(string memory initMessage) { - // Accepts a string argument `initMessage` and sets the value into the contract's `message` storage variable). + // Accetta un argomento stringa `initMessage` e imposta il valore nella variabile di archiviazione `message` del contratto). message = initMessage; } - // A public function that accepts a string argument and updates the `message` storage variable. + // Una funzione pubblica che accetta un argomento stringa e aggiorna la variabile di archiviazione `message`. function update(string memory newMessage) public { string memory oldMsg = message; message = newMessage; @@ -212,15 +215,15 @@ contract HelloWorld { } ``` -Questo è un contratto intelligente di base che memorizza un messaggio al momento della creazione. Può essere aggiornato richiamando la funzione `update`. +Si tratta di un contratto intelligente di base che memorizza un messaggio al momento della creazione. Può essere aggiornato chiamando la funzione `update`. -### Fase 11: connetti MetaMask e Alchemy al tuo progetto {#step-11-connect-metamask-alchemy-to-your-project} +### Passaggio 11: Collega MetaMask e Alchemy al tuo progetto {#step-11-connect-metamask-alchemy-to-your-project} -Abbiamo creato un portafoglio di MetaMask, un conto di Alchemy e scritto il nostro contratto intelligente; è arrivato il momento di collegarli. +Abbiamo creato un portafoglio MetaMask, un conto Alchemy e scritto il nostro smart contract, ora è il momento di collegare i tre. -Ogni transazione inviata dal tuo portafoglio richiede una firma tramite la tua chiave privata univoca. Per fornire al nostro programma quest'autorizzazione, possiamo memorizzare in sicurezza la nostra chiave privata in un file di ambiente. Qui memorizzeremo anche una chiave API per Alchemy. +Ogni transazione inviata dal tuo portafoglio richiede una firma che utilizza la tua chiave privata univoca. Per fornire al nostro programma questa autorizzazione, possiamo archiviare in modo sicuro la nostra chiave privata in un file di ambiente. Qui memorizzeremo anche una chiave API per Alchemy. -> Per saperne di più sull'invio delle transazioni, dai un'occhiata a [questo tutorial](https://docs.alchemyapi.io/alchemy/tutorials/sending-transactions-using-web3-and-alchemy) sull'invio di transazioni usando web3. +> Per saperne di più sull'invio di transazioni, consulta [questo tutorial](https://www.alchemy.com/docs/hello-world-smart-contract#step-11-connect-metamask--alchemy-to-your-project) sull'invio di transazioni tramite web3. Prima, installa il pacchetto dotenv nella cartella del tuo progetto: @@ -228,31 +231,31 @@ Prima, installa il pacchetto dotenv nella cartella del tuo progetto: npm install dotenv --save ``` -Quindi, crea un file `.env` nella cartella di root del progetto. Aggiungi nel file la tua chiave privata di MetaMask e l'URL HTTP dell'API Alchemy. +Quindi, crea un file `.env` nella directory principale del progetto. Aggiungi la tua chiave privata MetaMask e l'URL dell'API HTTP di Alchemy. -Il tuo file di ambiente deve essere nominato `.env` o non verrà riconosciuto come un file di ambiente. +Il tuo file di ambiente deve essere nominato `.env` o non sarà riconosciuto come tale. -Non nominarlo `process.env` o `.env-custom` o in altro modo. +Non nominarlo `process.env` o `.env-custom` o in qualsiasi altro modo. - Segui [queste istruzioni](https://metamask.zendesk.com/hc/en-us/articles/360015289632-How-to-Export-an-Account-Private-Key) per esportare la tua chiave privata -- Vedi sotto per ottenere l'URL dell'API di Alchemy HTTP +- Vedi di seguito per ottenere l'URL dell'API HTTP di Alchemy ![](./get-alchemy-api-key.gif) -Il tuo `.env` dovrebbe somigliare a questo: +Il tuo file `.env` dovrebbe avere questo aspetto: ``` -API_URL = "https://eth-goerli.alchemyapi.io/v2/your-api-key" -PRIVATE_KEY = "your-metamask-private-key" +API_URL = "https://eth-goerli.alchemyapi.io/v2/tua-chiave-api" +PRIVATE_KEY = "tua-chiave-privata-metamask" ``` -Per connetterli realmente al nostro codice, faremo riferimento a queste variabili nel nostro file `hardhat.config.js` nella fase 13. +Per collegarli effettivamente al nostro codice, faremo riferimento a queste variabili nel nostro file `hardhat.config.js` nella fase 13. -### Fase 12: installa Ethers.js {#step-12-install-ethersjs} +### Fase 12: Installa Ethers.js {#step-12-install-ethersjs} -Ethers.js è una libreria che rende più facile interagire ed effettuare richieste a Ethereum tramite wrapping dei metodi JSON-RPC standard con altri metodi più facili da usare. +Ethers.js è una libreria che semplifica l'interazione e l'invio di richieste a Ethereum, incapsulando i [metodi JSON-RPC standard](https://docs.alchemyapi.io/alchemy/documentation/alchemy-api-reference/json-rpc) con metodi più intuitivi. -Hardhat ci permette di integrare i [plugin](https://hardhat.org/plugins/) per avere strumenti aggiuntivi e funzionalità estese. Sfrutteremo il [plugin di Ethers](https://hardhat.org/docs/plugins/official-plugins#hardhat-ethers) per la distribuzione del contratto. +Hardhat ci consente di integrare [plugin](https://hardhat.org/plugins/) per strumenti aggiuntivi e funzionalità estese. Sfrutteremo il [plugin Ethers](https://hardhat.org/docs/plugins/official-plugins#hardhat-ethers) per la distribuzione del contratto. Nella cartella del tuo progetto digita: @@ -260,11 +263,11 @@ Nella cartella del tuo progetto digita: npm install --save-dev @nomiclabs/hardhat-ethers "ethers@^5.0.0" ``` -### Fase 13: aggiorna hardhat.config.js {#step-13-update-hardhat-configjs} +### Passaggio 13: Aggiorna hardhat.config.js {#step-13-update-hardhat-configjs} Finora abbiamo aggiunto diverse dipendenze e plugin, ora dobbiamo aggiornare `hardhat.config.js` in modo che il nostro progetto li riconosca tutti. -Aggiorna il tuo `hardhat.config.js` affinché somigli a questo: +Aggiorna il tuo `hardhat.config.js` perché abbia questo aspetto: ```javascript /** @@ -289,9 +292,9 @@ module.exports = { } ``` -### Fase 14: compila il contratto {#step-14-compile-our-contract} +### Passaggio 14: Compila il nostro contratto {#step-14-compile-our-contract} -Per assicurarti che tutto funzioni fino a questo punto, compila il contratto. L'attività di `compilazione` è una delle attività integrate di hardhat. +Per assicurarti che tutto funzioni fino a questo punto, compila il contratto. L'attività `compile` è una delle attività integrate di hardhat. Dalla riga di comando esegui: @@ -299,21 +302,21 @@ Dalla riga di comando esegui: npx hardhat compile ``` -Potresti ricevere un avviso `SPDX license identifier not provided in source file`, ma non ti preoccupare, si spera che tutto il resto funzioni! Altrimenti, puoi sempre inviare un messaggio nel [Discord di Alchemy](https://discord.gg/u72VCg3). +Potresti ricevere un avviso su `SPDX license identifier not provided in source file`, ma non preoccuparti: si spera che tutto il resto vada bene! In caso contrario, puoi sempre inviare un messaggio nel [discord di Alchemy](https://discord.gg/u72VCg3). -### Fase 15: scrivi lo script di distribuzione {#step-15-write-our-deploy-script} +### Passaggio 15: Scrivi il nostro script di distribuzione {#step-15-write-our-deploy-script} Ora che il nostro contratto è scritto e il nostro file di configurazione è pronto, è il momento di scrivere lo script di distribuzione del contratto. -Vai alla cartella `script/` e crea un nuovo file chiamato `deploy.js`, aggiungendo i seguenti contenuti: +Vai alla cartella `scripts/` e crea un nuovo file chiamato `deploy.js`, aggiungendovi i seguenti contenuti: ```javascript async function main() { const HelloWorld = await ethers.getContractFactory("HelloWorld") - // Start deployment, returning a promise that resolves to a contract object + // Avvia la distribuzione, restituendo una promise che si risolve in un oggetto contratto const hello_world = await HelloWorld.deploy("Hello World!") - console.log("Contract deployed to address:", hello_world.address) + console.log("Contratto distribuito all'indirizzo:", hello_world.address) } main() @@ -324,21 +327,21 @@ main() }) ``` -Nel suo [tutorial sui Contratti](https://hardhat.org/tutorial/testing-contracts.html#writing-tests) hardhat spiega in modo eccellente cosa fa ognuna di queste righe di codice nel loro, quindi riportiamo qui le loro spiegazioni. +Hardhat spiega molto bene cosa fa ciascuna di queste righe di codice nella sua [Guida ai contratti](https://hardhat.org/tutorial/testing-contracts.html#writing-tests), e qui abbiamo adottato le sue spiegazioni. ```javascript const HelloWorld = await ethers.getContractFactory("HelloWorld") ``` -Un `ContractFactory` su ethers.js è un'astrazione usata per distribuire nuovi contratti intelligenti, quindi `HelloWorld` qui è una [fabbrica](https://en.wikipedia.org/wiki/Factory_(object-oriented_programming)) di istanze del nostro contratto hello world. Usando il plugin `hardhat-ethers`, le istanze `ContractFactory` e `Contract` sono connesse di default al primo firmatario (proprietario). +Un `ContractFactory` in ethers.js è un'astrazione usata per distribuire nuovi contratti intelligenti, quindi `HelloWorld` qui è una [factory](https://en.wikipedia.org/wiki/Factory_\(object-oriented_programming\)) per le istanze del nostro contratto hello world. Quando si usa il plugin `hardhat-ethers`, le istanze `ContractFactory` e `Contract` sono collegate al primo firmatario (proprietario) per impostazione predefinita. ```javascript const hello_world = await HelloWorld.deploy() ``` -Chiamare `deploy()` su un `ContractFactory` avvierà la distribuzione e restituirà un `Promise` che si risolve in un oggetto `Contract`. Questo è l'oggetto che ha un metodo per ciascuna delle funzioni del nostro smart contract. +La chiamata di `deploy()` su un `ContractFactory` avvierà la distribuzione e restituirà una `Promise` che si risolve in un oggetto `Contract`. Questo è l'oggetto che ha un metodo per ciascuna delle funzioni del nostro smart contract. -### Fase 16: distribuisci il contratto {#step-16-deploy-our-contract} +### Fase 16: Distribuisci il nostro contratto {#step-16-deploy-our-contract} Siamo finalmente pronti a distribuire il nostro smart contract! Vai alla riga di comando ed esegui: @@ -349,34 +352,34 @@ npx hardhat run scripts/deploy.js --network goerli Vorrai poi vedere qualcosa del genere: ```bash -Contract deployed to address: 0x6cd7d44516a20882cEa2DE9f205bF401c0d23570 +Contratto distribuito all'indirizzo: 0x6cd7d44516a20882cEa2DE9f205bF401c0d23570 ``` **Salva questo indirizzo**. Lo useremo più avanti nel tutorial. -Se andiamo all'[etherscan di Goerli](https://goerli.etherscan.io) e cerchiamo l'indirizzo del nostro contratto, dovremmo poter vedere che è stato distribuito correttamente. La transazione somiglierà a questa: +Se andiamo su [Goerli etherscan](https://goerli.etherscan.io) e cerchiamo l'indirizzo del nostro contratto, dovremmo essere in grado di vedere che è stato distribuito con successo. La transazione somiglierà a questa: ![](./etherscan-contract.png) -L'indirizzo `From` dovrebbe corrispondere all'indirizzo del tuo conto di MetaMask mentre l'indirizzo `To` riporterà la dicitura **Creazione del contratto**. Se facciamo clic sulla transazione vedremo l'indirizzo del contratto nel campo `To`. +L'indirizzo `Da` dovrebbe corrispondere all'indirizzo del tuo account MetaMask e l'indirizzo `A` riporterà **Creazione del contratto**. Se facciamo clic sulla transazione, vedremo l'indirizzo del nostro contratto nel campo `A`. ![](./etherscan-transaction.png) -Congratulazioni! Hai appena distribuito un contratto intelligente su una rete di prova di Ethereum. +Congratulazioni! Hai appena distribuito un contratto intelligente su una rete di test di Ethereum. -Per capire cosa sta succedendo, andiamo alla scheda Explorer nel nostro [dashboard di Alchemy](https://dashboard.alchemyapi.io/explorer). Se hai diverse app di Alchemy assicurati di filtrare per app e selezionare **Hello World**. +Per capire cosa succede dietro le quinte, vai alla scheda Explorer nella tua [dashboard di Alchemy](https://dashboard.alchemy.com/explorer). Se hai più app Alchemy, assicurati di filtrare per app e seleziona **Hello World**. ![](./hello-world-explorer.png) -Qui vedrai numerosi metodi JSON-RPC che Harhat/Ethers ha creato dietro le quinte per noi quando abbiamo chiamato la funzione `.deploy()`. Due metodi importanti sono [`eth_sendRawTransaction`](https://docs.alchemyapi.io/alchemy/documentation/alchemy-api-reference/json-rpc#eth_sendrawtransaction), che è la richiesta per scrivere il nostro contratto sulla catena di Goeli, e [`eth_getTransactionByHash`](https://docs.alchemyapi.io/alchemy/documentation/alchemy-api-reference/json-rpc#eth_gettransactionbyhash), che è una richiesta di leggere le informazioni sulla nostra transazione in base all'hash. Per saperne di più sull'invio di transazioni, dai un'occhiata al [nostro tutorial sull'invio di transazioni usando Web3](/developers/tutorials/sending-transactions-using-web3-and-alchemy/). +Qui vedrai una manciata di metodi JSON-RPC che Hardhat/Ethers hanno eseguito per noi dietro le quinte quando abbiamo chiamato la funzione `.deploy()`. Due metodi importanti qui sono [`eth_sendRawTransaction`](https://docs.alchemyapi.io/alchemy/documentation/alchemy-api-reference/json-rpc#eth_sendrawtransaction), che è la richiesta di scrivere il nostro contratto sulla chain Goerli, e [`eth_getTransactionByHash`](https://docs.alchemyapi.io/alchemy/documentation/alchemy-api-reference/json-rpc#eth_gettransactionbyhash), che è una richiesta di leggere informazioni sulla nostra transazione dato l'hash. Per saperne di più sull'invio di transazioni, consulta [il nostro tutorial sull'invio di transazioni con Web3](/developers/tutorials/sending-transactions-using-web3-and-alchemy/). -## Parte 2: interagisci con il tuo contratto intelligente {#part-2-interact-with-your-smart-contract} +## Parte 2: Interagisci con il tuo contratto intelligente {#part-2-interact-with-your-smart-contract} -Adesso che abbiamo distribuito con successo un contratto intelligente nella rete di Goerli, impariamo come interagire con esso. +Ora che abbiamo distribuito con successo un contratto intelligente sulla rete Goerli, impariamo a interagire con esso. ### Crea un file interact.js {#create-a-interactjs-file} -Questo è il file dove scriveremo il nostro script di interazione. Useremo la libreria Ethers.js che hai installato precedentemente nella Parte 1. +Questo è il file in cui scriveremo il nostro script di interazione. Useremo la libreria Ethers.js che hai installato in precedenza nella Parte 1. All'interno della cartella `scripts/`, crea un nuovo file chiamato `interact.js` e aggiungi il seguente codice: @@ -390,24 +393,24 @@ const CONTRACT_ADDRESS = process.env.CONTRACT_ADDRESS ### Aggiorna il tuo file .env {#update-your-env-file} -Useremo delle nuove variabili di ambiente, quindi dobbiamo definirle nel file `.env` che [abbiamo creato in precedenza](#step-11-connect-metamask-&-alchemy-to-your-project). +Useremo nuove variabili d'ambiente, quindi dobbiamo definirle nel file `.env` che [abbiamo creato in precedenza](#step-11-connect-metamask-&-alchemy-to-your-project). -Dovremo aggiungere una definizione per la nostra `CHIAVE_API` di Alchemy e il `CONTRACT_ADDRESS` dove è stato distribuito il tuo contratto intelligente. +Dovremo aggiungere una definizione per la nostra `API_KEY` di Alchemy e il `CONTRACT_ADDRESS` dove è stato distribuito il tuo contratto intelligente. -Il tuo file `.env` dovrebbe assomigliare a questo: +Il tuo file `.env` dovrebbe avere un aspetto simile a questo: ```bash # .env -API_URL = "https://eth-goerli.alchemyapi.io/v2/" -API_KEY = "" -PRIVATE_KEY = "" -CONTRACT_ADDRESS = "0x" +API_URL = "https://eth-goerli.alchemyapi.io/v2/" +API_KEY = "" +PRIVATE_KEY = "" +CONTRACT_ADDRESS = "0x" ``` -### Prendi l'ABI del tuo contratto {#grab-your-contract-ABI} +### Recupera l'ABI del tuo contratto {#grab-your-contract-ABI} -L'[ABI (Interfaccia Binaria dell'Applicazione)](/glossary/#abi) del nostro contratto è l'interfaccia per interagire con il nostro contratto intelligente. Hardhat genera automaticamente l'ABI e la salva in `HelloWorld.json`. Per usare l'ABI, dobbiamo analizzarne il contenuto aggiungendo le seguenti righe di codice al nostro file `interact.js`: +L'[ABI (Application Binary Interface)](/glossary/#abi) del nostro contratto è l'interfaccia per interagire con il nostro contratto intelligente. Hardhat genera automaticamente un'ABI e la salva in `HelloWorld.json`. Per usare l'ABI, dovremo analizzarne il contenuto aggiungendo le seguenti righe di codice al nostro file `interact.js`: ```javascript // interact.js @@ -420,7 +423,7 @@ Se vuoi vedere l'ABI, puoi stamparla nella tua console: console.log(JSON.stringify(contract.abi)) ``` -Per vedere l'ABI stampata alla console, vai al terminale ed esegui: +Per vedere la tua ABI stampata sulla console, vai al tuo terminale ed esegui: ```bash npx hardhat run scripts/interact.js @@ -428,11 +431,11 @@ npx hardhat run scripts/interact.js ### Crea un'istanza del tuo contratto {#create-an-instance-of-your-contract} -Per interagire con il tuo contratto, dobbiamo creare un'istanza del contratto nel nostro codice. Per farlo con Ethers.js, dovremo lavorare con tre concetti: +Per interagire con il nostro contratto, dobbiamo creare un'istanza del contratto nel nostro codice. Per farlo con Ethers.js, dovremo lavorare con tre concetti: -1. Fornitore - un fornitore di nodi che consente l'accesso in lettura e scrittura alla blockchain -2. Firmatario - rappresenta un conto di Ethereum che può firmare transazioni -3. Contratto - un oggetto Ethers.js che rappresenta uno specifico contratto distribuito sulla catena +1. Provider - un provider di nodi che ti dà accesso in lettura e scrittura alla blockchain +2. Signer - rappresenta un account Ethereum che può firmare transazioni +3. Contratto - un oggetto Ethers.js che rappresenta uno specifico contratto distribuito on-chain Utilizzeremo l'ABI del contratto della fase precedente per creare la nostra istanza del contratto: @@ -448,7 +451,7 @@ const alchemyProvider = new ethers.providers.AlchemyProvider( // Signer const signer = new ethers.Wallet(PRIVATE_KEY, alchemyProvider) -// Contract +// Contratto const helloWorldContract = new ethers.Contract( CONTRACT_ADDRESS, contract.abi, @@ -456,17 +459,15 @@ const helloWorldContract = new ethers.Contract( ) ``` -Per saperne di più su fornitori, firmatari e contratti consultare la [documentazione di ethers.js](https://docs.ethers.io/v5/). +Scopri di più su Provider, Signer e Contratti nella [documentazione di ethers.js](https://docs.ethers.io/v5/). -### Leggi il messaggio init {#read-the-init-message} +### Leggi il messaggio di inizializzazione {#read-the-init-message} -Ricordi quando abbiamo distribuito il nostro contratto con il `initMessage = "Hello world!"`? Ora andremo a leggere il messaggio memorizzato nel nostro contratto intelligente e a stamparlo nella console. - -In JavaScript, quando si interagisce con le reti vengono usate funzioni asincrone. Per saperne di più sulle funzioni asincrone, [leggi questo articolo di Medium](https://blog.bitsrc.io/understanding-asynchronous-javascript-the-event-loop-74cd408419ff). - -Usa il codice qui sotto per chiamare la funzione `message` nel nostro contratto intelligente e leggere il messaggio init: +Ricordi quando abbiamo distribuito il nostro contratto con `initMessage = "Hello world!"`? Ora andremo a leggere il messaggio memorizzato nel nostro contratto intelligente e a stamparlo nella console. +In JavaScript, le funzioni asincrone vengono utilizzate quando si interagisce con le reti. Per saperne di più sulle funzioni asincrone, [leggi questo articolo su Medium](https://blog.bitsrc.io/understanding-asynchronous-javascript-the-event-loop-74cd408419ff). +Usa il codice qui sotto per chiamare la funzione `message` nel nostro contratto intelligente e leggere il messaggio di inizializzazione: ```javascript // interact.js @@ -475,33 +476,25 @@ Usa il codice qui sotto per chiamare la funzione `message` nel nostro contratto async function main() { const message = await helloWorldContract.message() - console.log("The message is: " + message) + console.log("Il messaggio è: " + message) } main() ``` - -Dopo aver eseguito il file usando il comando `npx hardhat run scripts/interact.js` da terminale, dovremmo vedere questa risposta: - - +Dopo aver eseguito il file usando `npx hardhat run scripts/interact.js` nel terminale, dovremmo vedere questa risposta: ``` -The message is: Hello world! +Il messaggio è: Hello world! ``` - -Congratulazioni! Hai appena letto con successo i dati dal contratto intelligente dalla blockchain Ethereum, complimenti! - - +Congratulazioni! Hai appena letto con successo i dati del contratto intelligente dalla blockchain di Ethereum, complimenti! ### Aggiorna il messaggio {#update-the-message} -Invece di limitarci a leggere il messaggio, possiamo anche aggiornare il messaggio salvato nel nostro contratto intelligente usando la funzione `update`! Piuttosto forte, vero? +Invece di limitarci a leggere il messaggio, possiamo anche aggiornare il messaggio salvato nel nostro contratto intelligente usando la funzione `update`! Forte, vero? Per aggiornare il messaggio, possiamo chiamare direttamente la funzione `update` nel nostro oggetto Contratto instanziato: - - ```javascript // interact.js @@ -509,28 +502,23 @@ Per aggiornare il messaggio, possiamo chiamare direttamente la funzione `update` async function main() { const message = await helloWorldContract.message() - console.log("The message is: " + message) + console.log("Il messaggio è: " + message) - console.log("Updating the message...") - const tx = await helloWorldContract.update("This is the new message.") + console.log("Aggiornamento del messaggio...") + const tx = await helloWorldContract.update("Questo è il nuovo messaggio.") await tx.wait() } main() ``` - -Da notare che alla riga 11, facciamo una chiamata a `.wait()` all'oggetto transazione restituito. Questo assicura che il nostro script aspetti che la transazione venga minata sulla blockchain prima di uscire dalla funzione. Se la chiamata `.wait()` non viene inclusa, lo script potrebbe non vedere il valore `message` aggiornato nel contratto. - - +Nota che alla riga 11, facciamo una chiamata a `.wait()` sull'oggetto transazione restituito. Questo assicura che il nostro script aspetti che la transazione venga minata sulla blockchain prima di uscire dalla funzione. Se la chiamata `.wait()` non viene inclusa, lo script potrebbe non vedere il valore `message` aggiornato nel contratto. ### Leggi il nuovo messaggio {#read-the-new-message} -Ora dovresti essere capace di ripetere la [fase precedente](#read-the-init-message) per leggere il valore `message` aggiornato. Prenditi un momento e vedi se riesci ad apportare le modifiche necessarie per stampare il nuovo valore! +Dovresti essere in grado di ripetere il [passaggio precedente](#read-the-init-message) per leggere il valore `message` aggiornato. Prenditi un momento e vedi se riesci ad apportare le modifiche necessarie per stampare il nuovo valore! Se hai bisogno di un suggerimento, ecco come dovrebbe apparire il tuo file `interact.js` a questo punto: - - ```javascript // interact.js @@ -549,7 +537,7 @@ const alchemyProvider = new ethers.providers.AlchemyProvider( // signer - you const signer = new ethers.Wallet(PRIVATE_KEY, alchemyProvider) -// contract instance +// istanza del contratto const helloWorldContract = new ethers.Contract( CONTRACT_ADDRESS, contract.abi, @@ -558,93 +546,73 @@ const helloWorldContract = new ethers.Contract( async function main() { const message = await helloWorldContract.message() - console.log("The message is: " + message) + console.log("Il messaggio è: " + message) - console.log("Updating the message...") - const tx = await helloWorldContract.update("this is the new message") + console.log("Aggiornamento del messaggio...") + const tx = await helloWorldContract.update("questo è il nuovo messaggio") await tx.wait() const newMessage = await helloWorldContract.message() - console.log("The new message is: " + newMessage) + console.log("Il nuovo messaggio è: " + newMessage) } main() ``` - -Adesso esegui solo script e dovresti essere in grado di vedere il vecchio messaggio, lo stato di aggiornamento e il nuovo messaggio stampato sul tuo terminale! +Ora esegui lo script e dovresti essere in grado di vedere il vecchio messaggio, lo stato di aggiornamento e il nuovo messaggio stampato sul tuo terminale! `npx hardhat run scripts/interact.js --network goerli` - - ``` -The message is: Hello World! -Updating the message... -The new message is: This is the new message. +Il messaggio è: Hello World! +Aggiornamento del messaggio... +Il nuovo messaggio è: Questo è il nuovo messaggio. ``` +Durante l'esecuzione dello script, potresti notare che la fase `Aggiornamento del messaggio...` richiede del tempo di caricamento prima che venga caricato il nuovo messaggio. Questo è dovuto al processo di mining; se sei curioso di tracciare le transazioni mentre vengono minate, visita la [mempool di Alchemy](https://dashboard.alchemyapi.io/mempool) per vedere lo stato di una transazione. Se la transazione viene eliminata, è sempre utile dare un'occhiata all'[Etherscan di Goerli](https://goerli.etherscan.io) e cercare l'hash della tua transazione. -Durante l'esecuzione dello script, potresti notare che la fase `Updating the message...` richiede del tempo di caricamento prima che venga caricato il nuovo messaggio. Questo è dovuto al processo di mining; se sei curioso di tracciare le transazioni mentre vengono minate, visita la [mempool di Alchemy](https://dashboard.alchemyapi.io/mempool) per vedere lo stato di una transazione. Se la transazione viene eliminata, è sempre utile dare un'occhiata all'[Etherscan di Goerli](https://goerli.etherscan.io) e cercare l'hash della tua transazione. +## Parte 3: Pubblica il tuo contratto intelligente su Etherscan {#part-3-publish-your-smart-contract-to-etherscan} - - -## Parte 3: pubblica il tuo contratto intelligente su Etherscan {#part-3-publish-your-smart-contract-to-etherscan} - -Hai fatto tutto il lavoro duro per dare vita il tuo contratto intelligente, ora è arrivato il momento di condividerlo con il mondo! +Hai fatto tutto il duro lavoro per dare vita al tuo contratto intelligente, ora è arrivato il momento di condividerlo con il mondo! Verificando il tuo contratto intelligente su Etherscan, chiunque può vedere il codice sorgente e interagire con il tuo contratto intelligente. Iniziamo! +### Passaggio 1: Genera una chiave API sul tuo account Etherscan {#step-1-generate-an-api-key-on-your-etherscan-account} +Una chiave API di Etherscan è necessaria per verificare che tu possieda il contratto intelligente che stai cercando di pubblicare. -### Fase 1: genera una chiave API nel tuo conto di Etherscan {#step-1-generate-an-api-key-on-your-etherscan-account} +Se non hai ancora un account Etherscan, [registrati per un account](https://etherscan.io/register). -La chiave API di Etherscan è necessaria per verificare che tu possieda il contratto intelligente che stai cercando di pubblicare. +Una volta effettuato l'accesso, trova il tuo nome utente nella barra di navigazione, passaci sopra e seleziona il pulsante **Il mio profilo**. -Se non hai ancora un conto di Etherscan [registrati per avere un conto](https://etherscan.io/register). +Nella tua pagina del profilo, dovresti vedere una barra di navigazione laterale. Dalla barra di navigazione laterale, seleziona **Chiavi API**. Quindi, premi il pulsante "Aggiungi" per creare una nuova chiave API, dai alla tua app il nome **hello-world** e premi il pulsante **Crea nuova chiave API**. -Una volta effettuato l'accesso, cerca il tuo nome utente nella barra di navigazione, passaci sopra e seleziona il pulsante **Il mio profilo**. - -Nella tua pagina del profilo, dovresti vedere una barra di navigazione laterale. Dalla barra di navigazione laterale, seleziona **Chiavi API**. Quindi, premi il pulsante "Aggiungi" per creare una nuova chiave API, dai un nome alla tua app **hello-world** e premi il pulsante **Crea una nuova chiave API**. - -La tua nuova chiave API dovrebbe apparire nella tabella delle chiavi API. Copia la chiave API nei tuoi appunti. +La tua nuova chiave API dovrebbe apparire nella tabella delle chiavi API. Copia la chiave API negli appunti. Successivamente, dobbiamo aggiungere la chiave API di Etherscan al nostro file `.env`. -Dopo averla aggiunta, il file `.env` dovrebbe apparire così: - - +Dopo averla aggiunta, il tuo file `.env` dovrebbe apparire così: ```javascript -API_URL = "https://eth-goerli.alchemyapi.io/v2/your-api-key" -PUBLIC_KEY = "your-public-account-address" -PRIVATE_KEY = "your-private-account-address" -CONTRACT_ADDRESS = "your-contract-address" -ETHERSCAN_API_KEY = "your-etherscan-key" +API_URL = "https://eth-goerli.alchemyapi.io/v2/tua-chiave-api" +PUBLIC_KEY = "il-tuo-indirizzo-account-pubblico" +PRIVATE_KEY = "il-tuo-indirizzo-account-privato" +CONTRACT_ADDRESS = "il-tuo-indirizzo-contratto" +ETHERSCAN_API_KEY = "la-tua-chiave-etherscan" ``` - - - -### Contratti intelligenti distribuiti su Hardhat {#hardhat-deployed-smart-contracts} - - +### Contratti intelligenti distribuiti con Hardhat {#hardhat-deployed-smart-contracts} #### Installa hardhat-etherscan {#install-hardhat-etherscan} -Pubblicare i tuoi contratti su Ethereum usando Hardhat è semplice. Per iniziare è necessario installare il plugin `hardhat-etherscan`. `hardhat-etherscan` verificherà automaticamente il codice sorgente e la ABI del contratto intelligente su Etherscan. Per aggiungerlo, esegui dalla cartella `hello-world`: - - +Pubblicare il tuo contratto su Etherscan usando Hardhat è semplice. Per iniziare dovrai prima installare il plugin `hardhat-etherscan`. `hardhat-etherscan` verificherà automaticamente il codice sorgente e l'ABI del contratto intelligente su Etherscan. Per aggiungerlo, esegui dalla directory `hello-world`: ```text npm install --save-dev @nomiclabs/hardhat-etherscan ``` - Una volta installato, includi la seguente dichiarazione in cima al tuo `hardhat.config.js` e aggiungi le opzioni di configurazione di Etherscan: - - ```javascript // hardhat.config.js @@ -665,129 +633,100 @@ module.exports = { }, }, etherscan: { - // Your API key for Etherscan - // Obtain one at https://etherscan.io/ + // La tua chiave API per Etherscan + // Ottienine una su https://etherscan.io/ apiKey: ETHERSCAN_API_KEY, }, } ``` - - - #### Verifica il tuo contratto intelligente su Etherscan {#verify-your-smart-contract-on-etherscan} Assicurati che tutti i file siano stati salvati e che tutte le variabili `.env` siano correttamente configurate. Esegui l'attività `verify`, passando l'indirizzo del contratto e la rete dove è stato distribuito: - - ```text npx hardhat verify --network goerli DEPLOYED_CONTRACT_ADDRESS 'Hello World!' ``` - -Assicurati che `DEPLOYED_CONTRACT_ADDRESS` sia l'indirizzo del tuo contratto intelligente distribuito sulla rete di prova di Goerli. Inoltre, l'argomento finale (`'Hello World!'`) deve essere lo stesso valore di stringa usato [durante la fase di distribuzione nella parte 1](#write-our-deploy-script). +Assicurati che `DEPLOYED_CONTRACT_ADDRESS` sia l'indirizzo del tuo contratto intelligente distribuito sulla rete di test Goerli. Inoltre, l'argomento finale (`'Hello World!'`) deve essere lo stesso valore di stringa usato [durante la fase di distribuzione nella parte 1](#write-our-deploy-script). Se tutto va bene, nel tuo terminale vedrai il seguente messaggio: - - ```text -Successfully submitted source code for contract -contracts/HelloWorld.sol:HelloWorld at 0xdeployed-contract-address -for verification on Etherscan. Waiting for verification result... +Codice sorgente inviato con successo per il contratto +contracts/HelloWorld.sol:HelloWorld all'indirizzo 0xdeployed-contract-address +per la verifica su Etherscan. In attesa del risultato della verifica... -Successfully verified contract HelloWorld on Etherscan. +Contratto HelloWorld verificato con successo su Etherscan. https://goerli.etherscan.io/address/#contracts ``` - Congratulazioni! Il codice del tuo contratto intelligente è su Etherscan! - - ### Dai un'occhiata al tuo contratto intelligente su Etherscan! {#check-out-your-smart-contract-on-etherscan} Quando vai al link fornito nel tuo terminale, dovresti essere in grado di vedere il codice e l'ABI del tuo contratto intelligente pubblicati su Etherscan! -**Fantastico: ce l'hai fatta! Ora chiunque può chiamare o scrivere sul tuo contratto intelligente! Non vediamo l'ora di vedere cosa svilupperai in futuro!** - - +**Fantastico: ce l'hai fatta, campione! Ora chiunque può chiamare o scrivere sul tuo contratto intelligente! Non vediamo l'ora di vedere cosa svilupperai in futuro!** -## Parte 4: integra il tuo contratto intelligente con il frontend {#part-4-integrating-your-smart-contract-with-the-frontend} +## Parte 4 - Integrazione del tuo contratto intelligente con il frontend {#part-4-integrating-your-smart-contract-with-the-frontend} -Alla fine di questo tutorial, saprai: +Alla fine di questo tutorial, saprai come: -- Collegare un portafoglio di MetaMask alla tua dapp -- Leggere dati da un contratto intelligente usando le API [Web3 di Alchemy](https://docs.alchemy.com/alchemy/documentation/alchemy-web3) +- Collegare un portafoglio MetaMask alla tua dApp +- Leggere i dati dal tuo contratto intelligente usando l'API [Alchemy Web3](https://docs.alchemy.com/alchemy/documentation/alchemy-web3) - Firmare le transazioni di Ethereum usando MetaMask -Per questa dapp, useremo [React](https://reactjs.org/) come nostro framwork di frontend; tuttavia è importante notare che non dedicheremo molto tempo alla descrizione dei suoi fondamentali, poiché ci concentreremo principalmente sull'introduzione delle funzionalità web3 nel nostro progetto. +Per questa dApp, useremo [React](https://react.dev/) come nostro framework frontend; tuttavia, è importante notare che non dedicheremo molto tempo alla scomposizione dei suoi fondamenti, poiché ci concentreremo principalmente sull'introduzione delle funzionalità Web3 nel nostro progetto. -Come prerequisito, è necessario avere una comprensione di React a livello principiante. In caso contrario, suggeriamo di completare il [tutorial Introduzione a React](https://reactjs.org/tutorial/tutorial.html) ufficiale. +Come prerequisito, è necessario avere una comprensione di React a livello principiante. In caso contrario, ti consigliamo di completare il [tutorial ufficiale di introduzione a React](https://react.dev/learn). +### Clonare i file di base {#clone-the-starter-files} +Per prima cosa, vai al [repository GitHub hello-world-part-four](https://github.com/alchemyplatform/hello-world-part-four-tutorial) per ottenere i file di base per questo progetto e clona questo repository sulla tua macchina locale. -### Clonare i file iniziali {#clone-the-starter-files} +Apri il repository clonato localmente. Nota che contiene due cartelle: `starter-files` e `completed`. -Per prima cosa, vai al [repository hello-world-part-four in Github](https://github.com/alchemyplatform/hello-world-part-four-tutorial) per ottenere i file iniziali per questo progetto e clona questo repository nella tua macchina in locale. +- `starter-files`- **lavoreremo in questa directory**, collegheremo l'interfaccia utente al tuo portafoglio Ethereum e al contratto intelligente che abbiamo pubblicato su Etherscan nella [Parte 3](#part-3). +- `completed` contiene l'intero tutorial completato e deve essere usato solo come riferimento se ti blocchi. -Apri il repository clonato localmente. Si noti che contiene due cartelle `starter-files` e `completed`. +Quindi, apri la tua copia di `starter-files` nel tuo editor di codice preferito, e poi vai alla cartella `src`. -- `starter-files`- **lavoreremo in questa cartella**, collegheremo l'interfaccia utente al tuo portafoglio di Ethereum e al contratto intelligente che abbiamo pubblicato nella [Parte 3](#part-3). -- `completed` contiene l'intero tutorial completato e deve essere usata solo come riferimento se ci si blocca. +Tutto il codice che scriveremo si troverà nella cartella `src`. Modificheremo il componente `HelloWorld.js` e i file JavaScript `util/interact.js` per dare al nostro progetto la funzionalità Web3. -Quindi, apri la tua copia di `starter-files` con il tuo editor di codice preferito, e poi vai alla cartella `src`. +### Controlla i file di base {#check-out-the-starter-files} -Tutto il codice che scriveremo sarà sotto la cartella `src`. Modificheremo il componente `HelloWorld.js` e i file Javascript `util/interact.js` per dare al nostro progetto la funzionalità Web3. +Prima di iniziare a programmare, esploriamo ciò che ci viene fornito nei file di base. - - -### Dai un'occhiata ai file iniziali {#check-out-the-starter-files} - -Prima di iniziare a programmare, diamo un'occhiata a ciò che ci viene fornito nei file iniziali. - - - -#### Metti in funzione il tuo progetto di React {#get-your-react-project-running} +#### Avviare il progetto React {#get-your-react-project-running} Iniziamo eseguendo il progetto di React nel browser. La bellezza di React è che una volta eseguito il nostro progetto nel browser, ogni modifica che salviamo sarà aggiornata dal vivo nel browser. -Per mettere il progetto in funzione, vai alla cartella di root della cartella `starter-files` ed esegui `npm install` nel terminale per installare le dipendenze del progetto: - - +Per avviare il progetto, vai alla directory principale della cartella `starter-files` ed esegui `npm install` nel tuo terminale per installare le dipendenze del progetto: ```bash cd starter-files npm install ``` - -Una volta terminata l'installazione, esegui `npm start` nel terminale: - - +Una volta terminata l'installazione, esegui `npm start` nel tuo terminale: ```bash npm start ``` +Facendo ciò, si dovrebbe aprire [http://localhost:3000/](http://localhost:3000/) nel browser, dove vedrai il frontend del nostro progetto. Dovrebbe consistere in un campo (un posto per aggiornare il messaggio memorizzato nel tuo contratto intelligente), un pulsante "Connetti portafoglio" e un pulsante "Aggiorna". -Così facendo, dovrebbe aprirsi [http://localhost:3000/](http://localhost:3000/) nel browser, dove vedrai il frontend per il nostro progetto. Dovrebbe consistere in un campo \(un posto per aggiornare il messaggio memorizzato nel tuo contratto intelligente\), il pulsante "Connetti portafoglio" e un pulsante "Aggiorna". - -Se provi a fare clic su uno dei pulsanti, noterai che non funzionano - questo perché devi ancora programmarne la funzionalità. - - +Se provi a fare clic su uno dei pulsanti, noterai che non funzionano: questo perché dobbiamo ancora programmarne la funzionalità. #### Il componente `HelloWorld.js` {#the-helloworld-js-component} -Torniamo la cartella `src` nell'editor e apriamo il file `HelloWorld.js`. È davvero importante comprendere tutto il contenuto di questo file, che è il componente principale di React su cui lavoreremo. - -All'inizio di questo file, noterai che abbiamo diverse dichiarazioni relative all'importazione che sono necessarie per far funzionare il nostro progetto, inclusa la libreria di React, gli hook useEffect ed useState, alcuni elementi da `./util/interact.js` (li descriveremo in dettaglio a breve!) e il logo di Alchemy. - +Torniamo alla cartella `src` nel nostro editor e apriamo il file `HelloWorld.js`. È davvero importante comprendere tutto il contenuto di questo file, che è il componente principale di React su cui lavoreremo. +All'inizio di questo file, noterai che abbiamo diverse dichiarazioni di importazione necessarie per far funzionare il nostro progetto, inclusa la libreria React, gli hook useEffect e useState, alcuni elementi da `./util/interact.js` (li descriveremo più in dettaglio a breve!) e il logo di Alchemy. ```javascript // HelloWorld.js @@ -805,140 +744,127 @@ import { import alchemylogo from "./alchemylogo.svg" ``` - Successivamente, abbiamo le nostre variabili di stato che aggiorneremo dopo eventi specifici. - - ```javascript // HelloWorld.js -//State variables +//Variabili di stato const [walletAddress, setWallet] = useState("") const [status, setStatus] = useState("") -const [message, setMessage] = useState("No connection to the network.") +const [message, setMessage] = useState("Nessuna connessione alla rete.") const [newMessage, setNewMessage] = useState("") ``` - Ecco cosa rappresenta ciascuna variabile: -- `walletAddress` - una stringa che memorizza l'indirizzo del portafoglio dell'utente -- `status`- una stringa che memorizza un messaggio utile che guida l'utente su come interagire con la dapp +- `walletAddress`: una stringa che memorizza l'indirizzo del portafoglio dell'utente +- `status`- una stringa che memorizza un messaggio utile che guida l'utente su come interagire con la dApp - `message` - una stringa che memorizza il messaggio corrente nel contratto intelligente - `newMessage` - una stringa che memorizza il nuovo messaggio che verrà scritto nel contratto intelligente -Dopo le variabili di stato, vedrai cinque funzioni non implementate: `useEffect` ,`addSmartContractListener`, `addWalletListener` , `connectWalletPressed` e `onUpdatePressed`. Illustreremo cosa fanno qui di seguito: - - +Dopo le variabili di stato, vedrai cinque funzioni non implementate: `useEffect`, `addSmartContractListener`, `addWalletListener`, `connectWalletPressed` e `onUpdatePressed`. Spiegheremo cosa fanno qui di seguito: ```javascript // HelloWorld.js -//called only once +//chiamato solo una volta useEffect(async () => { - //TODO: implement + //TODO: implementa }, []) function addSmartContractListener() { - //TODO: implement + //TODO: implementa } function addWalletListener() { - //TODO: implement + //TODO: implementa } const connectWalletPressed = async () => { - //TODO: implement + //TODO: implementa } const onUpdatePressed = async () => { - //TODO: implement + //TODO: implementa } ``` - -- [`useEffect`](https://reactjs.org/docs/hooks-effect.html) - questo è un hook di React chiamato dopo il rendering del tuo componente. Poiché in essa viene passato un array vuoto `[]` \(vedi la riga 4\), sarà chiamata solo al _primo_ rendering del componente. Qui caricheremo il messaggio corrente memorizzato nel nostro contratto intelligente, chiameremo i listener del nostro contratto intelligente e del portafoglio e aggiorneremo la nostra interfaccia utente per riflettere se un portafoglio sia già connesso. -- `addSmartContractListener`- questa funzione configura un listener che osserverà l'evento `UpdatedMessages` del nostro contratto HelloWorld e aggiornerà la nostra interfaccia utente quando il messaggio è cambiato nel nostro contratto intelligente. -- `addWalletListener`- questa funzione configura un listener che rileva i cambiamenti nel portafoglio di MetaMask dell'utente, come quando un utente disconnette il suo portafoglio o cambia indirizzo. -- `connectWalletPressed`- questa funzione sarà chiamata per connettere il portafoglio di MetaMask dell'utente alla nostra dapp. -- `onUpdatePressed` - questa funzione sarà chiamata quando un utente vuole aggiornare il messaggio memorizzato nel contratto intelligente. +- [`useEffect`](https://legacy.reactjs.org/docs/hooks-effect.html)- questo è un hook di React che viene chiamato dopo il rendering del tuo componente. Poiché ha una prop array vuoto `[]` passata ad esso (vedi riga 4), sarà chiamato solo al _primo_ rendering del componente. Qui caricheremo il messaggio corrente memorizzato nel nostro contratto intelligente, chiameremo i nostri listener di contratto intelligente e portafoglio e aggiorneremo la nostra interfaccia utente per riflettere se un portafoglio è già connesso. +- `addSmartContractListener` - questa funzione imposta un listener che osserverà l'evento `UpdatedMessages` del nostro contratto HelloWorld e aggiornerà la nostra interfaccia utente quando il messaggio viene modificato nel nostro contratto intelligente. +- `addWalletListener` - questa funzione imposta un listener che rileva i cambiamenti nello stato del portafoglio MetaMask dell'utente, come quando l'utente disconnette il suo portafoglio o cambia indirizzo. +- `connectWalletPressed`- questa funzione sarà chiamata per connettere il portafoglio MetaMask dell'utente alla nostra dApp. +- `onUpdatePressed` - questa funzione sarà chiamata quando l'utente vuole aggiornare il messaggio memorizzato nel contratto intelligente. Vicino alla fine di questo file, abbiamo l'UI del nostro componente. - - ```javascript // HelloWorld.js -//the UI of our component +//l'interfaccia utente del nostro componente return (
-

Current Message:

+

Messaggio corrente:

{message}

-

New Message:

+

Nuovo messaggio:

setNewMessage(e.target.value)} value={newMessage} />

{status}

-
-
+ + + ) ``` +Se analizzi questo codice con attenzione, noterai dove usiamo le nostre varie variabili di stato nell'interfaccia utente: -Se analizzi questo codice con attenzione, noterai dove usiamo le varie variabili di stato nella nostra interfaccia utente: - -- Nelle righe 6-12, se il portafoglio dell'utente è connesso \(ossia `walletAddress.length > 0`\), viene visualizzata una versione troncata del `walletAddress` dell'utente nel pulsante con ID "walletButton"; altrimenti si leggerà semplicemente "Connect Wallet". -- Nella riga 17, viene visualizzato il messaggio corrente memorizzato nel contratto intelligente, che è acquisito nella stringa `message`. -- Nelle righe 23-26, usiamo un [componente controllato](https://reactjs.org/docs/forms.html#controlled-components) per aggiornare la nostra variabile di stato `newMessage` quando l'input nel campo di testo cambia. - -Oltre alle variabili di stato, vedrai anche che le funzioni `connectWalletPressed` e `onUpdatePressed` vengono chiamate rispettivamente quando si fa clic sui pulsanti con ID `publishButton` e `walletButton`. +- Nelle righe 6-12, se il portafoglio dell'utente è connesso (cioè `walletAddress.length > 0`), visualizziamo una versione troncata del `walletAddress` dell'utente nel pulsante con ID "walletButton;" altrimenti dice semplicemente "Connetti Portafoglio". +- Alla riga 17, visualizziamo il messaggio corrente memorizzato nel contratto intelligente, che è catturato nella stringa `message`. +- Nelle righe 23-26, usiamo un [componente controllato](https://legacy.reactjs.org/docs/forms.html#controlled-components) per aggiornare la nostra variabile di stato `newMessage` quando l'input nel campo di testo cambia. -Infine vediamo dove viene aggiunto questo componente `HelloWorld.js`. +Oltre alle nostre variabili di stato, vedrai anche che le funzioni `connectWalletPressed` e `onUpdatePressed` vengono chiamate rispettivamente quando si fa clic sui pulsanti con ID `publishButton` e `walletButton`. -Se vai al file `App.js`, che è il componente principale su React e che agisce come contenitore per tutti gli altri componenti, vedrai che il nostro componente `HelloWorld.js` è inserito alla riga 7. - -Per ultimo, ma non meno importante, diamo un'occhiata ad un altro file fornito, il file `interact.js`. +Infine, vediamo dove viene aggiunto questo componente `HelloWorld.js`. +Se vai al file `App.js`, che è il componente principale in React che agisce come contenitore per tutti gli altri componenti, vedrai che il nostro componente `HelloWorld.js` è inserito alla riga 7. +Infine, ma non meno importante, diamo un'occhiata a un altro file fornito per te, il file `interact.js`. #### Il file `interact.js` {#the-interact-js-file} -Poiché vogliamo rispettare il paradigma [M-V-C](https://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller), vorremo un file separato che contiene tutte le nostre funzioni per gestire la logica, i dati e le regole della nostra dapp, ed essere quindi in grado di esportare queste funzioni al nostro frontend \(il nostro componente`HelloWorld.js`\). - -👆🏽Questo è esattamente lo scopo del file `interact.js`! - -Vai alla cartella `util`nella tua directory `src`, e noterai che abbiamo incluso un file chiamato `interact.js` che conterrà tutte le funzioni e le variabili per l'interazione con il nostro contratto intelligente e con il portafoglio. +Poiché vogliamo aderire al paradigma [M-V-C](https://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller), vorremo un file separato che contenga tutte le nostre funzioni per gestire la logica, i dati e le regole della nostra dApp, e quindi essere in grado di esportare quelle funzioni nel nostro frontend (il nostro componente `HelloWorld.js`). +👆🏽Questo è esattamente lo scopo del nostro file `interact.js`! +Vai alla cartella `util` nella tua directory `src`, e noterai che abbiamo incluso un file chiamato `interact.js` che conterrà tutte le funzioni e le variabili per l'interazione con il nostro contratto intelligente e con il portafoglio. ```javascript // interact.js -//export const helloWorldContract; +//esporta const helloWorldContract; export const loadCurrentMessage = async () => {} @@ -949,71 +875,55 @@ const getCurrentWalletConnected = async () => {} export const updateMessage = async (message) => {} ``` +Noterai che all'inizio del file abbiamo commentato l'oggetto `helloWorldContract`. Più avanti in questo tutorial, rimuoveremo il commento da questo oggetto e istanzieremo il nostro contratto intelligente in questa variabile, che esporteremo poi nel nostro componente `HelloWorld.js`. -Noterai che all'inizio del file abbiamo commentato l'oggetto `helloWorldContract`. Più avanti in questo tutorial, toglieremo il commento a questo oggetto e istanzieremo il nostro contratto intelligente in questa variabile, che esporteremo poi nel nostro componente `HelloWorld.js`. +Le quattro funzioni non implementate dopo il nostro oggetto `helloWorldContract` fanno quanto segue: -Le quatto funzioni non implementate dopo il nostro oggetto `helloWorldContract` fanno quanto segue: +- `loadCurrentMessage` - questa funzione gestisce la logica di caricamento del messaggio corrente salvato nel contratto intelligente. Effettuerà una chiamata di _lettura_ al contratto intelligente Hello World usando l'[API di Alchemy Web3](https://github.com/alchemyplatform/alchemy-web3). +- `connectWallet` - questa funzione connetterà il MetaMask dell'utente alla nostra dApp. +- `getCurrentWalletConnected` - questa funzione verificherà se un account Ethereum è già connesso alla nostra dApp al caricamento della pagina e aggiornerà l'interfaccia utente di conseguenza. +- `updateMessage` - questa funzione aggiornerà il messaggio memorizzato nel contratto intelligente. Effettuerà una chiamata di _scrittura_ al contratto intelligente Hello World, quindi il portafoglio MetaMask dell'utente dovrà firmare una transazione Ethereum per aggiornare il messaggio. -- `loadCurrentMessage` - questa funzione gestisce la logica di caricamento del messaggio corrente salvato nel contratto intelligente. Effettuerà una chiamata _read (leggi)_ al contratto intelligente Hello World usando l'[API Web3 di Alchemy](https://github.com/alchemyplatform/alchemy-web3). -- `connectWallet` - questa funzione connette il MetaMask dell'utente alla nostra dapp. -- `getCurrentWalletConnected` - questa funzione verificherà se un conto di Ethereum è già connesso alla nostra dapp durante il caricamento della pagina e aggiornerà l'interfaccia utente di conseguenza. -- `updateMessage` - questa funzione aggiornerà il messaggio memorizzato nel contratto intelligente. Effettuerà una chiamata di _scrittura_ al contratto intelligente Hello World, quindi il portafoglio di MetaMask dell'utente dovrà firmare una transazione di Ethereum per aggiornare il messaggio. +Ora che abbiamo capito con cosa stiamo lavorando, scopriamo come leggere dal nostro contratto intelligente! -Ora che ci è chiaro con cosa stiamo lavorando, cerchiamo di capire come leggere il nostro contratto intelligente! +### Passaggio 3: Leggi dal tuo contratto intelligente {#step-3-read-from-your-smart-contract} +Per leggere dal tuo contratto intelligente, dovrai configurare con successo: - -### Fase 3: leggi il tuo contratto intelligente {#step-3-read-from-your-smart-contract} - -Per leggere il tuo contratto intelligente, dovrai configurare con successo: - -- Una connessione API alla catena Ethereum +- Una connessione API alla chain di Ethereum - Un'istanza caricata del tuo contratto intelligente - Una funzione per chiamare la funzione del tuo contratto intelligente -- Un listener per rilevare gli aggiornamenti quando i dati letti dal contratto intelligente cambiano - -Questo può sembrare un gran numero di passaggi, ma non preoccuparti! Ti spiegheremo come affrontarli passo dopo passo! :\) - - +- Un listener per rilevare gli aggiornamenti quando i dati che stai leggendo dal contratto intelligente cambiano -#### Stabilire una connessione API alla catena Ethereum {#establish-an-api-connection-to-the-ethereum-chain} +Potrebbero sembrare tanti passaggi, ma non preoccuparti! Ti guideremo passo dopo passo! :\) -Ricordi che nella seconda parte di questo tutorial abbiamo usato la nostra [chiave Web3 di Alchemy per leggere il nostro contratto intelligente](https://docs.alchemy.com/alchemy/tutorials/hello-world-smart-contract/interacting-with-a-smart-contract#step-1-install-web3-library)? Ti servirà anche una chiave Web3 di Alchemy nella tua dapp per leggere dalla caena. - -Se non lo hai già, installa [Alchemy Web3](https://github.com/alchemyplatform/alchemy-web3) andando nella cartella di root dei tuoi `starter-files` ed eseguendo il seguente comando nel tuo terminale: +#### Stabilisci una connessione API alla chain di Ethereum {#establish-an-api-connection-to-the-ethereum-chain} +Ricordi come nella Parte 2 di questo tutorial abbiamo usato la nostra [chiave Alchemy Web3 per leggere dal nostro contratto intelligente](https://docs.alchemy.com/alchemy/tutorials/hello-world-smart-contract/interacting-with-a-smart-contract#step-1-install-web3-library)? Avrai bisogno di una chiave Alchemy Web3 anche nella tua dApp per leggere dalla chain. +Se non l'hai già fatto, installa prima [Alchemy Web3](https://github.com/alchemyplatform/alchemy-web3) navigando nella directory principale dei tuoi `starter-files` ed eseguendo quanto segue nel tuo terminale: ```text npm install @alch/alchemy-web3 ``` +[Alchemy Web3](https://github.com/alchemyplatform/alchemy-web3) è un wrapper di [Web3.js](https://docs.web3js.org/) che fornisce metodi API migliorati e altri benefici fondamentali per semplificare la vita agli sviluppatori web3. È progettato per richiedere una configurazione minima, così da poter iniziare a usarlo immediatamente nella tua app! -[Alchemy Web3](https://github.com/alchemyplatform/alchemy-web3) è un wrapper intorno a[Web3.js](https://docs.web3js.org/) che fornisce metodi API migliorati e altri benefici fondamentale per semplificare la tua vita a uno sviluppatore web3. È progettato per richiedere una configurazione minima, così da poter iniziare a usarlo immediatamente nella tua app! - -Quindi, installa il pacchetto [dotenv](https://www.npmjs.com/package/dotenv) nella cartella del tuo progetto, in modo da avere un posto sicuro per memorizzare la nostra chiave API dopo averla ottenuta. - - +Quindi, installa il pacchetto [dotenv](https://www.npmjs.com/package/dotenv) nella directory del tuo progetto, in modo da avere un posto sicuro per memorizzare la nostra chiave API dopo averla recuperata. ```text npm install dotenv --save ``` +Per la nostra dApp, **useremo la nostra chiave API Websockets** invece della nostra chiave API HTTP, poiché ci permetterà di impostare un listener che rileva quando il messaggio memorizzato nel contratto intelligente cambia. -Per la nostra dapp, **useremo la nostra chiave API Websockets** invece della nostra chiave API HTTP, perché ci permetterà di configurare un listener che rilevi quando il messaggio memorizzato nel contratto intelligente cambia. - -Una volta ottenuta la chiave API, crea un file `.env` nella tua cartella di root e aggiungici l'url di Alchemy Websockets. Successivamente, il tuo file `.env` dovrebbe avere il seguente aspetto: - - +Una volta ottenuta la tua chiave API, crea un file `.env` nella tua directory principale e aggiungi il tuo URL Alchemy Websockets. Successivamente, il tuo file `.env` dovrebbe avere il seguente aspetto: ```javascript -REACT_APP_ALCHEMY_KEY = wss://eth-goerli.ws.alchemyapi.io/v2/ +REACT_APP_ALCHEMY_KEY = wss://eth-goerli.ws.alchemyapi.io/v2/ ``` - -Ora siamo pronti a configurare il nostro endpoint Alchemy Web3 nella nostra dapp! Torniamo al nostro `interact.js`, che è contenuto nella cartella `util` e aggiungiamo il seguente codice all'inizio del file: - - +Ora siamo pronti a configurare il nostro endpoint Alchemy Web3 nella nostra dApp! Torniamo al nostro `interact.js`, che è annidato nella nostra cartella `util`, e aggiungiamo il seguente codice all'inizio del file: ```javascript // interact.js @@ -1023,33 +933,26 @@ const alchemyKey = process.env.REACT_APP_ALCHEMY_KEY const { createAlchemyWeb3 } = require("@alch/alchemy-web3") const web3 = createAlchemyWeb3(alchemyKey) -//export const helloWorldContract; +//esporta const helloWorldContract; ``` - -Sopra, abbiamo prima importato la chiave Alchemy dal nostro file `.env` e poi passato la nostra `alchemyKey` a `createAlchemyWeb3` per stabilire il nostro endpoint di Alchemy Web3. +Sopra, abbiamo prima importato la chiave Alchemy dal nostro file `.env` e poi passato la nostra `alchemyKey` a `createAlchemyWeb3` per stabilire il nostro endpoint Alchemy Web3. Con questo endpoint pronto, è il momento di caricare il nostro contratto intelligente! +#### Caricamento del tuo contratto intelligente Hello World {#loading-your-hello-world-smart-contract} - -#### Caricare il proprio contratto intelligente Hello World {#loading-your-hello-world-smart-contract} - -Per caricare il tuo contratto intelligente Hello World, sono necessari l'indirizzo e l'ABI del contratto, entrambi reperibili su Etherscan se hai completato la [Parte 3 di questo tutorial.](/developers/tutorials/hello-world-smart-contract-fullstack/#part-3-publish-your-smart-contract-to-etherscan-part-3-publish-your-smart-contract-to-etherscan) - - +Per caricare il tuo contratto intelligente Hello World, avrai bisogno del suo indirizzo e della sua ABI, entrambi reperibili su Etherscan se hai completato la [Parte 3 di questo tutorial](/developers/tutorials/hello-world-smart-contract-fullstack/#part-3-publish-your-smart-contract-to-etherscan-part-3-publish-your-smart-contract-to-etherscan). #### Come ottenere l'ABI del tuo contratto da Etherscan {#how-to-get-your-contract-abi-from-etherscan} -Se hai saltato la Parte 3 di questo tutorial, puoi usare il contratto HelloWorld con l'indirizzo [0x6f3f635A9762B47954229Ea479b4541eAF402A6A](https://goerli.etherscan.io/address/0x6f3f635a9762b47954229ea479b4541eaf402a6a#code). La sua ABI si trova [qui](https://goerli.etherscan.io/address/0x6f3f635a9762b47954229ea479b4541eaf402a6a#code). +Se hai saltato la Parte 3 di questo tutorial, puoi usare il contratto HelloWorld con l'indirizzo [0x6f3f635A9762B47954229Ea479b4541eAF402A6A](https://goerli.etherscan.io/address/0x6f3f635a9762b47954229ea479b4541eaf402a6a#code). La sua ABI può essere trovata [qui](https://goerli.etherscan.io/address/0x6f3f635a9762b47954229ea479b4541eaf402a6a#code). -L'ABI di un contratto serve per specificare quale funzione invocherà un contratto, oltre che per garantire che la funzione restituirà i dati nel formato previsto. Una volta copiata la ABI del nostro contratto, salviamola come file JSON chiamato `contract-abi.json` nella cartella `src`. - -Il file contract-abi.json deve essere memorizzato nella cartella src. - -Con l'indirizzo del contratto, l'ABI e l'endpoint di Alchemy Web3, possiamo usare il [metodo del contratto](https://docs.web3js.org/api/web3-eth-contract/class/Contract) per caricare un'istanza del nostro contratto intelligente. Importa la ABI del contratto nel file `interact.js` e aggiungi l'indirizzo del tuo contratto. +L'ABI di un contratto è necessaria per specificare quale funzione un contratto invocherà, oltre a garantire che la funzione restituirà i dati nel formato previsto. Una volta copiata l'ABI del nostro contratto, salviamola come file JSON chiamato `contract-abi.json` nella tua directory `src`. +Il tuo contract-abi.json dovrebbe essere salvato nella tua cartella src. +Armati dell'indirizzo del nostro contratto, dell'ABI e dell'endpoint di Alchemy Web3, possiamo usare il [metodo `contract`](https://docs.web3js.org/api/web3-eth-contract/class/Contract) per caricare un'istanza del nostro contratto intelligente. Importa l'ABI del tuo contratto nel file `interact.js` e aggiungi l'indirizzo del tuo contratto. ```javascript // interact.js @@ -1058,10 +961,7 @@ const contractABI = require("../contract-abi.json") const contractAddress = "0x6f3f635A9762B47954229Ea479b4541eAF402A6A" ``` - -Ora possiamo finalmente eliminare il commento dalla nostra variabile `helloWorldContract` e caricare il contratto intelligente usando il nostro endpoint di AlchemyWeb3: - - +Possiamo ora finalmente rimuovere il commento dalla nostra variabile `helloWorldContract` e caricare il contratto intelligente usando il nostro endpoint AlchemyWeb3: ```javascript // interact.js @@ -1071,10 +971,7 @@ export const helloWorldContract = new web3.eth.Contract( ) ``` - -Ricapitolando, le prime 12 righe del file `interact.js` dovrebbero avere questo aspetto: - - +Per ricapitolare, le prime 12 righe del tuo `interact.js` dovrebbero ora avere questo aspetto: ```javascript // interact.js @@ -1093,19 +990,14 @@ export const helloWorldContract = new web3.eth.Contract( ) ``` +Ora che il nostro contratto è caricato, possiamo implementare la nostra funzione `loadCurrentMessage`! -Ora che il nostro contratto è stato caricato, possiamo implementare la nostra funzione `loadCurrentMessage`! - +#### Implementazione di `loadCurrentMessage` nel tuo file `interact.js` {#implementing-loadCurrentMessage-in-your-interact-js-file} - -#### Implementare `loadCurrentMessage` nel proprio file `interact.js` {#implementing-loadCurrentMessage-in-your-interact-js-file} - -Questa funzione è semplicissima. Faremo una semplice invocazione asincrona web3 per leggere dal nostro contratto. La nostra funzione restituirà il messaggio memorizzato nel contratto intelligente: +Questa funzione è semplicissima. Faremo una semplice chiamata asincrona web3 per leggere dal nostro contratto. La nostra funzione restituirà il messaggio memorizzato nel contratto intelligente: Aggiorna `loadCurrentMessage` nel tuo file `interact.js` come segue: - - ```javascript // interact.js @@ -1115,70 +1007,60 @@ export const loadCurrentMessage = async () => { } ``` - Poiché vogliamo visualizzare questo contratto intelligente nella nostra interfaccia utente, aggiorniamo la funzione `useEffect` nel nostro componente `HelloWorld.js` come segue: - - ```javascript // HelloWorld.js -//called only once +//chiamato solo una volta useEffect(async () => { const message = await loadCurrentMessage() setMessage(message) }, []) ``` +Nota che vogliamo che il nostro `loadCurrentMessage` sia chiamato solo una volta durante il primo rendering del componente. Presto implementeremo `addSmartContractListener` per aggiornare automaticamente l'interfaccia utente dopo che il messaggio del contratto intelligente cambia. -Si noti che vogliamo che il nostro `loadCurrentMessage` sia chiamato solo una volta durante il primo rendering del componente. Presto implementeremo `addSmartContractListener` per aggiornare automaticamente l'interfaccia utente dopo che il messaggio del contratto intelligente cambia. - -Prima di addentrarci nel nostro listener, diamo un'occhiata a ciò che abbiamo finora! Salva i file `HelloWorld.js` e `interact.js`, quindi vai su [http://localhost:3000/](http://localhost:3000/) +Prima di addentrarci nel nostro listener, diamo un'occhiata a ciò che abbiamo finora! Salva i tuoi file `HelloWorld.js` e `interact.js`, e poi vai su [http://localhost:3000/](http://localhost:3000/) Noterai che il messaggio corrente non dice più "Nessuna connessione alla rete". Riflette invece il messaggio memorizzato nel contratto intelligente. Pazzesco! - - -#### L'interfaccia utente dovrebbe ora riflettere il messaggio memorizzato nel contratto intelligente {#your-UI-should-now-reflect-the-message-stored-in-the-smart-contract} +#### La tua UI dovrebbe ora riflettere il messaggio memorizzato nel contratto intelligente {#your-UI-should-now-reflect-the-message-stored-in-the-smart-contract} Ora, parlando di quel listener... - - #### Implementa `addSmartContractListener` {#implement-addsmartcontractlistener} -Se ripensi al file `HelloWorld.sol` che abbiamo scritto nella [Parte 1 di questa serie di tutorial](https://docs.alchemy.com/alchemy/tutorials/hello-world-smart-contract#step-10-write-our-contract), ricorderai che c'è un evento del contratto intelligente chiamato `UpdatedMessages` che viene emesso dopo aver invocato la funzione `update` del nostro contratto intelligente \(vedi righe 9 e 27\): - - +Se ripensi al file `HelloWorld.sol` che abbiamo scritto nella [Parte 1 di questa serie di tutorial](https://docs.alchemy.com/alchemy/tutorials/hello-world-smart-contract#step-10-write-our-contract), ricorderai che c'è un evento del contratto intelligente chiamato `UpdatedMessages` che viene emesso dopo aver invocato la funzione `update` del nostro contratto intelligente (vedi righe 9 e 27): ```javascript // HelloWorld.sol -// Specifies the version of Solidity, using semantic versioning. -// Learn more: https://solidity.readthedocs.io/en/v0.5.10/layout-of-source-files.html#pragma +// Specifica la versione di Solidity, usando il versioning semantico. +// Per saperne di più: https://solidity.readthedocs.io/en/v0.5.10/layout-of-source-files.html#pragma pragma solidity ^0.7.3; -// Defines a contract named `HelloWorld`. -// Un contratto è una raccolta di funzioni e dati (il suo stato). Once deployed, a contract resides at a specific address on the Ethereum blockchain. Learn more: https://solidity.readthedocs.io/en/v0.5.10/structure-of-a-contract.html +// Definisce un contratto chiamato `HelloWorld`. +// Un contratto è una raccolta di funzioni e dati (il suo stato). Una volta distribuito, un contratto risiede a un indirizzo specifico sulla blockchain di Ethereum. Per saperne di più: https://solidity.readthedocs.io/en/v0.5.10/structure-of-a-contract.html contract HelloWorld { - //Emitted when update function is called - //Smart contract events are a way for your contract to communicate that something happened on the blockchain to your app front-end, which can be 'listening' for certain events and take action when they happen. + //Emesso quando viene chiamata la funzione di aggiornamento + //Gli eventi dei contratti intelligenti sono un modo per il tuo contratto di comunicare che qualcosa è accaduto sulla blockchain alla tua app front-end, che può essere 'in ascolto' di determinati eventi e agire di conseguenza. event UpdatedMessages(string oldStr, string newStr); - // Declares a state variable `message` of type `string`. - // Le variabili di stato sono variabili con valori memorizzati in modo permanente nello spazio di archiviazione (storage) del contratto. The keyword `public` makes variables accessible from outside a contract and creates a function that other contracts or clients can call to access the value. + // Dichiara una variabile di stato `message` di tipo `string`. + // Le variabili di stato sono variabili i cui valori sono memorizzati in modo permanente nella memoria del contratto. La parola chiave `public` rende le variabili accessibili dall'esterno di un contratto e crea una funzione che altri contratti o client possono chiamare per accedere al valore. string public message; - // Similar to many class-based object-oriented languages, a constructor is a special function that is only executed upon contract creation. - // I costruttori sono utilizzati per inizializzare i dati del contratto. Learn more:https://solidity.readthedocs.io/en/v0.5.10/contracts.html#constructors + // Simile a molti linguaggi orientati agli oggetti basati su classi, un costruttore è una funzione speciale che viene eseguita solo alla creazione del contratto. + // I costruttori sono usati per inizializzare i dati del contratto. Per saperne di più:https://solidity.readthedocs.io/en/v0.5.10/contracts.html#constructors constructor(string memory initMessage) { - // Accepts a string argument `initMessage` and sets the value into the contract's `message` storage variable). + // Accetta un argomento stringa `initMessage` e imposta il valore nella variabile di archiviazione `message` del contratto). message = initMessage; } - // A public function that accepts a string argument and updates the `message` storage variable. + // Una funzione pubblica che accetta un argomento stringa e aggiorna la variabile di archiviazione `message`. function update(string memory newMessage) public { string memory oldMsg = message; message = newMessage; @@ -1187,15 +1069,12 @@ contract HelloWorld { } ``` +Gli eventi del contratto intelligente sono un modo per il contratto di comunicare che è successo qualcosa (cioè che c'è stato un _evento_) sulla blockchain alla tua applicazione front-end, che può essere 'in ascolto' di eventi specifici e agire quando si verificano. -Gli eventi del contratto intelligente sono un modo per il contratto di comunicare che è successo qualcosa (cioè che c'è stato un _evento_) sulla blockchain alla tua applicazione front-end, che può essere "in ascolto" per eventi specifici e agire quando si verificano. - -La funzione `addSmartContractListener` sarà in ascolto specificamente per l'evento `UpdatedMessages` del nostro contratto intelligente Hello World e aggiornerà l'interfaccia utente per visualizzare il nuovo messaggio. +La funzione `addSmartContractListener` sarà specificamente in ascolto dell'evento `UpdatedMessages` del nostro contratto intelligente Hello World, e aggiornerà la nostra interfaccia utente per visualizzare il nuovo messaggio. Modifica `addSmartContractListener` come segue: - - ```javascript // HelloWorld.js @@ -1206,21 +1085,18 @@ function addSmartContractListener() { } else { setMessage(data.returnValues[1]) setNewMessage("") - setStatus("🎉 Your message has been updated!") + setStatus("🎉 Il tuo messaggio è stato aggiornato!") } }) } ``` - Analizziamo cosa succede quando il listener rileva un evento: -- Se si verifica un errore quando viene emesso l'evento, questo si rifletterà nell'interfaccia utente tramite la variabile di stato `status`. -- Altrimenti, si utilizzerà l'oggetto `data` restituito. `data.returnValues` è un array indicizzato a zero in cui il primo elemento dell'array memorizza il messaggio precedente e il secondo quello aggiornato. Complessivamente, in caso di evento concluso con successo, imposteremo la stringa `message` con il messaggio aggiornato, cancelleremo la stringa `newMessage` e aggiorneremo la variabile di stato `status` per rispecchiare il fatto che un nuovo messaggio è stato pubblicato sul nostro contratto intelligente. - -Infine, chiamiamo il nostro listener nella funzione `useEffect`, in modo che venga inizializzato al primo rendering del componente `HelloWorld.js`. Complessivamente, la funzione `useEffect` dovrebbe avere questo aspetto: - +- Se si verifica un errore quando viene emesso l'evento, questo si rifletterà nell'interfaccia utente tramite la nostra variabile di stato `status`. +- Altrimenti, useremo l'oggetto `data` restituito. `data.returnValues` è un array indicizzato a zero in cui il primo elemento dell'array memorizza il messaggio precedente e il secondo elemento quello aggiornato. Complessivamente, in caso di evento concluso con successo, imposteremo la nostra stringa `message` con il messaggio aggiornato, cancelleremo la stringa `newMessage` e aggiorneremo la nostra variabile di stato `status` per riflettere il fatto che un nuovo messaggio è stato pubblicato sul nostro contratto intelligente. +Infine, chiamiamo il nostro listener nella nostra funzione `useEffect` in modo che sia inizializzato al primo rendering del componente `HelloWorld.js`. Complessivamente, la tua funzione `useEffect` dovrebbe avere questo aspetto: ```javascript // HelloWorld.js @@ -1232,64 +1108,46 @@ useEffect(async () => { }, []) ``` +Ora che siamo in grado di leggere dal nostro contratto intelligente, sarebbe bello capire anche come scrivergli! Tuttavia, per scrivere sulla nostra dApp, dobbiamo prima avere un portafoglio Ethereum collegato ad essa. -Ora che siamo in grado di leggere dal nostro contratto intelligente, sarebbe bello anche capire come scrivergli! Tuttavia, per scrivere alla nostra dapp, dobbiamo prima avere un portafoglio di Ethereum collegato ad essa. - -Quindi, ora ci occuperemo di configurare il nostro portafoglio di Ethereum (MetaMask) e di collegarlo alla nostra dapp! - - - -### Fase 4: configura il tuo portafoglio di Ethereum {#step-4-set-up-your-ethereum-wallet} +Quindi, ora ci occuperemo di configurare il nostro portafoglio Ethereum (MetaMask) e di collegarlo alla nostra dApp! -Per scrivere qualsiasi cosa nella catena di Ethereum, gli utenti devono firmare le transazioni utilizzando le chiavi private del proprio portafoglio virtuale. Per questo tutorial, utilizzeremo [MetaMask](https://metamask.io/), un portafoglio virtuale nel browser utilizzato per gestire l'indirizzo del conto di Ethereum, in quanto rende la firma delle transazioni molto semplice per l'utente finale. - -Se vuoi capire di più su come funzionano le transazioni su Ethereum, dai un'occhiata a [questa pagina](/developers/docs/transactions/) della Ethereum Foundation. +### Passaggio 4: Configura il tuo portafoglio Ethereum {#step-4-set-up-your-ethereum-wallet} +Per scrivere qualsiasi cosa sulla chain di Ethereum, gli utenti devono firmare le transazioni utilizzando le chiavi private del proprio portafoglio virtuale. Per questo tutorial, utilizzeremo [MetaMask](https://metamask.io/), un portafoglio virtuale nel browser utilizzato per gestire l'indirizzo del tuo account Ethereum, poiché rende la firma delle transazioni estremamente semplice per l'utente finale. +Se vuoi saperne di più su come funzionano le transazioni su Ethereum, consulta [questa pagina](/developers/docs/transactions/) della Ethereum Foundation. #### Scarica MetaMask {#download-metamask} -Puoi scaricare e creare gratuitamente un conto di MetaMask [qui](https://metamask.io/download). Quando crei un conto, o se ne possiedi già uno, assicurati di passare alla "rete di prova di Goerli" in alto a destra \(così da non avere a che fare con denaro reale\). - - - -#### Aggiungere ether da un Faucet {#add-ether-from-a-faucet} - -Per firmare una transazione sulla blockchain di Ethereum, abbiamo bisogno di un po' di Eth finti. Per ottenere Eth puoi andare su [FaucETH](https://fauceth.komputing.org) e inserire l'indirizzo del tuo conto di Goerli, cliccare su "Richiedi fondi", quindi selezionare "Rete di prova di Ethereum di Goerli" nel menu a discesa e infine fare clic di nuovo su "Richiedi fondi". Poco dopo, dovresti vedere gli Eth nel tuo conto di MetaMask! - +Puoi scaricare e creare un account MetaMask gratuitamente [qui](https://metamask.io/download). Quando crei un account, o se ne hai già uno, assicurati di passare alla “Rete di test Goerli” in alto a destra (in modo da non usare soldi veri). +#### Aggiungi ether da un Faucet {#add-ether-from-a-faucet} -#### Verifica il tuo saldo {#check-your-balance} - -Per ricontrollare che ci sia il saldo, facciamo una richiesta [eth_getBalance](https://docs.alchemyapi.io/alchemy/documentation/alchemy-api-reference/json-rpc#eth_getbalance) usando lo [strumento compositore di Alchemy](https://composer.alchemyapi.io/?composer_state=%7B%22network%22%3A0%2C%22methodName%22%3A%22eth_getBalance%22%2C%22paramValues%22%3A%5B%22%22%2C%22latest%22%5D%7D). Questo restituirà l'importo di Eth nel tuo portafoglio. Dopo aver inserito l'indirizzo del tuo conto di MetaMask e aver cliccato “Invia richiesta”, dovresti vedere una risposta come questa: +Per firmare una transazione sulla blockchain di Ethereum, avremo bisogno di Eth finti. Per ottenere Eth puoi andare su [FaucETH](https://fauceth.komputing.org) e inserire l'indirizzo del tuo account Goerli, fare clic su “Richiedi fondi”, quindi selezionare “Rete di test Goerli di Ethereum” nel menu a tendina e infine fare clic di nuovo sul pulsante “Richiedi fondi”. Poco dopo, dovresti vedere gli Eth nel tuo conto di MetaMask! +#### Controlla il tuo saldo {#check-your-balance} +Per verificare che il nostro saldo sia presente, effettuiamo una richiesta [eth_getBalance](https://docs.alchemyapi.io/alchemy/documentation/alchemy-api-reference/json-rpc#eth_getbalance) usando lo [strumento compositore di Alchemy](https://composer.alchemyapi.io/?composer_state=%7B%22network%22%3A0%2C%22methodName%22%3A%22eth_getBalance%22%2C%22paramValues%22%3A%5B%22%22%2C%22latest%22%5D%7D). Questo restituirà l'importo di Eth nel tuo portafoglio. Dopo aver inserito l'indirizzo del tuo conto di MetaMask e aver cliccato "Invia Richiesta", dovresti visualizzare una risposta simile alla seguente: ```text {"jsonrpc": "2.0", "id": 0, "result": "0xde0b6b3a7640000"} ``` - -**NOTA:** Questo risultato è in wei non in eth. Wei è usato come taglio più piccolo dell'ether. La conversione da wei a eth è: 1 eth = 10¹⁸ wei. Quindi se convertiamo 0xde0b6b3a7640000 in decimali, otteniamo 1\*10¹⁸, pari a 1 eth. +**NOTA:** questo risultato è in wei, non in eth. Wei è usato come taglio più piccolo dell'ether. La conversione da wei a eth è: 1 eth = 10¹⁸ wei. Quindi se convertiamo 0xde0b6b3a7640000 in decimali, otteniamo 1\*10¹⁸, pari a 1 eth. Meno male! I nostri soldi finti ci sono tutti! 🤑 - - -### Fase 5: connetti MetaMask alla tua interfaccia utente {#step-5-connect-metamask-to-your-UI} +### Passaggio 5: Collega MetaMask alla tua UI {#step-5-connect-metamask-to-your-UI} Ora che il nostro portafoglio di MetaMask è configurato, connettiamo la nostra dapp! - - #### La funzione `connectWallet` {#the-connectWallet-function} -Nel nostro file `interact.js`, implementiamo la funzione `connectWallet`, che poi potremo chiamare nel nostro componente `HelloWorld.js`. +Nel nostro file `interact.js`, implementiamo la funzione `connectWallet`, che potremo poi chiamare nel nostro componente `HelloWorld.js`. Modifichiamo `connectWallet` come segue: - - ```javascript // interact.js @@ -1300,7 +1158,7 @@ export const connectWallet = async () => { method: "eth_requestAccounts", }) const obj = { - status: "👆🏽 Write a message in the text-field above.", + status: "👆🏽 Scrivi un messaggio nel campo di testo qui sopra.", address: addressArray[0], } return obj @@ -1318,7 +1176,7 @@ export const connectWallet = async () => {

{" "} 🦊 - You must install MetaMask, a virtual Ethereum wallet, in your + Devi installare MetaMask, un portafoglio Ethereum virtuale, nel tuo browser.

@@ -1329,66 +1187,56 @@ export const connectWallet = async () => { } ``` +Quindi, cosa fa esattamente questo enorme blocco di codice? -Cosa fa esattamente questo enorme blocco di codice? - -Innanzitutto, controlla se `window.ethereum` sia abilitato nel browser. +Beh, per prima cosa, controlla se `window.ethereum` è abilitato nel tuo browser. -`window.ethereum` è un'API globale, iniettata da MetaMask e altri fornitori di portafogli, che consente ai siti web di richiedere i conti di Ethereum degli utenti. Se approvato, può leggere i dati dalle blockchain a cui l'utente è connesso e suggerire all'utente di firmare messaggi e transazioni. Dai un'occhiata alla [documentazione di MetaMask](https://docs.metamask.io/guide/ethereum-provider.html#table-of-contents) per ulteriori informazioni! +`window.ethereum` è un'API globale iniettata da MetaMask e da altri provider di portafogli che consente ai siti web di richiedere gli account Ethereum degli utenti. Se approvato, può leggere i dati dalle blockchain a cui l'utente è connesso e suggerire all'utente di firmare messaggi e transazioni. Consulta la [documentazione di MetaMask](https://docs.metamask.io/guide/ethereum-provider.html#table-of-contents) per maggiori informazioni! -Se `window.ethereum` _non è_ presente, significa che MetaMask non è installato. Verrà quindi restituito un oggetto JSON in cui l'`address` restituito è una stringa vuota e l'oggetto JSX di `status` indica che l'utente deve installare MetaMask. +Se `window.ethereum` _non è_ presente, significa che MetaMask non è installato. Questo restituisce un oggetto JSON, in cui l'`address` restituito è una stringa vuota e l'oggetto JSX `status` comunica che l'utente deve installare MetaMask. -Ora, se `window.ethereum` _è_ presente, le cose cominciano a farsi interessanti. +Ora, se `window.ethereum` _è_ presente, è qui che le cose si fanno interessanti. -Usando una struttura try/catch, proveremo a connetterci a MetaMask chiamando [`window.ethereum.request({ method: "eth_requestAccounts" });`](https://docs.metamask.io/guide/rpc-api.html#eth-requestaccounts). Chiamare questa funzione aprirà MetaMask nel browser, dove sarà richiesto all'utente di connettere il proprio portafoglio alla tua dapp. +Usando un ciclo try/catch, proveremo a connetterci a MetaMask chiamando [`window.ethereum.request({ method: "eth_requestAccounts" });`](https://docs.metamask.io/guide/rpc-api.html#eth-requestaccounts). Chiamare questa funzione aprirà MetaMask nel browser, dove sarà richiesto all'utente di connettere il proprio portafoglio alla tua dapp. -- Se l'utente sceglie di connettersi, il `method: "eth_requestAccounts"` restituirà un array contenente gli indirizzi di tutti gli account dell'utente connessi alla dapp. Nel complesso, la nostra funzione `connectWallet` restituirà un oggetto JSON contenente il _primo_ `address` in questo array \(vedi la riga 9\) e un messaggio di `status` che richiede all'utente di scrivere un messaggio nello smart contract. -- Se l'utente rifiuta la connessione, allora l'oggetto JSON conterrà una stringa vuota per l'`address` restituito e un messaggio di `status` che indica che l'utente ha rifiutato la connessione. +- Se l'utente sceglie di connettersi, `method: "eth_requestAccounts"` restituirà un array contenente gli indirizzi di tutti gli account dell'utente connessi alla dApp. Complessivamente, la nostra funzione `connectWallet` restituirà un oggetto JSON che contiene il _primo_ `address` in questo array (vedi riga 9) e un messaggio di `status` che chiede all'utente di scrivere un messaggio allo smart contract. +- Se l'utente rifiuta la connessione, l'oggetto JSON conterrà una stringa vuota per l'`address` restituito e un messaggio `status` che riflette il rifiuto della connessione da parte dell'utente. Ora che abbiamo scritto questa funzione `connectWallet`, il passo successivo è chiamarla nel nostro componente `HelloWorld.js`. - - -#### Aggiungi la funzione `connectWallet` al componente dell'interfaccia utente `HelloWorld.js` {#add-the-connectWallet-function-to-your-HelloWorld-js-ui-component} +#### Aggiungi la funzione `connectWallet` al tuo componente UI `HelloWorld.js` {#add-the-connectWallet-function-to-your-HelloWorld-js-ui-component} Vai alla funzione `connectWalletPressed` in `HelloWorld.js` e aggiornala come segue: - - ```javascript -/ HelloWorld.js +// HelloWorld.js -const c= async () => { +const connectWalletPressed = async () => { const walletResponse = await connectWallet() setStatus(walletResponse.status) setWallet(walletResponse.address) } ``` +Noti come la maggior parte della nostra funzionalità sia astratta dal nostro componente `HelloWorld.js` e si trovi nel file `interact.js`? Questo perché stiamo seguendo il modello M-V-C! -Nota come gran parte della nostra funzionalità è esterna al nostro componente `HelloWorld.js` dal file `interact.js`? Questo perché stiamo seguendo il modello M-V-C! +In `connectWalletPressed`, creiamo semplicemente una chiamata `await` alla nostra funzione `connectWallet` importata e, usando la sua risposta, aggiorniamo le nostre variabili `status` e `walletAddress` tramite i loro hook di stato. -In `connectWalletPressed`, creiamo semplicemente una chiamata d'attesa alla nostra funzione `connectWallet` importata e, usando la sua risposta, aggiorniamo le nostre variabili `status` e `walletAddress` tramite i loro hook di stato. - -Ora salviamo entrambi i file \(`HelloWorld.js` e `interact.js`\) e testiamo la nostra interfaccia utente. +Ora, salviamo entrambi i file (`HelloWorld.js` e `interact.js`) e testiamo la nostra interfaccia utente finora. Apri il browser sulla pagina [http://localhost:3000/](http://localhost:3000/) e premi il pulsante "Connetti portafoglio" in alto a destra della pagina. Se hai MetaMask installato, ti dovrebbe essere richiesto di connettere il tuo portafoglio alla tua dapp. Accetta l'invito a connetterti. -Dovresti vedere che il pulsante del portafoglio ora mostra che il tuo indirizzo è connesso! Sììììì 🔥 - -Prova quindi a ricaricare la pagina... questo è strano. Il nostro pulsante del portafoglio ci sta richiedendo di connetterci a MetaMask, anche se è già connesso... - -Tuttavia, non temere! Possiamo facilmente risolvere questo problema implementando `getCurrentWalletConnected`, che verificherà se un indirizzo è già connesso alla nostra dapp e aggiornerà l'interfaccia utente di conseguenza! +Dovresti vedere che il pulsante del portafoglio ora riflette che il tuo indirizzo è connesso! Fantasticooo 🔥 +Prova quindi a ricaricare la pagina... strano. Il nostro pulsante del portafoglio ci sta richiedendo di connetterci a MetaMask, anche se è già connesso... +Tuttavia, non temere! Possiamo facilmente risolvere questo problema! Implementando `getCurrentWalletConnected`, che verificherà se un indirizzo è già connesso alla nostra dApp e aggiornerà l'interfaccia utente di conseguenza! #### La funzione `getCurrentWalletConnected` {#the-getcurrentwalletconnected-function} -Aggiorna la funzione `getCurrentWalletConnected` nel file `interact.js` come segue: - - +Aggiorna la tua funzione `getCurrentWalletConnected` nel file `interact.js` come segue: ```javascript // interact.js @@ -1402,12 +1250,12 @@ export const getCurrentWalletConnected = async () => { if (addressArray.length > 0) { return { address: addressArray[0], - status: "👆🏽 Write a message in the text-field above.", + status: "👆🏽 Scrivi un messaggio nel campo di testo qui sopra.", } } else { return { address: "", - status: "🦊 Connect to MetaMask using the top right button.", + status: "🦊 Connettiti a MetaMask usando il pulsante in alto a destra.", } } } catch (err) { @@ -1424,7 +1272,7 @@ export const getCurrentWalletConnected = async () => {

{" "} 🦊 - You must install MetaMask, a virtual Ethereum wallet, in your + Devi installare MetaMask, un portafoglio Ethereum virtuale, nel tuo browser.

@@ -1435,14 +1283,11 @@ export const getCurrentWalletConnected = async () => { } ``` +Questo codice è _molto_ simile alla funzione `connectWallet` che abbiamo appena scritto nel passaggio precedente. -Questo codice è _molto_ simile alla funzione `connectWallet` che abbiamo appena scritto nella fase precedente. - -La differenza principale è che, invece di chiamare il metodo `eth_requestAccounts`, che apre MetaMask perché l'utente connetta il proprio portafoglio, qui chiamiamo il metodo `eth_accounts` che, semplicemente, restituisce un insieme contenente gli indirizzi di MetaMask correntemente connessi alla nostra dapp. - -Per vedere questa funzione in azione, chiamiamola nella funzione `useEffect` del nostro componente `HelloWorld.js`: - +La differenza principale è che, invece di chiamare il metodo `eth_requestAccounts`, che apre MetaMask perché l'utente connetta il proprio portafoglio, qui chiamiamo il metodo `eth_accounts` che, semplicemente, restituisce un array contenente gli indirizzi di MetaMask correntemente connessi alla nostra dApp. +Per vedere questa funzione in azione, chiamiamola nella nostra funzione `useEffect` del nostro componente `HelloWorld.js`: ```javascript // HelloWorld.js @@ -1458,14 +1303,11 @@ useEffect(async () => { }, []) ``` - Nota che stiamo usando la risposta alla nostra chiamata a `getCurrentWalletConnected` per aggiornare le nostre variabili di stato `walletAddress` e `status`. -Ora che abbiamo aggiunto questo codice, proviamo ad aggiornare la finestra del browser. - -Bellooooo! Il pulsante dovrebbe dire che sei connesso e mostrare un'anteprima dell'indirizzo del tuo portafoglio connesso, anche dopo un refresh! - +Ora che hai aggiunto questo codice, proviamo ad aggiornare la finestra del browser. +Benissimoooo! Il pulsante dovrebbe dire che sei connesso e mostrare un'anteprima dell'indirizzo del tuo portafoglio connesso, anche dopo un refresh! #### Implementa `addWalletListener` {#implement-addwalletlistener} @@ -1473,8 +1315,6 @@ Il passaggio finale della configurazione del portafoglio della nostra dapp è im Nel tuo file `HelloWorld.js`, modifica la tua funzione `addWalletListener` come segue: - - ```javascript // HelloWorld.js @@ -1483,10 +1323,10 @@ function addWalletListener() { window.ethereum.on("accountsChanged", (accounts) => { if (accounts.length > 0) { setWallet(accounts[0]) - setStatus("👆🏽 Write a message in the text-field above.") + setStatus("👆🏽 Scrivi un messaggio nel campo di testo qui sopra.") } else { setWallet("") - setStatus("🦊 Connect to MetaMask using the top right button.") + setStatus("🦊 Connettiti a MetaMask usando il pulsante in alto a destra.") } }) } else { @@ -1494,7 +1334,7 @@ function addWalletListener() {

{" "} 🦊 - You must install MetaMask, a virtual Ethereum wallet, in your browser. + Devi installare MetaMask, un portafoglio Ethereum virtuale, nel tuo browser.

) @@ -1502,16 +1342,13 @@ function addWalletListener() { } ``` +Scommetto che a questo punto non hai nemmeno bisogno del nostro aiuto per capire cosa sta succedendo, ma per completezza, analizziamolo rapidamente: -Scommetto che a questo punto non hai bisogno del nostro aiuto per capire cosa succede qui, ma per completezza di informazioni, vediamo di analizzare velocemente la situazione: - -- Per prima cosa, la nostra funzione verifica se `window.ethereum` è abilitata \(cioè se MetaMask è installato\). - - Se non lo è, impostiamo semplicemente la nostra variabile di stato `status`a una stringa JSX che richiede all'utente di installare MetaMask. - - Se è abilitato, configuriamo l'ascoltatore `window.ethereum.on("accountsChanged")` alla riga 3, affinché ascolti i cambiamenti di stato nel portafoglio di MetaMask, tra cui, quando l'utente connette un ulteriore conto alla dapp, cambia conto, o ne disconnette uno. Se è connesso almeno un conto, la variabile di stato `walletAddress` è aggiornata come primo conto nell'insieme `accounts`, restituito dall'ascoltatore. Altrimenti, `walletAddress` è impostato come una stringa vuota. - -Infine ma non meno importante, dobbiamo chiamare la funzione `useEffect`: - +- Innanzitutto, la nostra funzione controlla se `window.ethereum` è abilitato (cioè se MetaMask è installato). + - In caso contrario, impostiamo semplicemente la nostra variabile di stato `status` su una stringa JSX che richiede all'utente di installare MetaMask. + - Se è abilitato, configuriamo l'ascoltatore `window.ethereum.on("accountsChanged")` alla riga 3, affinché ascolti i cambiamenti di stato nel portafoglio di MetaMask, tra cui, quando l'utente connette un ulteriore account alla dApp, cambia account, o ne disconnette uno. Se è connesso almeno un account, la variabile di stato `walletAddress` è aggiornata come primo account nell'array `accounts`, restituito dall'ascoltatore. Altrimenti, `walletAddress` è impostato come una stringa vuota. +Infine, ma non meno importante, dobbiamo chiamarla nella nostra funzione `useEffect`: ```javascript // HelloWorld.js @@ -1529,30 +1366,23 @@ useEffect(async () => { }, []) ``` - E questo è tutto! Abbiamo completato con successo la programmazione di tutte le funzionalità del nostro portafoglio! Passiamo ora all'ultimo compito: aggiornare il messaggio memorizzato nel contratto intelligente! +### Passaggio 6: Implementa la funzione `updateMessage` {#step-6-implement-the-updateMessage-function} - -### Fase 6: implementa la funzione `updateMessage` {#step-6-implement-the-updateMessage-function} - -Bene, siamo in dirittura d'arrivo! Nel `updateMessage` del tuo file `interact.js`, faremo quanto segue: +Bene, siamo in dirittura d'arrivo! In `updateMessage` del tuo file `interact.js`, faremo quanto segue: 1. Assicurarci che il messaggio che vogliamo pubblicare nel nostro contratto intelligente sia valido 2. Firmare la transazione usando MetaMask -3. Chiamare questa funzione dal componente del frontend `HelloWorld.js` - -Non ci vorrà molto; finiamo questa dapp! - +3. Chiamare questa funzione dal nostro componente frontend `HelloWorld.js` +Non ci vorrà molto; finiamo questa dApp! -#### Gestione degli errori d'input {#input-error-handling} - -Naturalmente, è utile avere una certa gestione degli errori di input all'inizio della funzione. - -Vorremo che la nostra funzione ci faccia sapere subito se non c'è un'estensione MetaMask installata, se non c'è un portafoglio connesso \(ossia `address` passato è una stringa vuota\) o se `message` è una stringa vuota. Aggiungiamo la seguente gestione degli errori a `updateMessage`: +#### Gestione degli errori di input {#input-error-handling} +Naturalmente, ha senso avere una qualche forma di gestione degli errori di input all'inizio della funzione. +Vorremo che la nostra funzione termini presto se non è installata alcuna estensione MetaMask, non c'è un portafoglio connesso (cioè, l'`address` passato è una stringa vuota), o il `message` è una stringa vuota. Aggiungiamo la seguente gestione degli errori a `updateMessage`: ```javascript // interact.js @@ -1561,40 +1391,35 @@ export const updateMessage = async (address, message) => { if (!window.ethereum || address === null) { return { status: - "💡 Connect your MetaMask wallet to update the message on the blockchain.", + "💡 Connetti il tuo portafoglio MetaMask per aggiornare il messaggio sulla blockchain.", } } if (message.trim() === "") { return { - status: "❌ Your message cannot be an empty string.", + status: "❌ Il tuo messaggio non può essere una stringa vuota.", } } } ``` +Ora che abbiamo una corretta gestione degli errori di input, è il momento di firmare la transazione tramite MetaMask! -Ora che la gestione degli errori d'input è gestita correttamente, è tempo di firmare la transazione con MetaMask! - - - -#### Firmare la transazione {#signing-our-transaction} - -Se ti senti già a tuo agio con le transazioni web3 di Ethereum tradizionali, il codice che scriveremo in seguito ti risulterà molto familiare. Sotto il tuo codice di gestione degli errori di input, aggiungi quanto segue a `updateMessage`: - +#### Firma della nostra transazione {#signing-our-transaction} +Se hai già familiarità con le transazioni Ethereum web3 tradizionali, il codice che scriveremo di seguito ti sarà molto familiare. Sotto il codice di gestione degli errori di input, aggiungi quanto segue a `updateMessage`: ```javascript // interact.js -//set up transaction parameters +//imposta i parametri della transazione const transactionParameters = { - to: contractAddress, // Required except during contract publications. - from: address, // must match user's active address. + to: contractAddress, // Richiesto tranne durante le pubblicazioni di contratti. + from: address, // deve corrispondere all'indirizzo attivo dell'utente. data: helloWorldContract.methods.update(message).encodeABI(), } -//sign the transaction +//firma la transazione try { const txHash = await window.ethereum.request({ method: "eth_sendTransaction", @@ -1605,11 +1430,11 @@ try { ✅{" "} - View the status of your transaction on Etherscan! + Visualizza lo stato della tua transazione su Etherscan!
- ℹ️ Once the transaction is verified by the network, the message will be - updated automatically. + ℹ️ Una volta che la transazione sarà verificata dalla rete, il messaggio verrà + aggiornato automaticamente.
), } @@ -1620,50 +1445,47 @@ try { } ``` +Analizziamo cosa sta accadendo. Per prima cosa, impostiamo i parametri delle nostre transazioni, dove: -Analizziamo cosa sta accadendo. Per prima cosa importiamo i parametri delle transazioni, dove: - -- `to` specifica l'indirizzo del destinatario \(il nostro smart contract\) -- `from` specifica il firmatario della transazione, la variabile `address` che abbiamo passato nella nostra funzione +- `to` specifica l'indirizzo del destinatario (il nostro smart contract) +- `from` specifica il firmatario della transazione, la variabile `address` che abbiamo passato alla nostra funzione - `data` contiene la chiamata al metodo `update` del nostro contratto intelligente Hello World, ricevendo la nostra variabile stringa `message` come input -Creiamo quindi una chiamata d'attesa, `window.ethereum.request` in cui chiediamo a MetaMask di firmare la transazione. Nota che, alle righe 11 e 12, stiamo specificando il nostro metodo eth, `eth_sendTransaction`, e passando i nostri `transactionParameters`. +Quindi, facciamo una chiamata `await`, `window.ethereum.request`, in cui chiediamo a MetaMask di firmare la transazione. Nota che, alle righe 11 e 12, stiamo specificando il nostro metodo eth, `eth_sendTransaction`, e passando i nostri `transactionParameters`. A questo punto, MetaMask si aprirà nel browser e richiederà all'utente di firmare o rifiutare la transazione. - Se la transazione va a buon fine, la funzione restituirà un oggetto JSON in cui la stringa JSX `status` richiede all'utente di controllare Etherscan per ulteriori informazioni sulla sua transazione. -- Se la transazione non va a buon fine, la funzione restituirà un oggetto JSON in cui la stringa `status` trasmette il messaggio d'errore. +- Se la transazione non va a buon fine, la funzione restituirà un oggetto JSON in cui la stringa `status` trasmette il messaggio di errore. Complessivamente, la nostra funzione `updateMessage` dovrebbe avere questo aspetto: - - ```javascript // interact.js export const updateMessage = async (address, message) => { - //input error handling + //gestione degli errori di input if (!window.ethereum || address === null) { return { status: - "💡 Connect your MetaMask wallet to update the message on the blockchain.", + "💡 Connetti il tuo portafoglio MetaMask per aggiornare il messaggio sulla blockchain.", } } if (message.trim() === "") { return { - status: "❌ Your message cannot be an empty string.", + status: "❌ Il tuo messaggio non può essere una stringa vuota.", } } - //set up transaction parameters + //imposta i parametri della transazione const transactionParameters = { - to: contractAddress, // Required except during contract publications. - from: address, // must match user's active address. + to: contractAddress, // Richiesto tranne durante le pubblicazioni di contratti. + from: address, // deve corrispondere all'indirizzo attivo dell'utente. data: helloWorldContract.methods.update(message).encodeABI(), } - //sign the transaction + //firma la transazione try { const txHash = await window.ethereum.request({ method: "eth_sendTransaction", @@ -1674,11 +1496,11 @@ export const updateMessage = async (address, message) => { ✅{" "} - View the status of your transaction on Etherscan! + Visualizza lo stato della tua transazione su Etherscan!
- ℹ️ Once the transaction is verified by the network, the message will - be updated automatically. + ℹ️ Una volta che la transazione sarà verificata dalla rete, il messaggio + verrà aggiornato automaticamente.
), } @@ -1690,16 +1512,11 @@ export const updateMessage = async (address, message) => { } ``` +Infine, ma non meno importante, dobbiamo connettere la nostra funzione `updateMessage` al nostro componente `HelloWorld.js`. -Infine, ma non meno importante, dobbiamo connettere la nostra funzione`updateMessage` al nostro componente `HelloWorld.js`. - - - -#### Connetti `updateMessage`al frontend `HelloWorld.js` {#connect-updatemessage-to-the-helloworld-js-frontend} - -La nostra funzione `onUpdatePressed` dovrebbe effettuare una chiamata d'attesa alla funzione `updateMessage` importata e modificare la variabile di stato `status` per riflettere se la transazione è andata o meno a buon fine: - +#### Connetti `updateMessage` al frontend `HelloWorld.js` {#connect-updatemessage-to-the-helloworld-js-frontend} +La nostra funzione `onUpdatePressed` dovrebbe effettuare una chiamata `await` alla funzione importata `updateMessage` e modificare la variabile di stato `status` per riflettere se la nostra transazione è andata a buon fine o meno: ```javascript // HelloWorld.js @@ -1710,21 +1527,18 @@ const onUpdatePressed = async () => { } ``` +È super pulito e semplice. E indovina un po'... LA TUA DAPP È COMPLETA!!! -È super chiaro e semplice. E indovina un po'... LA TUA DAPP È COMPLETA!!! - -Prosegui e pova il pulsante **Aggiorna**! - - +Vai avanti e prova il pulsante **Aggiorna**! -### Crea la tua dapp personalizzata {#make-your-own-custom-dapp} +### Crea la tua dApp personalizzata {#make-your-own-custom-dapp} Fantastico, sei arrivato alla fine del tutorial! Per ricapitolare, hai imparato a: -- Collegare un portafoglio di MetaMask al tuo progetto dapp -- Leggere dati da un contratto intelligente usando le API [Web3 di Alchemy](https://docs.alchemy.com/alchemy/documentation/alchemy-web3) +- Collegare un portafoglio MetaMask al tuo progetto dApp +- Leggere i dati dal tuo contratto intelligente usando l'API [Alchemy Web3](https://docs.alchemy.com/alchemy/documentation/alchemy-web3) - Firmare le transazioni di Ethereum usando MetaMask -Ora hai tutti gli strumenti applicare le competenze apprese in questo tutorial per costruire il tuo progetto dapp! Come sempre, se hai domande, non esitare a contattarci per chiedere aiuto sul [Discord di Alchemy](https://discord.gg/gWuC7zB). 🧙‍♂️ +Ora hai tutti gli strumenti per applicare le competenze apprese in questo tutorial per costruire il tuo progetto dApp personalizzato! Come sempre, se hai domande, non esitare a contattarci per chiedere aiuto sul [Discord di Alchemy](https://discord.gg/gWuC7zB). 🧙‍♂️ -Una volta completato questo tutorial, facci sapere come è stata la tua esperienza o se hai qualche feedback taggandoci su Twitter [@alchemyplatform](https://twitter.com/AlchemyPlatform)! +Una volta completato questo tutorial, facci sapere com'è stata la tua esperienza o se hai qualche feedback taggandoci su Twitter [@alchemyplatform](https://twitter.com/AlchemyPlatform)! diff --git a/public/content/translations/it/developers/tutorials/hello-world-smart-contract/index.md b/public/content/translations/it/developers/tutorials/hello-world-smart-contract/index.md index 1c211718dd3..b80ffd1424b 100644 --- a/public/content/translations/it/developers/tutorials/hello-world-smart-contract/index.md +++ b/public/content/translations/it/developers/tutorials/hello-world-smart-contract/index.md @@ -3,73 +3,69 @@ title: Smart Contract "Hello World" per principianti description: Tutorial introduttivo su come scrivere e distribuire un semplice smart contract su Ethereum. author: "elanh" tags: - - "solidity" - - "hardhat" - - "alchemy" - - "smart contract" - - "distribuzione" + [ + "Solidity", + "hardhat", + "alchemy", + "smart contract", + "distribuzione" + ] skill: beginner lang: it published: 2021-03-31 --- -Se hai appena iniziato con lo sviluppo blockchain e non sai da dove cominciare, oppure se sei solo interessato a capire come distribuire e interagire con gli smart contract, questa è la guida che fa al caso tuo. Esamineremo la creazione e la distribuzione di un semplice contratto intelligente sulla rete di prova di Goerli, utilizzando un portafoglio virtuale di [MetaMask](https://metamask.io/), [Solidity](https://docs.soliditylang.org/en/v0.8.0/), [Hardhat](https://hardhat.org/) e [Alchemy](https://alchemyapi.io/eth) (non preoccuparti se non capisci cosa significhi, lo spiegheremo). +Se hai appena iniziato con lo sviluppo blockchain e non sai da dove cominciare, oppure se sei solo interessato a capire come distribuire e interagire con gli smart contract, questa è la guida che fa al caso tuo. Esamineremo la creazione e la distribuzione di un semplice contratto intelligente sulla rete di test Sepolia, utilizzando un portafoglio virtuale [MetaMask](https://metamask.io/), [Solidity](https://docs.soliditylang.org/en/v0.8.0/), [Hardhat](https://hardhat.org/) e [Alchemy](https://www.alchemy.com/eth) (non preoccuparti se non capisci ancora cosa significhi, lo spiegheremo). -> **Attenzione** -> -> 🚧 Avviso di obsolescenza -> -> Per l'intera guida, la rete di test Goerli viene utilizzata per creare e distribuire un contratto intelligente. Tuttavia, tieni presente che la Ethereum Foundation ha annunciato che [Goerli sarà presto abbandonata](https://www.alchemy.com/blog/goerli-faucet-deprecation). -> -> Ti consigliamo di utilizzare [Sepolia](https://sepoliafaucet.com/) e il [faucet di Sepolia](https://www.alchemy.com/overviews/sepolia-testnet) per questo tutorial. - -Nella [parte 2](https://docs.alchemy.com/docs/interacting-with-a-smart-contract) di questo tutorial, esamineremo come possiamo interagire con il nostro contratto intelligente una volta distribuito e, nella [parte 3](https://docs.alchemy.com/docs/submitting-your-smart-contract-to-etherscan), copriremo come pubblicarlo su Etherscan. +Nella [parte 2](https://docs.alchemy.com/docs/interacting-with-a-smart-contract) di questo tutorial vedremo come interagire con il nostro smart contract una volta distribuito, e nella [parte 3](https://www.alchemy.com/docs/submitting-your-smart-contract-to-etherscan) tratteremo come pubblicarlo su Etherscan. Se in qualsiasi momento hai domande, non esitare a contattarci nel [Discord di Alchemy](https://discord.gg/gWuC7zB)! -## Fase 1: connettersi alla rete di Ethereum {#step-1} +## Fase 1: Connettersi alla rete di Ethereum {#step-1} + +Esistono molti modi per effettuare richieste alla catena di Ethereum. Per semplicità, ci serviremo di un conto gratuito su Alchemy, una piattaforma per sviluppatori di blockchain e API che ci consentirà di comunicare con la catena di Ethereum senza dover operare i nostri nodi. La piattaforma offre anche strumenti per sviluppatori per il monitoraggio e l'analisi di cui ci serviremo in questo tutorial per comprendere cosa succede dietro le quinte durante la distribuzione del nostro smart contract. Se non possiedi già un conto di Alchemy, [puoi iscriverti gratuitamente qui](https://dashboard.alchemy.com/signup). -Esistono molti modi per effettuare richieste alla catena di Ethereum. Per semplicità, ci serviremo di un conto gratuito su Alchemy, una piattaforma per sviluppatori di blockchain e API che ci consentirà di comunicare con la catena di Ethereum senza dover operare i nostri nodi. La piattaforma offre anche strumenti di analisi e monitoraggio di cui ci serviremo in questo tutorial per comprendere al meglio l'andamento della distribuzione del nostro smart contract. Se non possiedi già un conto di Alchemy, [puoi iscriverti gratuitamente qui](https://dashboard.alchemyapi.io/signup). +## Fase 2: Crea la tua app (e chiave API) {#step-2} -## Fase 2: crea la tua app (e chiave API) {#step-2} +Una volta creato un conto di Alchemy, puoi generare una chiave API creando un'app. Questo ci consentirà di effettuare richieste alla rete di prova di Sepolia. Se non hai familiarità con le reti di test, dai un'occhiata a [questa pagina](/developers/docs/networks/). -Una volta creato un conto di Alchemy, puoi generare una chiave API creando un'app. Questo ci permetterà di effettuare delle richieste alla rete di prova di Goerli. Se non hai familiarità con le reti di prova, dai un'occhiata a [questa pagina](/developers/docs/networks/). +1. Vai alla pagina "Crea nuova app" nella tua dashboard di Alchemy selezionando "Seleziona un'app" nella barra di navigazione e cliccando "Crea nuova app" -1. Vai alla pagina “Crea App” nella tua dashboard di Alchemy passando su “App” nella barra di navigazione e cliccando “Crea App” +![Crea app Hello world](./hello-world-create-app.png) -![Creare l'app Hello world](./hello-world-create-app.png) +2. Dai un nome alla tua app, "Hello World", fornisci una breve descrizione e scegli un caso d'uso, ad esempio, "Infrastruttura e strumenti." Successivamente, cerca "Ethereum" e seleziona la rete. -2. Denomina la tua app "Ciao Mondo", offri una breve descrizione, seleziona "Staging" per l'Ambiente (utilizzato per la contabilità della tua app) e scegli "Goerli" per la tua rete. +![visualizzazione crea app hello world](./create-app-view-hello-world.png) -![Vista della creazione dell'app Hello world](./create-app-view-hello-world.png) +3. Fai clic su "Next" per procedere, quindi su "Create app" e il gioco è fatto! La tua app dovrebbe apparire nel menu a tendina della barra di navigazione, con una Chiave API disponibile per la copia. -3. Clicca “Create app” ed è tutto! La tua app dovrebbe apparire nella tabella sottostante. +## Fase 3: Crea un conto Ethereum (indirizzo) {#step-3} -## Fase 3: Crea un conto di Ethereum (indirizzo) {#step-3} +Per inviare e ricevere le transazioni, necessitiamo di un conto di Ethereum. Per questo tutorial, utilizzeremo MetaMask, un portafoglio virtuale nel browser, utilizzato per gestire l'indirizzo del tuo conto di Ethereum. Maggiori informazioni sulle [transazioni](/developers/docs/transactions/). -Per inviare e ricevere le transazioni, necessitiamo di un conto di Ethereum. Per questo tutorial, useremo MetaMask, un portafoglio virtuale nel browser per gestire l'indirizzo del tuo conto di Ethereum. Maggiori informazioni sulle [transazioni](/developers/docs/transactions/). +Puoi scaricare MetaMask e creare un conto Ethereum gratuito [qui](https://metamask.io/download). Quando crei un conto, o se ne hai già uno, assicurati di passare alla rete di test "Sepolia" utilizzando il menu a tendina della rete (in modo da non avere a che fare con denaro reale). -Puoi scaricare e creare gratuitamente un conto di MetaMask [qui](https://metamask.io/download). Quando crei un account, o se ne possiedi già uno, assicurati di passare alla "rete di prova di Goerli" in alto a destra (così da non avere a che fare con denaro reale). +Se non vedi Sepolia nell'elenco, vai nel menu, quindi su Avanzate e scorri verso il basso per attivare l'opzione "Mostra reti di test". Nel menu di selezione della rete, scegli la scheda "Personalizzata" per trovare un elenco di reti di test e seleziona "Sepolia." -![esempio ropsten metamask](./metamask-ropsten-example.png) +![esempio metamask sepolia](./metamask-sepolia-example.png) -## Fase 4: aggiungi ether da un Faucet {#step-4} +## Fase 4: Aggiungi ether da un faucet {#step-4} -Per poter distribuire il nostro contratto intelligente alla rete di prova, avremo bisogno di degli ETH finti. Per ottenere degli ETH, puoi andare al [faucet di Goerli](https://goerlifaucet.com/), accedere al tuo conto di Alchemy e inserire l'indirizzo del tuo portafoglio, cliccando poi su "Inviami gli ETH". Potrebbe volerci del tempo per ricevere i tuoi ETH finti, a causa del traffico della rete. (Al momento della scrittura di questo tutorial, ci sono voluti circa 30 minuti.) Dovresti vedere i tuoi ETH nel tuo conto di Metamask dopo qualche minuto! +Per distribuire il nostro smart contract sulla rete di test, avremo bisogno di Eth finti. Per ottenere ETH di Sepolia, puoi andare ai [dettagli della rete Sepolia](/developers/docs/networks/#sepolia) per visualizzare un elenco di vari faucet. Se uno non funziona, provane un altro perché a volte possono esaurirsi. Potrebbe essere necessario un po' di tempo per ricevere i tuoi ETH finti a causa del traffico di rete. Dovresti vedere gli ETH nel tuo conto MetaMask poco dopo! -## Fase 5: controlla il saldo {#step-5} +## Fase 5: Controlla il tuo saldo {#step-5} -Per ricontrollare che ci sia il saldo, facciamo una richiesta [eth_getBalance](https://docs.alchemyapi.io/alchemy/documentation/alchemy-api-reference/json-rpc#eth_getbalance) usando lo [strumento compositore di Alchemy](https://composer.alchemyapi.io?composer_state=%7B%22network%22%3A0%2C%22methodName%22%3A%22eth_getBalance%22%2C%22paramValues%22%3A%5B%22%22%2C%22latest%22%5D%7D). Questo restituirà l'importo di ETH nel nostro portafoglio. Dopo aver inserito l'indirizzo del tuo conto di MetaMask e aver cliccato su “Invia Richiesta”, dovresti vedere una risposta come questa: +Per verificare che il nostro saldo sia presente, effettuiamo una richiesta [eth_getBalance](/developers/docs/apis/json-rpc/#eth_getbalance) utilizzando lo [strumento composer di Alchemy](https://sandbox.alchemy.com/?network=ETH_SEPOLIA&method=eth_getBalance&body.id=1&body.jsonrpc=2.0&body.method=eth_getBalance&body.params%5B0%5D=&body.params%5B1%5D=latest). Questo restituirà l'importo di ETH nel nostro portafoglio. Dopo aver inserito l'indirizzo del tuo conto di MetaMask e aver cliccato "Invia Richiesta", dovresti visualizzare una risposta simile alla seguente: ```json { "jsonrpc": "2.0", "id": 0, "result": "0x2B5E3AF16B1880000" } ``` -> **NOTA:** questo risultato è in wei non in ETH. Wei è usato come taglio più piccolo dell'ether. La conversione da wei a ETH è: 1 eth = 1018 wei. Quindi se convertiamo 0x2B5E3AF16B1880000 in decimali, otteniamo 5\*10¹⁸, pari a 5 ETH. +> **NOTA:** questo risultato è in wei, non in ETH. Wei è usato come taglio più piccolo dell'ether. La conversione da wei a ETH è: 1 eth = 1018 wei. Quindi, se convertiamo 0x2B5E3AF16B1880000 in decimale, otteniamo 5\*10¹⁸, che equivale a 5 ETH. > > Meno male! I nostri soldi finti ci sono tutti . -## Fase 6: inizializza il progetto {#step-6} +## Fase 6: Inizializza il nostro progetto {#step-6} Prima, dovremo creare una cartella per il nostro progetto. Vai alla riga di comando e digita: @@ -78,18 +74,18 @@ mkdir hello-world cd hello-world ``` -Ora che siamo nella cartella del nostro progetto, useremo `npm init` per inizializzare il progetto. Se non hai già installato npm, segui [queste istruzioni](https://docs.alchemyapi.io/alchemy/guides/alchemy-for-macs#1-install-nodejs-and-npm) (avremo bisogno anche di Node.js, quindi scarica anche questo!). +Ora che siamo all'interno della nostra cartella del progetto, useremo `npm init` per inizializzare il progetto. Se non hai già installato npm, segui [queste istruzioni](https://docs.alchemyapi.io/alchemy/guides/alchemy-for-macs#1-install-nodejs-and-npm) (avremo bisogno anche di Node.js, quindi scarica anche quello!). ``` npm init ``` -Non è rilevante come rispondi alle domande d'installazione, ecco le nostre risposte come esempio: +Non è molto importante come rispondi alle domande di installazione, ecco come abbiamo fatto noi come riferimento: ``` package name: (hello-world) version: (1.0.0) -description: hello world smart contract +description: contratto intelligente hello world entry point: (index.js) test command: git repository: @@ -101,31 +97,31 @@ About to write to /Users/.../.../.../hello-world/package.json: { "name": "hello-world", "version": "1.0.0", - "description": "hello world smart contract", + "description": "contratto intelligente hello world", "main": "index.js", "scripts": { - "test": "echo \\"Error: no test specified\\" && exit 1" + "test": "echo \"Errore: nessun test specificato\\" && exit 1" }, "author": "", "license": "ISC" } ``` -Approva il package.json e siamo pronti! +Approva il file package.json e siamo pronti a partire! ## Fase 7: Scarica [Hardhat](https://hardhat.org/getting-started/#overview) {#step-7} Hardhat è un ambiente di sviluppo per compilare, distribuire, testare ed effettuare il debug del tuo software di Ethereum. Aiuta gli sviluppatori nella costruzione di contratti intelligenti e dapp localmente, prima di distribuirli alla catena. -Nel nostro progetto `hello-world` esegui: +All'interno del nostro progetto `hello-world`, esegui: ``` npm install --save-dev hardhat ``` -Dai un'occhiata a questa pagina per ulteriori dettagli sulle [istruzioni d'installazione](https://hardhat.org/getting-started/#overview). +Consulta questa pagina per maggiori dettagli sulle [istruzioni di installazione](https://hardhat.org/getting-started/#overview). -## Fase 8: crea un progetto Hardhat {#step-8} +## Fase 8: Crea un progetto Hardhat {#step-8} Nella cartella del nostro progetto esegui: @@ -145,17 +141,17 @@ Dovresti poi vedere un messaggio di benvenuto e l'opzione per selezionare cosa d 888 888 888 888 888 Y88b 888 888 888 888 888 Y88b. 888 888 "Y888888 888 "Y88888 888 888 "Y888888 "Y888 -👷 Welcome to Hardhat v2.0.11 👷‍? +👷 Benvenuto in Hardhat v2.0.11 👷‍? -What do you want to do? … -Create a sample project -❯ Create an empty hardhat.config.js -Quit +Cosa vuoi fare? … +Crea un progetto di esempio +❯ Crea un hardhat.config.js vuoto +Esci ``` -Questo genererà un file `hardhat.config.js`, in cui specificheremo tutta la configurazione per il nostro progetto (alla fase 13). +Questo genererà per noi un file `hardhat.config.js`, in cui specificheremo tutta la configurazione del nostro progetto (nella fase 13). -## Fase 9: aggiungi le cartelle del progetto {#step-9} +## Fase 9: Aggiungi le cartelle del progetto {#step-9} Per mantenere organizzato il nostro progetto creeremo due nuove cartelle. Vai alla cartella di root del tuo progetto nella tua riga di comando e digita: @@ -164,55 +160,55 @@ mkdir contracts mkdir scripts ``` -- `contracts/` è dove manterremo il file del codice del nostro smart contract hello world -- `scripts/` è dove manterremo gli script per distribuire e interagire con il nostro contratto +- `contracts/` è dove conserveremo il file del codice del nostro smart contract hello world +- `scripts/` è dove conserveremo gli script per distribuire e interagire con il nostro contratto -## Fase 10: compila il nostro contratto {#step-10} +## Fase 10: Scrivi il nostro contratto {#step-10} -Potresti chiederti, quando diavolo scriviamo il codice? Beh, eccoci qui, alla fase 10. +Ti starai chiedendo, ma quando diavolo scriviamo il codice?? Beh, eccoci qui, alla fase 10. -Apri il progetto hello-world nel tuo editor preferito (a noi piace [VSCode](https://code.visualstudio.com/)). Gli smart contract sono scritti in un linguaggio detto Solidity, che useremo per scrivere il nostro smart contract HelloWorld.sol. +Apri il progetto hello-world nel tuo editor preferito (a noi piace [VSCode](https://code.visualstudio.com/)). Gli smart contract sono scritti in un linguaggio chiamato Solidity, che useremo per scrivere il nostro smart contract HelloWorld.sol.‌ -1. Vai alla cartella "contracts" e crea un nuovo file chiamato HelloWorld.sol -2. Di seguito, un esempio dello smart contract Hello World dalla Ethereum Foundation che useremo per questo tutorial. Copia e incolla i contenuti seguenti nel tuo file HelloWorld.sol e assicurati di leggere i commenti per comprendere cosa fa il contratto: +1. Vai alla cartella "contracts" e crea un nuovo file chiamato HelloWorld.sol +2. Di seguito è riportato un esempio di smart contract Hello World della Ethereum Foundation che useremo per questo tutorial. Copia e incolla i contenuti sottostanti nel tuo file HelloWorld.sol e assicurati di leggere i commenti per capire cosa fa questo contratto: ```solidity -// Specifica la versione di Solidity, utilizzando il controllo delle versioni semantico. -// Learn more: https://solidity.readthedocs.io/en/v0.5.10/layout-of-source-files.html#pragma +// Specifica la versione di Solidity, utilizzando il versioning semantico. +// Per saperne di più: https://solidity.readthedocs.io/en/v0.5.10/layout-of-source-files.html#pragma pragma solidity ^0.7.0; -// Defines a contract named `HelloWorld`. -// Un contratto è una raccolta di funzioni e dati (il suo stato). Once deployed, a contract resides at a specific address on the Ethereum blockchain. Learn more: https://solidity.readthedocs.io/en/v0.5.10/structure-of-a-contract.html +// Definisce un contratto chiamato `HelloWorld`. +// Un contratto è una raccolta di funzioni e dati (il suo stato). Una volta distribuito, un contratto risiede a un indirizzo specifico sulla blockchain di Ethereum. Per saperne di più: https://solidity.readthedocs.io/en/v0.5.10/structure-of-a-contract.html contract HelloWorld { - // Declares a state variable `message` of type `string`. - // Le variabili di stato sono variabili con valori memorizzati in modo permanente nello spazio di archiviazione (storage) del contratto. The keyword `public` makes variables accessible from outside a contract and creates a function that other contracts or clients can call to access the value. + // Dichiara una variabile di stato `message` di tipo `string`. + // Le variabili di stato sono variabili i cui valori sono memorizzati in modo permanente nella memoria del contratto. La parola chiave `public` rende le variabili accessibili dall'esterno di un contratto e crea una funzione che altri contratti o client possono chiamare per accedere al valore. string public message; - // Similar to many class-based object-oriented languages, a constructor is a special function that is only executed upon contract creation. - // I costruttori sono utilizzati per inizializzare i dati del contratto. Learn more:https://solidity.readthedocs.io/en/v0.5.10/contracts.html#constructors + // Simile a molti linguaggi orientati agli oggetti basati su classi, un costruttore è una funzione speciale che viene eseguita solo alla creazione del contratto. + // I costruttori sono usati per inizializzare i dati del contratto. Per saperne di più:https://solidity.readthedocs.io/en/v0.5.10/contracts.html#constructors constructor(string memory initMessage) { - // Accepts a string argument `initMessage` and sets the value into the contract's `message` storage variable). + // Accetta un argomento di tipo stringa `initMessage` e imposta il valore nella variabile di archiviazione `message` del contratto). message = initMessage; } - // A public function that accepts a string argument and updates the `message` storage variable. + // Una funzione pubblica che accetta un argomento di tipo stringa e aggiorna la variabile di archiviazione `message`. function update(string memory newMessage) public { message = newMessage; } } ``` -Questo è uno smart contract semplicissimo che memorizza un messaggio alla creazione ed è aggiornabile chiamando la funzione `update`. +Questo è uno smart contract molto semplice che memorizza un messaggio alla sua creazione e può essere aggiornato chiamando la funzione `update`. -## Fase 11: connetti MetaMask e Alchemy al tuo progetto {#step-11} +## Fase 11: Connetti MetaMask e Alchemy al tuo progetto {#step-11} -Abbiamo creato un portafoglio di MetaMask, un conto di Alchemy e scritto il nostro contratto intelligente; è arrivato il momento di collegarli. +Abbiamo creato un portafoglio MetaMask, un conto Alchemy e scritto il nostro smart contract, ora è il momento di collegare i tre. Ogni transazione inviata dal tuo portafoglio virtuale richiede una firma tramite la tua chiave privata unica. Per fornire al nostro programma quest'autorizzazione, possiamo memorizzare in sicurezza la nostra chiave privata (e la chiave API di Alchemy) in un file ambientale. -> Per saperne di più sull'invio delle transazioni, dai un'occhiata a [questo tutorial](/developers/tutorials/sending-transactions-using-web3-and-alchemy/) sull'invio di transazioni usando web3. +> Per saperne di più sull'invio di transazioni, consulta [questa guida](/developers/tutorials/sending-transactions-using-web3-and-alchemy/) sull'invio di transazioni tramite web3. Prima, installa il pacchetto dotenv nella cartella del tuo progetto: @@ -220,37 +216,37 @@ Prima, installa il pacchetto dotenv nella cartella del tuo progetto: npm install dotenv --save ``` -Poi, crea un file `.env` nella cartella di root del nostro progetto e aggiungi la tua chiave privata di MetaMask e l'URL API di Alchemy HTTP. +Quindi, crea un file `.env` nella directory principale del nostro progetto e aggiungici la tua chiave privata di MetaMask e l'URL dell'API HTTP di Alchemy. -- Segui [queste istruzioni](https://metamask.zendesk.com/hc/en-us/articles/360015289632-How-to-Export-an-Account-Private-Key) per esportare la tua chiave privata -- Vedi sotto per ottenere l'URL dell'API di Alchemy HTTP +- Segui [queste istruzioni](https://support.metamask.io/configure/accounts/how-to-export-an-accounts-private-key/) per esportare la tua chiave privata +- Vedi di seguito per ottenere l'URL dell'API HTTP di Alchemy -![ottieni la chiave api di alchemy](./get-alchemy-api-key.gif) +![ottenere la chiave api di alchemy](./get-alchemy-api-key.png) Copia l'URL dell'API di Alchemy -Il tuo `.env` dovrebbe somigliare a questo: +Il tuo file `.env` dovrebbe avere questo aspetto: ``` -API_URL = "https://eth-goerli.alchemyapi.io/v2/your-api-key" +API_URL = "https://eth-sepolia.g.alchemy.com/v2/your-api-key" PRIVATE_KEY = "your-metamask-private-key" ``` -Per connetterli realmente al nostro codice, faremo riferimento a queste variabili nel nostro file `hardhat.config.js` nella fase 13. +Per collegarli effettivamente al nostro codice, faremo riferimento a queste variabili nel nostro file `hardhat.config.js` nella fase 13. -Non eseguire il commit di .env! Assicurati di non condividere o esporre mai il tuo file .env con nessuno, poiché così facendo comprometteresti i tuoi segreti. Se stai usando il controllo di versione, aggiungi il tuo .env a un file gitignore. +Non eseguire il commit di .env! Assicurati di non condividere o esporre mai il tuo file .env a nessuno, poiché così facendo comprometteresti i tuoi segreti. Se stai usando un sistema di controllo di versione, aggiungi il tuo file .env a un file .gitignore. -## Fase 12: installa Ethers.js {#step-12-install-ethersjs} +## Fase 12: Installa Ethers.js {#step-12-install-ethersjs} -Ethers.js è una libreria che rende più facile interagire ed effettuare richieste a Ethereum tramite wrapping dei [metodi JSON-RPC standard](/developers/docs/apis/json-rpc/) con altri metodi più facili da usare. +Ethers.js è una libreria che semplifica l'interazione e l'invio di richieste a Ethereum, eseguendo il wrapping dei [metodi JSON-RPC standard](/developers/docs/apis/json-rpc/) con metodi più intuitivi. -Hardhat rende davvero facile integrare [Plugin](https://hardhat.org/plugins/) per strumenti e funzionalità aggiuntive. Sfrutteremo il [plugin di Ethers](https://hardhat.org/docs/plugins/official-plugins#hardhat-ethers) per la distribuzione del contratto ([Ethers.js](https://github.com/ethers-io/ethers.js/) ha dei metodi di distribuzione del contratto molto puliti). +Hardhat rende semplicissima l'integrazione di [Plugin](https://hardhat.org/plugins/) per strumenti aggiuntivi e funzionalità estese. Approfitteremo del [plugin Ethers](https://hardhat.org/docs/plugins/official-plugins#hardhat-ethers) per la distribuzione dei contratti ([Ethers.js](https://github.com/ethers-io/ethers.js/) ha dei metodi di distribuzione dei contratti molto puliti). Nella cartella del tuo progetto digita: @@ -258,13 +254,13 @@ Nella cartella del tuo progetto digita: npm install --save-dev @nomiclabs/hardhat-ethers "ethers@^5.0.0" ``` -Avremo bisogno di ethers anche nel nostro `hardhat.config.js` nella prossima fase. +Richiederemo anche ethers nel nostro `hardhat.config.js` nel prossimo passo. -## Fase 13: aggiorna hardhat.config.js {#step-13-update-hardhatconfigjs} +## Fase 13: Aggiorna hardhat.config.js {#step-13-update-hardhatconfigjs} Finora abbiamo aggiunto diverse dipendenze e plugin, ora dobbiamo aggiornare `hardhat.config.js` in modo che il nostro progetto li riconosca tutti. -Aggiorna il tuo `hardhat.config.js` affinché somigli a questo: +Aggiorna il tuo `hardhat.config.js` perché abbia questo aspetto: ``` require('dotenv').config(); @@ -277,10 +273,10 @@ const { API_URL, PRIVATE_KEY } = process.env; */ module.exports = { solidity: "0.7.3", - defaultNetwork: "goerli", + defaultNetwork: "sepolia", networks: { hardhat: {}, - goerli: { + sepolia: { url: API_URL, accounts: [`0x${PRIVATE_KEY}`] } @@ -288,9 +284,9 @@ module.exports = { } ``` -## Fase 14: compila il contratto {#step-14-compile-our-contracts} +## Fase 14: Compila il nostro contratto {#step-14-compile-our-contracts} -Per assicurarti che tutto funzioni fino a questo punto, compila il contratto. L'attività di `compilazione` è una delle attività integrate di hardhat. +Per assicurarti che tutto funzioni fino a questo punto, compila il contratto. L'attività `compile` è una delle attività integrate di hardhat. Dalla riga di comando esegui: @@ -298,21 +294,21 @@ Dalla riga di comando esegui: npx hardhat compile ``` -Potresti ottenere un avviso sull'assenza `nel file sorgente dell'identificativo della licenza SPDX`, ma non preoccupartene, si spera che tutto il resto funzioni! Altrimenti, puoi sempre inviare un messaggio nel [Discord di Alchemy](https://discord.gg/u72VCg3). +Potresti ricevere un avviso `SPDX license identifier not provided in source file`, ma non c'è da preoccuparsi — si spera che tutto il resto vada bene! In caso contrario, puoi sempre inviare un messaggio nel [discord di Alchemy](https://discord.gg/u72VCg3). -## Fase 15: scrivi lo script di distribuzione {#step-15-write-our-deploy-scripts} +## Fase 15: Scrivi il nostro script di distribuzione {#step-15-write-our-deploy-scripts} Ora che il nostro contratto è scritto e il nostro file di configurazione è pronto, è il momento di scrivere lo script di distribuzione del contratto. -Vai alla cartella `script/` e crea un nuovo file chiamato `deploy.js`, aggiungendo i seguenti contenuti: +Vai alla cartella `scripts/` e crea un nuovo file chiamato `deploy.js`, aggiungendovi i seguenti contenuti: ``` async function main() { const HelloWorld = await ethers.getContractFactory("HelloWorld"); - // Start deployment, returning a promise that resolves to a contract object + // Inizia la distribuzione, restituendo una promessa che si risolve in un oggetto contratto const hello_world = await HelloWorld.deploy("Hello World!"); - console.log("Contract deployed to address:", hello_world.address);} + console.log("Contratto distribuito all'indirizzo:", hello_world.address);} main() .then(() => process.exit(0)) @@ -322,48 +318,50 @@ main() }); ``` -Nel suo [tutorial sui Contratti](https://hardhat.org/tutorial/testing-contracts.html#writing-tests) hardhat spiega in modo eccellente cosa fa ognuna di queste righe di codice nel loro, quindi riportiamo qui le loro spiegazioni. +Hardhat spiega molto bene cosa fa ciascuna di queste righe di codice nella sua [Guida ai contratti](https://hardhat.org/tutorial/testing-contracts.html#writing-tests), e qui abbiamo adottato le sue spiegazioni. ``` const HelloWorld = await ethers.getContractFactory("HelloWorld"); ``` -Un `ContractFactory` su ethers.js è un'astrazione usata per distribuire nuovi smart contract, quindi `HelloWorld` qui è una fabbrica di istanze del nostro contratto hello world. Usando il plugin `hardhat-ethers`, le istanze `ContractFactory` e `Contract` sono connesse di default al primo firmatario. +Una `ContractFactory` in ethers.js è un'astrazione usata per distribuire nuovi smart contract, quindi `HelloWorld` qui è una factory per le istanze del nostro contratto hello world. Quando si utilizza il plugin `hardhat-ethers`, le istanze di `ContractFactory` e `Contract` sono collegate di default al primo firmatario. ``` const hello_world = await HelloWorld.deploy(); ``` -Chiamare `deploy()` su un `ContractFactory` avvierà la distribuzione e restituirà un `Promise` che si risolve in un `Contract`. Questo è l'oggetto che ha un metodo per ciascuna delle funzioni del nostro smart contract. +Chiamare `deploy()` su una `ContractFactory` avvierà la distribuzione e restituirà una `Promise` che si risolve in un `Contract`. Questo è l'oggetto che ha un metodo per ciascuna delle funzioni del nostro smart contract. -## Fase 16: distribuisci il contratto {#step-16-deploy-our-contract} +## Fase 16: Distribuisci il nostro contratto {#step-16-deploy-our-contract} Siamo finalmente pronti a distribuire il nostro smart contract! Vai alla riga di comando ed esegui: ``` -npx hardhat run scripts/deploy.js --network goerli +npx hardhat run scripts/deploy.js --network sepolia ``` Vorrai poi vedere qualcosa del genere: ``` -Contract deployed to address: 0x6cd7d44516a20882cEa2DE9f205bF401c0d23570 +Contratto distribuito all'indirizzo: 0x6cd7d44516a20882cEa2DE9f205bF401c0d23570 ``` -Se andiamo all'[Etherscan di Goerli](https://goerli.etherscan.io/) e cerchiamo l'indirizzo del nostro contratto, dovremmo poter vedere che è stato distribuito correttamente. La transazione somiglierà a questa: +Se andiamo su [Etherscan di Sepolia](https://sepolia.etherscan.io/) e cerchiamo l'indirizzo del nostro contratto, dovremmo essere in grado di vedere che è stato distribuito con successo. La transazione somiglierà a questa: ![contratto etherscan](./etherscan-contract.png) -L'indirizzo `From` dovrebbe corrispondere all'indirizzo del tuo conto di MetaMask e, l'indirizzo To indicherà la "Creazione del Contratto"; ma cliccando sulla transazione, vedremo l'indirizzo del nostro contratto nel campo `To`: +L'indirizzo `From` dovrebbe corrispondere all'indirizzo del tuo conto MetaMask e l'indirizzo To indicherà “Creazione del Contratto”, ma se facciamo clic sulla transazione vedremo l'indirizzo del nostro contratto nel campo `To`: ![transazione etherscan](./etherscan-transaction.png) -Congratulazioni! Hai appena distribuito uno smart contract nella chain di Ethereum +Congratulazioni! Hai appena distribuito uno smart contract sulla chain di Ethereum 🎉 -Per capire cosa sta succedendo, andiamo alla scheda Explorer nel nostro [dashboard di Alchemy](https://dashboard.alchemyapi.io/explorer). Se hai diverse app di Alchemy, assicurati di filtrare per app e selezionare "Hello World". ![explorer hello world](./hello-world-explorer.png) +Per capire cosa sta succedendo dietro le quinte, vai alla scheda Explorer nella nostra [dashboard di Alchemy](https://dashboard.alchemyapi.io/explorer). Se hai più app di Alchemy, assicurati di filtrare per app e selezionare “Hello World”. +![explorer hello world](./hello-world-explorer.png) -Qui vedrai numerose chiamate a JSON-RPC che Hardhat/Ethers ha effettuato per noi quando abbiamo chiamato la funzione `.deploy()`. Due funzioni importanti da chiamare qui sono [`eth_sendRawTransaction`](https://docs.alchemyapi.io/alchemy/documentation/alchemy-api-reference/json-rpc#eth_sendrawtransaction), che è la richiesta per scrivere effettivamente il nostro contratto sulla catena di Goerli, e [`eth_getTransactionByHash`](https://docs.alchemyapi.io/alchemy/documentation/alchemy-api-reference/json-rpc#eth_gettransactionbyhash), che è una richiesta di leggere le informazioni sulla nostra transazione, dato l'hash (uno schema tipico nelle transazioni). Per saperne di più sull'invio delle transazioni, dai un'occhiata a questo tutorial [ sull'invio di transazioni usando web3](/developers/tutorials/sending-transactions-using-web3-and-alchemy/) +Qui vedrai una manciata di chiamate JSON-RPC che Hardhat/Ethers hanno fatto per noi dietro le quinte quando abbiamo chiamato la funzione `.deploy()`. Due importanti da segnalare qui sono [`eth_sendRawTransaction`](https://www.alchemy.com/docs/node/abstract/abstract-api-endpoints/eth-send-raw-transaction), che è la richiesta per scrivere effettivamente il nostro contratto sulla catena di Sepolia, e [`eth_getTransactionByHash`](https://www.alchemy.com/docs/node/abstract/abstract-api-endpoints/eth-get-transaction-by-hash), che è una richiesta per leggere informazioni sulla nostra transazione dato l'hash (un modello tipico quando si effettuano +transazioni). Per saperne di più sull'invio di transazioni, consulta questo tutorial su [come inviare transazioni usando Web3](/developers/tutorials/sending-transactions-using-web3-and-alchemy/) -Questo è tutto per la parte 1 di questo tutorial, nella parte 2, [interagiremo realmente con il nostro smart contract](https://docs.alchemyapi.io/alchemy/tutorials/hello-world-smart-contract#part-2-interact-with-your-smart-contract) aggiornando il nostro messaggio iniziale e nella parte 3 [pubblicheremo il nostro smart contract su Etherscan](https://docs.alchemyapi.io/alchemy/tutorials/hello-world-smart-contract#optional-part-3-publish-your-smart-contract-to-etherscan), così che tutti sapranno come interagire con esso. +Questo è tutto per la parte 1 di questo tutorial, nella [parte 2](https://www.alchemy.com/docs/interacting-with-a-smart-contract) interagiremo effettivamente con il nostro smart contract aggiornando il nostro messaggio iniziale, e nella [parte 3](https://www.alchemy.com/docs/submitting-your-smart-contract-to-etherscan) pubblicheremo il nostro smart contract su Etherscan in modo che tutti sappiano come interagire con esso. -**Vuoi saperne di più su Alchemy? Dai un'occhiata al nostro [sito web](https://alchemyapi.io/eth). Non vuoi mai perderti un aggiornamento? Iscriviti alla nostra newsletter [qui](https://www.alchemyapi.io/newsletter)! Assicurati anche di seguire il nostro [Twitter](https://twitter.com/alchemyplatform) e di unirti al nostro [Discord](https://discord.com/invite/u72VCg3)**. +**Vuoi saperne di più su Alchemy?** Visita il nostro [sito web](https://www.alchemy.com/eth). Non vuoi perderti nessun aggiornamento? Iscriviti alla nostra newsletter [qui](https://www.alchemy.com/newsletter)! Assicurati di unirti anche al nostro [Discord](https://discord.gg/u72VCg3).\*\*. diff --git a/public/content/translations/it/developers/tutorials/how-to-implement-an-erc721-market/index.md b/public/content/translations/it/developers/tutorials/how-to-implement-an-erc721-market/index.md index c0ab631254c..d282b5fa2ea 100644 --- a/public/content/translations/it/developers/tutorials/how-to-implement-an-erc721-market/index.md +++ b/public/content/translations/it/developers/tutorials/how-to-implement-an-erc721-market/index.md @@ -2,11 +2,7 @@ title: Come implementare un market ERC-721 description: Come mettere in vendita oggetti tokenizzati su bacheche di annunci decentralizzate author: "Alberto Cuesta Cañada" -tags: - - "smart contract" - - "erc-721" - - "Solidity" - - "token" +tags: [ "Smart Contract", "erc-721", "solidity", "token" ] skill: intermediate lang: it published: 2020-03-19 @@ -26,13 +22,13 @@ Con la blockchain questi mercati sono destinati a cambiare di nuovo, vediamo com Il modello di business di una bacheca di annunci su blockchain pubblica sarà diverso da quello di Ebay e simili. -Prima di tutto, c'è la [questione della decentralizzazione](/developers/docs/web2-vs-web3/). Le piattaforme esistenti devono mantenere i loro server. Una piattaforma decentralizzata è gestita dai suoi utenti, quindi il costo per tenere attiva la piattaforma base scende a zero per il proprietario della piattaforma. +Innanzitutto, c'è [l'aspetto del decentramento](/developers/docs/web2-vs-web3/). Le piattaforme esistenti devono mantenere i loro server. Una piattaforma decentralizzata è gestita dai suoi utenti, quindi il costo per tenere attiva la piattaforma base scende a zero per il proprietario della piattaforma. -Poi c'è il front end, ossia il sito Web o l'interfaccia che dà accesso alla piattaforma. Qua ci sono molte opzioni. Il proprietario della piattaforma può limitare l'accesso e costringere tutti a usare la propria interfaccia, imponendo un costo di utilizzo. I proprietari della piattaforma possono anche decidere di lasciare libero l'accesso (potere al popolo!) e di permettere che chiunque crei interfacce per la piattaforma. Oppure, potrebbero decidere qualsiasi altro tipo di approccio tra questi due estremi. +Poi c'è il front end, ossia il sito Web o l'interfaccia che dà accesso alla piattaforma. Qua ci sono molte opzioni. Il proprietario della piattaforma può limitare l'accesso e costringere tutti a usare la propria interfaccia, imponendo un costo di utilizzo. I proprietari della piattaforma possono anche decidere di aprire l'accesso (Potere al popolo!) e permettere a chiunque di creare interfacce per la piattaforma. Oppure, potrebbero decidere qualsiasi altro tipo di approccio tra questi due estremi. _Chi si occupa di affari e ha più visione di me saprà come monetizzare tutto questo. Tutto quello che io riesco a capire è che questo è diverso dallo status quo e probabilmente redditizio._ -In più, c'è la questione dell'automazione e dei pagamenti. Alcuni articoli si prestano molto ad essere [tokenizzati in modo efficace](https://hackernoon.com/tokenization-of-digital-assets-g0ffk3v8s?ref=hackernoon.com) e scambiati in una bacheca di annunci. Le risorse tokenizzate sono facilmente trasferibili su una blockchain. Metodi di pagamento altamente complessi possono essere facilmente implementati su una blockchain. +In più, c'è la questione dell'automazione e dei pagamenti. Alcune cose possono essere [tokenizzate molto efficacemente](https://hackernoon.com/tokenization-of-digital-assets-g0ffk3v8s?ref=hackernoon.com) e scambiate in una bacheca di annunci. Le risorse tokenizzate sono facilmente trasferibili su una blockchain. Metodi di pagamento altamente complessi possono essere facilmente implementati su una blockchain. Sento odore di business. Una bacheca di annunci senza costi di gestione può facilmente essere implementata con complessi percorsi di pagamento inclusi in ogni transazione. Sono sicuro che qualcuno verrà fuori con qualche idea su come utilizzare tutto questo. @@ -40,9 +36,9 @@ Io sono felice di occuparmi della programmazione. Diamo un'occhiata al codice. ## Implementazione {#implementation} -Un po' di tempo fa abbiamo iniziato un [repository open source](https://github.com/HQ20/contracts?ref=hackernoon.com) con implementazioni di esempio e altre cose interessanti, consiglio di dare una sbirciata. +Qualche tempo fa abbiamo avviato un [repository open source](https://github.com/HQ20/contracts?ref=hackernoon.com) con implementazioni di esempi di casi aziendali e altre cose interessanti, dai un'occhiata. -Il codice di questa [bacheca di annunci Ethereum](https://github.com/HQ20/contracts/tree/master/contracts/classifieds?ref=hackernoon.com) è qui, potete usarlo e anche abusarne. Occhio solo che non è stato verificato e quindi fate molta attenzione prima di metterci dei soldi. +Il codice per questa [Bacheca di Annunci di Ethereum](https://github.com/HQ20/contracts/tree/master/contracts/classifieds?ref=hackernoon.com) è lì, per favore usalo e sfruttalo al massimo. Occhio solo che non è stato verificato e quindi fate molta attenzione prima di metterci dei soldi. Le basi della bacheca non sono difficili. Tutti gli annunci della bacheca saranno semplicemente uno struct con pochi campi: @@ -67,9 +63,9 @@ Usare un mapping significa solo che dobbiamo trovare un ID per ogni annuncio pri La seconda questione è capire quali sono gli elementi con cui lavoriamo e qual è la valuta che deve essere usata per pagare la transazione. -Per gli elementi, chiederemo solo che implementino l'interfaccia [ERC-721](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC721/IERC721.sol?ref=hackernoon.com), che è semplicemente un modo per rappresentare gli oggetti del mondo reale su una blockchain, anche se [funziona meglio con le risorse digitali](https://hackernoon.com/tokenization-of-digital-assets-g0ffk3v8s?ref=hackernoon.com). Specificheremo il nostro contratto ERC271 nel costruttore, dicendo che ogni risorsa della nostra bacheca di annunci deve prima essere tokenizzata. +Per gli articoli, chiederemo solo che implementino l'interfaccia [ERC-721](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC721/IERC721.sol?ref=hackernoon.com), che in realtà è solo un modo per rappresentare oggetti del mondo reale in una blockchain, anche se [funziona meglio con gli asset digitali](https://hackernoon.com/tokenization-of-digital-assets-g0ffk3v8s?ref=hackernoon.com). Specificheremo il nostro contratto ERC271 nel costruttore, dicendo che ogni risorsa della nostra bacheca di annunci deve prima essere tokenizzata. -Per i pagamenti, faremo qualcosa di simile. La maggior parte dei progetti di blockchain definisce la propria criptovaluta [ERC-20](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC20/ERC20.sol?ref=hackernoon.com). Altri preferiscono usarne una popolare come DAI. In questa bacheca di annunci, dovrai solo decidere al momento della creazione quale sarà la tua valuta. Facile. +Per i pagamenti, faremo qualcosa di simile. La maggior parte dei progetti blockchain definisce la propria criptovaluta [ERC-20](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC20/ERC20.sol?ref=hackernoon.com). Altri preferiscono usarne una popolare come DAI. In questa bacheca di annunci, dovrai solo decidere al momento della creazione quale sarà la tua valuta. Facile. ```solidity constructor ( @@ -127,16 +123,16 @@ function cancelTrade(uint256 _trade) Trade memory trade = trades[_trade]; require( msg.sender == trade.poster, - "Trade can be cancelled only by poster." + "Lo scambio può essere annullato solo da chi lo ha pubblicato." ); - require(trade.status == "Open", "Trade is not Open."); + require(trade.status == "Open", "Lo scambio non è Aperto."); itemToken.transferFrom(address(this), trade.poster, trade.item); trades[_trade].status = "Cancelled"; emit TradeStatusChange(_trade, "Cancelled"); } ``` -Ecco qua. Siamo giunti alla fine dell'implementazione. È sorprendente come alcuni concetti di business siano compatti quando vengono espressi con codice, e questo è uno di questi esempi. Guarda il contratto completo [nel nostro repo](https://github.com/HQ20/contracts/blob/master/contracts/classifieds/Classifieds.sol). +Ecco qua. Siamo giunti alla fine dell'implementazione. È sorprendente come alcuni concetti di business siano compatti quando vengono espressi con codice, e questo è uno di questi esempi. Consulta il contratto completo [nel nostro repository](https://github.com/HQ20/contracts/blob/master/contracts/classifieds/Classifieds.sol). ## Conclusione {#conclusion} @@ -146,4 +142,4 @@ Sono anche uno strumento facile da replicare in un ambiente blockchain, con cara In questo articolo ho fatto un tentativo di collegare la realtà delle bacheche di annunci con l'implementazione tecnologica. Queste conoscenze, con le giuste capacità, dovrebbero aiutare a creare una vision e una roadmap per l'implementazione. -Come sempre, se vuoi creare qualcosa di interessante e vorresti qualche consiglio, [scrivimi](https://albertocuesta.es/)! Sono sempre felice di dare una mano. +Come sempre, se vuoi creare qualcosa di interessante e vorresti qualche consiglio, [scrivimi pure](https://albertocuesta.es/)! Sono sempre felice di dare una mano. diff --git a/public/content/translations/it/developers/tutorials/how-to-mint-an-nft/index.md b/public/content/translations/it/developers/tutorials/how-to-mint-an-nft/index.md index bacc5b8b167..369926d711c 100644 --- a/public/content/translations/it/developers/tutorials/how-to-mint-an-nft/index.md +++ b/public/content/translations/it/developers/tutorials/how-to-mint-an-nft/index.md @@ -1,38 +1,36 @@ --- -title: Come coniare un NFT (Parte 2/3 della Serie di tutorial sugli NFT) -description: Questo tutorial descrive come coniare un NFT sulla Blockchain di Ethereum usando il nostro contratto intelligente e Web3. +title: Come coniare un NFT (Parte 2/3 della serie di tutorial sugli NFT) +description: Questo tutorial descrive come coniare un NFT sulla blockchain di Ethereum usando il nostro contratto intelligente e Web3. author: "Sumi Mudgil" -tags: - - "ERC-721" - - "alchemy" - - "solidity" - - "contratti intelligenti" +tags: [ "ERC-721", "alchemy", "Solidity", "smart contract" ] skill: beginner lang: it published: 2021-04-22 --- -[Beeple](https://www.nytimes.com/2021/03/11/arts/design/nft-auction-christies-beeple.html): $69 milioni [3LAU](https://www.forbes.com/sites/abrambrown/2021/03/03/3lau-nft-nonfungible-tokens-justin-blau/?sh=5f72ef64643b): $11 milioni [Grimes](https://www.theguardian.com/music/2021/mar/02/grimes-sells-digital-art-collection-non-fungible-tokens): $6 milioni +[Beeple](https://www.nytimes.com/2021/03/11/arts/design/nft-auction-christies-beeple.html): 69 milioni di dollari +[3LAU](https://www.forbes.com/sites/abrambrown/2021/03/03/3lau-nft-nonfungible-tokens-justin-blau/?sh=5f72ef64643b): 11 milioni di dollari +[Grimes](https://www.theguardian.com/music/2021/mar/02/grimes-sells-digital-art-collection-non-fungible-tokens): 6 milioni di dollari -Tutti loro hanno coniato i propri NFT utilizzando la potente API di Alchemy. In questo tutorial ti insegneremo come fare lo stesso in meno di 10 minuti. +Tutti loro hanno coniato i propri NFT utilizzando la potente API di Alchemy. In questo tutorial ti insegneremo come fare lo stesso in \<10 minuti. -"Coniare un NFT" è l'atto di pubblicare un'istanza unica del tuo token ERC-721 sulla blockchain. Usando il nostro contratto intelligente dalla [Parte 1 di questa serie di tutorial sugli NFT](/developers/tutorials/how-to-write-and-deploy-an-nft/), dimostriamo le nostre abilità di Web3 e coniamo un NFT. Alla fine di questo tutorial, potrai coniare tutti gli NFT che desideri (e che può permettersi il tuo portafoglio)! +"Coniare un NFT" è l'atto di pubblicare un'istanza unica del tuo token ERC-721 sulla blockchain. Usando il nostro contratto intelligente dalla [Parte 1 di questa serie di tutorial sugli NFT](/developers/tutorials/how-to-write-and-deploy-an-nft/), dimostriamo le nostre abilità con Web3 e coniamo un NFT. Alla fine di questo tutorial, potrai coniare tutti gli NFT che desideri (e che può permettersi il tuo portafoglio)! Iniziamo! -## Fase 1: installa Web3 {#install-web3} +## Fase 1: Installare Web3 {#install-web3} -Se hai seguito il primo tutorial sulla creazione del tuo contratto intelligente di NFT, hai già esperienza usando Ethers.js. Web3 è simile a Ethers, trattandosi di una libreria usata per effettuare più facilmente richieste di creazione alla Blockchain di Ethereum. In questo tutorial, useremo [Alchemy Web3](https://docs.alchemyapi.io/alchemy/documentation/alchemy-web3), una libreria Web3 migliorata che offre tentativi automatici e robusto supporto a WebSocket. +Se hai seguito il primo tutorial sulla creazione del tuo contratto intelligente di NFT, hai già esperienza con Ethers.js. Web3 è simile a Ethers, trattandosi di una libreria usata per effettuare più facilmente richieste alla blockchain di Ethereum. In questo tutorial useremo [Alchemy Web3](https://docs.alchemyapi.io/alchemy/documentation/alchemy-web3), una libreria Web3 migliorata che offre tentativi automatici e un solido supporto a WebSocket. -Nella cartella home del tuo progetto, esegui: +Nella cartella principale del tuo progetto, esegui: ``` npm install @alch/alchemy-web3 ``` -## Fase 2: crea un file `mint-nft.js` {#create-mintnftjs} +## Fase 2: Crea un file `mint-nft.js` {#create-mintnftjs} -Nella tua cartella di script, crea un `mint-nft.js` e aggiungi le seguenti righe di codice: +Nella tua cartella degli script, crea un file `mint-nft.js` e aggiungi le seguenti righe di codice: ```js require("dotenv").config() @@ -41,9 +39,9 @@ const { createAlchemyWeb3 } = require("@alch/alchemy-web3") const web3 = createAlchemyWeb3(API_URL) ``` -## Fase 3: prendi l'ABI del tuo contratto {#contract-abi} +## Fase 3: Prendi l'ABI del tuo contratto {#contract-abi} -L'ABI (Interfaccia Binaria dell'Applicazione) del nostro contratto è l'interfaccia per interagire con il nostro contratto intelligente. Puoi saperne di più sull'ABI dei contratti leggi [qui](https://docs.alchemyapi.io/alchemy/guides/eth_getlogs#what-are-ab-is). Hardhat genera automaticamente un'ABI e la salva nel file `MyNFT.json`. Per poterla usare, dovremo analizzare i contenuti aggiungendo le seguenti righe di codice al nostro `mint-nft.js`: +L'ABI (Application Binary Interface) del nostro contratto è l'interfaccia per interagire con il nostro contratto intelligente. Puoi saperne di più sugli ABI dei contratti [qui](https://docs.alchemyapi.io/alchemy/guides/eth_getlogs#what-are-ab-is). Hardhat genera automaticamente un'ABI per noi e la salva nel file `MyNFT.json`. Per poterla usare, dovremo analizzarne i contenuti aggiungendo le seguenti righe di codice al nostro file `mint-nft.js`: ```js const contract = require("../artifacts/contracts/MyNFT.sol/MyNFT.json") @@ -55,69 +53,69 @@ Se vuoi vedere l'ABI, puoi stamparla nella tua console: console.log(JSON.stringify(contract.abi)) ``` -Per eseguire `mint-nft.js` e vedere l'ABI stampata alla console, vai alla console ed esegui: +Per eseguire `mint-nft.js` e vedere la tua ABI stampata sulla console, vai al tuo terminale ed esegui: ```js node scripts/mint-nft.js ``` -## Fase 4: configura i metadati del tuo NFT usando IPFS {#config-meta} +## Fase 4: Configura i metadati del tuo NFT usando IPFS {#config-meta} -Se ti ricordi dal nostro tutorial nella Parte 1, la funzione del nostro contratto intelligente `mintNFT` prende un parametro tokenURl che dovrebbe risolversi a un documento JSON che descrive i metadati del NFT; che è ciò che porta realmente in vita lo NFT, consentendogli di avere proprietà configurabili, come un nome, una descrizione, un'immagine e altri attributi. +Se ricordi dal nostro tutorial nella Parte 1, la funzione del nostro contratto intelligente `mintNFT` riceve un parametro tokenURI, che dovrebbe risolversi in un documento JSON che descrive i metadati dell'NFT, ed è questo che porta realmente in vita l'NFT, consentendogli di avere proprietà configurabili, quali nome, descrizione, immagine e altri attributi. -> _Il Planetary File System (IPFS) è un protocollo decentralizzato e una rete peer-to-peer per memorizzare e condividere i dati in un file di sistema distribuito._ +> _L'Interplanetary File System (IPFS) è un protocollo decentralizzato e una rete peer-to-peer per l'archiviazione e la condivisione di dati in un file system distribuito._ -Useremo Pinata, una comoda API di IPFS e strumento per memorizzare la nostra risorsa NFT e i metadati, per essere sicuri che il nostro NFT sia realmente decentralizzato. Se non hai un conto di Pinata, registrane uno gratuito [qui](https://app.pinata.cloud) e completa i passaggi per verificare la tua email. +Useremo Pinata, una comoda API e un pratico toolkit di IPFS per archiviare le risorse e i metadati del nostro NFT e per garantire che il nostro NFT sia veramente decentralizzato. Se non hai un account Pinata, creane uno gratuito [qui](https://app.pinata.cloud) e completa i passaggi per verificare la tua e-mail. -Una volta creato un conto: +Una volta creato un account: -- Vai alla pagina "File" e clicca il pulsante "Carica" blu in alto a sinistra alla pagina. +- Vai alla pagina "File" e fai clic sul pulsante blu "Carica" in alto a sinistra nella pagina. -- Carica un'immagine su Pinata, sarà la risorsa immagine del tuo NFT. Assegna alla risorsa il nome desideri +- Carica un'immagine su Pinata: sarà la risorsa immagine del tuo NFT. Puoi dare alla risorsa il nome che desideri -- Dopo il caricamento, vedrai le informazioni del file nella tabella sulla pagina "File". Vedrai anche una colonna CID. Puoi copiare il CID cliccando il pulsante di copia accanto. Puoi visualizzare il tuo caricamento su: `https://gateway.pinata.cloud/ipfs/`. Puoi trovare l'immagine che abbiamo usato su IPFS [qui](https://gateway.pinata.cloud/ipfs/QmZdd5KYdCFApWn7eTZJ1qgJu18urJrP9Yh1TZcZrZxxB5), ad esempio. +- Dopo il caricamento, vedrai le informazioni del file nella tabella sulla pagina "File". Vedrai anche una colonna CID. Puoi copiare il CID facendo clic sul pulsante di copia accanto. Puoi visualizzare il file caricato su: `https://gateway.pinata.cloud/ipfs/`. Ad esempio, puoi trovare l'immagine che abbiamo usato su IPFS [qui](https://gateway.pinata.cloud/ipfs/QmZdd5KYdCFApWn7eTZJ1qgJu18urJrP9Yh1TZcZrZxxB5). -Per chi preferisce un apprendimento "visivo", i passaggi sopra sono riassunti qui: +Per chi impara più facilmente con supporti visivi, i passaggi precedenti sono riassunti qui: -![Come caricare l'immagine su Pinata](./instructionsPinata.gif) +![Come caricare la tua immagine su Pinata](./instructionsPinata.gif) -Vogliamo caricare ora un altro documento su Pinata. Ma prima, dobbiamo crearlo! +Ora caricheremo un altro documento su Pinata. Ma prima, dobbiamo crearlo! -Nella tua cartella di root, crea un nuovo file chiamato `nft-metadata.json` e aggiungi il seguente codice json: +Nella tua cartella radice, crea un nuovo file chiamato `nft-metadata.json` e aggiungi il seguente codice json: ```json { "attributes": [ { - "trait_type": "Breed", + "trait_type": "Razza", "value": "Maltipoo" }, { - "trait_type": "Eye color", - "value": "Mocha" + "trait_type": "Colore occhi", + "value": "Moka" } ], - "description": "The world's most adorable and sensitive pup.", + "description": "Il cucciolo più adorabile e sensibile del mondo.", "image": "ipfs://QmWmvTJmJU3pozR9ZHFmQC2DNDwi2XJtf3QGyYiiagFSWb", "name": "Ramses" } ``` -Puoi modificare liberamente i dati nel json. Puoi rimuoverli o aggiungerli alla sezione degli attributi. Soprattutto, assicurati che il campo immagine punti alla posizione della tua immagine IPFS; altrimenti, il tuo NFT includerà la foto di un cane (molto carino!). +Puoi modificare liberamente i dati nel file json. Puoi rimuovere attributi o aggiungerne di nuovi. Soprattutto, assicurati che il campo dell'immagine punti alla posizione della tua immagine IPFS, altrimenti il tuo NFT includerà una foto di un ( carinissimo!) cane. Una volta finito di modificare il file JSON, salvalo e caricalo su Pinata, seguendo gli stessi passaggi di caricamento dell'immagine. -![Come caricare il tuo nft-metadata.json su Pinata](./uploadPinata.gif) +![Come caricare il file nft-metadata.json su Pinata](./uploadPinata.gif) -## Fase 5: crea un'istanza del tuo contratto {#instance-contract} +## Fase 5: Crea un'istanza del tuo contratto {#instance-contract} -Ora, per interagire con il nostro contratto, dobbiamo crearne un'istanza nel nostro codice. Per farlo, avremo bisogno dell'indirizzo del nostro contratto, che possiamo ottenere dalla distribuzione o da [Etherscan](https://sepolia.etherscan.io/), cercando l'indirizzo usato per distribuire il contratto. +Ora, per interagire con il nostro contratto, dobbiamo crearne un'istanza nel nostro codice. Per farlo, avremo bisogno dell'indirizzo del nostro contratto, che possiamo ottenere dalla distribuzione o da [Blockscout](https://eth-sepolia.blockscout.com/) cercando l'indirizzo che hai usato per distribuire il contratto. ![Visualizza l'indirizzo del tuo contratto su Etherscan](./view-contract-etherscan.png) Nell'esempio precedente, l'indirizzo del nostro contratto è 0x5a738a5c5fe46a1fd5ee7dd7e38f722e2aef7778. -Poi useremo il [metodo di contratto](https://docs.web3js.org/api/web3-eth-contract/class/Contract) di Web3 per creare il nostro contratto usando l'ABI e l'indirizzo. Nel tuo file `mint-nft.js`, aggiungi quanto segue: +Successivamente, useremo il [metodo contract](https://docs.web3js.org/api/web3-eth-contract/class/Contract) di Web3 per creare il nostro contratto usando l'ABI e l'indirizzo. Nel tuo file `mint-nft.js`, aggiungi quanto segue: ```js const contractAddress = "0x5a738a5c5fe46a1fd5ee7dd7e38f722e2aef7778" @@ -125,11 +123,11 @@ const contractAddress = "0x5a738a5c5fe46a1fd5ee7dd7e38f722e2aef7778" const nftContract = new web3.eth.Contract(contract.abi, contractAddress) ``` -## Fase 6: aggiorna il file `.env` {#update-env} +## Fase 6: Aggiorna il file `.env` {#update-env} -Ora, per poter creare e inviare le transazioni alla catena di Ethereum, useremo l'indirizzo pubblico del tuo conto di Ethereum per ottenerne il nonce (spiegheremo in seguito). +Ora, per creare e inviare transazioni alla catena di Ethereum, useremo l'indirizzo pubblico del tuo account Ethereum per ottenere il nonce dell'account (lo spiegheremo più avanti). -Aggiungi la tua chiave pubblica al tuo file `.env`; se hai completato la parte 1 del tutorial, il nostro file `.env` dovrebbe somigliare a questo: +Aggiungi la tua chiave pubblica al tuo file `.env`; se hai completato la parte 1 del tutorial, il nostro file `.env` dovrebbe ora avere questo aspetto: ```js API_URL = "https://eth-sepolia.g.alchemy.com/v2/your-api-key" @@ -137,27 +135,27 @@ PRIVATE_KEY = "your-private-account-address" PUBLIC_KEY = "your-public-account-address" ``` -## Fase 7: crea la tua transazione {#create-txn} +## Fase 7: Crea la tua transazione {#create-txn} -Prima di tutto, definiamo una funzione denominata `mintNFT(tokenData)` e creiamo la nostra transazione facendo quanto segue: +Prima di tutto, definiamo una funzione denominata `mintNFT(tokenData)` e creiamo la nostra transazione nel modo seguente: -1. Prendi la tua _PRIVATE_KEY_ e _PUBLIC_KEY_ dal file `.env`. +1. Prendi i tuoi _PRIVATE_KEY_ e _PUBLIC_KEY_ dal file `.env`. -1. Poi, dobbiamo trovare il nonce del conto. La specifica di nonce è usata per tracciare il numero di transazioni inviate dal tuo indirizzo, di cui necessitiamo per motivi di sicurezza e per impedire gli [attacchi di riproduzione](https://docs.alchemyapi.io/resources/blockchain-glossary#account-nonce). Per ottenere il numero di transazioni inviate dal tuo indirizzo, usiamo [getTransactionCount](https://docs.alchemyapi.io/documentation/alchemy-api-reference/json-rpc#eth_gettransactioncount). +2. Successivamente, dovremo ricavare il nonce dell'account. La specifica del nonce è usata per tracciare il numero di transazioni inviate dal tuo indirizzo, di cui necessitiamo per motivi di sicurezza e per impedire gli [attacchi di riproduzione](https://docs.alchemyapi.io/resources/blockchain-glossary#account-nonce). Per ottenere il numero di transazioni inviate dal tuo indirizzo, usiamo [getTransactionCount](https://docs.alchemyapi.io/documentation/alchemy-api-reference/json-rpc#eth_gettransactioncount). -1. Infine, configureremo la nostra transazione con le seguenti informazioni: +3. Infine, configureremo la nostra transazione con le seguenti informazioni: - `'from': PUBLIC_KEY` — L'origine della nostra transazione è il nostro indirizzo pubblico - `'to': contractAddress` — Il contratto con cui vogliamo interagire e a cui vogliamo inviare la transazione -- `'nonce': nonce`: l'account nonce con il numero di transazioni inviate dal nostro indirizzo +- `'nonce': nonce` — Il nonce dell'account con il numero di transazioni inviate dal nostro indirizzo -- `'gas': estimatedGas`: Il gas stimato necessario per completare la transazione +- `'gas': estimatedGas` — Il gas stimato necessario per completare la transazione - `'data': nftContract.methods.mintNFT(PUBLIC_KEY, md).encodeABI()` — Il calcolo che vogliamo eseguire in questa transazione, che in questo caso è il conio di un NFT -Il tuo file `mint-nft.js` dovrebbe somigliare a questo ora: +Il tuo file `mint-nft.js` dovrebbe ora avere questo aspetto: ```js require('dotenv').config(); @@ -173,9 +171,9 @@ Il tuo file `mint-nft.js` dovrebbe somigliare a questo ora: const nftContract = new web3.eth.Contract(contract.abi, contractAddress); async function mintNFT(tokenURI) { - const nonce = await web3.eth.getTransactionCount(PUBLIC_KEY, 'latest'); //get latest nonce + const nonce = await web3.eth.getTransactionCount(PUBLIC_KEY, 'latest'); // ottieni l'ultimo nonce - //the transaction + // la transazione const tx = { 'from': PUBLIC_KEY, 'to': contractAddress, @@ -186,11 +184,11 @@ Il tuo file `mint-nft.js` dovrebbe somigliare a questo ora: }​ ``` -## Fase 8: firma la transazione {#sign-txn} +## Fase 8: Firma la transazione {#sign-txn} -Ora che abbiamo creato la nostra transazione, dobbiamo firmarla per inviarla. Ecco dove useremo la nostra chiave privata. +Ora che abbiamo creato la nostra transazione, dobbiamo firmarla per poterla inviare. Qui è dove useremo la nostra chiave privata. -`web3.eth. endSignedTransaction` ci darà l'hash della transazione, che possiamo usare per assicurarci che la nostra transazione sia stata minata e non sia stata eliminata dalla rete. Noterai nella sezione di firma della transazione che abbiamo aggiunto dei controlli degli errori, per poter sapere se la nostra transazione è passata correttamente. +`web3.eth.sendSignedTransaction` ci darà l'hash della transazione, che possiamo usare per assicurarci che la nostra transazione sia stata minata e non sia stata scartata dalla rete. Noterai che nella sezione di firma della transazione abbiamo aggiunto dei controlli degli errori, per poter sapere se la nostra transazione è andata a buon fine. ```js require("dotenv").config() @@ -206,9 +204,9 @@ const contractAddress = "0x5a738a5c5fe46a1fd5ee7dd7e38f722e2aef7778" const nftContract = new web3.eth.Contract(contract.abi, contractAddress) async function mintNFT(tokenURI) { - const nonce = await web3.eth.getTransactionCount(PUBLIC_KEY, "latest") //get latest nonce + const nonce = await web3.eth.getTransactionCount(PUBLIC_KEY, "latest") // ottieni l'ultimo nonce - //the transaction + // la transazione const tx = { from: PUBLIC_KEY, to: contractAddress, @@ -225,13 +223,13 @@ async function mintNFT(tokenURI) { function (err, hash) { if (!err) { console.log( - "The hash of your transaction is: ", + "L'hash della tua transazione è: ", hash, - "\nCheck Alchemy's Mempool to view the status of your transaction!" + "\nControlla il Mempool di Alchemy per visualizzare lo stato della tua transazione!" ) } else { console.log( - "Something went wrong when submitting your transaction:", + "Qualcosa è andato storto durante l'invio della transazione:", err ) } @@ -239,24 +237,24 @@ async function mintNFT(tokenURI) { ) }) .catch((err) => { - console.log(" Promise failed:", err) + console.log(" Promise non riuscita:", err) }) } ``` -## Fase 9: chiama `mintNFT` ed esegui il nodo `mint-nft.js` {#call-mintnft-fn} +## Fase 9: Chiama `mintNFT` ed esegui `node mint-nft.js` {#call-mintnft-fn} -Ricordi il `metadata.json` che hai caricato su Pinata? Ottieni il suo hashcode da Pinata e passa il seguente come un parametro alla funzione `mintNFT` `https://gateway.pinata.cloud/ipfs/` +Ricordi il file `metadata.json` che hai caricato su Pinata? Ottieni il suo codice hash da Pinata e passalo come parametro alla funzione `mintNFT` `https://gateway.pinata.cloud/ipfs/` -Ecco come ottenere l'hashcode: +Ecco come ottenere il codice hash: -![Come ottenere l'hashcode dei metadati del tuo NFT su Pinata](./metadataPinata.gif)_Come ottenere l'hashcode dei metadati del tuo NFT su Pinata_ +![Come ottenere il codice hash dei metadati del tuo NFT su Pinata](./metadataPinata.gif)_Come ottenere il codice hash dei metadati del tuo NFT su Pinata_ -> Ricontrolla che l'hashcode che hai copiato si colleghi al tuo **metadata.json**, caricando `https://gateway.pinata.cloud/ipfs/` in una finestra separata. La pagina dovrebbe somigliare al seguente screenshot: +> Verifica che il codice hash che hai copiato rimandi al tuo file **metadata.json** caricando `https://gateway.pinata.cloud/ipfs/` in una finestra separata. La pagina dovrebbe avere un aspetto simile allo screenshot qui sotto: -![La tua pagina dovrebbe visualizzare i metadati in json](./metadataJSON.png)_La tua pagina deve mostrare i metadati in json_ +![La tua pagina dovrebbe visualizzare i metadati json](./metadataJSON.png)_La tua pagina dovrebbe visualizzare i metadati json_ -Nel complesso, il tuo codice dovrebbe somigliare a questo: +Nel complesso, il tuo codice dovrebbe avere questo aspetto: ```js require("dotenv").config() @@ -272,9 +270,9 @@ const contractAddress = "0x5a738a5c5fe46a1fd5ee7dd7e38f722e2aef7778" const nftContract = new web3.eth.Contract(contract.abi, contractAddress) async function mintNFT(tokenURI) { - const nonce = await web3.eth.getTransactionCount(PUBLIC_KEY, "latest") //get latest nonce + const nonce = await web3.eth.getTransactionCount(PUBLIC_KEY, "latest") // ottieni l'ultimo nonce - //the transaction + // la transazione const tx = { from: PUBLIC_KEY, to: contractAddress, @@ -291,13 +289,13 @@ async function mintNFT(tokenURI) { function (err, hash) { if (!err) { console.log( - "The hash of your transaction is: ", + "L'hash della tua transazione è: ", hash, - "\nCheck Alchemy's Mempool to view the status of your transaction!" + "\nControlla il Mempool di Alchemy per visualizzare lo stato della tua transazione!" ) } else { console.log( - "Something went wrong when submitting your transaction:", + "Qualcosa è andato storto durante l'invio della transazione:", err ) } @@ -305,26 +303,27 @@ async function mintNFT(tokenURI) { ) }) .catch((err) => { - console.log("Promise failed:", err) + console.log("Promise non riuscita:", err) }) } mintNFT("ipfs://QmYueiuRNmL4MiA2GwtVMm6ZagknXnSpQnB3z2gWbz36hP") ``` -Ora, esegui `scripts/mint-nft.js` per distribuire il tuo NFT. Dopo qualche secondo, dovresti vedere una risposta come questa nel tuo terminale: +Ora, esegui `node scripts/mint-nft.js` per distribuire il tuo NFT. Dopo qualche secondo, dovresti vedere una risposta come questa nel tuo terminale: - L'hash della tua transazione è: - 0x301791fdf492001fcd9d5e5b12f3aa1bbbea9a88ed24993a8ab2cdae2d06e1e8 + ``` + L'hash della tua transazione è: 0x301791fdf492001fcd9d5e5b12f3aa1bbbea9a88ed24993a8ab2cdae2d06e1e8 - Consulta il Mempool di Alchemy per visualizzare lo stato della tua transazione! + Controlla il Mempool di Alchemy per visualizzare lo stato della tua transazione! + ``` -Vai quindi alla tua [mempool di Alchemy](https://dashboard.alchemyapi.io/mempool) per vedere lo stato della transazione (se è sospesa, minata o eliminata dalla rete). Se la tua transazione è stata eliminata, è utile dare un'occhiata anche su [Sepolia Etherscan](https://sepolia.etherscan.io/) e cercare l'hash della tua transazione. +Successivamente, visita il [mempool di Alchemy](https://dashboard.alchemyapi.io/mempool) per vedere lo stato della tua transazione (se è in sospeso, minata o è stata scartata dalla rete). Se la transazione è stata scartata, è utile anche controllare su [Blockscout](https://eth-sepolia.blockscout.com/) e cercare l'hash della transazione. -![Visualizza l'hash della tua transazione NFT su Etherscan](./view-nft-etherscan.png)_Visualizza l'hash della tua transazione NFT su Etherscan_ +![Visualizza l'hash della transazione del tuo NFT su Etherscan](./view-nft-etherscan.png)_Visualizza l'hash della transazione del tuo NFT su Etherscan_ -Ecco fatto! Hai ora distribuito E coniato con un NFT sulla Blockchain di Ethereum +Ecco fatto! Hai distribuito E coniato un NFT sulla blockchain di Ethereum -Utilizzando `mint-nft.js`, puoi coniare quanti NFT il tuo cuore, e portafoglio, desiderino! Basta che ti accerti di passare un nuovo tokenURI che descriva i metadati dell'NFT (altrimenti, finirai per crearne tanti identici con ID differenti). +Utilizzando `mint-nft.js`, puoi coniare quanti NFT il tuo cuore (e portafoglio) desidera! Basta che ti accerti di passare un nuovo tokenURI che descriva i metadati dell'NFT (altrimenti, finirai per crearne tanti identici con ID differenti). -Molto probabilmente vorrai visualizzare il tuo NFT nel tuo portafoglio, quindi assicurati di leggere la [Parte 3: come visualizzare il tuo NFT nel portafoglio](/developers/tutorials/how-to-view-nft-in-metamask/)! +Probabilmente vorrai poter mostrare il tuo NFT nel portafoglio, quindi assicurati di consultare la [Parte 3: Come visualizzare il tuo NFT nel tuo portafoglio](/developers/tutorials/how-to-view-nft-in-metamask/)! diff --git a/public/content/translations/it/developers/tutorials/how-to-mock-solidity-contracts-for-testing/index.md b/public/content/translations/it/developers/tutorials/how-to-mock-solidity-contracts-for-testing/index.md index cec6a7b6dab..fca229e8088 100644 --- a/public/content/translations/it/developers/tutorials/how-to-mock-solidity-contracts-for-testing/index.md +++ b/public/content/translations/it/developers/tutorials/how-to-mock-solidity-contracts-for-testing/index.md @@ -1,30 +1,26 @@ --- title: Come simulare i contratti intelligenti in Solidity per testarli -description: Perché è importante prendersi gioco dei propri contratti in fase di test +description: "Perché è importante prendersi gioco dei propri contratti in fase di test" author: Markus Waas lang: it -tags: - - "solidity" - - "contratti intelligenti" - - "test" - - "simulazione" +tags: [ "Solidity", "smart contract", "test", "simulazione" ] skill: intermediate published: 2020-05-02 source: soliditydeveloper.com sourceUrl: https://soliditydeveloper.com/mocking-contracts --- -[Gli oggetti Mock](https://wikipedia.org/wiki/Mock_object) sono un modello di progettazione comune nella programmazione orientata agli oggetti. Il termine inglese per "simulare" è "to mock", dal francese antico "mocquer" col significato di "prendersi gioco di". Questo significato si è poi evoluto in "imitare qualcosa di reale", che è ciò che in effetti facciamo nella programmazione. Prenditi gioco dei tuoi contratti intelligenti quanto vuoi, ma simulali ogni volta che puoi. Ti semplificherà la vita. +[Oggetti mock](https://wikipedia.org/wiki/Mock_object) sono un modello di progettazione comune nella programmazione orientata agli oggetti. Il termine inglese per "simulare" è "to mock", dal francese antico "mocquer" col significato di "prendersi gioco di". Questo significato si è poi evoluto in "imitare qualcosa di reale", che è ciò che in effetti facciamo nella programmazione. Prenditi gioco dei tuoi contratti intelligenti quanto vuoi, ma simulali ogni volta che puoi. Ti semplificherà la vita. -## Condurre unit test dei contratti con le simulazioni {#unit-testing-contracts-with-mocks} +## Unit test di contratti con mock {#unit-testing-contracts-with-mocks} -Simulare un contratto significa essenzialmente creare una seconda versione di quel contratto che si comporta in modo simile a quello originale, ma in modo che possa essere facilmente controllato dallo sviluppatore. Ci si ritrova spesso con contratti complessi in cui si desidera solo [eseguire unit test di piccole parti del contratto](/developers/docs/smart-contracts/testing/). Ma cosa succede se il test di questa piccola parte richiede uno condizione molto specifica del contratto, difficile da ottenere? +Simulare un contratto significa essenzialmente creare una seconda versione di quel contratto che si comporta in modo simile a quello originale, ma in modo che possa essere facilmente controllato dallo sviluppatore. Spesso ci si ritrova con contratti complessi in cui si desidera solo [eseguire unit test di piccole parti del contratto](/developers/docs/smart-contracts/testing/). Ma cosa succede se il test di questa piccola parte richiede uno condizione molto specifica del contratto, difficile da ottenere? Potresti scrivere una complessa logica di configurazione del test ogni volta che porta il contratto nello stato richiesto o scrivi una simulazione. Simulare un contratto tramite ereditarietà è semplice. Basta creare un secondo contratto simulato che erediti da quello originale. Ora puoi sovrascrivere le funzioni nella tua simulazione. Vediamolo con un esempio. -## Esempio: ERC20 Privato {#example-private-erc20} +## Esempio: ERC20 privato {#example-private-erc20} -Usiamo un contratto ERC-20 di esempio dotato di un tempo privato iniziale. Il proprietario può gestire utenti privati, che saranno gli unici autorizzati a ricevere token all'inizio. Una volta trascorso un certo intervallo di tempo, a tutti sarà consentito utilizzare i token. Se sei curioso, stiamo usando l'hook [`_beforeTokenTransfer`](https://docs.openzeppelin.com/contracts/5.x/extending-contracts#using-hooks) dalla nuova libreria di contratti OpenZeppelin v3. +Usiamo un contratto ERC-20 di esempio dotato di un tempo privato iniziale. Il proprietario può gestire utenti privati, che saranno gli unici autorizzati a ricevere token all'inizio. Una volta trascorso un certo intervallo di tempo, a tutti sarà consentito utilizzare i token. Se sei curioso, stiamo usando l'hook [`_beforeTokenTransfer`](https://docs.openzeppelin.com/contracts/5.x/extending-contracts#using-hooks) dei nuovi contratti v3 di OpenZeppelin. ```solidity pragma solidity ^0.6.0; @@ -51,7 +47,7 @@ contract PrivateERC20 is ERC20, Ownable { function _beforeTokenTransfer(address from, address to, uint256 amount) internal virtual override { super._beforeTokenTransfer(from, to, amount); - require(_validRecipient(to), "PrivateERC20: invalid recipient"); + require(_validRecipient(to), "PrivateERC20: destinatario non valido"); } function _validRecipient(address to) private view returns (bool) { @@ -87,20 +83,20 @@ contract PrivateERC20Mock is PrivateERC20 { Otterrai uno dei seguenti messaggi d'errore: -- `PrivateERC20Mock.sol: TypeError: Overriding function is missing "override" specifier.` -- `PrivateERC20.sol: TypeError: Trying to override non-virtual function. Did you forget to add "virtual"?.` +- `PrivateERC20Mock.sol: TypeError: La funzione di sovrascrizione manca dello specificatore "override".` +- `PrivateERC20.sol: TypeError: Tentativo di sovrascrivere una funzione non virtuale.` `Hai dimenticato di aggiungere "virtual"?` -Poiché stiamo usando la nuova versione di Solidity 0.6, dobbiamo aggiungere la parola chiave `virtual` per le funzioni sovrascrivibili e `override` per la funzione di sovrascrizione. Quindi, aggiungiamoli a entrambe le funzioni `isPublic`. +Poiché stiamo usando la nuova versione 0.6 di Solidity, dobbiamo aggiungere la parola chiave `virtual` per le funzioni che possono essere sovrascritte e override per la funzione di sovrascrizione. Quindi, aggiungiamoli a entrambe le funzioni `isPublic`. -Ora, nei tuoi unit test, puoi invece usare `PrivateERC20Mock`. Quando desideri testare il comportamento durante il tempo di utilizzo privato, usa `setIsPublic(false` e, allo stesso modo, `setIsPublic(true)` per testare il tempo di utilizzo pubblico. Ovviamente, nel nostro esempio, abbiamo potuto usare soltanto i [time helper](https://docs.openzeppelin.com/test-helpers/0.5/api#increase) per modificare anche i tempi di conseguenza. Ma l'idea della simulazione dovrebbe ora esserti chiara e puoi immaginarti scenari in cui non sia facile come far procedere semplicemente il tempo. +Ora, nei tuoi unit test, puoi invece usare `PrivateERC20Mock`. Quando vuoi testare il comportamento durante il periodo di utilizzo privato, usa `setIsPublic(false)` e, allo stesso modo, `setIsPublic(true)` per testare il periodo di utilizzo pubblico. Ovviamente, nel nostro esempio, potremmo anche usare semplicemente gli [helper di tempo](https://docs.openzeppelin.com/test-helpers/0.5/api#increase) per modificare i tempi di conseguenza. Ma l'idea della simulazione dovrebbe ora esserti chiara e puoi immaginarti scenari in cui non sia facile come far procedere semplicemente il tempo. -## Simulare molti contratti {#mocking-many-contracts} +## Mocking di molti contratti {#mocking-many-contracts} -Può diventare caotico creare un altro contratto per ogni singola simulazione. Se ciò ti preoccupa, puoi dare un'occhiata alla libreria [MockContract](https://github.com/gnosis/mock-contract). Ti consente di sovrascrivere e modificare i comportamenti dei contratti al volo. Tuttavia, funziona solo per le chiamate di simulazione a un altro contratto, quindi non funzionerebbe per il nostro esempio. +Può diventare caotico creare un altro contratto per ogni singola simulazione. Se questo ti dà fastidio, puoi dare un'occhiata alla libreria [MockContract](https://github.com/gnosis/mock-contract). Ti consente di sovrascrivere e modificare i comportamenti dei contratti al volo. Tuttavia, funziona solo per le chiamate di simulazione a un altro contratto, quindi non funzionerebbe per il nostro esempio. -## La simulazione può essere ancora più potente {#mocking-can-be-even-more-powerful} +## Il mocking può essere ancora più potente {#mocking-can-be-even-more-powerful} I poteri della simulazione non finiscono qui. -- Aggiungere funzioni: è utile non solo sovrascrivere una funzione specifica, ma anche aggiungere funzioni aggiuntive. Un buon esempio per i token è proprio avere una funzione `mint` aggiuntiva per consentire a qualsiasi utente di ottenere nuovi token gratuitamente. +- Aggiungere funzioni: è utile non solo sovrascrivere una funzione specifica, ma anche aggiungere funzioni aggiuntive. Un buon esempio per i token è avere una funzione `mint` aggiuntiva per consentire a qualsiasi utente di ottenere nuovi token gratuitamente. - Uso nelle testnet: quando distribuisci e testi i tuoi contratti sulle reti di prova insieme alla tua dApp, prendi in considerazione l'uso di una versione simulata. Evita di sovrascrivere le funzioni, a meno che non sia davvero necessario. Dopotutto, vuoi testare la logica reale. Ma può essere utile aggiungere una funzione di ripristino che ripristini semplicemente lo stato del contratto all'inizio, senza necessità di alcuna nuova distribuzione. Ovviamente, non vorresti farlo in un contratto sulla Rete mainnet. diff --git a/public/content/translations/it/developers/tutorials/how-to-use-echidna-to-test-smart-contracts/index.md b/public/content/translations/it/developers/tutorials/how-to-use-echidna-to-test-smart-contracts/index.md index bc374533d9a..f0f8495a5ba 100644 --- a/public/content/translations/it/developers/tutorials/how-to-use-echidna-to-test-smart-contracts/index.md +++ b/public/content/translations/it/developers/tutorials/how-to-use-echidna-to-test-smart-contracts/index.md @@ -1,23 +1,25 @@ --- -title: Come usare Echidna per testare gli smart contract -description: Come usare Echidna per testare automaticamente gli smart contract +title: Come usare Echidna per testare i contratti intelligenti +description: Come usare Echidna per testare automaticamente i contratti intelligenti author: "Trailofbits" lang: it tags: - - "solidity" - - "contratti intelligenti" - - "sicurezza" - - "test" - - "fuzzing" + [ + "Solidity", + "smart contract", + "sicurezza", + "test", + "fuzzing" + ] skill: advanced published: 2020-04-10 -source: Creare contratti sicuri +source: Building secure contracts sourceUrl: https://github.com/crytic/building-secure-contracts/tree/master/program-analysis/echidna --- ## Installazione {#installation} -Echidna è installabile tramite docker o usando il binario pre-compilato. +Echidna può essere installato tramite docker o usando il binario pre-compilato. ### Echidna tramite docker {#echidna-through-docker} @@ -26,9 +28,9 @@ docker pull trailofbits/eth-security-toolbox docker run -it -v "$PWD":/home/training trailofbits/eth-security-toolbox ``` -_L'ultimo comando esegue eth-security-toolbox in un docker che ha accesso alla tua cartella corrente. Puoi modificare i file dal tuo host ed eseguire gli strumenti sui file dal docker_ +_L'ultimo comando esegue eth-security-toolbox in un docker che ha accesso alla tua directory corrente. Puoi modificare i file dal tuo host ed eseguire gli strumenti sui file dal docker_ -Nel docker, esegui: +All'interno di docker, esegui: ```bash solc-select 0.5.11 @@ -39,33 +41,33 @@ cd /home/training [https://github.com/crytic/echidna/releases/tag/v1.4.0.0](https://github.com/crytic/echidna/releases/tag/v1.4.0.0) -## Introduzione al fuzzing basato sulla proprietà {#introduction-to-property-based-fuzzing} +## Introduzione al fuzzing basato sulle proprietà {#introduction-to-property-based-fuzzing} -Echidna è un fuzzer basato sulla proprietà, che abbiamo descritto nei nostri post del blog precedenti ([1](https://blog.trailofbits.com/2018/03/09/echidna-a-smart-fuzzer-for-ethereum/), [2](https://blog.trailofbits.com/2018/05/03/state-machine-testing-with-echidna/), [3](https://blog.trailofbits.com/2020/03/30/an-echidna-for-all-seasons/)). +Echidna è un fuzzer basato sulle proprietà, come descritto nei nostri precedenti post del blog ([1](https://blog.trailofbits.com/2018/03/09/echidna-a-smart-fuzzer-for-ethereum/), [2](https://blog.trailofbits.com/2018/05/03/state-machine-testing-with-echidna/), [3](https://blog.trailofbits.com/2020/03/30/an-echidna-for-all-seasons/)). ### Fuzzing {#fuzzing} -Il [fuzzing](https://wikipedia.org/wiki/Fuzzing) è una ben nota tecnica nella community della sicurezza. Consiste nella generazione di input più o meno randomici, per trovare i bug nel programma. I fuzzer per il software tradizionale (come [AFL](http://lcamtuf.coredump.cx/afl/) o [LibFuzzer](https://llvm.org/docs/LibFuzzer.html)) sono noti per essere strumenti efficienti per trovare i bug. +[Il fuzzing](https://wikipedia.org/wiki/Fuzzing) è una tecnica ben nota nella comunità della sicurezza. Consiste nel generare input più o meno casuali per trovare bug nel programma. I fuzzer per il software tradizionale (come [AFL](http://lcamtuf.coredump.cx/afl/) o [LibFuzzer](https://llvm.org/docs/LibFuzzer.html)) sono noti per essere strumenti efficienti per la ricerca di bug. -Oltre alla generazione di input puramente casuale, esistono molte tecniche e strategie per generare input validi, tra cui: +Oltre alla generazione di input puramente casuali, esistono molte tecniche e strategie per generare input validi, tra cui: -- Ottenere feedback da ogni esecuzione e generazione della guida durante l'utilizzo. Ad esempio, se un input appena generato conduce alla scoperta di un nuovo percorso, può avere senso generare nuovi input vicini a esso. -- Generare l'input rispettando un vincolo strutturale. Ad esempio, se il tuo input contiene un'intestazione con un checksum, avrà senso lasciare che il fuzzer generi input a convalida del checksum. -- Usare input noti per generarne di nuovi: se hai accesso a un grande dataset di input validi, il tuo fuzzer può generarne di nuovi, anziché iniziare da zero la generazione. In genere sono detti _seed_. +- Ottenere un feedback da ogni esecuzione e usarlo per guidare la generazione. Ad esempio, se un input appena generato porta alla scoperta di un nuovo percorso, può avere senso generare nuovi input vicini ad esso. +- Generare l'input rispettando un vincolo strutturale. Ad esempio, se il tuo input contiene un'intestazione con un checksum, avrà senso lasciare che il fuzzer generi un input che convalidi il checksum. +- Usare input noti per generarne di nuovi: se hai accesso a un grande dataset di input validi, il tuo fuzzer può generare nuovi input da essi, anziché iniziare la generazione da zero. Questi sono solitamente chiamati _seed_. -### Fuzzing basato sulla proprietà {#property-based-fuzzing} +### Fuzzing basato sulle proprietà {#property-based-fuzzing} -Echidna appartiene a una famiglia specifica di fuzzer: il fuzzing basato sulla proprietà, ampiamente ispirato da [QuickCheck](https://wikipedia.org/wiki/QuickCheck). In contrasto al fuzzer classico che prova a trovare i crash, Echidna prova a rompere le invarianti definite dall'utente. +Echidna appartiene a una famiglia specifica di fuzzer: il fuzzing basato sulle proprietà, fortemente ispirato da [QuickCheck](https://wikipedia.org/wiki/QuickCheck). A differenza del fuzzer classico, che tenta di trovare i crash, Echidna tenta di violare le invarianti definite dall'utente. -Negli smart contract, le invarianti sono funzioni di Solidity, che possono rappresentare ogni stato non corretto o non valido raggiungibile dal contratto, tra cui: +Nei contratti intelligenti, le invarianti sono funzioni di Solidity, che possono rappresentare qualsiasi stato errato o non valido che il contratto può raggiungere, tra cui: -- Controllo d'accesso errato: il malintenzionato diventa il proprietario del contratto. -- Macchina di stato errata: i token sono trasferibili mentre il contratto è in pausa. -- Aritmetica errata: l'utente può sottovalutare il proprio saldo e ottenere token gratuiti illimitati. +- Controllo degli accessi errato: l'autore dell'attacco è diventato il proprietario del contratto. +- Macchina a stati errata: i token possono essere trasferiti mentre il contratto è in pausa. +- Aritmetica errata: l'utente può causare un underflow del suo saldo e ottenere token gratuiti illimitati. ### Testare una proprietà con Echidna {#testing-a-property-with-echidna} -Vedremo come testare un contratto intelligente con Echidna. L'obiettivo è il seguente smart contract [`token.sol`](https://github.com/crytic/building-secure-contracts/blob/master/program-analysis/echidna/example/token.sol): +Vedremo come testare un contratto intelligente con Echidna. L'obiettivo è il seguente contratto intelligente [`token.sol`](https://github.com/crytic/building-secure-contracts/blob/master/program-analysis/echidna/example/token.sol): ```solidity contract Token{ @@ -83,26 +85,26 @@ contract Token{ } ``` -Presumeremo che questo token debba avere le seguenti proprietà: +Partiremo dal presupposto che questo token debba avere le seguenti proprietà: -- Chiunque può avere al massimo 1.000 token -- Il token non è trasferibile (non è un token ERC20) +- Chiunque può avere al massimo 1000 token +- Il token non può essere trasferito (non è un token ERC20) -### Scrivi una proprietà {#write-a-property} +### Scrivere una proprietà {#write-a-property} -Le proprietà di Echidna sono funzioni di Solidity. Una proprietà deve: +Le proprietà di Echidna sono funzioni Solidity. Una proprietà deve: -- Non avere alcun argomento -- Restituire `true` se va a buon fine -- Avere un nome che inizia per `echidna` +- Non avere argomenti +- Restituire `true` se ha successo +- Avere un nome che inizia con `echidna` Echidna: -- Genererà automaticamente transazioni arbitrarie per testare la proprietà. -- Segnalare ogni transazione che fa sì che una proprietà restituisca `false` o generi un errore. -- Scartare l'effetto collaterale quando si chiama una proprietà (ad es. se la proprietà cambia una variabile di stato, viene scartata dopo il test) +- Generare automaticamente transazioni arbitrarie per testare la proprietà. +- Segnalare qualsiasi transazione che porti una proprietà a restituire `false` o a sollevare un errore. +- Annullare gli effetti collaterali quando si chiama una proprietà (cioè, se la proprietà modifica una variabile di stato, la modifica viene annullata dopo il test) -La seguente proprietà controlla che il chiamante non abbia più di 1.000 token: +La seguente proprietà controlla che il chiamante non abbia più di 1000 token: ```solidity function echidna_balance_under_1000() public view returns(bool){ @@ -110,7 +112,7 @@ function echidna_balance_under_1000() public view returns(bool){ } ``` -Usa l'eredità per separare il contratto dalle proprietà: +Usa l'ereditarietà per separare il tuo contratto dalle tue proprietà: ```solidity contract TestToken is Token{ @@ -122,34 +124,34 @@ contract TestToken is Token{ [`token.sol`](https://github.com/crytic/building-secure-contracts/blob/master/program-analysis/echidna/example/token.sol) implementa la proprietà ed eredita dal token. -### Avviare un contratto {#initiate-a-contract} +### Inizializzare un contratto {#initiate-a-contract} -Echidna necessita di un [costruttore](/developers/docs/smart-contracts/anatomy/#constructor-functions) senza argomento. Se il tuo contratto necessita di un'inizializzazione specifica, devi farlo nel costruttore. +Echidna necessita di un [costruttore](/developers/docs/smart-contracts/anatomy/#constructor-functions) senza argomenti. Se il tuo contratto necessita di un'inizializzazione specifica, devi effettuarla nel costruttore. -Esistono degli indirizzi specifici in Echidna: +In Echidna ci sono alcuni indirizzi specifici: -- `0x00a329c0648769A73afAc7F9381E08FB43dBEA72` per chiamare il costruttore. -- `0x10000`, `0x20000`, e `0x00a329C0648769a73afAC7F9381e08fb43DBEA70` per chiamare casualmente le altre funzioni. +- `0x00a329c0648769A73afAc7F9381E08FB43dBEA72` che chiama il costruttore. +- `0x10000`, `0x20000` e `0x00a329C0648769a73afAC7F9381e08fb43DBEA70` che chiamano casualmente le altre funzioni. -Non necessitiamo di alcuna inizializzazione particolare nel nostro esempio corrente, di conseguenza il nostro costruttore è vuoto. +Non abbiamo bisogno di alcuna inizializzazione particolare nel nostro esempio attuale, di conseguenza il nostro costruttore è vuoto. ### Eseguire Echidna {#run-echidna} -Echidna è avviato con: +Echidna si avvia con: ```bash echidna-test contract.sol ``` -Se contract.sol contiene più contratti, puoi specificare l'obiettivo: +Se contract.sol contiene più contratti, puoi specificare la destinazione: ```bash echidna-test contract.sol --contract MyContract ``` -### Riepilogo: Testare una proprietà {#summary-testing-a-property} +### Riepilogo: testare una proprietà {#summary-testing-a-property} -Di seguito è riepilogata l'esecuzione di Echidna nel nostro esempio: +Quanto segue riassume l'esecuzione di echidna sul nostro esempio: ```solidity contract TestToken is Token{ @@ -164,19 +166,20 @@ contract TestToken is Token{ echidna-test testtoken.sol --contract TestToken ... -echidna_balance_under_1000: failed!💥 - Call sequence, shrinking (1205/5000): +echidna_balance_under_1000: fallito!💥 + Sequenza di chiamate, riduzione in corso (1205/5000): airdrop() backdoor() ... ``` -Echidna ha individuato che la proprietà è violata se `backdoor` viene chiamata. +Echidna ha rilevato che la proprietà viene violata se si chiama `backdoor`. ## Filtrare le funzioni da chiamare durante una campagna di fuzzing {#filtering-functions-to-call-during-a-fuzzing-campaign} -Vedremo come filtrare le funzioni da sottoporre a fuzzing. L'obiettivo è il seguente smart contract: +Vedremo come filtrare le funzioni da sottoporre a fuzzing. +L'obiettivo è il seguente contratto intelligente: ```solidity contract C { @@ -227,35 +230,39 @@ contract C { } ``` -Questo piccolo esempio forza Echidna a trovare una certa sequenza di transazioni per modificare una variabile di stato. Ciò è difficile per un fuzzer (si consiglia di usare uno strumento di esecuzione simbolica come [Manticore](https://github.com/trailofbits/manticore)). Possiamo eseguire Echidna per verificarlo: +Questo piccolo esempio costringe Echidna a trovare una determinata sequenza di transazioni per modificare una variabile di stato. +Questo è difficile per un fuzzer (si consiglia di usare uno strumento di esecuzione simbolica come [Manticore](https://github.com/trailofbits/manticore)). +Possiamo eseguire Echidna per verificarlo: ```bash echidna-test multi.sol ... -echidna_state4: passed! 🎉 +echidna_state4: superato! 🎉 Seed: -3684648582249875403 ``` ### Funzioni di filtraggio {#filtering-functions} -Echidna fa fatica a trovare la sequenza corretta per testare questo contratto perché le due funzioni di reset (`reset1` e `reset2`) imposteranno tutte le variabili di stato su `false`. Tuttavia, possiamo usare una funzionalità speciale di Echidna per inserire nella blacklist la funzione di reset o nella whitelist solo le funzioni `f`, `g`, `h` e `i`. +Echidna ha difficoltà a trovare la sequenza corretta per testare questo contratto perché le due funzioni di ripristino (`reset1` e `reset2`) imposteranno tutte le variabili di stato su `false`. +Tuttavia, possiamo usare una funzionalità speciale di Echidna per inserire nella blacklist la funzione di ripristino o per inserire nella whitelist solo le funzioni `f`, `g`, +`h` e `i`. -Per inserire le funzioni nella blacklist, possiamo usare questo file di configurazione: +Per inserire funzioni nella blacklist, possiamo usare questo file di configurazione: ```yaml filterBlacklist: true filterFunctions: ["reset1", "reset2"] ``` -Un altro approccio per filtrare le funzioni è elencare quelle nella whitelist. Per farlo, possiamo usare questo file di configurazione: +Un altro approccio per filtrare le funzioni è elencare quelle inserite nella whitelist. A tal fine, possiamo usare questo file di configurazione: ```yaml filterBlacklist: false filterFunctions: ["f", "g", "h", "i"] ``` -- `filterBlacklist` è `true` di default. -- Il filtraggio sarà eseguito solo per nome (senza parametri). Se hai `f()` e `f(uint256)`, il filtro `"f"` abbinerà entrambe le funzioni. +- `filterBlacklist` è `true` per impostazione predefinita. +- Il filtraggio sarà eseguito solo per nome (senza parametri). Se si dispone di `f()` e `f(uint256)`, il filtro `"f"` corrisponderà a entrambe le funzioni. ### Eseguire Echidna {#run-echidna-1} @@ -264,19 +271,19 @@ Per eseguire Echidna con un file di configurazione `blacklist.yaml`: ```bash echidna-test multi.sol --config blacklist.yaml ... -echidna_state4: failed! - Call sequence: +echidna_state4: fallito!💥 + Sequenza di chiamate: f(12) g(8) h(42) i() ``` -Echidna troverà la sequenza di transazioni per falsificare la proprietà quasi immediatamente. +Echidna troverà quasi subito la sequenza di transazioni per falsificare la proprietà. -### Riepilogo: Filtrare le funzioni {#summary-filtering-functions} +### Riepilogo: funzioni di filtraggio {#summary-filtering-functions} -Echidna può inserire le funzioni di blacklist o whitelist da chiamare durante una campagna di fuzzing usando: +Echidna può inserire nella blacklist o nella whitelist le funzioni da chiamare durante una campagna di fuzzing usando: ```yaml filterBlacklist: true @@ -288,11 +295,12 @@ echidna-test contract.sol --config config.yaml ... ``` -Echidna avvia una campagna di fuzzing inserendo `f1`, `f2` e `f3` nella blacklist o solo chiamandole, in base al valore del booleano `filterBlacklist`. +Echidna avvia una campagna di fuzzing inserendo `f1`, `f2` e `f3` nella blacklist o chiamando solo queste, a seconda +del valore del booleano `filterBlacklist`. -## Come testare l'affermazione di Solidity con Echidna {#how-to-test-soliditys-assert-with-echidna} +## Come testare l'assert di Solidity con Echidna {#how-to-test-soliditys-assert-with-echidna} -In questo breve tutorial, mostreremo come usare Echidna per testare il controllo dell'affermazione nei contratti. Supponiamo di avere un contratto come questo: +In questo breve tutorial, mostreremo come usare Echidna per testare il controllo delle asserzioni nei contratti. Supponiamo di avere un contratto come questo: ```solidity contract Incrementor { @@ -309,7 +317,8 @@ contract Incrementor { ### Scrivere un'asserzione {#write-an-assertion} -Vogliamo assicurarci che `tmp` sia minore o uguale al `counter` dopo averne restituita la differenza. Potremmo scrivere una proprietà di Echidna, ma dovremmo memorizzare da qualche parte il valore `tmp`. Invece, potremmo usare un'asserzione come questa: +Vogliamo assicurarci che `tmp` sia minore o uguale a `counter` dopo aver restituito la loro differenza. Potremmo scrivere una +proprietà di Echidna, ma dovremmo memorizzare il valore di `tmp` da qualche parte. Invece, potremmo usare un'asserzione come questa: ```solidity contract Incrementor { @@ -326,19 +335,19 @@ contract Incrementor { ### Eseguire Echidna {#run-echidna-2} -Per abilitare il test di insuccesso dell'asserzione, crea un [file di configurazione di Echidna](https://github.com/crytic/echidna/wiki/Config) `config.yaml`: +Per abilitare il test di fallimento dell'asserzione, crea un [file di configurazione di Echidna](https://github.com/crytic/echidna/wiki/Config) `config.yaml`: ```yaml checkAsserts: true ``` -Quando eseguiamo questo contratto in Echidna, otteniamo i risultati previsti: +Quando eseguiamo questo contratto in Echidna, otteniamo i risultati attesi: ```bash echidna-test assert.sol --config config.yaml Analyzing contract: assert.sol:Incrementor -assertion in inc: failed!💥 - Call sequence, shrinking (2596/5000): +assertion in inc: fallita!💥 + Sequenza di chiamate, riduzione in corso (2596/5000): inc(21711016731996786641919559689128982722488122124807605757398297001483711807488) inc(7237005577332262213973186563042994240829374041602535252466099000494570602496) inc(86844066927987146567678238756515930889952488499230423029593188005934847229952) @@ -346,15 +355,15 @@ assertion in inc: failed!💥 Seed: 1806480648350826486 ``` -Come puoi vedere, Echidna segnala alcuni insuccessi dell'asserzione nella funzione `inc`. Aggiungere più di un'asserzione per funzione è possibile, ma Echidna non può dire quale sia fallita. +Come puoi vedere, Echidna segnala un fallimento dell'asserzione nella funzione `inc`. È possibile aggiungere più di un'asserzione per funzione, ma Echidna non è in grado di dire quale asserzione sia fallita. ### Quando e come usare le asserzioni {#when-and-how-use-assertions} -Le asserzioni sono utilizzabili come alternative a proprietà esplicite, specialmente se le condizioni per il controllo sono direttamente correlate all'uso corretto della stessa operazione `f`. Aggiungere le asserzioni dopo il codice farà sì che il controllo abbia luogo immediatamente dopo la sua esecuzione: +Le asserzioni possono essere usate come alternative a proprietà esplicite, specialmente se le condizioni da verificare sono direttamente correlate all'uso corretto di un'operazione `f`. L'aggiunta di asserzioni dopo una porzione di codice garantirà che il controllo avvenga immediatamente dopo la sua esecuzione: ```solidity function f(..) public { - // some complex code + // un po' di codice complesso ... assert (condition); ... @@ -362,7 +371,7 @@ function f(..) public { ``` -Al contrario, l'utilizzo di una proprietà esplicita di Echidna eseguirà casualmente le transazioni e non esiste alcun metodo semplice per imporre esattamente quando verrà controllata. È comunque possibile sfruttare questa scappatoia: +Al contrario, usando una proprietà esplicita di echidna si eseguiranno transazioni in modo casuale e non c'è un modo semplice per imporre esattamente quando verrà controllata. È comunque possibile sfruttare questa scappatoia: ```solidity function echidna_assert_after_f() public returns (bool) { @@ -373,20 +382,20 @@ function echidna_assert_after_f() public returns (bool) { Tuttavia, esistono dei problemi: -- Fallisce se `f` è dichiarata come `internal` o `external`. +- Fallisce se `f` è dichiarato come `internal` o `external`. - Non è chiaro quali argomenti dovrebbero essere usati per chiamare `f`. -- Se `f` si ripristina, la proprietà fallirà. +- Se `f` esegue il revert, la proprietà fallirà. -In generale, consigliamo di seguire i [consigli di John Regehr](https://blog.regehr.org/archives/1091) su come usare le affermazioni: +In generale, raccomandiamo di seguire la [raccomandazione di John Regehr](https://blog.regehr.org/archives/1091) su come usare le asserzioni: -- Non forzare alcun effetto collaterale durante il controllo dell'affermazione. Ad esempio: `assert(ChangeStateAndReturn() == 1)` -- Non affermare dichiarazioni ovvie. Ad esempio `assert(var >= 0)` dove `var` è dichiarata come `uint`. +- Non forzare alcun effetto collaterale durante il controllo dell'asserzione. Ad esempio: `assert(ChangeStateAndReturn() == 1)` +- Non asserire dichiarazioni ovvie. Ad esempio `assert(var >= 0)` dove `var` è dichiarato come `uint`. -Infine, consigliamo di **non usare** `require` al posto di `assert`, poiché Echidna non potrà rilevarlo (ma il contratto si ripristinerà ugualmente). +Infine, **non usare** `require` invece di `assert`, poiché Echidna non sarà in grado di rilevarlo (ma il contratto eseguirà comunque un revert). -### Riepilogo: Controllo dell'asserzione {#summary-assertion-checking} +### Riepilogo: controllo delle asserzioni {#summary-assertion-checking} -Quanto segue riepiloga l'esecuzione di Echidna nel nostro esempio: +Quanto segue riassume l'esecuzione di echidna sul nostro esempio: ```solidity contract Incrementor { @@ -404,8 +413,8 @@ contract Incrementor { ```bash echidna-test assert.sol --config config.yaml Analyzing contract: assert.sol:Incrementor -assertion in inc: failed!💥 - Call sequence, shrinking (2596/5000): +assertion in inc: fallita!💥 + Sequenza di chiamate, riduzione in corso (2596/5000): inc(21711016731996786641919559689128982722488122124807605757398297001483711807488) inc(7237005577332262213973186563042994240829374041602535252466099000494570602496) inc(86844066927987146567678238756515930889952488499230423029593188005934847229952) @@ -413,11 +422,11 @@ assertion in inc: failed!💥 Seed: 1806480648350826486 ``` -Echidna ha trovato che l'asserzione in `inc` può fallire se questa funzione è chiamata diverse volte con grandi argomenti. +Echidna ha rilevato che l'asserzione in `inc` può fallire se questa funzione viene chiamata più volte con argomenti di grandi dimensioni. ## Raccogliere e modificare un corpus di Echidna {#collecting-and-modifying-an-echidna-corpus} -Vedremo come raccogliere e usare un corpus di transazioni con Echidna. L'obiettivo è il seguente smart contract [`magic.sol`](https://github.com/crytic/building-secure-contracts/blob/master/program-analysis/echidna/example/magic.sol): +Vedremo come raccogliere e usare un corpus di transazioni con Echidna. L'obiettivo è il seguente contratto intelligente [`magic.sol`](https://github.com/crytic/building-secure-contracts/blob/master/program-analysis/echidna/example/magic.sol): ```solidity contract C { @@ -437,20 +446,22 @@ contract C { } ``` -Questo piccolo esempio forza Echidna a trovare una certi valori per modificare una variabile di stato, il che è difficile per un fuzzer (si consiglia di usare uno strumento d'esecuzione simbolica come [Manticore](https://github.com/trailofbits/manticore)). Possiamo eseguire Echidna per verificarlo: +Questo piccolo esempio costringe Echidna a trovare determinati valori per modificare una variabile di stato. Questo è difficile per un fuzzer +(si consiglia di usare uno strumento di esecuzione simbolica come [Manticore](https://github.com/trailofbits/manticore)). +Possiamo eseguire Echidna per verificarlo: ```bash echidna-test magic.sol ... -echidna_magic_values: passed! 🎉 +echidna_magic_values: superato! 🎉 Seed: 2221503356319272685 ``` Tuttavia, possiamo comunque usare Echidna per raccogliere il corpus mentre si esegue questa campagna di fuzzing. -### Raccogliere un corpus {#collecting-a-corpus} +### Raccolta di un corpus {#collecting-a-corpus} Per abilitare la raccolta, crea la cartella di un corpus: @@ -471,7 +482,8 @@ Ora possiamo eseguire il nostro strumento e controllare il corpus raccolto: echidna-test magic.sol --config config.yaml ``` -Echidna non è ancora in grado di trovare i valori magici corretti, ma possiamo dare un'occhiata al corpus raccolto. Ad esempio, uno di questi file era: +Echidna non è ancora in grado di trovare i valori magici corretti, ma possiamo dare un'occhiata al corpus raccolto. +Ad esempio, uno di questi file era: ```json [ @@ -518,21 +530,22 @@ Echidna non è ancora in grado di trovare i valori magici corretti, ma possiamo Chiaramente, questo input non innescherà il fallimento nella nostra proprietà. Tuttavia, nel prossimo passaggio, vedremo come modificarlo a tale scopo. -### Seeding di un corpus {#seeding-a-corpus} +### Fornire un corpus come seed {#seeding-a-corpus} -Echidna necessita di un po' di aiuto per poter affrontare la funzione `magic`. Copieremo e modificheremo l'input per usare parametri idonei a tale scopo: +Echidna necessita di un po' di aiuto per poter affrontare la funzione magic. Copieremo e modificheremo l'input per usare parametri idonei +a tale scopo: ```bash cp corpus/2712688662897926208.txt corpus/new.txt ``` -Modificheremo `new.txt` per chiamare `magic(42,129,333,0)`. Ora possiamo ri-eseguire Echidna: +Modificheremo `new.txt` per chiamare `magic(42,129,333,0)`. Ora possiamo rieseguire Echidna: ```bash echidna-test magic.sol --config config.yaml ... -echidna_magic_values: failed!💥 - Call sequence: +echidna_magic_values: fallito!💥 + Sequenza di chiamate: magic(42,129,333,0) @@ -544,9 +557,9 @@ Seed: -7293830866560616537 Questa volta, ha scoperto che la proprietà è immediatamente violata. -## Individuare le transazioni ad alto consumo di gas {#finding-transactions-with-high-gas-consumption} +## Trovare transazioni con un elevato consumo di gas {#finding-transactions-with-high-gas-consumption} -Vedremo come individuare le transazioni con un alto consumo di gas con Echidna. L'obiettivo è il seguente smart contract: +Vedremo come individuare le transazioni con un alto consumo di gas con Echidna. L'obiettivo è il seguente contratto intelligente: ```solidity contract C { @@ -573,17 +586,18 @@ contract C { Qui `expensive` può avere un gran consumo di gas. -Attualmente, Echidna necessità sempre di una proprietà da testare: qui `echidna_test` restituisce sempre `true`. Possiamo eseguire Echidna per verificarlo: +Attualmente, Echidna necessità sempre di una proprietà da testare: qui `echidna_test` restituisce sempre `true`. +Possiamo eseguire Echidna per verificarlo: ``` echidna-test gas.sol ... -echidna_test: passed! 🎉 +echidna_test: superato! 🎉 Seed: 2320549945714142710 ``` -### Misurare il Consumo di Gas {#measuring-gas-consumption} +### Misurare il consumo di gas {#measuring-gas-consumption} Per abilitare il consumo di gas con Echidna, crea un file di configurazione `config.yaml`: @@ -594,92 +608,85 @@ estimateGas: true In questo esempio, ridurremo anche le dimensioni della sequenza di transazione per facilitare la comprensione dei risultati: ```yaml -seqLen: 2 -estimateGas: true +In questo esempio, ridurremo anche le dimensioni della sequenza di transazione per facilitare la comprensione dei risultati: ``` -### Eseguire Echidna {#run-echidna-3} +### seqLen: 2 estimateGas: true -Una volta creato il file di configurazione, possiamo eseguire Echidna come segue: +Eseguire Echidna {#run-echidna-3} ```bash -echidna-test gas.sol --config config.yaml -... -echidna_test: passed! 🎉 - -f used a maximum of 1333608 gas - Call sequence: - f(42,123,249) Gas price: 0x10d5733f0a Time delay: 0x495e5 Block delay: 0x88b2 - -Unique instructions: 157 -Unique codehashes: 1 -Seed: -325611019680165325 - +Una volta creato il file di configurazione, possiamo eseguire Echidna come segue: ``` -- Il gas mostrato è una stima fornita da [HEVM](https://github.com/dapphub/dapptools/tree/master/src/hevm#hevm-). +- echidna-test gas.sol --config config.yaml + ... + echidna_test: superato! 🎉f ha usato un massimo di 1333608 di gas + Sequenza di chiamate: + f(42,123,249) Prezzo del gas: 0x10d5733f0a Ritardo: 0x495e5 Ritardo blocco: 0x88b2Unique instructions: 157 + Unique codehashes: 1 + Seed: -325611019680165325 -### Filtrare le Chiamate di Riduzione del Gas {#filtering-out-gas-reducing-calls} +### Il gas mostrato è una stima fornita da [HEVM](https://github.com/dapphub/dapptools/tree/master/src/hevm#hevm-). -Il tutorial precedente sulle **funzioni di filtraggio da chiamare durante una campagna di fuzzing**, mostra come rimuovere alcune funzioni dal tuo test. -Questo può esser critico per ottenere una stima accurata del gas. Considera l'esempio seguente: +Filtrare le chiamate che riducono il gas {#filtering-out-gas-reducing-calls} +Il tutorial precedente su come **filtrare le funzioni da chiamare durante una campagna di fuzzing** mostra come +rimuovere alcune funzioni dal tuo test. +Si consideri l'esempio seguente: ```solidity +Questo può essere fondamentale per ottenere una stima accurata del gas. +``` + contract C { - address [] addrs; - function push(address a) public { - addrs.push(a); - } - function pop() public { - addrs.pop(); - } - function clear() public{ - addrs.length = 0; - } - function check() public{ - for(uint256 i = 0; i < addrs.length; i++) - for(uint256 j = i+1; j < addrs.length; j++) - if (addrs[i] == addrs[j]) - addrs[j] = address(0x0); - } - function echidna_test() public returns (bool) { - return true; - } +address [] addrs; +function push(address a) public { +addrs.push(a); +} +function pop() public { +addrs.pop(); +} +function clear() public{ +addrs.length = 0; +} +function check() public{ +for(uint256 i = 0; i < addrs.length; i++) +for(uint256 j = i+1; j < addrs.length; j++) +if (addrs[i] == addrs[j]) +addrs[j] = address(0x0); +} +function echidna_test() public returns (bool) { +return true; +} } -``` +``` Se Echidna può chiamare tutte le funzioni, non troverà facilmente le transazioni a costo elevato di gas: - ``` + echidna-test pushpop.sol --config config.yaml ... -pop used a maximum of 10746 gas +pop ha usato un massimo di 10746 di gas ... -check used a maximum of 23730 gas +check ha usato un massimo di 23730 di gas ... -clear used a maximum of 35916 gas +clear ha usato un massimo di 35916 di gas ... -push used a maximum of 40839 gas -``` - -Questo perché il costo dipende dalla dimensione di `addrs` e le chiamate casuali tendono a lasciare l'array quasi vuoto. L'inserimento in blacklist di `pop` e `clear`, tuttavia, fornisce risultati molto più efficaci: +push ha usato un massimo di 40839 di gas +Questo perché il costo dipende dalla dimensione di `addrs` e le chiamate casuali tendono a lasciare l'array quasi vuoto. ```yaml -filterBlacklist: true -filterFunctions: ["pop", "clear"] +Tuttavia, inserire `pop` e `clear` in una blacklist, ci fornisce risultati molto migliori: ``` ``` -echidna-test pushpop.sol --config config.yaml -... -push used a maximum of 40839 gas -... -check used a maximum of 1484472 gas +filterBlacklist: true +filterFunctions: ["pop", "clear"] ``` -### Sommario: Individuare le transazioni ad alto consumo di gas {#summary-finding-transactions-with-high-gas-consumption} +### echidna-test pushpop.sol --config config.yaml ... push ha usato un massimo di 40839 di gas ... check ha usato un massimo di 1484472 di gas -Echidna può trovare le transazioni ad alto consumo di gas usando l'opzione di configurazione `estimateGas`: +Riepilogo: trovare transazioni con un elevato consumo di gas {#summary-finding-transactions-with-high-gas-consumption} ```yaml estimateGas: true @@ -690,4 +697,4 @@ echidna-test contract.sol --config config.yaml ... ``` -Echidna segnalerà una sequenza con il consumo massimo di gas per ogni funzione, una volta terminata la campagna di fuzzing. +Echidna può trovare le transazioni ad alto consumo di gas usando l'opzione di configurazione `estimateGas`: diff --git a/public/content/translations/it/developers/tutorials/how-to-use-manticore-to-find-smart-contract-bugs/index.md b/public/content/translations/it/developers/tutorials/how-to-use-manticore-to-find-smart-contract-bugs/index.md index 7d97bd4a966..5772b59ff98 100644 --- a/public/content/translations/it/developers/tutorials/how-to-use-manticore-to-find-smart-contract-bugs/index.md +++ b/public/content/translations/it/developers/tutorials/how-to-use-manticore-to-find-smart-contract-bugs/index.md @@ -4,40 +4,42 @@ description: Come usare Manticore per trovare automaticamente bug negli Smart Co author: Trailofbits lang: it tags: - - "solidity" - - "contratti intelligenti" - - "sicurezza" - - "test" - - "verifica formale" + [ + "Solidity", + "smart contract", + "sicurezza", + "test", + "verifica formale" + ] skill: advanced published: 2020-01-13 -source: Creare contratti sicuri +source: Building secure contracts sourceUrl: https://github.com/crytic/building-secure-contracts/tree/master/program-analysis/manticore --- -L'obiettivo di questo tutorial è mostrare come usare Manticore per trovare automaticamente bug negli Smart Contract. +L'obiettivo di questa guida è mostrare come usare Manticore per trovare automaticamente bug negli Smart Contract. ## Installazione {#installation} -Manticore richiede >= Python 3.6. Può essere installato tramite pip o usando docker. +Manticore richiede python >= 3.6. Può essere installato tramite pip o usando docker. -### Manticore con docker {#manticore-through-docker} +### Manticore tramite docker {#manticore-through-docker} ```bash docker pull trailofbits/eth-security-toolbox docker run -it -v "$PWD":/home/training trailofbits/eth-security-toolbox ``` -_L'ultimo comando esegue eth-security-toolbox in un docker avente accesso alla tua directory corrente. Puoi cambiare i file dal tuo host ed eseguire gli strumenti sui file dal docker_ +_L'ultimo comando esegue eth-security-toolbox in un docker che ha accesso alla tua directory corrente. Puoi modificare i file dal tuo host ed eseguire gli strumenti sui file dal docker_ -In docker, esegui: +All'interno del docker, esegui: ```bash solc-select 0.5.11 cd /home/trufflecon/ ``` -### Manticore con pip {#manticore-through-pip} +### Manticore tramite pip {#manticore-through-pip} ```bash pip3 install --user manticore @@ -45,7 +47,7 @@ pip3 install --user manticore È consigliato solc 0.5.11. -### Esecuzione di uno script {#running-a-script} +### Eseguire uno script {#running-a-script} Per eseguire uno script Python con Python 3: @@ -55,18 +57,18 @@ python3 script.py ## Introduzione all'esecuzione simbolica dinamica {#introduction-to-dynamic-symbolic-execution} -### Esecuzione simbolica dinamica in pillole {#dynamic-symbolic-execution-in-a-nutshell} +### Esecuzione Simbolica Dinamica in poche parole {#dynamic-symbolic-execution-in-a-nutshell} -L'esecuzione simbolica dinamica (DSE) è una tecnica di analisi di un programma che esplora uno spazio di stati con un alto grado di consapevolezza semantica. Questa tecnica si basa sulla scoperta dei "percorsi del programma", rappresentati da formule matematiche dette `predicati di percorso`. Concettualmente, opera su predicati di percorso in due passaggi: +L'esecuzione simbolica dinamica (DSE) è una tecnica di analisi di un programma che esplora uno spazio degli stati con un alto grado di consapevolezza semantica. Questa tecnica si basa sulla scoperta dei "percorsi del programma", rappresentati da formule matematiche chiamate `predicati di percorso`. Concettualmente, questa tecnica opera sui predicati di percorso in due passaggi: -1. Vengono costruiti usando vincoli nell'input del programma. -2. Vengono usati per generare input del programma che causeranno l'esecuzione dei percorsi associati. +1. Sono costruiti usando vincoli sull'input del programma. +2. Sono usati per generare input del programma che causeranno l'esecuzione dei percorsi associati. -Questo approccio non produce falsi positivi nel senso che tutti gli stati del programma identificati possono essere attivati durante l'esecuzione concreta. Per esempio, se le analisi trova un overflow di valori interi, è garantito che sia riproducibile. +Questo approccio non produce falsi positivi, nel senso che tutti gli stati del programma identificati possono essere attivati durante l'esecuzione concreta. Ad esempio, se l'analisi rileva un overflow di valori interi, è garantito che sia riproducibile. -### Esempio di predicato di percorso {#path-predicate-example} +### Esempio di Predicato di Percorso {#path-predicate-example} -Per avere un'idea di funziona la DSE, considera il seguente esempio: +Per avere un'idea di come funziona la DSE, si consideri il seguente esempio: ```solidity function f(uint a){ @@ -83,17 +85,17 @@ Poiché `f()` contiene due percorsi, una DSE costruirà due diversi predicati di - Percorso 1: `a == 65` - Percorso 2: `Not (a == 65)` -Ogni predicato di percorso è una formula matematica che può essere passata a un cosiddetto [risolutore SMT](https://wikipedia.org/wiki/Satisfiability_modulo_theories), che proverà a risolvere l'equazione. Per il `Percorso 1`, il risolutore dirà che il percorso può essere esplorato con `a = 65`. Per il `Percorso 2`, il risolutore può assegnare ad `a` tutti i valori diversi da 65, per esempio `a = 0`. +Ogni predicato di percorso è una formula matematica che può essere data a un cosiddetto [risolutore SMT](https://wikipedia.org/wiki/Satisfiability_modulo_theories), che proverà a risolvere l'equazione. Per `Percorso 1`, il risolutore dirà che il percorso può essere esplorato con `a = 65`. Per `Percorso 2`, il risolutore può dare ad `a` qualsiasi valore diverso da 65, ad esempio `a = 0`. ### Verifica delle proprietà {#verifying-properties} -Manticore permette un controllo completo su tutta l'esecuzione di ogni percorso. Di conseguenza, consente di aggiungere vincoli arbitrari quasi a tutto. Questo controllo permette di creare proprietà sul contratto. +Manticore permette un controllo completo su tutta l'esecuzione di ogni percorso. Di conseguenza, consente di aggiungere vincoli arbitrari a quasi tutto. Questo controllo permette la creazione di proprietà sul contratto. -Considera l'esempio seguente: +Si consideri l'esempio seguente: ```solidity function unsafe_add(uint a, uint b) returns(uint c){ - c = a + b; // no overflow protection + c = a + b; // nessuna protezione da overflow return c; } ``` @@ -102,13 +104,13 @@ Qui c'è un solo percorso da esplorare nella funzione: - Percorso 1: `c = a + b` -Usando Manticore, si può controllare l'overflow e aggiungere vincoli al predicato di percorso: +Usando Manticore, si può verificare la presenza di overflow e aggiungere vincoli al predicato di percorso: - `c = a + b AND (c < a OR c < b)` -Se è possibile trovare una valutazione di `a` e `b` per cui il predicato di percorso qui sopra sia fattibile, significa che è stato trovato un overflow. Ad esempio, il risolutore può generare l'input `a = 10 , b = MAXUINT256`. +Se è possibile trovare una valutazione di `a` e `b` per cui il predicato di percorso di cui sopra è fattibile, significa che si è trovato un overflow. Ad esempio, il risolutore può generare l'input `a = 10, b = MAXUINT256`. -Se consideri una versione fissa: +Se si considera una versione corretta: ```solidity function safe_add(uint a, uint b) returns(uint c){ @@ -119,17 +121,17 @@ function safe_add(uint a, uint b) returns(uint c){ } ``` -La formula associata al controllo dell'overflow sarebbe: +La formula associata con il controllo dell'overflow sarebbe: - `c = a + b AND (c >= a) AND (c=>b) AND (c < a OR c < b)` -Questa formula non è risolvibile; in altri mondi questa è una **prova** che in `safe_add`, `c` aumenterà sempre. +Questa formula non può essere risolta; in altre parole, questa è una **prova** che in `safe_add`, `c` aumenterà sempre. -La DSE è quindi uno strumento potente, che può verificare i vincoli arbitrari nel codice. +La DSE è quindi uno strumento potente, in grado di verificare vincoli arbitrari sul codice. -## Esecuzione in Manticore {#running-under-manticore} +## Esecuzione con Manticore {#running-under-manticore} -Vedremo come esplorare uno Smart Contract con l'API Manticore. La destinazione è il seguente Smart Contract [`example.sol`](https://github.com/crytic/building-secure-contracts/blob/master/program-analysis/manticore/examples/example.sol): +Vedremo come esplorare uno Smart Contract con l'API Manticore. L'obiettivo è il seguente Smart Contract [`example.sol`](https://github.com/crytic/building-secure-contracts/blob/master/program-analysis/manticore/examples/example.sol): ```solidity pragma solidity >=0.4.24 <0.6.0; @@ -143,15 +145,15 @@ contract Simple { } ``` -### Esplorazione indipendente {#run-a-standalone-exploration} +### Eseguire un'esplorazione autonoma {#run-a-standalone-exploration} -Manticore può essere eseguito direttamente sullo Smart Contract con il comando seguente (`project` può essere un file Solidity o una directory del progetto): +È possibile eseguire Manticore direttamente sullo Smart Contract tramite il seguente comando (`project` può essere un file Solidity o una directory di progetto): ```bash $ manticore project ``` -Otterrai l'output dei casi di prova, come il seguente (l'ordine potrebbe variare): +Si otterrà l'output dei casi di test come questo (l'ordine potrebbe cambiare): ``` ... @@ -162,43 +164,43 @@ Otterrai l'output dei casi di prova, come il seguente (l'ordine potrebbe variare ... m.c.manticore:INFO: Generated testcase No. 4 - STOP ... m.c.manticore:INFO: Generated testcase No. 5 - REVERT ... m.c.manticore:INFO: Generated testcase No. 6 - REVERT -... m.c.manticore:INFO: Results in /home/ethsec/workshops/Automated Smart Contract Audit - TruffleCon 2018/manticore/examples/mcore_t6vi6ij3 +... m.c.manticore:INFO: Results in /home/ethsec/workshops/Automated Smart Contracts Audit - TruffleCon 2018/manticore/examples/mcore_t6vi6ij3 ... ``` -Senza altre informazioni, Manticore esplorerà il contratto con nuove transazioni simboliche, finché non esplorerà nuovi percorsi sul contratto. Manticore non esegue nuove transazioni se una non riesce (ad esempio dopo un ripristino). +Senza informazioni aggiuntive, Manticore esplorerà il contratto con nuove transazioni simboliche finché non esplorerà nuovi percorsi sul contratto. Manticore non esegue nuove transazioni dopo una non riuscita (ad es. dopo un revert). -Manticore restituirà le informazioni un una directory `mcore_*`. In questa directory troverai, tra altre cose: +Manticore genererà l'output delle informazioni in una directory `mcore_*`. Tra le altre cose, in questa directory si troverà: - `global.summary`: copertura e avvisi del compilatore -- `test_XXXXX.summary`: copertura, ultima istruzione, saldi del conto per casi di prova -- `test_XXXXX.tx`: elenco dettagliato delle transazioni per test case +- `test_XXXXX.summary`: copertura, ultima istruzione, saldi dei conti per caso di test +- `test_XXXXX.tx`: elenco dettagliato delle transazioni per caso di test -Qui Manticore trova 7 test case che corrispondono a (l'ordine dei nomi dei file potrebbe variare): +Qui Manticore trova 7 casi di test, che corrispondono a (l'ordine dei nomi dei file potrebbe cambiare): -| | Transazione 0 | Transazione 1 | Transazione 2 | Risultato | -|:--------------------:|:-----------------------:|:--------------------:| -------------------- |:---------:| -| **test_00000000.tx** | Creazione del contratto | f(!=65) | f(!=65) | STOP | -| **test_00000001.tx** | Creazione del contratto | funzione di fallback | | REVERT | -| **test_00000002.tx** | Creazione del contratto | | | RETURN | -| **test_00000003.tx** | Creazione del contratto | f(65) | | REVERT | -| **test_00000004.tx** | Creazione del contratto | f(!=65) | | STOP | -| **test_00000005.tx** | Creazione del contratto | f(!=65) | f(65) | REVERT | -| **test_00000006.tx** | Creazione del contratto | f(!=65) | funzione di fallback | REVERT | +| | Transazione 0 | Transazione 1 | Transazione 2 | Risultato | +| :-------------------------------------------------------: | :---------------------: | :------------------------: | -------------------------- | :-------: | +| **test_00000000.tx** | Creazione del contratto | f(!=65) | f(!=65) | STOP | +| **test_00000001.tx** | Creazione del contratto | funzione di fallback | | REVERT | +| **test_00000002.tx** | Creazione del contratto | | | RETURN | +| **test_00000003.tx** | Creazione del contratto | f(65) | | REVERT | +| **test_00000004.tx** | Creazione del contratto | f(!=65) | | STOP | +| **test_00000005.tx** | Creazione del contratto | f(!=65) | f(65) | REVERT | +| **test_00000006.tx** | Creazione del contratto | f(!=65) | funzione di fallback | REVERT | -_Il riepilogo dell'esplorazione f(!=65) denota f chiamata con ogni valore diverso da 65._ +_Riepilogo dell'esplorazione: f(!=65) denota f chiamata con qualsiasi valore diverso da 65._ -Come puoi notare, Manticore genera un test case univoco per ogni transazione riuscita o ripristinata. +Come si può notare, Manticore genera un caso di test univoco per ogni transazione riuscita o ripristinata. -Usa il flag `--quick-mode` se desideri un'esplorazione veloce del codice (disabilita rilevatori di bug, calcolo del carburante, etc.) +Usare il flag `--quick-mode` per un'esplorazione rapida del codice (disabilita i rilevatori di bug, il calcolo del gas, ...). -### Manipolazione di uno Smart Contract tramite l'API {#manipulate-a-smart-contract-through-the-api} +### Manipolare uno Smart Contract tramite l'API {#manipulate-a-smart-contract-through-the-api} -Questa sezione contiene informazioni su come manipolare uno Smart Contract tramite l'API Python di Manticore. Puoi creare un nuovo file con l'estensione di Python `*.py` e scrivere il codice necessario aggiungendo i comandi dell'API (le basi saranno descritte di seguito) in questo file e poi eseguirlo con il comando `$ python3 *.py`. Puoi anche eseguire i comandi qui sotto direttamente nella console Python. Per eseguirla usa il comando `$ python3`. +Questa sezione descrive in dettaglio come manipolare uno Smart Contract tramite l'API Python di Manticore. È possibile creare un nuovo file con l'estensione python `*.py` e scrivere il codice necessario aggiungendo i comandi dell'API (le cui basi saranno descritte di seguito) in questo file e quindi eseguirlo con il comando `$ python3 *.py`. Inoltre è possibile eseguire i comandi seguenti direttamente nella console di python; per avviare la console, usare il comando `$ python3`. -### Creare i Conti {#creating-accounts} +### Creazione di Conti {#creating-accounts} -La prima da fare è inizializzare una nuova blockchain con i comandi seguenti: +La prima cosa da fare è avviare una nuova blockchain con i seguenti comandi: ```python from manticore.ethereum import ManticoreEVM @@ -206,7 +208,7 @@ from manticore.ethereum import ManticoreEVM m = ManticoreEVM() ``` -Un conto privo di contratto è creato usando [m.create_account](https://manticore.readthedocs.io/en/latest/evm.html?highlight=create_account#manticore.ethereum.ManticoreEVM.create_account): +Un conto non di contratto viene creato usando [m.create_account](https://manticore.readthedocs.io/en/latest/evm.html?highlight=create_account#manticore.ethereum.ManticoreEVM.create_account): ```python user_account = m.create_account(balance=1000) @@ -231,9 +233,9 @@ contract_account = m.solidity_create_contract(source_code, owner=user_account) #### Riepilogo {#summary} -- Puoi creare conti dell'utente e del contratto con [m.create_account](https://manticore.readthedocs.io/en/latest/evm.html?highlight=create_account#manticore.ethereum.ManticoreEVM.create_account) e [m.solidity_create_contract](https://manticore.readthedocs.io/en/latest/evm.html?highlight=solidity_create#manticore.ethereum.ManticoreEVM.create_contract). +- È possibile creare conti utente e conti di contratto con [m.create_account](https://manticore.readthedocs.io/en/latest/evm.html?highlight=create_account#manticore.ethereum.ManticoreEVM.create_account) e [m.solidity_create_contract](https://manticore.readthedocs.io/en/latest/evm.html?highlight=solidity_create#manticore.ethereum.ManticoreEVM.create_contract). -### Esecuzione di transazioni {#executing-transactions} +### Esecuzione delle transazioni {#executing-transactions} Manticore supporta due tipi di transazione: @@ -254,9 +256,9 @@ m.transaction(caller=user_account, Il chiamante, l'indirizzo, i dati o il valore della transazione possono essere concreti o simbolici: - [m.make_symbolic_value](https://manticore.readthedocs.io/en/latest/evm.html?highlight=make_symbolic_value#manticore.ethereum.ManticoreEVM.make_symbolic_value) crea un valore simbolico. -- [m.make_symbolic_buffer(size)](https://manticore.readthedocs.io/en/latest/evm.html?highlight=make_symbolic_buffer#manticore.ethereum.ManticoreEVM.make_symbolic_buffer) crea un array di byte simbolici. +- [m.make_symbolic_buffer(size)](https://manticore.readthedocs.io/en/latest/evm.html?highlight=make_symbolic_buffer#manticore.ethereum.ManticoreEVM.make_symbolic_buffer) crea un array di byte simbolico. -Ad esempio: +Per esempio: ```python symbolic_value = m.make_symbolic_value() @@ -267,40 +269,41 @@ m.transaction(caller=user_account, value=symbolic_value) ``` -Se i dati sono simbolici, Manticore esplorerà tutte le funzioni del contratto durante l'esecuzione della transazione. È utile consultare la spiegazione della funzione di fallback nell'articolo [Hands on the Ethernaut CTF](https://blog.trailofbits.com/2017/11/06/hands-on-the-ethernaut-ctf/) per comprendere come funziona la selezione delle funzioni. +Se i dati sono simbolici, Manticore esplorerà tutte le funzioni del contratto durante l'esecuzione della transazione. Sarà utile consultare la spiegazione della Funzione di Fallback nell'articolo [Hands on the Ethernaut CTF](https://blog.trailofbits.com/2017/11/06/hands-on-the-ethernaut-ctf/) per capire come funziona la selezione della funzione. #### Transazione con nome {#named-transaction} -Le funzioni sono eseguibili tramite il loro nome. Per eseguire `f(uint var)` con un valore simbolico, da user_account e con 0 ether, usa: +Le funzioni possono essere eseguite tramite il loro nome. +Per eseguire `f(uint var)` con un valore simbolico, da user_account, e con 0 ether, usare: ```python symbolic_var = m.make_symbolic_value() contract_account.f(symbolic_var, caller=user_account, value=0) ``` -Se `value` della transazione non è specificato, è 0 di default. +Se il `value` della transazione non è specificato, è 0 per impostazione predefinita. #### Riepilogo {#summary-1} - Gli argomenti di una transazione possono essere concreti o simbolici - Una transazione grezza esplorerà tutte le funzioni -- La funzione può essere chiamata con il suo nome +- Le funzioni possono essere chiamate per nome ### Area di lavoro {#workspace} -`m.workspace` è la directory usata come output per tutti i file generati: +`m.workspace` è la directory utilizzata come directory di output per tutti i file generati: ```python print("Results are in {}".format(m.workspace)) ``` -### Chiusura dell'esplorazione {#terminate-the-exploration} +### Terminare l'esplorazione {#terminate-the-exploration} -Per interrompere l'esplorazione usa [m.finalize()](https://manticore.readthedocs.io/en/latest/evm.html?highlight=finalize#manticore.ethereum.ManticoreEVM.finalize). Nessun'altra transazione dovrebbe essere inviata una volta chiamato questo metodo e dopo che Manticore ha generato test case per ognuno dei percorsi esplorati. +Per interrompere l'esplorazione, usare [m.finalize()](https://manticore.readthedocs.io/en/latest/evm.html?highlight=finalize#manticore.ethereum.ManticoreEVM.finalize). Nessuna ulteriore transazione deve essere inviata una volta chiamato questo metodo e Manticore genererà i casi di test per ciascun percorso esplorato. -### Riepilogo: esecuzione in Manticore {#summary-running-under-manticore} +### Riepilogo: Esecuzione con Manticore {#summary-running-under-manticore} -Mettendo insieme tutti i passaggi precedenti, otteniamo: +Mettendo insieme tutti i passaggi precedenti, si ottiene: ```python from manticore.ethereum import ManticoreEVM @@ -317,14 +320,14 @@ symbolic_var = m.make_symbolic_value() contract_account.f(symbolic_var) print("Results are in {}".format(m.workspace)) -m.finalize() # stop the exploration +m.finalize() # interrompe l'esplorazione ``` -Tutto il codice sopra lo puoi trovare in [`example_run.py`](https://github.com/crytic/building-secure-contracts/blob/master/program-analysis/manticore/examples/example_run.py) +Tutto il codice di cui sopra si trova in [`example_run.py`](https://github.com/crytic/building-secure-contracts/blob/master/program-analysis/manticore/examples/example_run.py) ## Ottenere i percorsi che generano eccezioni {#getting-throwing-paths} -Ora creeremo input specifici per i percorsi che generano un'eccezione in `f()`. La destinazione è ancora il seguente Smart Contract [`example.sol`](https://github.com/crytic/building-secure-contracts/blob/master/program-analysis/manticore/examples/example.sol): +Ora genereremo input specifici per i percorsi che sollevano un'eccezione in `f()`. L'obiettivo è ancora il seguente Smart Contract [`example.sol`](https://github.com/crytic/building-secure-contracts/blob/master/program-analysis/manticore/examples/example.sol): ```solidity pragma solidity >=0.4.24 <0.6.0; @@ -337,35 +340,35 @@ contract Simple { } ``` -### Uso delle informazioni di stato {#using-state-information} +### Utilizzo delle informazioni sullo stato {#using-state-information} -Ogni percorso eseguito ha il proprio stato della blockchain. Uno stato è pronto o terminato, a significare che ha raggiunto un'istruzione THROW o REVERT: +Ogni percorso eseguito ha il suo stato della blockchain. Uno stato è pronto o terminato, il che significa che raggiunge un'istruzione THROW o REVERT: -- [m.ready_states](https://manticore.readthedocs.io/en/latest/states.html#accessing): l'elenco degli stati pronti (cioè che non hanno eseguito un REVERT/INVALID) +- [m.ready_states](https://manticore.readthedocs.io/en/latest/states.html#accessing): l'elenco degli stati pronti (che non hanno eseguito un REVERT/INVALID) - [m.killed_states](https://manticore.readthedocs.io/en/latest/states.html#accessings): l'elenco degli stati terminati - [m.all_states](https://manticore.readthedocs.io/en/latest/states.html#accessings): tutti gli stati ```python for state in m.all_states: - # esegue un'operazione con lo stato + # fai qualcosa con lo stato ``` -Puoi accedere alle informazioni sullo stato. Per esempio: +È possibile accedere alle informazioni sullo stato. Per esempio: - `state.platform.get_balance(account.address)`: il saldo del conto - `state.platform.transactions`: l'elenco delle transazioni - `state.platform.transactions[-1].return_data`: i dati restituiti dall'ultima transazione -I dati restituiti dall'ultima transazione sono un array, convertibile in un valore con ABI.deserialize, per esempio: +I dati restituiti dall'ultima transazione sono un array, che può essere convertito in un valore con ABI.deserialize, ad esempio: ```python data = state.platform.transactions[0].return_data data = ABI.deserialize("uint", data) ``` -### Come generare test case {#how-to-generate-testcase} +### Come generare un caso di test {#how-to-generate-testcase} -Usa [m.generate_testcase(state, name)](https://manticore.readthedocs.io/en/latest/evm.html?highlight=generate_testcase#manticore.ethereum.ManticoreEVM.generate_testcase) per generare test case: +Usare [m.generate_testcase(state, name)](https://manticore.readthedocs.io/en/latest/evm.html?highlight=generate_testcase#manticore.ethereum.ManticoreEVM.generate_testcase) per generare un caso di test: ```python m.generate_testcase(state, 'BugFound') @@ -373,13 +376,13 @@ m.generate_testcase(state, 'BugFound') ### Riepilogo {#summary-2} -- Puoi eseguire iterazioni sullo stato con m.all_states +- È possibile iterare sullo stato con m.all_states - `state.platform.get_balance(account.address)` restituisce il saldo del conto - `state.platform.transactions` restituisce l'elenco delle transazioni - `transaction.return_data` sono i dati restituiti - `m.generate_testcase(state, name)` genera input per lo stato -### Riepilogo: ottenere il percorso che genera eccezioni {#summary-getting-throwing-path} +### Riepilogo: Ottenere percorsi che generano eccezioni {#summary-getting-throwing-path} ```python from manticore.ethereum import ManticoreEVM @@ -395,7 +398,8 @@ contract_account = m.solidity_create_contract(source_code, owner=user_account) symbolic_var = m.make_symbolic_value() contract_account.f(symbolic_var) -## Controlla se l'esecuzione termina con REVERT o INVALID +## Controlla se un'esecuzione termina con un REVERT o INVALID + for state in m.terminated_states: last_tx = state.platform.transactions[-1] if last_tx.result in ['REVERT', 'INVALID']: @@ -403,13 +407,13 @@ for state in m.terminated_states: m.generate_testcase(state, 'ThrowFound') ``` -Tutto il codice qui sopra si trova in [`example_run.py`](https://github.com/crytic/building-secure-contracts/blob/master/program-analysis/manticore/examples/example_run.py) +Tutto il codice di cui sopra si trova in [`example_run.py`](https://github.com/crytic/building-secure-contracts/blob/master/program-analysis/manticore/examples/example_run.py) -_Nota: avremmo potuto generare uno script molto più semplice poiché tutti gli stati restituiti da terminated_state hanno REVERT o INVALID nel risultato. Questo esempio era inteso solo per dimostrare come manipolare l'API._ +_Nota: avremmo potuto generare uno script molto più semplice, poiché tutti gli stati restituiti da terminated_state hanno REVERT o INVALID nel loro risultato: questo esempio aveva solo lo scopo di dimostrare come manipolare l'API._ ## Aggiunta di vincoli {#adding-constraints} -Vediamo ora come vincolare l'esplorazione. Presumiamo che la documentazione di `f()` indichi che la funzione non viene mai chiamata con `a == 65`, quindi ogni bug con `a == 65` non è un vero bug. La destinazione è ancora il seguente Smart Contract [`example.sol`](https://github.com/crytic/building-secure-contracts/blob/master/program-analysis/manticore/examples/example.sol): +Vedremo come vincolare l'esplorazione. Assumeremo che la documentazione di `f()` dichiari che la funzione non viene mai chiamata con `a == 65`, quindi qualsiasi bug con `a == 65` non è un bug reale. L'obiettivo è ancora il seguente Smart Contract [`example.sol`](https://github.com/crytic/building-secure-contracts/blob/master/program-analysis/manticore/examples/example.sol): ```solidity pragma solidity >=0.4.24 <0.6.0; @@ -424,7 +428,7 @@ contract Simple { ### Operatori {#operators} -Il modulo [Operators](https://github.com/trailofbits/manticore/blob/master/manticore/core/smtlib/operators.py) facilita la manipolazione dei vincoli, fornendo tra l'altro: +Il modulo [Operators](https://github.com/trailofbits/manticore/blob/master/manticore/core/smtlib/operators.py) facilita la manipolazione dei vincoli e, tra le altre cose, fornisce: - Operators.AND, - Operators.OR, @@ -433,13 +437,13 @@ Il modulo [Operators](https://github.com/trailofbits/manticore/blob/master/manti - Operators.ULT (minore di senza segno), - Operators.ULE (minore o uguale a senza segno). -Per importare il modulo usa: +Per importare il modulo, usare quanto segue: ```python from manticore.core.smtlib import Operators ``` -`Operators.CONCAT` è usato per concatenare un array a un valore. Per esempio, return_data di una transazione deve essere modificato in valore per poter essere verificato a fronte di un altro valore: +`Operators.CONCAT` viene usato per concatenare un array a un valore. Ad esempio, il return_data di una transazione deve essere modificato in un valore per essere confrontato con un altro valore: ```python last_return = Operators.CONCAT(256, *last_return) @@ -447,11 +451,12 @@ last_return = Operators.CONCAT(256, *last_return) ### Vincoli {#state-constraint} -Puoi usare vincoli globalmente o per uno stato specifico. +È possibile usare vincoli a livello globale o per uno stato specifico. #### Vincolo globale {#state-constraint} -Usa `m.constrain(constraint)` per aggiungere un vincolo globale. Per esempio, puoi chiamare un contratto da un indirizzo simbolico e limitare quest'indirizzo a valori specifici: +Usare `m.constrain(constraint)` per aggiungere un vincolo globale. +Ad esempio, è possibile chiamare un contratto da un indirizzo simbolico e vincolare questo indirizzo a valori specifici: ```python symbolic_address = m.make_symbolic_value() @@ -464,11 +469,13 @@ m.transaction(caller=user_account, #### Vincolo di stato {#state-constraint} -Usa [state.constrain(constraint)](https://manticore.readthedocs.io/en/latest/states.html?highlight=StateBase#manticore.core.state.StateBase.constrain) per aggiungere un vincolo a uno stato specifico Può essere usato per vincolare lo stato dopo la sua esplorazione per verificarvi della proprietà. +Usare [state.constrain(constraint)](https://manticore.readthedocs.io/en/latest/states.html?highlight=StateBase#manticore.core.state.StateBase.constrain) per aggiungere un vincolo a uno stato specifico. +Può essere usato per vincolare lo stato dopo la sua esplorazione per verificare una proprietà su di esso. -### Controllo di un vincolo {#checking-constraint} +### Verifica del vincolo {#checking-constraint} -Usa `solver.check(state.constraints)` per sapere se un vincolo è ancora fattibile. Per esempio, il codice seguente vincola symbolic_value ad essere diverso da 65 e controlla se lo stato è ancora fattibile: +Usare `solver.check(state.constraints)` per sapere se un vincolo è ancora fattibile. +Ad esempio, quanto segue vincolerà symbolic_value a essere diverso da 65 e verificherà se lo stato è ancora fattibile: ```python state.constrain(symbolic_var != 65) @@ -476,9 +483,9 @@ if solver.check(state.constraints): # lo stato è fattibile ``` -### Riepilogo: aggiunta di vincoli {#summary-adding-constraints} +### Riepilogo: Aggiunta di vincoli {#summary-adding-constraints} -Aggiungendo il vincolo al codice precedente, otteniamo: +Aggiungendo un vincolo al codice precedente, si ottiene: ```python from manticore.ethereum import ManticoreEVM @@ -499,18 +506,19 @@ contract_account.f(symbolic_var) no_bug_found = True -## Controlla se l'esecuzione termina con REVERT o INVALID +## Controlla se un'esecuzione termina con un REVERT o INVALID + for state in m.terminated_states: last_tx = state.platform.transactions[-1] if last_tx.result in ['REVERT', 'INVALID']: - # we do not consider the path were a == 65 + # non consideriamo il percorso in cui a == 65 condition = symbolic_var != 65 if m.generate_testcase(state, name="BugFound", only_if=condition): - print(f'Bug found, results are in {m.workspace}') + print(f'Trovato bug, i risultati sono in {m.workspace}') no_bug_found = False if no_bug_found: - print(f'No bug found') + print(f'Nessun bug trovato') ``` -Tutto il codice sopra si può trovare in [`example_run.py`](https://github.com/crytic/building-secure-contracts/blob/master/program-analysis/manticore/examples/example_run.py) +Tutto il codice di cui sopra si trova in [`example_run.py`](https://github.com/crytic/building-secure-contracts/blob/master/program-analysis/manticore/examples/example_run.py) diff --git a/public/content/translations/it/developers/tutorials/how-to-use-slither-to-find-smart-contract-bugs/index.md b/public/content/translations/it/developers/tutorials/how-to-use-slither-to-find-smart-contract-bugs/index.md index 28111da448b..2d63a281cb6 100644 --- a/public/content/translations/it/developers/tutorials/how-to-use-slither-to-find-smart-contract-bugs/index.md +++ b/public/content/translations/it/developers/tutorials/how-to-use-slither-to-find-smart-contract-bugs/index.md @@ -1,49 +1,44 @@ --- -title: Come usare Slither per trovare i bug dello Smart Contract -description: Come usare Slither per trovare automaticamente bug negli Smart Contract +title: Come usare Slither per trovare bug nei contratti intelligenti +description: Come usare Slither per trovare automaticamente bug nei contratti intelligenti author: Trailofbits lang: it -tags: - - "solidity" - - "contratti intelligenti" - - "sicurezza" - - "test" - - "analisi statica" +tags: [ "Solidity", "smart contract", "sicurezza", "test" ] skill: advanced published: 2020-06-09 -source: Creare contratti sicuri +source: Building secure contracts sourceUrl: https://github.com/crytic/building-secure-contracts/tree/master/program-analysis/slither --- ## Come usare Slither {#how-to-use-slither} -L'obiettivo di questo tutorial è mostrare come usare Slither per trovare automaticamente bug negli Smart Contract. +L'obiettivo di questo tutorial è mostrare come usare Slither per trovare automaticamente bug nei contratti intelligenti. - [Installazione](#installation) -- [Uso dalla riga di comando](#command-line) -- [Introduzione all'analisi statica](#static-analysis): breve introduzione all'analisi statica -- [API](#api-basics): descrizione dell'API Python +- [Uso della riga di comando](#command-line) +- [Introduzione all'analisi statica](#static-analysis): Breve introduzione all'analisi statica +- [API](#api-basics): Descrizione dell'API Python ## Installazione {#installation} -Slither richiede Python >=3.6. Può essere installato tramite pip o usando docker. +Slither richiede Python >= 3.6. Può essere installato tramite pip o usando docker. -Slither con pip: +Slither tramite pip: ```bash pip3 install --user slither-analyzer ``` -Slither con docker: +Slither tramite docker: ```bash docker pull trailofbits/eth-security-toolbox docker run -it -v "$PWD":/home/trufflecon trailofbits/eth-security-toolbox ``` -_L'ultimo comando esegue eth-security-toolbox in un docker che ha accesso alla directory corrente. Puoi cambiare i file dall'host ed eseguire gli strumenti sui file dal docker_ +_L'ultimo comando esegue eth-security-toolbox in un docker che ha accesso alla tua directory corrente. Puoi modificare i file dal tuo host ed eseguire gli strumenti sui file dal docker_ -In docker, esegui: +All'interno del docker, esegui: ```bash solc-select 0.5.11 @@ -60,23 +55,23 @@ python3 script.py ### Riga di comando {#command-line} -**Riga di comando e script definiti dall'utente.** Slither comprende una serie di rilevatori predefiniti che trovano molti bug comuni. Chiamare Slither dalla riga di comando eseguirà tutti i rilevatori, non è necessaria alcuna conoscenza dettagliata dell'analisi statica: +**Riga di comando e script definiti dall'utente.** Slither è dotato di una serie di rilevatori predefiniti che trovano molti bug comuni. Chiamare Slither dalla riga di comando eseguirà tutti i rilevatori; non è necessaria alcuna conoscenza dettagliata dell'analisi statica: ```bash slither project_paths ``` -Oltre ai rilevatori, Slither ha capacità di revisione del codice tramite le sue [stampanti](https://github.com/crytic/slither#printers) e i suoi [strumenti](https://github.com/crytic/slither#tools). +Oltre ai rilevatori, Slither ha funzionalità di revisione del codice tramite i suoi [printer](https://github.com/crytic/slither#printers) e [strumenti](https://github.com/crytic/slither#tools). -Usa [crytic.io](https://github.com/crytic) per ottenere accesso ai rilevatori privati e integrazione con GitHub. +Usa [crytic.io](https://github.com/crytic) per ottenere l'accesso ai rilevatori privati e all'integrazione con GitHub. ## Analisi statica {#static-analysis} -Le capacità e il design del framework di analisi statica di Slither sono stati descritti in post di blog ([1](https://blog.trailofbits.com/2018/10/19/slither-a-solidity-static-analysis-framework/), [2](https://blog.trailofbits.com/2019/05/27/slither-the-leading-static-analyzer-for-smart-contracts/)) e in un [paper accademico](https://github.com/trailofbits/publications/blob/master/papers/wetseb19.pdf). +Le funzionalità e il design del framework di analisi statica di Slither sono stati descritti in post del blog ([1](https://blog.trailofbits.com/2018/10/19/slither-a-solidity-static-analysis-framework/), [2](https://blog.trailofbits.com/2019/05/27/slither-the-leading-static-analyzer-for-smart-contracts/)) e in un [articolo accademico](https://github.com/trailofbits/publications/blob/master/papers/wetseb19.pdf). -L'analisi statica esiste in diversi tipi. Molto probabilmente ti renderai conto che compilatori come [clang](https://clang-analyzer.llvm.org/) e [gcc](https://lwn.net/Articles/806099/) dipendono da queste tecniche di ricerca, che sono anche alla base di [Infer](https://fbinfer.com/), [CodeClimate](https://codeclimate.com/), [FindBugs](http://findbugs.sourceforge.net/) e strumenti basati sui metodi formali come [Frama-C](https://frama-c.com/) e [Polyspace](https://www.mathworks.com/products/polyspace.html). +L'analisi statica esiste in diverse varianti. Molto probabilmente ti rendi conto che i compilatori come [clang](https://clang-analyzer.llvm.org/) e [gcc](https://lwn.net/Articles/806099/) dipendono da queste tecniche di ricerca, ma essa è anche alla base di ([Infer](https://fbinfer.com/), [CodeClimate](https://codeclimate.com/), [FindBugs](http://findbugs.sourceforge.net/) e strumenti basati su metodi formali come [Frama-C](https://frama-c.com/) e [Polyspace](https://www.mathworks.com/products/polyspace.html)). -Qui non esamineremo in modo esaustivo le tecniche di analisi statica e il ricercatore. Ci concentreremo invece su ciò che serve per capire come funziona Slither così da poterlo usare più efficacemente per trovare bug e comprendere il codice. +Qui non esamineremo in modo esaustivo le tecniche di analisi statica e la ricerca in materia. Ci concentreremo invece su ciò che serve per capire come funziona Slither, in modo da poterlo usare più efficacemente per trovare bug e comprendere il codice. - [Rappresentazione del codice](#code-representation) - [Analisi del codice](#analysis) @@ -84,13 +79,13 @@ Qui non esamineremo in modo esaustivo le tecniche di analisi statica e il ricerc ### Rappresentazione del codice {#code-representation} -A differenza dell'analisi dinamica, che ragiona su un percorso di esecuzione singolo, l'analisi statica ragiona su tutti i percorsi contemporaneamente. Per farlo, si basa su una diversa rappresentazione del codice. Le due tipologie più comuni sono l'albero di sintassi astratta (AST) e il grafico del flusso di controllo (CFG). +A differenza di un'analisi dinamica, che ragiona su un singolo percorso di esecuzione, l'analisi statica ragiona su tutti i percorsi contemporaneamente. Per farlo, si basa su una diversa rappresentazione del codice. Le due più comuni sono l'albero di sintassi astratta (AST) e il grafico del flusso di controllo (CFG). ### Alberi di sintassi astratta (AST) {#abstract-syntax-trees-ast} -Gli AST sono usati ogni volta che il compilatore analizza il codice. Sono probabilmente la struttura più basilare su cui è eseguibile l'analisi statica. +Gli AST sono usati ogni volta che il compilatore analizza sintatticamente il codice. Sono probabilmente la struttura più basilare su cui è possibile eseguire un'analisi statica. -In pillole, un AST è un albero strutturato dove, di solito, ogni foglia contiene una variabile o una costante e i nodi interni sono operandi o controllano le operazioni del flusso. Considera il codice seguente: +In breve, un AST è un albero strutturato in cui, di solito, ogni foglia contiene una variabile o una costante e i nodi interni sono operandi o operazioni di controllo del flusso. Considera il codice seguente: ```solidity function safeAdd(uint a, uint b) pure internal returns(uint){ @@ -107,9 +102,9 @@ L'AST corrispondente è mostrato in: Slither usa l'AST esportato da solc. -Sebbene semplice da costruire, l'AST è una struttura nidificata. A volte, non è la più semplice da analizzare. Per esempio, per identificare le operazioni usate dall'espressione `a + b <= a`, devi prima analizzare `<=` e poi `+`. Un approccio comune è usare il cosiddetto schema dei visitatori, che naviga l'albero in modo ricorsivo. Slither contiene un visitatore generico in [`ExpressionVisitor`](https://github.com/crytic/slither/blob/master/slither/visitors/expression/expression.py). +Sebbene sia semplice da costruire, l'AST è una struttura nidificata. A volte, non è la più semplice da analizzare. Ad esempio, per identificare le operazioni usate dall'espressione `a + b <= a`, devi prima analizzare `<=` e poi `+`. Un approccio comune è usare il cosiddetto pattern visitor, che naviga ricorsivamente l'albero. Slither contiene un visitor generico in [`ExpressionVisitor`](https://github.com/crytic/slither/blob/master/slither/visitors/expression/expression.py). -Il codice seguente usa `ExpressionVisitor` per rilevare se l'espressione contiene una somma: +Il codice seguente usa `ExpressionVisitor` per rilevare se l'espressione contiene un'addizione: ```python from slither.visitors.expression.expression import ExpressionVisitor @@ -124,43 +119,43 @@ class HasAddition(ExpressionVisitor): if expression.type == BinaryOperationType.ADDITION: self._result = True -visitor = HasAddition(expression) # expression is the expression to be tested +visitor = HasAddition(expression) # expression è l'espressione da testare print(f'The expression {expression} has a addition: {visitor.result()}') ``` ### Grafico del flusso di controllo (CFG) {#control-flow-graph-cfg} -La seconda rappresentazione più comune del codice è il grafico del flusso di controllo (CFG). Come suggerisce il nome, è una rappresentazione basata su un grafico, che espone tutti i percorsi d'esecuzione. Ogni nodo contiene una o più istruzioni. I bordi nel grafico rappresentano le operazioni del flusso di controllo (if/then/else, loop, ecc). Il CFG del nostro esempio precedente è: +La seconda rappresentazione più comune del codice è il grafico del flusso di controllo (CFG). Come suggerisce il nome, è una rappresentazione basata su grafico che espone tutti i percorsi di esecuzione. Ogni nodo contiene una o più istruzioni. Gli archi nel grafico rappresentano le operazioni di controllo del flusso (if/then/else, loop, ecc.). Il CFG del nostro esempio precedente è: ![CFG](./cfg.png) -Il CFG è la rappresentazione su cui gran parte delle analisi sono costruite. +Il CFG è la rappresentazione su cui si basa la maggior parte delle analisi. Esistono molte altre rappresentazioni del codice. Ogni rappresentazione ha vantaggi e svantaggi a seconda dell'analisi che si desidera eseguire. ### Analisi {#analysis} -Il tipo più semplice di analisi eseguibile con Slither è l'analisi sintattica. +Il tipo di analisi più semplice che puoi eseguire con Slither è l'analisi sintattica. ### Analisi della sintassi {#syntax-analysis} -Slither può navigare attraverso diversi componenti del codice e la loro rappresentazione per trovare incoerenze e difetti usando un approccio simile all'abbinamento a schemi. +Slither può navigare attraverso i diversi componenti del codice e la loro rappresentazione per trovare incoerenze e difetti usando un approccio simile al pattern matching. -Per esempio i seguenti rilevatori cercano problemi correlati alla sintassi: +Ad esempio, i seguenti rilevatori cercano problemi relativi alla sintassi: -- [Shadowing della variabile di stato](https://github.com/crytic/slither/wiki/Detector-Documentation#state-variable-shadowing): esegue iterazioni su tutte le variabili di stato e controlla se qualcuna esegue lo shadowing di una variabile da un contratto ereditato ([state.py#L51-L62](https://github.com/crytic/slither/blob/0441338e055ab7151b30ca69258561a5a793f8ba/slither/detectors/shadowing/state.py#L51-L62)) +- [Shadowing di variabile di stato](https://github.com/crytic/slither/wiki/Detector-Documentation#state-variable-shadowing): itera su tutte le variabili di stato e controlla se qualcuna di esse nasconde una variabile di un contratto ereditato ([state.py#L51-L62](https://github.com/crytic/slither/blob/0441338e055ab7151b30ca69258561a5a793f8ba/slither/detectors/shadowing/state.py#L51-L62)) -- [Interfaccia errata di ERC20](https://github.com/crytic/slither/wiki/Detector-Documentation#incorrect-erc20-interface): cerca firme della funzione ERC20 errate ([incorrect_erc20_interface.py#L34-L55](https://github.com/crytic/slither/blob/0441338e055ab7151b30ca69258561a5a793f8ba/slither/detectors/erc/incorrect_erc20_interface.py#L34-L55)) +- [Interfaccia ERC20 non corretta](https://github.com/crytic/slither/wiki/Detector-Documentation#incorrect-erc20-interface): cerca le firme di funzione ERC20 non corrette ([incorrect_erc20_interface.py#L34-L55](https://github.com/crytic/slither/blob/0441338e055ab7151b30ca69258561a5a793f8ba/slither/detectors/erc/incorrect_erc20_interface.py#L34-L55)) ### Analisi semantica {#semantic-analysis} -A differenza dell'analisi di sintassi, un'analisi semantica va più in profondità e analizza il "significato" del codice. Questa famiglia include alcuni tipi generici di analisi. Conducono a risultati più potenti e utili, ma anche più complessi da scrivere. +A differenza dell'analisi della sintassi, un'analisi semantica va più in profondità e analizza il "significato" del codice. Questa famiglia include alcuni tipi ampi di analisi. Portano a risultati più potenti e utili, ma sono anche più complessi da scrivere. -Le analisi semantiche sono usate per i rilevamenti più avanzati delle vulnerabilità. +Le analisi semantiche sono usate per i rilevamenti di vulnerabilità più avanzati. #### Analisi della dipendenza dei dati {#fixed-point-computation} -Una variabile `variable_a` si dice dipendente dai dati di `variable_b` se esiste un percorso per cui il valore di `variable_a` è influenzato da `variable_b`. +Una variabile `variable_a` si dice dipendente dai dati di `variable_b` se esiste un percorso per il quale il valore di `variable_a` è influenzato da `variable_b`. Nel codice seguente, `variable_a` dipende da `variable_b`: @@ -169,13 +164,13 @@ Nel codice seguente, `variable_a` dipende da `variable_b`: variable_a = variable_b + 1; ``` -Slither è dotato di capacità integrate di [dipendenza dai dati](https://github.com/crytic/slither/wiki/data-dependency), grazie alla sua rappresentazione intermedia (discussa in una sezione successiva). +Slither è dotato di funzionalità integrate di [dipendenza dei dati](https://github.com/crytic/slither/wiki/data-dependency), grazie alla sua rappresentazione intermedia (discussa in una sezione successiva). -Un esempio di uso della dipendenza dei dati si può trovare nel [rilevatore di uguaglianze rigorose pericolose](https://github.com/crytic/slither/wiki/Detector-Documentation#dangerous-strict-equalities). In questo caso Slither cercherà confronti tra uguaglianze rigorose a un valore pericoloso ([incorrect_strict_equality.py#L86-L87](https://github.com/crytic/slither/blob/6d86220a53603476f9567c3358524ea4db07fb25/slither/detectors/statements/incorrect_strict_equality.py#L86-L87)), e informerà l'utente che dovrebbe usare `>=` o `<=` anziché `==`, per impedire a un malintenzionato di bloccare il contratto. Tra gli altri, il rilevatore considererà come pericoloso il valore restituito da una chiamata di `balanceOf(address)` ([incorrect_strict_equality.py#L63-L64](https://github.com/crytic/slither/blob/6d86220a53603476f9567c3358524ea4db07fb25/slither/detectors/statements/incorrect_strict_equality.py#L63-L64)), e userà il motore delle dipendenze dei dati per monitorarne l'uso. +Un esempio di utilizzo della dipendenza dei dati si trova nel [rilevatore di uguaglianze strette pericolose](https://github.com/crytic/slither/wiki/Detector-Documentation#dangerous-strict-equalities). Qui Slither cercherà un confronto di uguaglianza stretta con un valore pericoloso ([incorrect_strict_equality.py#L86-L87](https://github.com/crytic/slither/blob/6d86220a53603476f9567c3358524ea4db07fb25/slither/detectors/statements/incorrect_strict_equality.py#L86-L87)) e informerà l'utente che dovrebbe usare `>=` o `<=` invece di `==`, per impedire a un utente malintenzionato di intrappolare il contratto. Tra le altre cose, il rilevatore considererà pericoloso il valore restituito di una chiamata a `balanceOf(indirizzo)` ([incorrect_strict_equality.py#L63-L64](https://github.com/crytic/slither/blob/6d86220a53603476f9567c3358524ea4db07fb25/slither/detectors/statements/incorrect_strict_equality.py#L63-L64)) e utilizzerà il motore di dipendenza dei dati per tracciarne l'uso. #### Calcolo del punto fisso {#fixed-point-computation} -Se l'analisi naviga attraverso il CFG e segue i bordi, potresti vedere nodi già visitati. Per esempio, se un ciclo viene presentato come mostrato sotto: +Se la tua analisi naviga attraverso il CFG e ne segue gli archi, è probabile che tu veda nodi già visitati. Ad esempio, se un loop è presentato come mostrato di seguito: ```solidity for(uint i; i < range; ++){ @@ -183,37 +178,37 @@ for(uint i; i < range; ++){ } ``` -L'analisi dovrà sapere quando interrompersi. Qui esistono due strategie principali: (1) itera su ogni nodo un numero finito di volte, (2) calcola un cosiddetto _fixpoint_ (punto fisso). Un punto fisso indica fondamentalmente che analizzare il nodo non fornisce alcuna informazione utile. +La tua analisi dovrà sapere quando fermarsi. Ci sono due strategie principali: (1) iterare su ogni nodo un numero finito di volte, (2) calcolare un cosiddetto _punto fisso_. Un punto fisso significa fondamentalmente che l'analisi di questo nodo non fornisce più alcuna informazione significativa. -Un esempio di punto fisso usato si può trovare nei rilevatori di rientranza: Slither esplora i nodi e cerca chiamate esterne, scrive e legge lo storage. Una volta raggiunto un punto fisso ([reentrancy.py#L125-L131](https://github.com/crytic/slither/blob/master/slither/detectors/reentrancy/reentrancy.py#L125-L131)), interrompe l'esplorazione e analizza i risultati per vedere se è presente una rientranza, tramite diversi schemi di rientranza ([reentrancy_benign.py](https://github.com/crytic/slither/blob/b275bcc824b1b932310cf03b6bfb1a1fef0ebae1/slither/detectors/reentrancy/reentrancy_benign.py), [reentrancy_read_before_write.py](https://github.com/crytic/slither/blob/b275bcc824b1b932310cf03b6bfb1a1fef0ebae1/slither/detectors/reentrancy/reentrancy_read_before_write.py), [reentrancy_eth.py](https://github.com/crytic/slither/blob/b275bcc824b1b932310cf03b6bfb1a1fef0ebae1/slither/detectors/reentrancy/reentrancy_eth.py)). +Un esempio di utilizzo del punto fisso si può trovare nei rilevatori di rientranza: Slither esplora i nodi e cerca chiamate esterne, operazioni di scrittura e lettura dello storage. Una volta raggiunto un punto fisso ([reentrancy.py#L125-L131](https://github.com/crytic/slither/blob/master/slither/detectors/reentrancy/reentrancy.py#L125-L131)), interrompe l'esplorazione e analizza i risultati per vedere se è presente una rientranza, attraverso diversi pattern di rientranza ([reentrancy_benign.py](https://github.com/crytic/slither/blob/b275bcc824b1b932310cf03b6bfb1a1fef0ebae1/slither/detectors/reentrancy/reentrancy_benign.py), [reentrancy_read_before_write.py](https://github.com/crytic/slither/blob/b275bcc824b1b932310cf03b6bfb1a1fef0ebae1/slither/detectors/reentrancy/reentrancy_read_before_write.py), [reentrancy_eth.py](https://github.com/crytic/slither/blob/b275bcc824b1b932310cf03b6bfb1a1fef0ebae1/slither/detectors/reentrancy/reentrancy_eth.py)). -La scrittura dell'analisi tramite un calcolo efficiente dei punti fissi richiede una buona comprensione di come l'analisi propaga le informazioni. +Scrivere analisi utilizzando un calcolo efficiente del punto fisso richiede una buona comprensione di come l'analisi propaga le sue informazioni. ### Rappresentazione intermedia {#intermediate-representation} -Una rappresentazione intermedia (IR) è un linguaggio pensato per essere più adatto all'analisi statica che a quella originale. Slither traduce Solidity nella propria rappresentazione intermedia: [SlithIR](https://github.com/crytic/slither/wiki/SlithIR). +Una rappresentazione intermedia (IR) è un linguaggio inteso per essere più adatto all'analisi statica rispetto a quello originale. Slither traduce Solidity nella sua IR: [SlithIR](https://github.com/crytic/slither/wiki/SlithIR). -Comprendere SlithIR non è necessario per scrivere controlli di base. È invece utile se pensi di scrivere analisi semantiche avanzate. Le stampanti [SlithIR](https://github.com/crytic/slither/wiki/Printer-documentation#slithir) e [SSA](https://github.com/crytic/slither/wiki/Printer-documentation#slithir-ssa) aiuteranno a comprendere come è tradotto il codice. +Comprendere SlithIR non è necessario se si vogliono scrivere solo controlli di base. Tuttavia, sarà utile se hai intenzione di scrivere analisi semantiche avanzate. I printer [SlithIR](https://github.com/crytic/slither/wiki/Printer-documentation#slithir) e [SSA](https://github.com/crytic/slither/wiki/Printer-documentation#slithir-ssa) ti aiuteranno a capire come viene tradotto il codice. -## Fondamenti delle API {#api-basics} +## Nozioni di base sull'API {#api-basics} -Slither ha un'API che consente di esplorare gli attributi di base del contratto e le sue funzioni. +Slither ha un'API che ti permette di esplorare gli attributi di base del contratto e le sue funzioni. -Per caricare una base di codice: +Per caricare una codebase: ```python from slither import Slither -slither = Slither('/path/to/project') +slither = Slither('/percorso/del/progetto') ``` -### Esplorare contratti e funzioni {#exploring-contracts-and-functions} +### Esplorazione di contratti e funzioni {#exploring-contracts-and-functions} Un oggetto `Slither` ha: - `contracts (list(Contract)`: elenco di contratti -- `contracts_derived (list(Contract)`: elenco dei contratti che non vengono ereditati da un altro contratto (sottoinsieme di contratti) -- `get_contract_from_name (str)`: restituisce un contratto dal nome +- `contracts_derived (list(Contract)`: elenco di contratti non ereditati da un altro contratto (sottoinsieme di contratti) +- `get_contract_from_name (str)`: restituisce un contratto dal suo nome Un oggetto `Contract` ha: @@ -222,17 +217,17 @@ Un oggetto `Contract` ha: - `modifiers (list(Modifier))`: elenco di funzioni - `all_functions_called (list(Function/Modifier))`: elenco di tutte le funzioni interne raggiungibili dal contratto - `inheritance (list(Contract))`: elenco di contratti ereditati -- `get_function_from_signature (str)`: restituisce una funzione dalla firma -- `get_modifier_from_signature (str)`: restituisce un modificatore dalla firma -- `get_state_variable_from_name (str)`: restituisce una variabile di stato dal nome +- `get_function_from_signature (str)`: restituisce una funzione dalla sua firma +- `get_modifier_from_signature (str)`: restituisce un modificatore dalla sua firma +- `get_state_variable_from_name (str)`: restituisce una StateVariable dal suo nome Un oggetto `Function` o `Modifier` ha: - `name (str)`: nome della funzione -- `contract (contract)`: il contratto in cui è dichiarata la funzione -- `nodes (list(Node))`: elenco dei nodi che compongono il CFG della funzione o del modificatore +- `contract (contract)`: il contratto in cui la funzione è dichiarata +- `nodes (list(Node))`: elenco dei nodi che compongono il CFG della funzione/modificatore - `entry_point (Node)`: punto di ingresso del CFG -- `variables_read (list(Variable))`: elenco delle variabili lette -- `variables_written (list(Variable))`: elenco delle variabili scritte -- `state_variables_read (list(StateVariable))`: elenco delle variabili di stato lette (sottoinsieme di variables`read) -- `state_variables_written (list(StateVariable))`: elenco delle variabili di stato scritte (sottoinsieme di variables`written) +- `variables_read (list(Variable))`: elenco di variabili lette +- `variables_written (list(Variable))`: elenco di variabili scritte +- `state_variables_read (list(StateVariable))`: elenco di variabili di stato lette (sottoinsieme di `variables_read`) +- `state_variables_written (list(StateVariable))`: elenco di variabili di stato scritte (sottoinsieme di `variables_written`) diff --git a/public/content/translations/it/developers/tutorials/how-to-use-tellor-as-your-oracle/index.md b/public/content/translations/it/developers/tutorials/how-to-use-tellor-as-your-oracle/index.md index 8a4d38bb867..e53056c8f23 100644 --- a/public/content/translations/it/developers/tutorials/how-to-use-tellor-as-your-oracle/index.md +++ b/public/content/translations/it/developers/tutorials/how-to-use-tellor-as-your-oracle/index.md @@ -1,51 +1,48 @@ --- -title: Come Configurare Tellor come tuo Oracolo +title: Come configurare Tellor come proprio oracolo description: Una guida per iniziare a integrare l'oracolo di Tellor nel tuo protocollo author: "Tellor" lang: it -tags: - - "solidity" - - "contratti intelligenti" - - "oracoli" +tags: [ "Solidity", "smart contract", "oracoli" ] skill: beginner published: 2021-06-29 -source: Documentazione di Tellor +source: Tellor Docs sourceUrl: https://docs.tellor.io/tellor/ --- -Quiz: il tuo protocollo è appena terminato, ma ti serve un oracolo per avere accesso ai dati esterni alla catena... Cosa fai? +Quiz: il tuo protocollo è quasi finito, ma ha bisogno di un oracolo per accedere a dati fuori dalla catena... Cosa fai? -## (Soft) Prerequisiti {#soft-prerequisites} +## (Prerequisiti consigliati) {#soft-prerequisites} Questo post intende rendere l'accesso al feed dell'oracolo il più semplice e diretto possibile. Detto ciò, per concentrarci sull'aspetto dell'oracolo, presumiamo da parte tua le seguenti abilità di programmazione. -Premesse: +Presupposti: -- se capage di muoverti nella console +- sai muoverti in un terminale - hai installato npm - sai come usare npm per gestire le dipendenze -Tellor è un oracolo in diretta e open source pronto all'implementazione. Questa guida per principianti serve a mostrare la facilità con cui puoi metterti al lavoro con Tellor, fornendo il tuo progetto con un oracolo completamente decentralizzato e resistente alla censura. +Tellor è un oracolo open-source attivo e pronto per l'implementazione. Questa guida per principianti serve a mostrare la facilità con cui è possibile iniziare a usare Tellor, fornendo al tuo progetto un oracolo completamente decentralizzato e resistente alla censura. ## Panoramica {#overview} -Tellor è un sistema di oracolo in cui le parti possono richiedere il valore di un punto di dati esterno alla catena (es. BTC/USD) e i segnalatori competono ad aggiungere tale valore a una banca dati sulla catena, accessibile da tutti i contratti intelligenti di Ethereum. Gli input a questa banca dati sono protetti da una rete di reporter di staking. Tellor utilizza dei meccanismi d'incentivazione cripto-economica, ricompensando gli invii di dati onesti dai segnalatori e punendo gli utenti malevoli tramite l'emissione del token di Tellor, Tributes (TRB) e un meccanismo di disputa. +Tellor è un sistema di oracolo in cui le parti possono richiedere il valore di un dato fuori dalla catena (ad es., BTC/USD) e i reporter competono per aggiungere questo valore a una banca dati sulla catena, accessibile da tutti gli smart contract di Ethereum. Gli input di questa banca dati sono protetti da una rete di reporter con staking. Tellor utilizza meccanismi di incentivazione cripto-economica, premiando l'invio di dati onesti da parte dei reporter e punendo gli attori malintenzionati tramite l'emissione del token di Tellor, Tributes (TRB), e un meccanismo di disputa. -In questo tutorial, esamineremo: +In questa guida vedremo: -- Configurazione del toolkit iniziale di cui ha bisogno per metterti al lavoro. -- Guida a un semplice esempio. -- Elenco degli indirizzi testnet delle reti su cui puoi testare Tellor in questo momento. +- Configurazione del toolkit iniziale di cui avrai bisogno per iniziare. +- Analisi di un semplice esempio. +- Elenco degli indirizzi delle reti di test su cui puoi attualmente provare Tellor. -## Usare Tellor {#usingtellor} +## UsingTellor {#usingtellor} -La prima cosa che dovrai fare è installare gli strumenti di base necessari per usare Tellor come oracolo. Usa [questo pacchetto](https://github.com/tellor-io/usingtellor) per installare i Contratti Utente di Tellor: +La prima cosa che dovrai fare è installare gli strumenti di base necessari per usare Tellor come tuo oracolo. Usa [questo pacchetto](https://github.com/tellor-io/usingtellor) per installare i Tellor User Contracts: `npm install usingtellor` Una volta installato, i tuoi contratti potranno ereditare le funzioni dal contratto 'UsingTellor'. -Ottimo! Ora che hai preparato gli strumenti, guardiamo un semplice esercizio in cui recuperiamo il prezzo Bitcoin: +Ottimo! Ora che hai gli strumenti pronti, esaminiamo un semplice esercizio in cui recuperiamo il prezzo di bitcoin: ### Esempio BTC/USD {#btcusd-example} @@ -59,7 +56,7 @@ import "usingtellor/contracts/UsingTellor.sol"; contract PriceContract is UsingTellor { uint256 public btcPrice; - //This Contract now has access to all functions in UsingTellor + //Questo Contratto ora ha accesso a tutte le funzioni in UsingTellor constructor(address payable _tellorAddress) UsingTellor(_tellorAddress) public {} @@ -77,8 +74,8 @@ function setBtcPrice() public { } ``` -Per un elenco completo degli indirizzi dei contratti, fai riferimento a [questa guida](https://docs.tellor.io/tellor/the-basics/contracts-reference). +Per un elenco completo degli indirizzi dei contratti, consulta [qui](https://docs.tellor.io/tellor/the-basics/contracts-reference). -Per semplicità d'uso, la repository UsingTellort è dotata di una versione del contratto [Tellor Playground](https://github.com/tellor-io/TellorPlayground), per una più facile integrazione. Visualizza [questa pagina](https://github.com/tellor-io/sampleUsingTellor#tellor-playground) per un elenco delle funzioni utili. +Per facilità d'uso, il repo UsingTellor include una versione del contratto [Tellor Playground](https://github.com/tellor-io/TellorPlayground) per un'integrazione più semplice. Consulta [qui](https://github.com/tellor-io/sampleUsingTellor#tellor-playground) per un elenco di funzioni utili. -Per un'implementazione più robusta dell'oracolo di Tellor, consulta [qui](https://github.com/tellor-io/usingtellor/blob/master/README.md) l'elenco completo delle funzioni disponibili. +Per un'implementazione più robusta dell'oracolo Tellor, consulta l'elenco completo delle funzioni disponibili [qui](https://github.com/tellor-io/usingtellor/blob/master/README.md). diff --git a/public/content/translations/it/developers/tutorials/how-to-view-nft-in-metamask/index.md b/public/content/translations/it/developers/tutorials/how-to-view-nft-in-metamask/index.md index c9b3a494aea..bfe832a3e93 100644 --- a/public/content/translations/it/developers/tutorials/how-to-view-nft-in-metamask/index.md +++ b/public/content/translations/it/developers/tutorials/how-to-view-nft-in-metamask/index.md @@ -1,35 +1,32 @@ --- title: Come visualizzare il tuo NFT nel portafoglio (Parte 3/3 della Serie di tutorial sugli NFT) -description: Questo tutorial descrive come visualizzare un NFT esistente su Metamask! +description: Questo tutorial descrive come visualizzare un NFT esistente su MetaMask! author: "Sumi Mudgil" -tags: - - "ERC-721" - - "Alchemy" - - "Solidity" +tags: [ "ERC-721", "Alchemy", "Solidity" ] skill: beginner lang: it published: 2021-04-22 --- -Questo tutorial è la Parte 3/3 della serie di Tutorial sugli NFT, dove visualizziamo il nostro NFT appena coniato. Tuttavia, puoi usare il tutorial generico per qualsiasi token ERC-721 usando MetaMask, anche sulla rete principale o su qualsiasi testnet. Se vorresti imparare come coniare il tuo NFT su Ethereum, dovresti dare un'occhiata alla [Parte 1 su Come Scrivere e Distribuire un contratto intelligente NFT](/developers/tutorials/how-to-write-and-deploy-an-nft)! +Questo tutorial è la Parte 3/3 della serie di Tutorial sugli NFT, dove visualizziamo il nostro NFT appena coniato. Tuttavia, puoi usare il tutorial generico per qualsiasi token ERC-721 usando MetaMask, anche sulla Mainnet o su qualsiasi rete di test. Se desideri imparare a coniare il tuo NFT su Ethereum, dai un'occhiata alla [Parte 1 su come scrivere e distribuire uno smart contract NFT](/developers/tutorials/how-to-write-and-deploy-an-nft)! Congratulazioni! Sei arrivato alla parte più breve e semplice della nostra serie di tutorial sugli NFT: come visualizzare il tuo NFT appena coniato in un portafoglio virtuale. Useremo MetaMask per questo esempio poiché lo abbiamo usato nelle due parti precedenti. -Come prerequisito, dovresti già aver installato MetaMask sullo smartphone e dovrebbe includere il conto in cui hai coniato il tuo NFT, puoi ottenere l'app gratuitamente su [iOS](https://apps.apple.com/us/app/metamask-blockchain-wallet/id1438144202) o su [Android](https://play.google.com/store/apps/details?id=io.metamask&hl=en_US&gl=US). +Come prerequisito, dovresti avere già installato MetaMask sul cellulare e dovrebbe includere il conto su cui hai coniato il tuo NFT — puoi scaricare l'app gratuitamente su [iOS](https://apps.apple.com/us/app/metamask-blockchain-wallet/id1438144202) o [Android](https://play.google.com/store/apps/details?id=io.metamask&hl=en_US&gl=US). -## Fase 1: imposta la tua rete su Sepolia {#set-network-to-sepolia} +## Passaggio 1: Imposta la tua rete su Sepolia {#set-network-to-sepolia} -Nella parte superiore dell'app, premi il pulsante “Portafoglio”, dopodiché ti sarà richiesto di selezionare una rete. Dato che il nostro NFT è stato coniato sulla rete di Sepolia, ti consigliamo di selezionare Sepolia come tua rete. +Nella parte superiore dell'app, premi il pulsante "Portafoglio", dopodiché ti sarà richiesto di selezionare una rete. Dato che il nostro NFT è stato coniato sulla rete di Sepolia, ti consigliamo di selezionare Sepolia come tua rete. ![Come impostare Sepolia come tua rete su MetaMask Mobile](./goerliMetamask.gif) -## Fase 2: aggiungi il tuo oggetto collezionabile a MetaMask {#add-nft-to-metamask} +## Passaggio 2: Aggiungi il tuo oggetto collezionabile a MetaMask {#add-nft-to-metamask} -Una volta sulla rete di Sepolia, seleziona la scheda "Collezionabili" sulla destra e aggiungi l'indirizzo del contratto intelligente NFT e l'ID del token ERC-721 del tuo NFT (dovrebbe essere reperibile su Etherscan a seconda dell'hash della transazione del tuo NFT, distribuito nella parte II del nostro tutorial). +Una volta sulla rete di Sepolia, seleziona la scheda "Collezionabili" sulla destra e aggiungi l'indirizzo dello smart contract NFT e l'ID del token ERC-721 del tuo NFT — che dovrebbe essere reperibile su Etherscan in base all'hash della transazione del tuo NFT, distribuito nella parte II del nostro tutorial. ![Come trovare l'hash della tua transazione e l'ID del token ERC-721](./findNFTEtherscan.png) -È possibile che tu debba ricaricare un paio di volte per vedere il tuo NFT — ma ci sarà ! +Potresti dover aggiornare un paio di volte per visualizzare il tuo NFT — ma sarà lì ! ![Come caricare il tuo NFT su MetaMask](./findNFTMetamask.gif) diff --git a/public/content/translations/it/developers/tutorials/how-to-write-and-deploy-an-nft/index.md b/public/content/translations/it/developers/tutorials/how-to-write-and-deploy-an-nft/index.md index c7995522e44..3609c5c24fd 100644 --- a/public/content/translations/it/developers/tutorials/how-to-write-and-deploy-an-nft/index.md +++ b/public/content/translations/it/developers/tutorials/how-to-write-and-deploy-an-nft/index.md @@ -1,12 +1,8 @@ --- -title: Come Scrivere e Distribuire un NFT (Parte 1/3 della Serie di tutorial sugli NFT) -description: Questo tutorial è la Parte 1 di una serie sui NFT che ti guiderà passo dopo passo alla scrittura e distribuzione del contratto intelligente di un Token Non Fungibile (token ERC-721) usando Ethereum e l'InterPlanetary File System (IPFS). +title: Come scrivere e distribuire un NFT (Parte 1/3 della serie di guide sugli NFT) +description: "Questo tutorial è la Parte 1 di una serie sui NFT che ti guiderà passo dopo passo alla scrittura e distribuzione del contratto intelligente di un Token Non Fungibile (token ERC-721) usando Ethereum e l'InterPlanetary File System (IPFS)." author: "Sumi Mudgil" -tags: - - "ERC-721" - - "Alchemy" - - "Solidity" - - "contratti intelligenti" +tags: [ "ERC-721", "Alchemy", "Solidity", "Smart Contract" ] skill: beginner lang: it published: 2021-04-22 @@ -14,23 +10,23 @@ published: 2021-04-22 Ora che gli NFT rendono nota la blockchain al grande pubblico, si presenta un'eccellente opportunità per comprendere questo interesse, pubblicando il tuo NFT (Token ERC-721) sulla blockchain di Ethereum! -Alchemy è estremamente orgogliosa di supportare i più grandi nomi nello spazio degli NFT, tra cui Makersplace (ha recentemente toccato un record nella vendita di opere d'arte digitali a Christie, per $69 milioni), Dapper Labs (creatori di NBA Top Shot e Crypto Kitties), OpenSea (il più grande mercato di NFT al mondo), Zora, Super Rare, NFTfi, Foundation, Enjin, Origin Protocol, Immutable e altri. +Alchemy è estremamente orgogliosa di supportare i più grandi nomi nello spazio degli NFT, tra cui Makersplace (ha recentemente toccato un record nella vendita di opere d'arte digitali a Christie, per 69 milioni di dollari), Dapper Labs (creatori di NBA Top Shot e Crypto Kitties), OpenSea (il più grande mercato di NFT al mondo), Zora, Super Rare, NFTfi, Foundation, Enjin, Origin Protocol, Immutable e altri. -In questo tutorial, ti guideremo alla creazione e distribuzione di un contratto intelligente ERC-721 sulla rete di prova di Sepolia, utilizzando [MetaMask](https://metamask.io/), [Solidity](https://docs.soliditylang.org/en/v0.8.0/), [Hardhat](https://hardhat.org/), [Pinata](https://pinata.cloud/) e [Alchemy](https://alchemy.com/signup/eth) (non preoccuparti se ancora non capisci che significa; te lo spiegheremo!). +In questa guida, illustreremo la creazione e la distribuzione di un contratto intelligente ERC-721 sulla rete di test di Sepolia usando [MetaMask](https://metamask.io/), [Solidity](https://docs.soliditylang.org/en/v0.8.0/), [Hardhat](https://hardhat.org/), [Pinata](https://pinata.cloud/) e [Alchemy](https://alchemy.com/signup/eth) (non preoccuparti se non hai ancora capito cosa significa, te lo spiegheremo!). Nella Parte 2 di questo tutorial affronteremo come possiamo usare il nostro contratto intelligente per coniare un NFT e nella Parte 3 spiegheremo come visualizzare il tuo NFT su MetaMask. -E, ovviamente, se in qualsiasi momento hai domande, non esitare a contattarci nel [Discord di Alchemy](https://discord.gg/gWuC7zB) o consulta [la documentazione sulle NFT API di Alchemy](https://docs.alchemy.com/alchemy/enhanced-apis/nft-api)!! +E, naturalmente, se hai domande in qualsiasi momento, non esitare a contattarci sul [Discord di Alchemy](https://discord.gg/gWuC7zB) o a visitare la [documentazione dell'API NFT di Alchemy](https://docs.alchemy.com/alchemy/enhanced-apis/nft-api)! -## Fase 1: connettersi alla rete di Ethereum {#connect-to-ethereum} +## Fase 1: Connettiti alla rete Ethereum {#connect-to-ethereum} -Esistono molti modi per effettuare richieste alla blockchain di Ethereum, ma per semplificare le cose, utilizzeremo un conto gratuito su [Alchemy](https://alchemy.com/signup/eth), una piattaforma per sviluppatori della blockchain e API, che ci consente di comunicare con la catena di Ethereum senza dover operare i nostri nodi. +Ci sono molti modi per effettuare richieste alla blockchain di Ethereum, ma per semplificare le cose, useremo un account gratuito su [Alchemy](https://alchemy.com/signup/eth), una piattaforma di sviluppo blockchain e API che ci permette di comunicare con la chain di Ethereum senza dover gestire i nostri nodi. -In questo tutorial, approfitteremo anche degli strumenti per monitoraggio e analisi per sviluppatori messi a disposizione da Alchemy per comprendere cosa succede dietro le quinte quando distribuiamo il nostro contratto intelligente. Se non hai già un conto di Alchemy, puoi iscriverti gratuitamente [qui](https://alchemy.com/signup/eth). +In questo tutorial, approfitteremo anche degli strumenti per monitoraggio e analisi per sviluppatori messi a disposizione da Alchemy per comprendere cosa succede dietro le quinte quando distribuiamo il nostro contratto intelligente. Se non hai già un account Alchemy, puoi iscriverti gratuitamente [qui](https://alchemy.com/signup/eth). -## Fase 2: crea la tua app (e chiave API) {#make-api-key} +## Fase 2: Crea la tua app (e la chiave API) {#make-api-key} -Una volta creato un profilo di Alchemy, puoi generare una chiave API creando un'app. Questo ci consentirà di effettuare richieste alla rete di prova di Sepolia. Dai un'occhiata a [questa guida](https://docs.alchemyapi.io/guides/choosing-a-network) se vuoi maggiori informazioni sulle reti di prova. +Una volta creato un conto di Alchemy, puoi generare una chiave API creando un'app. Questo ci consentirà di effettuare richieste alla rete di prova di Sepolia. Consulta [questa guida](https://docs.alchemyapi.io/guides/choosing-a-network) se sei curioso di saperne di più sulle reti di test. 1. Naviga fino alla pagina "Create App" nella tua Dashboard di Alchemy passando il puntatore del mouse su "Apps" nella barra di navigazione e cliccando su "Create App" @@ -40,46 +36,53 @@ Una volta creato un profilo di Alchemy, puoi generare una chiave API creando un' ![Configura e pubblica la tua app](./alchemy-explorer-sepolia.png) -3. Clicca su “Create app” e il gioco è fatto! La tua app dovrebbe apparire nella tabella seguente. +3. Clicca “Crea app” ed è tutto! La tua app dovrebbe apparire nella tabella seguente. -## Fase 3: crea un conto di Ethereum (indirizzo) {#create-eth-address} +## Fase 3: Crea un account Ethereum (indirizzo) {#create-eth-address} -Per inviare e ricevere le transazioni, necessitiamo di un conto di Ethereum. Per questo tutorial, useremo MetaMask, un portafoglio virtuale nel browser per gestire l'indirizzo del tuo conto di Ethereum. Se vuoi capire di più su come funzionano le transazioni su Ethereum, dai un'occhiata a [questa pagina](/developers/docs/transactions/) della Ethereum Foundation. +Per inviare e ricevere le transazioni, necessitiamo di un conto di Ethereum. Per questo tutorial, utilizzeremo MetaMask, un portafoglio virtuale nel browser, utilizzato per gestire l'indirizzo del tuo conto di Ethereum. Se vuoi saperne di più su come funzionano le transazioni su Ethereum, consulta [questa pagina](/developers/docs/transactions/) della Ethereum Foundation. -Puoi scaricare e creare gratuitamente un conto di MetaMask [qui](https://metamask.io/download). Quando crei un account, o se ne possiedi già uno, assicurati di passare alla "Rete di prova di Sepolia" in alto a destra (così da non avere a che fare con denaro reale). +Puoi scaricare e creare un account MetaMask gratuitamente [qui](https://metamask.io/download). Quando crei un account, o se ne possiedi già uno, assicurati di passare alla "Rete di prova di Sepolia" in alto a destra (così da non avere a che fare con denaro reale). ![Imposta Sepolia come tua rete](./metamask-goerli.png) -## Fase 4: aggiungi ether da un Faucet {#step-4-add-ether-from-a-faucet} +## Fase 4: Aggiungi ether da un Faucet {#step-4-add-ether-from-a-faucet} -Per poter distribuire il nostro contratto intelligente alla rete di prova, avremo prima bisogno di degli ETH finti. Per ottenere ETH puoi andare al [Faucet di Sepolia](https://sepoliafaucet.com/) ospitato da Alchemy, accedi e inserisci l'indirizzo del tuo account, fai clic su “Inviami ETH”. Subito dopo, dovresti vedere gli ETH nel tuo conto di MetaMask! +Per poter distribuire il nostro contratto intelligente alla rete di prova, avremo bisogno di degli ETH finti. Per ottenere ETH, vai al [Sepolia Faucet](https://sepoliafaucet.com/) ospitato da Alchemy, accedi, inserisci l'indirizzo del tuo account e fai clic su “Inviami ETH”. Subito dopo, dovresti vedere gli ETH nel tuo conto di MetaMask! -## Fase 5: controlla il saldo {#check-balance} +## Fase 5: Controlla il tuo saldo {#check-balance} -Per ricontrollare che ci sia il saldo, facciamo una richiesta [eth_getBalance](https://docs.alchemyapi.io/alchemy/documentation/alchemy-api-reference/json-rpc#eth_getbalance) usando lo [strumento compositore di Alchemy](https://composer.alchemyapi.io?composer_state=%7B%22network%22%3A0%2C%22methodName%22%3A%22eth_getBalance%22%2C%22paramValues%22%3A%5B%22%22%2C%22latest%22%5D%7D). Questo restituirà l'importo di ETH nel nostro portafoglio. Dopo aver inserito l'indirizzo del tuo conto di MetaMask e aver cliccato “Invia richiesta”, dovresti vedere una risposta come questa: +Per verificare che il nostro saldo sia presente, effettuiamo una richiesta [eth_getBalance](https://docs.alchemyapi.io/alchemy/documentation/alchemy-api-reference/json-rpc#eth_getbalance) utilizzando lo [strumento composer di Alchemy](https://composer.alchemyapi.io?composer_state=%7B%22network%22%3A0%2C%22methodName%22%3A%22eth_getBalance%22%2C%22paramValues%22%3A%5B%22%22%2C%22latest%22%5D%7D). Questo restituirà l'importo di ETH nel nostro portafoglio. Dopo aver inserito l'indirizzo del tuo conto di MetaMask e aver cliccato "Invia Richiesta", dovresti visualizzare una risposta simile alla seguente: + ``` `{"jsonrpc": "2.0", "id": 0, "result": "0xde0b6b3a7640000"}` + ``` -> **NOTA:** Questo risultato è in wei, non in ETH. Wei è usato come taglio più piccolo dell'ether. La conversione da wei a ETH è: 1 eth = 1018 wei. Quindi se convertiamo 0xde0b6b3a7640000 in decimali, otteniamo 1\*1018 wei, pari a 1 ETH. +> **Nota**: questo risultato è in wei, non in ETH. Wei è usato come taglio più piccolo dell'ether. La conversione da wei a ETH è: 1 eth = 1018 wei. Quindi se convertiamo 0xde0b6b3a7640000 in decimali, otteniamo 1\*1018 wei, pari a 1 ETH. Meno male! I nostri soldi finti ci sono tutti. -## Fase 6: inizializza il progetto {#initialize-project} +## Fase 6: Inizializza il nostro progetto {#initialize-project} Prima, dovremo creare una cartella per il nostro progetto. Vai alla riga di comando e digita: + ``` mkdir my-nft cd my-nft + ``` -Ora che siamo nella cartella del nostro progetto, useremo npm init per inizializzare il progetto. Se non hai già installato npm, segui [queste istruzioni](https://docs.alchemyapi.io/alchemy/guides/alchemy-for-macs#1-install-nodejs-and-npm) (avremo anche bisogno di [Node.js](https://nodejs.org/en/download/), quindi scarica anche questo!). +Ora che siamo nella cartella del nostro progetto, useremo npm init per inizializzare il progetto. Se non hai ancora installato npm, segui [queste istruzioni](https://docs.alchemyapi.io/alchemy/guides/alchemy-for-macs#1-install-nodejs-and-npm) (avremo bisogno anche di [Node.js](https://nodejs.org/en/download/), quindi scarica anche quello!). + ``` npm init + ``` Non è importante come rispondi alle domande d'installazione; a titolo di esempio, ecco le nostre risposte: + ```json package name: (my-nft) version: (1.0.0) - description: My first NFT! + description: Il mio primo NFT! entry point: (index.js) test command: git repository: @@ -91,7 +94,7 @@ Non è importante come rispondi alle domande d'installazione; a titolo di esempi { "name": "my-nft", "version": "1.0.0", - "description": "My first NFT!", + "description": "Il mio primo NFT!", "main": "index.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1" @@ -100,26 +103,32 @@ Non è importante come rispondi alle domande d'installazione; a titolo di esempi "license": "ISC" } ``` + Approva il package.json, e siamo pronti! -## Fase 7: installa [Hardhat](https://hardhat.org/getting-started/#overview) {#install-hardhat} +## Fase 7: Installa [Hardhat](https://hardhat.org/getting-started/#overview) {#install-hardhat} Hardhat è un ambiente di sviluppo per compilare, distribuire, testare ed effettuare il debug del tuo software di Ethereum. Aiuta gli sviluppatori nella costruzione di contratti intelligenti e dapp localmente, prima di distribuirli alla catena. Nel nostro progetto my-nft esegui: + ``` npm install --save-dev hardhat + ``` -Dai un'occhiata a questa pagina per ulteriori dettagli sulle [istruzioni d'installazione](https://hardhat.org/getting-started/#overview). +Consulta questa pagina per maggiori dettagli sulle [istruzioni di installazione](https://hardhat.org/getting-started/#overview). -## Fase 8: crea un progetto Hardhat {#create-hardhat-project} +## Fase 8: Crea un progetto Hardhat {#create-hardhat-project} Nella cartella del nostro progetto esegui: + ``` npx hardhat + ``` Dovresti poi vedere un messaggio di benvenuto e l'opzione per selezionare cosa desideri fare. Seleziona “crea un hardhat.config.js vuoto”: + ``` 888 888 888 888 888 888 888 888 888 888 888 888 888 888 888 @@ -128,37 +137,40 @@ Dovresti poi vedere un messaggio di benvenuto e l'opzione per selezionare cosa d 888 888 .d888888 888 888 888 888 888 .d888888 888 888 888 888 888 888 Y88b 888 888 888 888 888 Y88b. 888 888 "Y888888 888 "Y88888 888 888 "Y888888 "Y888 - 👷 Welcome to Hardhat v2.0.11 👷‍ + 👷 Benvenuto in Hardhat v2.0.11 👷‍ ? Cosa vuoi fare? … - Create a sample project - ❯ Create an empty hardhat.config.js - Quit + Crea un progetto di esempio + ❯ Crea un hardhat.config.js vuoto + Esci + ``` Questo genererà un file hardhat.config.js, in cui specificheremo tutta la configurazione per il nostro progetto (alla fase 13). -## Fase 9: aggiungi le cartelle del progetto {#add-project-folders} +## Fase 9: Aggiungi le cartelle di progetto {#add-project-folders} Per mantenere organizzato il nostro progetto, creeremo due nuove cartelle. Vai alla cartella di root del tuo progetto nella tua riga di comando e digita: + ``` mkdir contracts mkdir scripts + ``` - contracts/ è dove manterremo il codice del contratto intelligente del nostro NFT - scripts/ è dove manterremo gli script per distribuire e interagire con il nostro contratto intelligente -## Fase 10: compila il nostro contratto {#write-contract} +## Fase 10: Scrivi il nostro contratto {#write-contract} -Ora che il nostro ambiente è configurato, passiamo alle cose più entusiasmanti: _scrivere il codice del nostro contratto intelligente!_ +Ora che il nostro ambiente è configurato, passiamo a cose più entusiasmanti: _scrivere il codice del nostro contratto intelligente!_ Apri il progetto my-nft nel tuo editor preferito (a noi piace [VSCode](https://code.visualstudio.com/)). I contratti intelligenti sono scritti in un linguaggio detto Solidity, che useremo per scrivere il nostro contratto intelligente MyNFT.sol. 1. Vai alla cartella `contracts` e crea un nuovo file chiamato MyNFT.sol -2. Segue il codice del contratto intelligente del nostro NFT, che abbiamo basato sull'implementazione ERC-721 della libreria di [OpenZeppelin](https://docs.openzeppelin.com/contracts/3.x/erc721). Copia e incolla i seguenti contenuti nel tuo file MyNFT.sol. +2. Di seguito è riportato il codice del nostro contratto intelligente NFT, che si basa sull'implementazione ERC-721 della libreria di [OpenZeppelin](https://docs.openzeppelin.com/contracts/3.x/erc721). Copia e incolla i seguenti contenuti nel tuo file MyNFT.sol. ```solidity - //Contract based on [https://docs.openzeppelin.com/contracts/3.x/erc721](https://docs.openzeppelin.com/contracts/3.x/erc721) + //Contratto basato su [https://docs.openzeppelin.com/contracts/3.x/erc721](https://docs.openzeppelin.com/contracts/3.x/erc721) // SPDX-License-Identifier: MIT pragma solidity ^0.8.0; @@ -188,72 +200,78 @@ Apri il progetto my-nft nel tuo editor preferito (a noi piace [VSCode](https://c } ``` -3. Poiché stiamo ereditando classi dalla libreria di contratti di OpenZeppelin, nella riga di comando esegui `npm install @openzeppelin/contracts` per installare la libreria nella nostra cartella. +3. Poiché stiamo ereditando le classi dalla libreria di contratti OpenZeppelin, nella riga di comando esegui `npm install @openzeppelin/contracts^4.0.0` per installare la libreria nella nostra cartella. Quindi, cosa _fa_ esattamente questo codice? Analizziamolo, riga dopo riga. -In cima al nostro contratto intelligente, importiamo tre classi del contratto intelligente di [OpenZeppelin](https://openzeppelin.com/): +Nella parte superiore del nostro contratto intelligente, importiamo tre classi di contratto intelligente di [OpenZeppelin](https://openzeppelin.com/): -- @openzeppelin/contracts/token/ERC721/ERC721.sol contiene l'implementazione dello standard ERC-721, che il contratto intelligente del nostro NFT erediterà. (Per essere un NFT valido, il tuo contratto intelligente deve implementare tutti i metodi dello standard ERC-721.) Per saperne di più sulle funzioni ERC-721 ereditate, dai un'occhiata alla definizione dell'interfaccia [qui](https://eips.ethereum.org/EIPS/eip-721). +- @openzeppelin/contracts/token/ERC721/ERC721.sol contiene l'implementazione dello standard ERC-721, che il contratto intelligente del nostro NFT erediterà. (Per essere un NFT valido, il tuo contratto intelligente deve implementare tutti i metodi dello standard ERC-721.) Per saperne di più sulle funzioni ERC-721 ereditate, consulta la definizione dell'interfaccia [qui](https://eips.ethereum.org/EIPS/eip-721). - @openzeppelin/contracts/utils/Counters.sol fornisce contatori che possono esser solo incrementati o diminuiti di unità alla volta. Il nostro contratto intelligente usa un contatore per tener traccia del numero totale di NFT coniati e impostare l'ID univoco sul nostro nuovo NFT. (A ogni NFT coniato usando un contratto intelligente, dev'esser assegnato un ID univoco, qui il nostro ID univoco è determinato solo dal numero totale di NFT esistenti. Ad esempio, il primo NFT che coniamo con il nostro contratto intelligente ha un ID di "1," il nostro secondo NFT ha un ID di "2," ecc.) -- @openzeppelin/contracts/access/Ownable.sol imposta [il controllo d'accesso](https://docs.openzeppelin.com/contracts/3.x/access-control) sul nostro contratto intelligente, così solo il proprietario del contratto intelligente (tu) può coniare NFT. (Nota, prevedere il controllo dell'accesso è totalmente facoltativo. Se volessi che tutti potessero coniare un NFT usando il tuo contratto intelligente, dovresti rimuovere la parola Ownable alla riga 10 e onlyOwner alla riga 17.) +- `@openzeppelin/contracts/access/Ownable.sol` imposta il [controllo degli accessi](https://docs.openzeppelin.com/contracts/3.x/access-control) sul nostro contratto intelligente, in modo che solo il proprietario del contratto intelligente (tu) possa coniare NFT. (Nota, prevedere il controllo dell'accesso è totalmente facoltativo. Se volessi che tutti potessero coniare un NFT usando il tuo contratto intelligente, dovresti rimuovere la parola Ownable alla riga 10 e onlyOwner alla riga 17.) -Dopo le nostre dichiarazioni d'importazione, abbiamo il contratto intelligente del nostro NFT personalizzato, che è sorprendentemente corto: contiene solo un contatore, un costruttore e una funzione singola! Questo grazie ai nostri contratti ereditati da OpenZeppelin, che implementa gran parte dei metodi che necessitiamo per creare un NFT, come `ownerOf`, che restituisce il proprietario del NFT e `transferFrom`, che trasferisce la proprietà del NFT da un conto a un altro. +Dopo le nostre dichiarazioni d'importazione, abbiamo il contratto intelligente del nostro NFT personalizzato, che è sorprendentemente corto: contiene solo un contatore, un costruttore e una funzione singola! Questo è possibile grazie ai nostri contratti OpenZeppelin ereditati, che implementano la maggior parte dei metodi necessari per creare un NFT, come `ownerOf`, che restituisce il proprietario dell'NFT, e `transferFrom`, che trasferisce la proprietà dell'NFT da un account a un altro. Nel nostro costruttore ERC-721, noterai che passiamo 2 stringhe, “MyNFT” e “NFT.” La prima variabile è il nome del contratto intelligente e la seconda è il suo simbolo. Puoi assegnare a ciascuna di queste variabili il nome che desideri! -Infine, abbiamo la nostra funzione `mintNFT(address recipient, string tokenURI)` che ci consente di coniare un NFT! Noterai che questa funzione usa due variabili: +Infine, abbiamo la nostra funzione `mintNFT(address recipient, string memory tokenURI)` che ci permette di coniare un NFT! Noterai che questa funzione usa due variabili: -- `address recipient` specifica l'indirizzo che riceverà il tuo NFT appena coniato +- `address recipient` specifica l'indirizzo che riceverà il tuo NFT appena coniato. - `string memory tokenURI` è una stringa che dovrebbe risolversi in un documento JSON che descrive i metadati dell'NFT. I metadati di un NFT sono davvero ciò che lo porta in vita, consentendogli di avere proprietà configurabili, quali nome, descrizione, immagine e altri attributi. Nella parte 2 di questo tutorial, descriveremo come configurare questi metadati. `mintNFT` chiama alcuni metodi dalla libreria ERC-721 ereditata e, infine, restituisce un numero che rappresenta l'ID dell'NFT appena coniato. -## Fase 11: connetti MetaMask e Alchemy al tuo progetto {#connect-metamask-and-alchemy} +## Fase 11: Collega MetaMask e Alchemy al tuo progetto {#connect-metamask-and-alchemy} Ora che abbiamo creato un portafoglio di MetaMask, un conto di Alchemy e scritto il nostro contratto intelligente, è il momento di collegarli. Ogni transazione inviata dal tuo portafoglio virtuale richiede una firma tramite la tua chiave privata unica. Per fornire al nostro programma quest'autorizzazione, possiamo memorizzare in sicurezza la nostra chiave privata (e la chiave API di Alchemy) in un file ambientale. -Per saperne di più sull'invio delle transazioni, dai un'occhiata a [questo tutorial](/developers/tutorials/sending-transactions-using-web3-and-alchemy/) sull'invio di transazioni usando web3. +Per saperne di più sull'invio di transazioni, consulta [questa guida](/developers/tutorials/sending-transactions-using-web3-and-alchemy/) sull'invio di transazioni tramite web3. Prima, installa il pacchetto dotenv nella cartella del tuo progetto: + ``` npm install dotenv --save + ``` -Poi, crea un file `.env` nella cartella di root del nostro progetto e aggiungi la tua chiave privata di MetaMask e l'URL API di Alchemy HTTP. +Quindi, crea un file `.env` nella directory principale del nostro progetto e aggiungici la tua chiave privata di MetaMask e l'URL dell'API HTTP di Alchemy. -- Segui [queste istruzioni](https://metamask.zendesk.com/hc/en-us/articles/360015289632-How-to-Export-an-Account-Private-Key) per esportare la tua chiave privata da MetaMask +- Segui [queste istruzioni](https://metamask.zendesk.com/hc/en-us/articles/360015289632-How-to-Export-an-Account-Private-Key) per esportare la tua chiave privata da MetaMask. - Vedi di seguito come ottenere l'URL dell'API di Alchemy HTTP e copialo negli appunti -![Copia l'URL dell'API di Alchemy](./copy-alchemy-api-url.gif) +![Copia l'URL della tua API di Alchemy](./copy-alchemy-api-url.gif) -Il tuo `.env` dovrebbe somigliare a questo: +Il tuo file `.env` dovrebbe ora apparire così: + ``` API_URL="https://eth-sepolia.g.alchemy.com/v2/your-api-key" PRIVATE_KEY="your-metamask-private-key" + ``` Per connetterli realmente al nostro codice, faremo riferimento a queste variabili nel nostro file hardhat.config.js nella fase 13. -## Fase 12: installa Ethers.js {#install-ethers} +## Fase 12: Installa Ethers.js {#install-ethers} -Ethers.js è una libreria che rende più facile interagire ed effettuare richieste a Ethereum tramite wrapping dei [metodi JSON-RPC standard](/developers/docs/apis/json-rpc/) con altri metodi più facili da usare. +Ethers.js è una libreria che semplifica l'interazione e l'invio di richieste a Ethereum, eseguendo il wrapping dei [metodi JSON-RPC standard](/developers/docs/apis/json-rpc/) con metodi più intuitivi. -Hardhat rende davvero facile integrare [Plugin](https://hardhat.org/plugins/) per strumenti e funzionalità aggiuntive. Sfrutteremo il [plugin di Ethers](https://hardhat.org/docs/plugins/official-plugins#hardhat-ethers) per la distribuzione del contratto ([Ethers.js](https://github.com/ethers-io/ethers.js/) ha dei metodi di distribuzione del contratto molto puliti). +Hardhat rende semplicissima l'integrazione di [Plugin](https://hardhat.org/plugins/) per strumenti aggiuntivi e funzionalità estese. Approfitteremo del [plugin Ethers](https://hardhat.org/docs/plugins/official-plugins#hardhat-ethers) per la distribuzione dei contratti ([Ethers.js](https://github.com/ethers-io/ethers.js/) ha dei metodi di distribuzione dei contratti molto puliti). Nella cartella del tuo progetto digita: + ``` npm install --save-dev @nomiclabs/hardhat-ethers ethers@^5.0.0 + ``` Avremo bisogno di ethers anche nel nostro hardhat.config.js nella prossima fase. -## Fase 13: aggiorna hardhat.config.js {#update-hardhat-config} +## Fase 13: Aggiorna hardhat.config.js {#update-hardhat-config} Finora abbiamo aggiunto diverse dipendenze e plugin, ora dobbiamo aggiornare hardhat.config.js in modo che il nostro progetto li riconosca tutti. @@ -279,30 +297,32 @@ Aggiorna il tuo hardhat.config.js affinché appaia così: } ``` -## Fase 14: compila il contratto {#compile-contract} +## Fase 14: Compila il nostro contratto {#compile-contract} Per assicurarti che tutto funzioni fino a questo punto, compila il contratto. L'attività di compilazione è una delle attività integrate di hardhat. Dalla riga di comando esegui: + ``` npx hardhat compile + ``` -Potresti ottenere un avviso sull'assenza nel file sorgente dell'identificativo della licenza SPDX, ma non preoccupartene, tutto il resto dovrebbe funzionare! Altrimenti, puoi sempre inviare un messaggio nel [Discord di Alchemy](https://discord.gg/u72VCg3). +Potresti ottenere un avviso sull'assenza nel file sorgente dell'identificativo della licenza SPDX, ma non preoccupartene, tutto il resto dovrebbe funzionare! In caso contrario, puoi sempre inviare un messaggio nel [discord di Alchemy](https://discord.gg/u72VCg3). -## Fase 15: scrivi lo script di distribuzione {#write-deploy} +## Fase 15: Scrivi il nostro script di distribuzione {#write-deploy} Ora che il nostro contratto è scritto e il nostro file di configurazione è pronto, è il momento di scrivere lo script di distribuzione del contratto. -Vai alla cartella `script/` e crea un nuovo file chiamato `deploy.js`, aggiungendo i seguenti contenuti: +Vai alla cartella `scripts/` e crea un nuovo file chiamato `deploy.js`, aggiungendovi i seguenti contenuti: ```js async function main() { const MyNFT = await ethers.getContractFactory("MyNFT") - // Start deployment, returning a promise that resolves to a contract object + // Avvia la distribuzione, restituendo una promise che si risolve in un oggetto contratto const myNFT = await MyNFT.deploy() await myNFT.deployed() - console.log("Contract deployed to address:", myNFT.address) + console.log("Contratto distribuito all'indirizzo:", myNFT.address) } main() @@ -313,40 +333,48 @@ main() }) ``` -Nel suo [tutorial sui Contratti](https://hardhat.org/tutorial/testing-contracts.html#writing-tests) hardhat spiega in modo eccellente cosa fa ognuna di queste righe di codice nel loro, quindi riportiamo qui le loro spiegazioni. +Hardhat spiega molto bene cosa fa ciascuna di queste righe di codice nella sua [Guida ai contratti](https://hardhat.org/tutorial/testing-contracts.html#writing-tests), e qui abbiamo adottato le sue spiegazioni. + ``` const MyNFT = await ethers.getContractFactory("MyNFT"); + ``` Un ContractFactory su ethers.js è un'astrazione usata per distribuire nuovi contratti intelligenti, quindi MyNFT qui è una fabbrica di istanze del nostro contratto NFT. Usando il plugin hardhat-ethers, le istanze ContractFactory e Contract sono connesse di default al primo firmatario. + ``` const myNFT = await MyNFT.deploy(); + ``` Chiamare deploy() su un ContractFactory avvierà la distribuzione e restituirà una promessa che si risolverà in un contratto. Questo è l'oggetto che ha un metodo per ciascuna delle funzioni del nostro smart contract. -## Fase 16: distribuisci il contratto {#deploy-contract} +## Fase 16: Distribuisci il nostro contratto {#deploy-contract} Siamo finalmente pronti a distribuire il nostro smart contract! Torna alla root della cartella del tuo progetto e nella riga di comando esegui: + ``` npx hardhat --network sepolia run scripts/deploy.js + ``` Vorrai poi vedere qualcosa del genere: + ``` Contratto distribuito all'indirizzo: 0x4C5266cCc4b3F426965d2f51b6D910325a0E7650 + ``` -Se andiamo su [Sepolia etherscan](https://sepolia.etherscan.io/) e cerchiamo l'indirizzo del nostro contratto, dovremmo poter vedere che è stato distribuito correttamente. Se non riesci a vederlo immediatamente, attendi alcuni istanti poiché potrebbe essere necessario un po' di tempo. La transazione somiglierà a questa: +Se andiamo su [Sepolia Etherscan](https://sepolia.etherscan.io/) e cerchiamo l'indirizzo del nostro contratto, dovremmo essere in grado di vedere che è stato distribuito con successo. Se non riesci a vederlo immediatamente, attendi alcuni istanti poiché potrebbe essere necessario un po' di tempo. La transazione somiglierà a questa: ![Visualizza l'indirizzo della tua transazione su Etherscan](./etherscan-sepoila-contract-creation.png) -L'indirizzo "Da" dovrebbe corrispondere all'indirizzo del tuo account di MetaMask mentre l'indirizzo "A" sarà: “Creazione del contratto.” Se facciamo clic sulla transazione, vediamo l'indirizzo del nostro contratto nel campo "A": +L'indirizzo "Da" dovrebbe corrispondere all'indirizzo del tuo account di MetaMask mentre l'indirizzo "A" sarà: “Creazione del contratto”. Se facciamo clic sulla transazione, vediamo l'indirizzo del nostro contratto nel campo "A": ![Visualizza l'indirizzo del tuo contratto su Etherscan](./etherscan-sepolia-tx-details.png) Sììììììììììì! Hai appena distribuito il tuo contratto intelligente NFT alla catena (testnet) di Ethereum! -Per capire cosa sta succedendo, andiamo alla scheda Explorer nel nostro [dashboard di Alchemy](https://dashboard.alchemyapi.io/explorer). Se hai diverse app di Alchemy, assicurati di filtrare per app e selezionare "MyNFT". +Per capire cosa sta succedendo dietro le quinte, vai alla scheda Explorer nella nostra [dashboard di Alchemy](https://dashboard.alchemyapi.io/explorer). Se hai diverse app di Alchemy, assicurati di filtrare per app e selezionare "MyNFT". -![Visualizza le chiamate effettuate "dietro le quinte" con il pannello Explorer di Alchemy](./alchemy-explorer-goerli.png) +![Visualizza le chiamate effettuate “dietro le quinte” con la dashboard Explorer di Alchemy](./alchemy-explorer-goerli.png) -Qui vedrai numerose chiamate a JSON-RPC che Hardhat/Ethers ha effettuato per noi quando abbiamo chiamato la funzione .deploy(). Due funzioni importanti da chiamare qui sono [eth_sendRawTransaction](/developers/docs/apis/json-rpc/#eth_sendrawtransaction), che è la richiesta di scrivere realmente il nostro contratto intelligente sulla catena di Sepolia e [eth_getTransactionByHash](/developers/docs/apis/json-rpc/#eth_gettransactionbyhash), che è una richiesta di leggere le informazioni sulla nostra transazione dato l'hash (uno schema tipico quando si inviano le transazioni). Per saperne di più sull'invio delle transazioni, dai un'occhiata a questo tutorial [ sull'invio di transazioni usando web3](/developers/tutorials/sending-transactions-using-web3-and-alchemy/). +Qui vedrai numerose chiamate a JSON-RPC che Hardhat/Ethers ha effettuato per noi quando abbiamo chiamato la funzione .deploy(). Due funzioni importanti da menzionare sono [`eth_sendRawTransaction`](/developers/docs/apis/json-rpc/#eth_sendrawtransaction), che è la richiesta di scrivere effettivamente il nostro contratto intelligente sulla chain di Sepolia, e [`eth_getTransactionByHash`](/developers/docs/apis/json-rpc/#eth_gettransactionbyhash), che è una richiesta di leggere le informazioni sulla nostra transazione dato l'hash (un modello tipico quando si inviano transazioni). Per saperne di più sull'invio di transazioni, consulta questa guida su come [inviare transazioni usando Web3](/developers/tutorials/sending-transactions-using-web3-and-alchemy/). -È tutto per la parte 1 di questo tutorial. Nella [parte 2 interagiremo realmente con il nostro contratto intelligente, coniando un NFT](/developers/tutorials/how-to-mint-an-nft/) e nella [parte 3 ti mostreremo come visualizzare il tuo NFT nel tuo portafoglio di Ethereum](/developers/tutorials/how-to-view-nft-in-metamask/)! +È tutto per la parte 1 di questo tutorial. Nella [parte 2, interagiremo con il nostro contratto intelligente coniando un NFT](/developers/tutorials/how-to-mint-an-nft/) e, nella [parte 3, ti mostreremo come visualizzare il tuo NFT nel tuo portafoglio Ethereum](/developers/tutorials/how-to-view-nft-in-metamask/)! diff --git a/public/content/translations/it/developers/tutorials/interact-with-other-contracts-from-solidity/index.md b/public/content/translations/it/developers/tutorials/interact-with-other-contracts-from-solidity/index.md index 63c082a5be6..14da62d03a3 100644 --- a/public/content/translations/it/developers/tutorials/interact-with-other-contracts-from-solidity/index.md +++ b/public/content/translations/it/developers/tutorials/interact-with-other-contracts-from-solidity/index.md @@ -1,13 +1,15 @@ --- title: Interazione con altri contratti da Solidity -description: Come distribuire uno Smart Contract da uno esistente e interagirvi +description: Come distribuire un contratto intelligente da un contratto esistente e interagire con esso author: "jdourlens" tags: - - "smart contract" - - "Solidity" - - "remix" - - "distribuzione" - - "componibilità" + [ + "smart contract", + "Solidity", + "remix", + "distribuzione", + "componibilità" + ] skill: advanced lang: it published: 2020-04-05 @@ -16,9 +18,9 @@ sourceUrl: https://ethereumdev.io/interact-with-other-contracts-from-solidity/ address: "0x19dE91Af973F404EDF5B4c093983a7c6E3EC8ccE" --- -Nei tutorial precedenti abbiamo imparato molto su [come distribuire il primo Smart Contract](/developers/tutorials/deploying-your-first-smart-contract/) e aggiungervi alcune funzionalità come il [controllo degli accessi con modificatori](https://ethereumdev.io/organize-your-code-and-control-access-to-your-smart-contract-with-modifiers/) o la [gestione degli errori in Solidity](https://ethereumdev.io/handle-errors-in-solidity-with-require-and-revert/). In questo tutorial impareremo come distribuire uno Smart Contract da uno esistente e interagirvi. +Nelle guide precedenti abbiamo imparato molto, ad esempio [come distribuire il tuo primo contratto intelligente](/developers/tutorials/deploying-your-first-smart-contract/) e ad aggiungervi alcune funzionalità come [il controllo degli accessi con i modificatori](https://ethereumdev.io/organize-your-code-and-control-access-to-your-smart-contract-with-modifiers/) o [la gestione degli errori in Solidity](https://ethereumdev.io/handle-errors-in-solidity-with-require-and-revert/). In questa guida impareremo come distribuire un contratto intelligente da un contratto esistente e interagire con esso. -Creeremo un contratto che permetta a chiunque ad avere uno Smart Contract `Counter` creando una factory associata, il cui nome sarà `CounterFactory`. Prima di tutto, ecco il codice del nostro Smart Contract iniziale `Counter`: +Creeremo un contratto che consenta a chiunque di avere il proprio contratto intelligente `Counter`, creando una factory per esso, il cui nome sarà `CounterFactory`. Prima di tutto, ecco il codice del nostro contratto intelligente `Counter` iniziale: ```solidity pragma solidity 0.5.17; @@ -56,19 +58,19 @@ contract Counter { } ``` -Nota: abbiamo leggermente modificato il codice del contratto per tenere traccia dell'indirizzo della factory e dell'indirizzo del proprietario del contratto. Quando si chiama il codice di un contratto da un altro contratto, msg.sender fa riferimento all'indirizzo della factory del contratto. È **molto importante comprendere questo concetto**, perché usare un contratto per interagire con altri contratti è una prassi comune. Dovresti quindi saper gestire il mittente nei casi complessi. +Nota: abbiamo leggermente modificato il codice del contratto per tenere traccia dell'indirizzo della factory e dell'indirizzo del proprietario del contratto. Quando si chiama il codice di un contratto da un altro contratto, `msg.sender` si riferisce all'indirizzo della nostra factory del contratto. È molto importante comprendere questo concetto, perché usare un contratto per interagire con altri contratti è una prassi comune. Dovresti quindi prestare attenzione a chi è il mittente nei casi complessi. -Per questo motivo abbiamo aggiunto anche un modificatore `onlyFactory` che fa in modo che la funzione di cambiamento dello stato sia chiamabile solo dalla factory che passerà il chiamante originale come parametro. +Per questo motivo abbiamo aggiunto anche un modificatore `onlyFactory` che fa in modo che la funzione di cambiamento dello stato possa essere chiamata solo dalla factory, che passerà il chiamante originale come parametro. -Nella nostra nuova `CounterFactory` che gestirà tutti gli altri Counter aggiungeremo un mapping che assocerà un proprietario all'indirizzo del relativo contratto Counter: +All'interno della nostra nuova `CounterFactory` che gestirà tutti gli altri `Counter`, aggiungeremo un `mapping` che assocerà un proprietario all'indirizzo del suo contratto `Counter`: ```solidity mapping(address => Counter) _counters; ``` -In Ethereum, i mapping equivalgono agli oggetti di Javascript, che permettono di mappare una chiave di tipo A a un valore di tipo B. In questo caso mappiamo l'indirizzo di un proprietario all'istanza del suo Counter. +In Ethereum, i `mapping` sono l'equivalente degli oggetti in JavaScript: permettono di mappare una chiave di tipo A a un valore di tipo B. In questo caso, mappiamo l'indirizzo di un proprietario con l'istanza del suo `Counter`. -Istanziare un nuovo Counter per un utente sarà più o meno: +Istanziare un nuovo `Counter` per qualcuno sarà così: ```solidity function createCounter() public { @@ -77,9 +79,9 @@ Istanziare un nuovo Counter per un utente sarà più o meno: } ``` -Prima controlliamo se la persona possiede già un Counter. Se non lo possiede, istanziamo un nuovo Counter passandone l'indirizzo al costruttore del `Counter` e assegniamo l'istanza appena creata al mapping. +Per prima cosa, verifichiamo se la persona possiede già un `Counter`. Se non ne possiede uno, istanziamo un nuovo `Counter` passando il suo indirizzo al costruttore di `Counter` e assegniamo l'istanza appena creata al `mapping`. -Ottenere il conteggio di un Counter specifico significa: +Per ottenere il conteggio di un `Counter` specifico, il codice sarà simile a questo: ```solidity function getCount(address account) public view returns (uint256) { @@ -92,9 +94,9 @@ function getMyCount() public view returns (uint256) { } ``` -La prima funzione controlla se il contratto Counter esiste per un determinato indirizzo e poi chiama il metodo `getCount` dall'istanza. La seconda funzione: `getMyCount` è passa direttamente msg.sender alla funzione `getCount`. +La prima funzione controlla se il contratto `Counter` esiste per un dato indirizzo e poi chiama il metodo `getCount` dall'istanza. La seconda funzione, `getMyCount`, è solo una scorciatoia per passare `msg.sender` direttamente alla funzione `getCount`. -La funzione `increment` è abbastanza simile ma passa il mittente della transazione originale al contratto `Counter`: +La funzione `increment` è abbastanza simile, ma passa il mittente della transazione originale al contratto `Counter`: ```solidity function increment() public { @@ -103,9 +105,9 @@ function increment() public { } ``` -Nota: se chiamato troppe volte, il Counter potrebbe rimanere vittima di overflow. È consigliabile usare la [libreria di SafeMath](https://ethereumdev.io/using-safe-math-library-to-prevent-from-overflows/) il più possibile per evitare questa eventualità. +Nota che, se chiamato troppe volte, il nostro `Counter` potrebbe essere vittima di un sovraflusso. Dovresti usare il più possibile la [libreria SafeMath](https://ethereumdev.io/using-safe-math-library-to-prevent-from-overflows/) per proteggerti da questo possibile caso. -Per distribuire il contratto, dovrai fornire sia il codice della `CounterFactory` che il `Counter`. Quando si esegue la distribuzione ad esempio in Remix, è necessario selezionare CounterFactory. +Per distribuire il nostro contratto, dovrai fornire sia il codice di `CounterFactory` sia quello di `Counter`. Quando si esegue la distribuzione, ad esempio in Remix, è necessario selezionare `CounterFactory`. Ecco il codice completo: @@ -170,8 +172,8 @@ contract CounterFactory { } ``` -Dopo la compilazione, nella sezione di distribuzione di Remix si selezionerà la factory da distribuire: +Dopo la compilazione, nella sezione di distribuzione di Remix, selezionerai la factory da distribuire: ![Selezione della factory da distribuire in Remix](./counterfactory-deploy.png) -A questo punto puoi fare esperimenti la factory del contratto e controllare il valore che cambia. Se vorresti chiamare il contratto intelligente da un indirizzo differente, dovrai cambiare l'indirizzo nella selezione Conto di Remix. +A questo punto puoi fare esperimenti con la factory del tuo contratto e controllare il cambiamento del valore. Se desideri chiamare il contratto intelligente da un indirizzo diverso, dovrai modificare l'indirizzo nella selezione 'Conto' di Remix. diff --git a/public/content/translations/it/developers/tutorials/ipfs-decentralized-ui/index.md b/public/content/translations/it/developers/tutorials/ipfs-decentralized-ui/index.md new file mode 100644 index 00000000000..64ea9520cdc --- /dev/null +++ b/public/content/translations/it/developers/tutorials/ipfs-decentralized-ui/index.md @@ -0,0 +1,73 @@ +--- +title: IPFS per interfacce utente decentralizzate +description: Questa guida insegna al lettore come usare IPFS per archiviare l'interfaccia utente per una dApp. Sebbene i dati e la logica di business dell'applicazione siano decentralizzati, senza un'interfaccia utente resistente alla censura gli utenti potrebbero comunque perdere l'accesso ad essa. +author: Ori Pomerantz +tags: [ "ipfs" ] +skill: beginner +lang: it +published: 2024-06-29 +--- + +Hai scritto una nuova dApp incredibile. Hai persino scritto un'[interfaccia utente](/developers/tutorials/creating-a-wagmi-ui-for-your-contract/) per essa. Ma ora temi che qualcuno tenterà di censurarla disattivando la tua interfaccia utente, che è solo un server nel cloud. In questa guida imparerai come evitare la censura caricando la tua interfaccia utente su **[interplanetary file system (IPFS)](https://ipfs.tech/developers/)**, così chiunque sia interessato potrà fissarla su un server per potervi accedere in futuro. + +Potresti usare un servizio di terze parti come [Fleek](https://resources.fleek.xyz/docs/) per fare tutto il lavoro. Questa guida è per le persone che vogliono fare abbastanza per capire cosa stanno facendo, anche se comporta più lavoro. + +## Introduzione in locale {#getting-started-locally} + +Esistono diversi [provider IPFS di terze parti](https://docs.ipfs.tech/how-to/work-with-pinning-services/#use-a-third-party-pinning-service), ma è meglio iniziare eseguendo IPFS in locale per i test. + +1. Installa l'[interfaccia utente IPFS](https://docs.ipfs.tech/install/ipfs-desktop/#install-instructions). + +2. Crea una directory con il tuo sito web. Se stai usando [Vite](https://vite.dev/), usa questo comando: + + ```sh + pnpm vite build + ``` + +3. In IPFS Desktop, fai clic su **Importa > Cartella** e seleziona la directory che hai creato nel passaggio precedente. + +4. Seleziona la cartella che hai appena caricato e fai clic su **Rinomina**. Dagli un nome più significativo. + +5. Selezionala di nuovo e fai clic su **Condividi link**. Copia l'URL negli appunti. Il link sarà simile a `https://ipfs.io/ipfs/QmaCuQ7yN6iyBjLmLGe8YiFuCwnePoKfVu6ue8vLBsLJQJ`. + +6. Fai clic su **Stato**. Espandi la scheda **Avanzate** per visualizzare l'indirizzo del gateway. Ad esempio, sul mio sistema l'indirizzo è `http://127.0.0.1:8080`. + +7. Combina il percorso del passaggio del link con l'indirizzo del gateway per trovare il tuo indirizzo. Ad esempio, per l'esempio precedente, l'URL è `http://127.0.0.1:8080/ipfs/QmaCuQ7yN6iyBjLmLGe8YiFuCwnePoKfVu6ue8vLBsLJQJ`. Apri l'URL in un browser per visualizzare il tuo sito. + +## Caricamento {#uploading} + +Ora puoi usare IPFS per servire file in locale, il che non è molto entusiasmante. Il passo successivo è renderli disponibili a tutto il mondo quando sei offline. + +Ci sono diversi noti [servizi di pinning](https://docs.ipfs.tech/concepts/persistence/#pinning-services). Scegline uno. Qualunque servizio tu usi, dovrai creare un account e fornirgli l'**identificatore di contenuto (CID)** nel tuo desktop IPFS. + +Personalmente, ho trovato [4EVERLAND](https://docs.4everland.org/storage/4ever-pin/guides) il più facile da usare. Ecco le istruzioni: + +1. Vai alla [dashboard](https://dashboard.4everland.org/overview) e accedi con il tuo portafoglio. + +2. Nella barra laterale sinistra fai clic su **Archiviazione > 4EVER Pin**. + +3. Fai clic su **Carica > CID Selezionato**. Dai un nome al tuo contenuto e fornisci il CID dal desktop IPFS. Attualmente un CID è una stringa che inizia con `Qm` seguita da 44 lettere e cifre che rappresentano un [hash codificato in base-58](https://medium.com/bootdotdev/base64-vs-base58-encoding-c25553ff4524), come `QmaCuQ7yN6iyBjLmLGe8YiFuCwnePoKfVu6ue8vLBsLJQJ`, ma [è probabile che questo cambi](https://docs.ipfs.tech/concepts/content-addressing/#version-1-v1). + +4. Lo stato iniziale è **In coda**. Ricarica finché non cambia in **Fissato**. + +5. Fai clic sul tuo CID per ottenere il link. Puoi vedere la mia applicazione [qui](https://bafybeifqka2odrne5b6l5guthqvbxu4pujko2i6rx2zslvr3qxs6u5o7im/). + +6. Potrebbe essere necessario attivare il tuo account per averlo fissato per più di un mese. L'attivazione dell'account costa circa 1 $. Se l'hai chiuso, disconnettiti e riaccedi per ricevere di nuovo la richiesta di attivazione. + +## Utilizzo da IPFS {#using-from-ipfs} + +A questo punto hai un link a un gateway centralizzato che serve i tuoi contenuti IPFS. In breve, la tua interfaccia utente potrebbe essere un po' più sicura ma non è ancora resistente alla censura. Per una vera resistenza alla censura, gli utenti devono usare IPFS [direttamente da un browser](https://docs.ipfs.tech/install/ipfs-companion/#prerequisites). + +Una volta installato (e con il desktop IPFS funzionante), puoi andare su [/ipfs/``](https://any.site/ipfs/bafybeifqka2odrne5b6l5guthqvbxu4pujko2i6rx2zslvr3qxs6u5o7im) su qualsiasi sito e otterrai quel contenuto, servito in modo decentralizzato. + +## Svantaggi {#drawbacks} + +Non puoi eliminare in modo affidabile i file IPFS, quindi finché stai modificando la tua interfaccia utente, è probabilmente meglio lasciarla centralizzata, o usare l'[interplanetary name system (IPNS)](https://docs.ipfs.tech/concepts/ipns/#mutability-in-ipfs), un sistema che fornisce mutabilità su IPFS. Naturalmente, tutto ciò che è mutabile può essere censurato, nel caso di IPNS facendo pressione sulla persona con la chiave privata a cui corrisponde. + +Inoltre, alcuni pacchetti hanno un problema con IPFS, quindi se il tuo sito web è molto complicato potrebbe non essere una buona soluzione. E ovviamente, tutto ciò che si basa sull'integrazione del server non può essere decentralizzato semplicemente avendo il lato client su IPFS. + +## Conclusione {#conclusion} + +Proprio come Ethereum ti permette di decentralizzare gli aspetti del database e della logica di business della tua dApp, IPFS ti permette di decentralizzare l'interfaccia utente. Ciò ti consente di eliminare un altro vettore di attacco contro la tua dApp. + +[Vedi qui per altri miei lavori](https://cryptodocguy.pro/). diff --git a/public/content/translations/it/developers/tutorials/kickstart-your-dapp-frontend-development-with-create-eth-app/index.md b/public/content/translations/it/developers/tutorials/kickstart-your-dapp-frontend-development-with-create-eth-app/index.md index 8d093e6360e..5aa0ea06b7a 100644 --- a/public/content/translations/it/developers/tutorials/kickstart-your-dapp-frontend-development-with-create-eth-app/index.md +++ b/public/content/translations/it/developers/tutorials/kickstart-your-dapp-frontend-development-with-create-eth-app/index.md @@ -1,14 +1,15 @@ --- -title: Avvia lo sviluppo del frontend della tua dapp con create-eth-app -description: Una panoramica su come usare create-eth-app e le sue funzionalità +title: Avvia lo sviluppo del frontend della tua dApp con create-eth-app +description: "Una panoramica su come usare create-eth-app e le sue funzionalità" author: "Markus Waas" tags: - - "create-eth-app" - - "frontend" - - "javascript" - - "ethers.js" - - "the graph" - - "defi" + [ + "frontend", + "javascript", + "ethers.js", + "the graph", + "defi" + ] skill: beginner lang: it published: 2020-04-27 @@ -16,11 +17,11 @@ source: soliditydeveloper.com sourceUrl: https://soliditydeveloper.com/create-eth-app --- -L'ultima volta abbiamo dato un'occhiata al [quadro generale di Solidity](https://soliditydeveloper.com/solidity-overview-2020) e abbiamo già accennato a [create-eth-app](https://github.com/PaulRBerg/create-eth-app). Ora scoprirai come usarlo, quali funzionalità sono integrate e alcune idee aggiuntive su come approfondilo. Creata da Paul Razvan Berg, fondatore di [Sablier](http://sablier.com/), quest'app avvierà lo sviluppo del tuo frontend, offrendo diverse integrazioni facoltative tra cui scegliere. +L'ultima volta abbiamo dato uno sguardo [alla panoramica di Solidity](https://soliditydeveloper.com/solidity-overview-2020) e abbiamo già menzionato [create-eth-app](https://github.com/PaulRBerg/create-eth-app). Ora scoprirai come usarlo, quali funzionalità sono integrate e idee aggiuntive su come espanderlo. Creata da Paul Razvan Berg, il fondatore di [Sablier](http://sablier.com/), questa app darà il via allo sviluppo del tuo frontend e offre diverse integrazioni opzionali tra cui scegliere. ## Installazione {#installation} -L'installazione richiede Yarn 0.25 o superiore (`npm install yarn -- global`). L'esecuzione è semplicissima: +L'installazione richiede Yarn 0.25 o superiore (`npm install yarn --global`). È semplice come eseguire: ```bash yarn create eth-app my-eth-app @@ -28,44 +29,44 @@ cd my-eth-app yarn react-app:start ``` -Come sistema sottostante utilizza [create-react-app](https://github.com/facebook/create-react-app). Per vedere la tua app, apri `http://localhost:3000/`. Quando sei pronto a distribuire in produzione, crea un pacchetto minimizzato con yarn build. Un modo facile per ospitarlo sarebbe [Netlify](https://www.netlify.com/). Puoi creare una repo di GitHub, aggiungerla a Netlify, configurare il comando build e hai finito! La tua app sarà ospitata e utilizzabile da tutti. E tutto gratuitamente. +Utilizza [create-react-app](https://github.com/facebook/create-react-app) sotto il cofano. Per vedere la tua app, apri `http://localhost:3000/`. Quando sei pronto a eseguire il deploy in produzione, crea un bundle minimizzato con yarn build. Un modo semplice per ospitarlo sarebbe [Netlify](https://www.netlify.com/). Puoi creare un repository GitHub, aggiungerlo a Netlify, configurare il comando di build e il gioco è fatto! La tua app sarà ospitata e utilizzabile da tutti. E tutto gratuitamente. -## Caratteristiche {#features} +## Funzionalità {#features} ### React e create-react-app {#react--create-react-app} -Prima di tutto, il cuore dell'app: React e tutte le funzionalità aggiuntive fornite con _create-react-app_. Usare solo questo strumento è un'ottima opzione se non vuoi integrare Ethereum. [React](https://reactjs.org/) stesso rende semplicissima la costruzione di UI interattive. Potrebbe non esser facile per i principianti come [Vue](https://vuejs.org/), ma è comunque molto usato, ha più funzionalità e, soprattutto, ha migliaia di librerie aggiuntive tra cui scegliere. _create-react-app_ è facilissimo per iniziare e include: +Prima di tutto il cuore dell'app: React e tutte le funzionalità aggiuntive che derivano da _create-react-app_. Usare solo questo è un'ottima opzione se non vuoi integrare Ethereum. [React](https://react.dev/) stesso rende la creazione di interfacce utente (UI) interattive molto semplice. Potrebbe non essere così facile per i principianti come [Vue](https://vuejs.org/), ma è comunque il più utilizzato, ha più funzionalità e, soprattutto, migliaia di librerie aggiuntive tra cui scegliere. L'_create-react-app_ rende anche molto facile iniziare e include: -- Supporto alla sintassi di React, JSX, ES6, TypeScript, Flow. -- Extra linguistici oltre ES6 come l'operatore di diffusione dell'oggetto. -- CSS auto-prefissato, così da non necessitare -webkit- o altri prefissi. -- Un veloce esecutore di test unitari interattivi con supporto integrato per la segnalazione della copertura. -- Un server di sviluppo live che avverte degli errori comuni. -- Uno script di costruzione per riunire JS, CSS e immagini per la produzione, con hash e mappe sorgente. +- Supporto della sintassi di React, JSX, ES6, TypeScript e Flow. +- Funzionalità extra del linguaggio oltre a ES6 come l'operatore spread dell'oggetto. +- CSS con prefisso automatico, quindi non sono necessari `-webkit-` o altri prefissi. +- Un veloce esecutore di unit test interattivo con supporto integrato per la segnalazione della copertura. +- Un server di sviluppo in tempo reale che avverte degli errori comuni. +- Uno script di build per creare un bundle di JS, CSS e immagini per la produzione, con hash e sourcemap. -_create-eth-app_ in particolare, fa uso dei nuovi [effetti hook](https://reactjs.org/docs/hooks-effect.html). Un metodo per scrivere componenti funzionali potenti ma molto piccoli. Vedi di seguito la sezione su Apollo per capire come vengono usati in _create-eth-app_. +In particolare, _create-eth-app_ fa uso dei nuovi [effetti degli hook](https://legacy.reactjs.org/docs/hooks-effect.html). Un metodo per scrivere i cosiddetti componenti funzionali, potenti ma molto piccoli. Vedi la sezione sottostante su Apollo per scoprire come vengono utilizzati in _create-eth-app_. ### Yarn Workspaces {#yarn-workspaces} -[Yarn Workspaces](https://classic.yarnpkg.com/en/docs/workspaces/) ti consente di utilizzare più pacchetti e di gestirli tutti dalla cartella di root e installare le dipendenze per tutti in una volta, usando `yarn install`. Ciò è utile soprattutto per i pacchetti aggiuntivi più piccoli, come la gestione di indirizzi/ABI degli smart contract (le informazioni su dove hai distribuito quali smart contract e come comunicare con essi) o l'integrazione di Graph, entrambi parte di `create-eth-app`. +[Yarn Workspaces](https://classic.yarnpkg.com/en/docs/workspaces/) permette di avere più pacchetti, gestendoli tutti dalla cartella radice e installando le dipendenze per tutti in una volta sola usando `yarn install`. Ciò ha senso soprattutto per pacchetti aggiuntivi più piccoli come la gestione di indirizzi/ABI dei contratti intelligenti (le informazioni su dove hai distribuito quali contratti intelligenti e come comunicare con essi) o l'integrazione di The Graph, entrambi parte di `create-eth-app`. ### ethers.js {#ethersjs} -Mentre [Web3](https://docs.web3js.org/) è ancora molto usato, nell'ultimo anno [ethers.js](https://docs.ethers.io/) ha riscosso molto successo come strumento alternativo ed è integrato in _create-eth-app_. Puoi lavorare con questo strumento, passare a Web3 o considerare di aggiornare a [ethers.js v5](https://docs.ethers.org/v5/), che ha quasi terminato la fase beta. +Anche se [Web3](https://docs.web3js.org/) è ancora il più utilizzato, [ethers.js](https://docs.ethers.io/) ha guadagnato molta più popolarità come alternativa nell'ultimo anno ed è quello integrato in _create-eth-app_. Puoi lavorare con questo, passare a Web3 o considerare l'aggiornamento a [ethers.js v5](https://docs.ethers.org/v5/) che è quasi uscito dalla beta. -### Graph {#the-graph} +### The Graph {#the-graph} -[GraphQL](https://graphql.org/) è un metodo alternativo per gestire i dati rispetto a un'[API di Restful](https://restfulapi.net/). Ha diversi vantaggi rispetto alle Api di Restful, specialmente per i dati della blockchain decentralizzata. Se sei interessato al ragionamento dietro questo metodo, dai un'occhiata a [GraphQL Will Power the Decentralized Web](https://medium.com/graphprotocol/graphql-will-power-the-decentralized-web-d7443a69c69a). +[GraphQL](https://graphql.org/) è un modo alternativo per gestire i dati rispetto a una [API RESTful](https://restfulapi.net/). Presenta diversi vantaggi rispetto alle API RESTful, specialmente per i dati decentralizzati della blockchain. Se sei interessato al ragionamento che c'è dietro, dai un'occhiata a [GraphQL Will Power the Decentralized Web](https://medium.com/graphprotocol/graphql-will-power-the-decentralized-web-d7443a69c69a). -Solitamente recupereresti i dati direttamente dal tuo smart contract. Vuoi leggere l'ora dell'ultima operazione? Basta chiamare `MyContract.methods.latestTradeTime().call()`, che recupera i dati da un nodo di Ethereum nella tua dapp. E se ci fossero centinaia di punti di dati diversi? Ciò risulterebbe in centinaia di recuperi di dati al nodo, richiedendo ogni volta un [RTT](https://wikipedia.org/wiki/Round-trip_delay_time) e rendendo la tua dapp lenta e inefficace. Una scappatoia potrebbe essere una funzione di chiamata del recuperatore nel tuo contratto, in modo da restituire più dati in una volta. Questa soluzione però non è sempre ideale. +Di solito, recupereresti i dati direttamente dal tuo contratto intelligente. Vuoi leggere l'ora dell'ultima operazione? Basta chiamare `MyContract.methods.latestTradeTime().call()`, che recupera i dati da un nodo di Ethereum nella tua dApp. Ma cosa succede se hai bisogno di centinaia di punti dati diversi? Ciò comporterebbe centinaia di recuperi di dati al nodo, ognuno dei quali richiederebbe un [RTT](https://wikipedia.org/wiki/Round-trip_delay_time), rendendo la tua dApp lenta e inefficiente. Una soluzione alternativa potrebbe essere una funzione di chiamata fetcher all'interno del tuo contratto che restituisce più dati contemporaneamente. Questa soluzione però non è sempre ideale. -E poi potresti essere interessato anche ai dati storici. Vuoi sapere non solo l'orario dell'ultima operazione, ma gli orari per tutte le operazioni che tu stesso hai mai eseguito? Usa il pacchetto subgraph _create-eth-app_, leggi la [documentazione](https://thegraph.com/docs/en/subgraphs/developing/creating/starting-your-subgraph) e adattalo ai tuoi contratti. Se stai cercando degli smart contract popolari, potrebbe anche esistere già un subgraph. Dai un'occhiata al [subgraph explorer](https://thegraph.com/explorer/). +E poi potresti essere interessato anche ai dati storici. Vuoi conoscere non solo l'ora dell'ultima operazione, ma anche gli orari di tutte le operazioni che hai eseguito. Usa il pacchetto subgraph di _create-eth-app_, leggi la [documentazione](https://thegraph.com/docs/en/subgraphs/developing/creating/starting-your-subgraph) e adattalo ai tuoi contratti. Se stai cercando contratti intelligenti popolari, potrebbe già esistere un subgraph. Dai un'occhiata all'[esploratore di subgraph](https://thegraph.com/explorer/). -Una volta che hai un grafico secondario, ti consente di scrivere una semplice richiesta nella tua dapp che recuperi tutti i dati importanti della blockchain, inclusi quelli storici che necessiti, tramite un solo recupero necessario. +Una volta che hai un subgraph, questo ti permette di scrivere una semplice query nella tua dApp che recupera tutti i dati importanti della blockchain di cui hai bisogno, inclusi quelli storici, con un solo recupero richiesto. ### Apollo {#apollo} -Grazie all'integrazione di [Apollo Boost](https://www.apollographql.com/docs/react/get-started/), puoi integrare facilmente il grafico nella tua dapp di React. Specialmente quando si utilizzano gli [hook di React e Apollo](https://www.apollographql.com/blog/apollo-client-now-with-react-hooks), recuperare i dati è tanto facile quanto scrivere una singola query di GraphQL nel tuo componente: +Grazie all'integrazione di [Apollo Boost](https://www.apollographql.com/docs/react/get-started/), puoi facilmente integrare The Graph nella tua dApp React. Soprattutto quando si usano gli [hook di React e Apollo](https://www.apollographql.com/blog/apollo-client-now-with-react-hooks), recuperare i dati è semplice come scrivere una singola query GraphQL nel tuo componente: ```js const { loading, error, data } = useQuery(myGraphQlQuery) @@ -79,32 +80,32 @@ React.useEffect(() => { ## Modelli {#templates} -Inoltre, puoi scegliere tra diversi modelli. Finora puoi usare un'integrazione di Aave, Compound, Uniswap o Sablier. Aggiungono tutti importanti indirizzi di servizi degli smart contract con integrazioni di subgraph pre-realizzate. Basta aggiungere il modello al comando di creazione come in `yarn create eth-app my-eth-app --with-template aave`. +Inoltre, puoi scegliere tra diversi modelli. Finora puoi usare un'integrazione Aave, Compound, UniSwap o sablier. Tutti aggiungono importanti indirizzi di contratti intelligenti di servizio insieme a integrazioni subgraph pre-realizzate. Basta aggiungere il modello al comando di creazione, ad esempio `yarn create eth-app my-eth-app --with-template aave`. ### Aave {#aave} -[Aave](https://aave.com/) è un mercato per il prestito di denaro decentralizzato. I depositanti forniscono liquidità al mercato per guadagnare un reddito passivo, mentre i debitori possono prendere in prestito usando garanzie. Una funzionalità unica di Aave sono quei [prestiti flash](https://docs.aave.com/developers/guides/flash-loans) che ti consentono di prendere in prestito denaro senza alcuna garanzia, finché restituisci il prestito entro una transazione. Questo può essere utile, ad esempio, per fornirti denaro extra sul trading d'arbitraggio. +[Aave](https://aave.com/) è un mercato decentralizzato di prestiti monetari. I depositanti forniscono liquidità al mercato per guadagnare un reddito passivo, mentre i mutuatari sono in grado di prendere in prestito usando garanzie. Una caratteristica unica di Aave sono i [prestiti flash](https://aave.com/docs/developers/flash-loans) che ti consentono di prendere in prestito denaro senza alcuna garanzia, a condizione che il prestito venga restituito all'interno di una singola transazione. Questo può essere utile, ad esempio, per darti liquidità extra nel trading di arbitraggio. -I token scambiati che ti fanno guadagnare interessi si chiamano _aTokens_. +I token scambiati che ti fruttano interessi sono chiamati _aTokens_. -Quando scegli di integrare Aave con _create-eth-app_, otterrai un'[integrazione del subgraph](https://docs.aave.com/developers/getting-started/using-graphql). Aave usa The Graph e ti fornisce già diversi subgraph pronti all'uso su [Ropsten](https://thegraph.com/explorer/subgraph/aave/protocol-ropsten) e sulla [rete principale](https://thegraph.com/explorer/subgraph/aave/protocol) in forma [grezza](https://thegraph.com/explorer/subgraph/aave/protocol-raw) o [formattata](https://thegraph.com/explorer/subgraph/aave/protocol). +Quando scegli di integrare Aave con _create-eth-app_, otterrai un'[integrazione subgraph](https://docs.aave.com/developers/getting-started/using-graphql). Aave usa The Graph e ti fornisce già diversi subgraph pronti per l'uso su [Ropsten](https://thegraph.com/explorer/subgraph/aave/protocol-ropsten) e [Rete Principale](https://thegraph.com/explorer/subgraph/aave/protocol) in forma [grezza](https://thegraph.com/explorer/subgraph/aave/protocol-raw) o [formattata](https://thegraph.com/explorer/subgraph/aave/protocol). -![Meme sui Prestiti Flash di Aave – "Eh già... se potessi mantenere il mio prestito flash per più di una transazione, sarebbe fantastico"](./flashloan-meme.png) +![Meme sui Prestiti Flash di Aave – "Sììì, se potessi tenere il mio prestito flash per più di una transazione, sarebbe fantastico"](./flashloan-meme.png) ### Compound {#compound} -[Compound](https://compound.finance/) è simile ad Aave. L'integrazione include già il nuovo [Compound v2 Subgraph](https://medium.com/graphprotocol/https-medium-com-graphprotocol-compound-v2-subgraph-highlight-a5f38f094195). A gran sorpresa, qui i token che guadagnano interessi sono chiamati _cToken_. +[Compound](https://compound.finance/) è simile ad Aave. L'integrazione include già il nuovo [Subgraph di Compound v2](https://medium.com/graphprotocol/https-medium-com-graphprotocol-compound-v2-subgraph-highlight-a5f38f094195). I token che generano interessi qui sono sorprendentemente chiamati _cTokens_. ### Uniswap {#uniswap} -[Uniswap](https://uniswap.exchange/) è uno scambio decentralizzato (DEX). I fornitori di liquidità possono guadagnare commissioni fornendo i token richiesti o ether per ambe le parti di uno scambio. È ampiamente usato e dunque ha una delle liquidità più elevate per una gamma davvero ampia di token. Puoi integrarla facilmente nella tua dapp, ad esempio, per consentire agli utenti di scambiare i propri ETH per DAI. +[Uniswap](https://uniswap.exchange/) è una borsa decentralizzata (DEX). I fornitori di liquidità possono guadagnare commissioni fornendo i token o l'ether necessari per entrambe le parti di uno scambio. È ampiamente utilizzato e quindi ha una delle più alte liquidità per una vasta gamma di token. Puoi integrarlo facilmente nella tua dApp per, ad esempio, consentire agli utenti di scambiare i loro ETH con DAI. -Sfortunatamente, al momento della redazione del del presente articolo, l'integrazione è solo per Uniswap v1 e non per [la recente v2](https://uniswap.org/blog/uniswap-v2/). +Sfortunatamente, al momento della stesura di questo articolo, l'integrazione è solo per Uniswap v1 e non per la [v2 appena rilasciata](https://uniswap.org/blog/uniswap-v2/). ### Sablier {#sablier} -[Sablier](https://sablier.com/) consente agli utenti di trasmettere pagamenti in denaro. Invece di un singolo giorno di pagamento, in realtà puoi ricevere denaro costantemente senza ulteriore amministrazione dopo la configurazione iniziale. L'integrazione include i [propri subgraph](https://thegraph.com/explorer/subgraph/sablierhq/sablier). +[Sablier](https://sablier.com/) consente agli utenti lo streaming di pagamenti in denaro. Invece di un singolo giorno di paga, ricevi il tuo denaro costantemente senza ulteriore amministrazione dopo la configurazione iniziale. L'integrazione include il suo [subgraph personale](https://thegraph.com/explorer/subgraph/sablierhq/sablier). -## E poi? {#whats-next} +## Quali sono i prossimi passi? {#whats-next} -Se hai domande su _create-eth-app_, vai al [server della community di Sablier](https://discord.gg/bsS8T47), dove puoi contattare gli autori di _create-eth-app_. Come passaggi iniziali, potrebbe essere utile integrare un framework dell'UI come [Material UI](https://material-ui.com/), scrivere query di GraphQL per i dati che ti servono realmente e configurare la distribuzione. +Se hai domande su _create-eth-app_, vai al [server della community di Sablier](https://discord.gg/bsS8T47), dove puoi metterti in contatto con gli autori di _create-eth-app_. Come primi passi successivi, potresti voler integrare un framework UI come [Material UI](https://mui.com/material-ui/), scrivere query GraphQL per i dati di cui hai effettivamente bisogno e impostare il deploy. diff --git a/public/content/translations/it/developers/tutorials/kickstart-your-dapp-frontend-development-wth-create-eth-app/index.md b/public/content/translations/it/developers/tutorials/kickstart-your-dapp-frontend-development-wth-create-eth-app/index.md index 8d093e6360e..20ef58025ce 100644 --- a/public/content/translations/it/developers/tutorials/kickstart-your-dapp-frontend-development-wth-create-eth-app/index.md +++ b/public/content/translations/it/developers/tutorials/kickstart-your-dapp-frontend-development-wth-create-eth-app/index.md @@ -1,6 +1,6 @@ --- title: Avvia lo sviluppo del frontend della tua dapp con create-eth-app -description: Una panoramica su come usare create-eth-app e le sue funzionalità +description: "Una panoramica su come usare create-eth-app e le sue funzionalità" author: "Markus Waas" tags: - "create-eth-app" diff --git a/public/content/translations/it/developers/tutorials/merkle-proofs-for-offline-data-integrity/index.md b/public/content/translations/it/developers/tutorials/merkle-proofs-for-offline-data-integrity/index.md index eb020f647c1..ac53cd738cf 100644 --- a/public/content/translations/it/developers/tutorials/merkle-proofs-for-offline-data-integrity/index.md +++ b/public/content/translations/it/developers/tutorials/merkle-proofs-for-offline-data-integrity/index.md @@ -1,6 +1,6 @@ --- -title: Prove di Merkle per l'integrità dei dati offline -description: Garantire l'integrità dei dati sulla catena per i dati memorizzati principalmente al di fuori di essa +title: "Prove di Merkle per l'integrità dei dati offline" +description: "Garantire l'integrità dei dati sulla catena per i dati memorizzati principalmente al di fuori di essa" author: Ori Pomerantz tags: - "archiviazione" @@ -33,7 +33,7 @@ L'hash principale è l'unica parte che deve essere memorizzata sulla catena. Per [Il campione di codice è disponibile qui](https://github.com/qbzzt/merkle-proofs-for-offline-data-integrity). -### Codice esterno alla catena {#off-chain-code} +### Codice esterno alla catena {#offchain-code} In questo articolo usiamo JavaScript per i calcoli al di fuori della catena. Gran parte delle app decentralizzate hanno i propri componenti esterni alla catena su JavaScript. @@ -163,7 +163,7 @@ Eseguiamo l'hashing di `(v[0],v[1])`, `(v[2],v[3])`, ecc. Quindi per i valori pa }   // getMerkleProof ``` -### Codice on-chain {#on-chain-code} +### Codice on-chain {#onchain-code} Finalmente abbiamo il codice che verifica la prova. Il codice on-chain è scritto in [Solidity](https://docs.soliditylang.org/en/v0.8.11/). L'ottimizzazione è molto più importante qui, perché il gas è relativamente costoso. diff --git a/public/content/translations/it/developers/tutorials/nft-minter/index.md b/public/content/translations/it/developers/tutorials/nft-minter/index.md index 5029f29175f..6f777a22037 100644 --- a/public/content/translations/it/developers/tutorials/nft-minter/index.md +++ b/public/content/translations/it/developers/tutorials/nft-minter/index.md @@ -183,7 +183,7 @@ return ( Mint NFT

{status}

- + ) ``` diff --git a/public/content/translations/it/developers/tutorials/optimism-std-bridge-annotated-code/index.md b/public/content/translations/it/developers/tutorials/optimism-std-bridge-annotated-code/index.md index 623a368b33e..20ffd103981 100644 --- a/public/content/translations/it/developers/tutorials/optimism-std-bridge-annotated-code/index.md +++ b/public/content/translations/it/developers/tutorials/optimism-std-bridge-annotated-code/index.md @@ -1,6 +1,6 @@ --- title: "Guida del ponte standard di Optimism per contratti" -description: Come funziona il ponte standard per Optimism? Perché funziona così? +description: "Come funziona il ponte standard per Optimism? Perché funziona così?" author: Ori Pomerantz tags: - "solidity" diff --git a/public/content/translations/it/developers/tutorials/run-node-raspberry-pi/index.md b/public/content/translations/it/developers/tutorials/run-node-raspberry-pi/index.md index 0b7f03a7701..a5d4e6b6795 100644 --- a/public/content/translations/it/developers/tutorials/run-node-raspberry-pi/index.md +++ b/public/content/translations/it/developers/tutorials/run-node-raspberry-pi/index.md @@ -10,7 +10,7 @@ tags: lang: it skill: intermediate published: 2022-06-10 -source: Ethereum su ARM +source: Ethereum on ARM sourceUrl: https://ethereum-on-arm-documentation.readthedocs.io/en/latest/ --- diff --git a/public/content/translations/it/developers/tutorials/secure-development-workflow/index.md b/public/content/translations/it/developers/tutorials/secure-development-workflow/index.md index 124522bb671..4d961ea14a3 100644 --- a/public/content/translations/it/developers/tutorials/secure-development-workflow/index.md +++ b/public/content/translations/it/developers/tutorials/secure-development-workflow/index.md @@ -9,7 +9,7 @@ tags: skill: intermediate lang: it published: 2020-09-07 -source: Creare contratti sicuri +source: Building secure contracts sourceUrl: https://github.com/crytic/building-secure-contracts/blob/master/development-guidelines/workflow.md --- diff --git a/public/content/translations/it/developers/tutorials/sending-transactions-using-web3-and-alchemy/index.md b/public/content/translations/it/developers/tutorials/sending-transactions-using-web3-and-alchemy/index.md index ac548d8aaa8..4db85d9821c 100644 --- a/public/content/translations/it/developers/tutorials/sending-transactions-using-web3-and-alchemy/index.md +++ b/public/content/translations/it/developers/tutorials/sending-transactions-using-web3-and-alchemy/index.md @@ -9,7 +9,7 @@ tags: skill: beginner lang: it published: 2020-11-04 -source: documentazione Alchemy +source: Alchemy docs sourceUrl: https://www.alchemy.com/docs/how-to-send-transactions-on-ethereum --- diff --git a/public/content/translations/it/developers/tutorials/short-abi/index.md b/public/content/translations/it/developers/tutorials/short-abi/index.md index 15b2ff853f5..0ebe8f089b4 100644 --- a/public/content/translations/it/developers/tutorials/short-abi/index.md +++ b/public/content/translations/it/developers/tutorials/short-abi/index.md @@ -327,7 +327,7 @@ Crea una transazione di trasferimento. Il primo byte è "0x02", seguito dall'ind }) // describe ``` -### Esempio {#example} +### Esempio {#reducing-the-cost-when-you-do-control-the-destination-contract} Se desideri vedere questi file in azione senza eseguirli tu stesso, segui questi link: @@ -337,13 +337,13 @@ Se desideri vedere questi file in azione senza eseguirli tu stesso, segui questi 4. [Chiamata a `OrisUselessToken.approve()`](https://kovan-optimistic.etherscan.io/tx/1410747). Questa chiamata deve andare direttamente al contratto del token, poiché l'elaborazione si affida al `msg.sender`. 5. [Chiamata a `transfer()`](https://kovan-optimistic.etherscan.io/tx/1410748). -## Ridurre il costo quando hai il controllo del contratto di destinazione {#reducing-the-cost-when-you-do-control-the-destination-contract} +## Ridurre il costo quando hai il controllo del contratto di destinazione {#token-sol-2} Se hai il controllo sul contratto di destinazione, puoi creare funzioni che bypassano i controlli `msg.sender` poiché si fidano dell'interprete dei calldata. [Puoi vedere un esempio di come funziona qui, nel ramo `control-contract`](https://github.com/qbzzt/ethereum.org-20220330-shortABI/tree/control-contract). Se il contratto rispondesse solo alle transazioni esterne, potremmo riuscirsi con un solo contratto. Tuttavia, questo spezzerebbe la [componibilità](/developers/docs/smart-contracts/composability/). È molto meglio avere un contratto che risponda alle normali chiamate ERC-20 e un altro che risponda alle transazioni con dati della chiamata brevi. -### Token.sol {#token-sol-2} +### Token.sol {#calldatainterpreter-sol-2} In questo esempio, possiamo modificare `Token.sol`. Questo ci permette di avere un numero di funzioni che solo il proxy può chiamare. Ecco le nuove parti: @@ -441,7 +441,7 @@ Queste sono tre operazioni che normalmente richiedono che il messaggio provenga 1. È modificata da `onlyProxy()`, così che nessun altro possa controllarla. 2. Ottiene l'indirizzo che sarebbe normalmente `msg.sender` come un parametro aggiuntivo. -### CalldataInterpreter.sol {#calldatainterpreter-sol-2} +### CalldataInterpreter.sol {#test-js-2} L'interprete dei dati della chiamata è praticamente identico a quello precedente, tranne che le funzioni in proxy ricevono un parametro `msg.sender` e non è necessaria un'indennità per `transfer`. @@ -475,7 +475,7 @@ L'interprete dei dati della chiamata è praticamente identico a quello precedent } ``` -### Test.js {#test-js-2} +### Test.js {#conclusion} Ci sono alcune modifiche tra il codice di test precedente e questo. diff --git a/public/content/translations/it/developers/tutorials/smart-contract-security-guidelines/index.md b/public/content/translations/it/developers/tutorials/smart-contract-security-guidelines/index.md index d58a2b840ee..72c04d2ac1e 100644 --- a/public/content/translations/it/developers/tutorials/smart-contract-security-guidelines/index.md +++ b/public/content/translations/it/developers/tutorials/smart-contract-security-guidelines/index.md @@ -9,7 +9,7 @@ tags: skill: intermediate lang: it published: 2020-09-06 -source: Creare contratti sicuri +source: Building secure contracts sourceUrl: https://github.com/crytic/building-secure-contracts/blob/master/development-guidelines/guidelines.md --- @@ -27,7 +27,7 @@ La documentazione può essere scritta su diversi livelli e deve essere aggiornat - **Schema e diagrammi architettonici**, incluse le interazioni del contratto e la macchina a stati del sistema. Le [stampanti Slither](https://github.com/crytic/slither/wiki/Printer-documentation) possono aiutare a generare questi schemi. - **Documentazione approfondita sul codice**, il [formato Natspec](https://solidity.readthedocs.io/en/develop/natspec-format.html) si può usare per Solidity. -### Calcolo sulla catena ed esterno alla catena {#on-chain-vs-off-chain-computation} +### Calcolo sulla catena ed esterno alla catena {#onchain-vs-offchain-computation} - **Mantieni quanto più codice possibile al di fuori della catena.** Il livello sulla catena deve essere il più ridotto possibile. Elabora anticipatamente i dati con il codice esternamente alla catena così che la verifica su di essa sia semplice. Ti serve un elenco ordinato? Ordina l'elenco esternamente alla catena, poi controlla solo l'ordine sulla catena. diff --git a/public/content/translations/it/developers/tutorials/the-graph-fixing-web3-data-querying/index.md b/public/content/translations/it/developers/tutorials/the-graph-fixing-web3-data-querying/index.md index 1adc5485c36..74a030740b1 100644 --- a/public/content/translations/it/developers/tutorials/the-graph-fixing-web3-data-querying/index.md +++ b/public/content/translations/it/developers/tutorials/the-graph-fixing-web3-data-querying/index.md @@ -1,6 +1,6 @@ --- title: "The Graph: query di dati in Web3" -description: La blockchain è come un database ma senza SQL. Contiene tutti i dati, ma non c'è modo di accedervi. Vediamo come risolvere la situazione con The Graph e GraphQL. +description: "La blockchain è come un database ma senza SQL. Contiene tutti i dati, ma non c'è modo di accedervi. Vediamo come risolvere la situazione con The Graph e GraphQL." author: Markus Waas lang: it tags: diff --git a/public/content/translations/it/developers/tutorials/token-integration-checklist/index.md b/public/content/translations/it/developers/tutorials/token-integration-checklist/index.md index 50630419398..d6579c04b63 100644 --- a/public/content/translations/it/developers/tutorials/token-integration-checklist/index.md +++ b/public/content/translations/it/developers/tutorials/token-integration-checklist/index.md @@ -10,7 +10,7 @@ tags: - "token" skill: intermediate published: 2020-08-13 -source: Creare contratti sicuri +source: Building secure contracts sourceUrl: https://github.com/crytic/building-secure-contracts/blob/master/development-guidelines/token_integration.md --- diff --git a/public/content/translations/it/developers/tutorials/uniswap-v2-annotated-code/index.md b/public/content/translations/it/developers/tutorials/uniswap-v2-annotated-code/index.md index 23ed18a2053..82e24f12a55 100644 --- a/public/content/translations/it/developers/tutorials/uniswap-v2-annotated-code/index.md +++ b/public/content/translations/it/developers/tutorials/uniswap-v2-annotated-code/index.md @@ -1,6 +1,6 @@ --- title: "Guida dettagliata al contratto Uniswap-v2" -description: Come funziona il contratto Uniswap-v2? Perché è scritto così? +description: "Come funziona il contratto Uniswap-v2? Perché è scritto così?" author: Ori Pomerantz tags: - "solidity" @@ -55,9 +55,8 @@ Questo è il flusso più comune, usato dai trader: 3. Identifica l'importo necessario da scambiare su ogni scambio lungo il percorso. 4. Itera sul percorso. Per ogni scambio lungo il percorso, invia il token di input e poi chiama la funzione di `swap` dello scambio. In gran parte dei casi, l'indirizzo di destinazione per i token è lo scambio in pari successivo nel percorso. Nello scambio finale è presente l'indirizzo fornito dal trader. -#### Nel contratto principale (UniswapV2Pair.sol) {#in-the-core-contract-uniswapv2pairsol-2} +#### Nel contratto principale (UniswapV2Pair.sol) {#in-the-core-contract-uniswapv2pairsol-2}5. Verifica che il contratto principale non raggiri il sistema e possa mantenere liquidità sufficiente dopo lo scambio. -5. Verifica che il contratto principale non raggiri il sistema e possa mantenere liquidità sufficiente dopo lo scambio. 6. Vede quanti token aggiuntivi abbiamo, in aggiunta alle riserve note. Quell'importo è il numero di token di input ricevuti da scambiare. 7. Invia i token d'output alla destinazione. 8. Chiama `_update` per aggiornare gli importi della riserva @@ -743,7 +742,7 @@ Questa è la funzione principale della factory, per creare uno scambio in pari t (address token0, address token1) = tokenA < tokenB ? (tokenA, tokenB) : (tokenB, tokenA); ``` -Vogliamo che l'indirizzo del nuovo scambio sia deterministico, quindi calcolabile in anticipo al di fuori della catena (questo può essere utile per le [transazioni di livello 2](/developers/docs/layer-2-scaling/)). Per farlo, dobbiamo avere un ordine coerente degli indirizzi del token, indipendentemente dall'ordine in cui li abbiamo ricevuti, quindi li ordiniamo qui. +Vogliamo che l'indirizzo del nuovo scambio sia deterministico, quindi calcolabile in anticipo al di fuori della catena (questo può essere utile per le [transazioni di livello 2](/developers/docs/scaling/)). Per farlo, dobbiamo avere un ordine coerente degli indirizzi del token, indipendentemente dall'ordine in cui li abbiamo ricevuti, quindi li ordiniamo qui. ```solidity require(token0 != address(0), 'UniswapV2: ZERO_ADDRESS'); diff --git a/public/content/translations/it/developers/tutorials/using-websockets/index.md b/public/content/translations/it/developers/tutorials/using-websockets/index.md index 892853e0405..f96fc83dfca 100644 --- a/public/content/translations/it/developers/tutorials/using-websockets/index.md +++ b/public/content/translations/it/developers/tutorials/using-websockets/index.md @@ -9,8 +9,8 @@ tags: - "query" - "javascript" skill: beginner -source: documentazione Alchemy -sourceUrl: https://docs.alchemyapi.io/guides/using-websockets +source: Alchemy docs +sourceUrl: https://www.alchemy.com/docs/reference/best-practices-for-using-websockets-in-web3 published: 2020-12-01 --- diff --git a/public/content/translations/it/developers/tutorials/waffle-dynamic-mocking-and-testing-calls/index.md b/public/content/translations/it/developers/tutorials/waffle-dynamic-mocking-and-testing-calls/index.md index bec9d55112b..676f647e349 100644 --- a/public/content/translations/it/developers/tutorials/waffle-dynamic-mocking-and-testing-calls/index.md +++ b/public/content/translations/it/developers/tutorials/waffle-dynamic-mocking-and-testing-calls/index.md @@ -295,4 +295,4 @@ Il codice sorgente di questo tutorial si può trovare [qui](https://github.com/E Altri tutorial che potrebbero interessarti: -- [Test di Smart Contract con Waffle](/developers/tutorials/testing-smart-contract-with-waffle/) +- [Test di Smart Contract con Waffle](/developers/tutorials/waffle-test-simple-smart-contract/) diff --git a/public/content/translations/it/developers/tutorials/waffle-test-simple-smart-contract/index.md b/public/content/translations/it/developers/tutorials/waffle-test-simple-smart-contract/index.md index d440693878a..6b30dec8150 100644 --- a/public/content/translations/it/developers/tutorials/waffle-test-simple-smart-contract/index.md +++ b/public/content/translations/it/developers/tutorials/waffle-test-simple-smart-contract/index.md @@ -30,7 +30,6 @@ published: 2021-02-26 Il tutorial dimostra la configurazione di prova e opera utilizzando yarn, ma non ci sono problemi se preferisci npm: fornirò gli adeguati riferimenti alla [documentazione](https://ethereum-waffle.readthedocs.io/en/latest/index.html) ufficiale di Waffle. ### Installa dipendenze {#install-dependencies} - [Aggiungi](https://ethereum-waffle.readthedocs.io/en/latest/getting-started.html#installation) ethereum-waffle e le dipendenze di TypeScript alle dipendenze di sviluppo del tuo progetto. ```bash @@ -38,7 +37,6 @@ yarn add --dev ethereum-waffle ts-node typescript @types/jest ``` ### Esempio di contratto intelligente {#example-smart-contract} - Durante il tutorial lavoreremo a un esempio di contratto intelligente semplice: EtherSplitter. Non fa molto, tranne che consentire a chiunque di inviare wei e dividerli uniformemente tra due destinatari predefiniti. La funzione di divisione richiede che il numero di wei sia pari, altrimenti si ripristinerà. Per entrambi i destinatari esegue un trasferimento di wei, seguito dall'emissione dell'evento Trasferimento. Posiziona il frammento del codice di EtherSplitter in `src/EtherSplitter.sol`. @@ -68,7 +66,6 @@ contract EtherSplitter { ``` ### Compila il contratto {#compile-the-contract} - Per [compilare](https://ethereum-waffle.readthedocs.io/en/latest/getting-started.html#compiling-the-contract) il contratto, aggiungi il seguente elemento al file package.json: ```json @@ -91,7 +88,6 @@ Poi, crea un file di configurazione di Waffle nella cartella di root del progett Esegui `yarn build`. Di conseguenza, la cartella `build` apparirà con il contratto compilato di EtherSplitter nel formato JSON. ### Testare la configurazione {#test-setup} - Testare con Waffle richiede l'utilizzo di abbinatori Chai e Mocha, quindi, devi [aggiungerli](https://ethereum-waffle.readthedocs.io/en/latest/getting-started.html#writing-tests) al tuo progetto. Aggiorna il tuo file package.json e aggiungi l'elemento `test` nella parte degli script: ```json @@ -135,7 +131,6 @@ Solo due parole prima di iniziare. `MockProvider` offre una versione fittizia de Quindi, dichiariamo una variabile detta "splitter" (divisore), che è il nostro contratto fittizio EtherSplitter. È creato prima di ogni esecuzione di un singolo test dal metodo `deployContract`. Questo metodo simula la distribuzione di un contratto dal portafoglio passato come primo parametro (nel nostro caso, il portafoglio del mittente). Il secondo parametro è l'ABI e il bytecode del contratto testato; qui, passiamo il file json del contratto compilato EtherSplitter dalla cartella `build`. Il terzo parametro è un insieme con gli argomenti del costruttore del contratto che, nel nostro caso, sono gli indirizzi dei due destinatari. ### changeBalances {#changebalances} - Prima controlleremo se il metodo di divisione modifica effettivamente i saldi dei portafogli dei destinatari. Se dividiamo 50 wei dall'account del mittente, i saldi di entrambi i destinatari dovrebbero aumentare di 25 wei. Utilizzeremo l'abbinatore di Waffle "`changeBalances`: ```ts @@ -163,7 +158,6 @@ Nota che in entrambi i casi di `changeBalance` e `changeBalances`, passiamo la f Poi, testeremo se l'evento Trasferimento è stato emesso dopo ogni trasferimento di wei. Ci rivolgeremo a un altro abbinatore da Waffle: ### Emetti {#emit} - ```ts it("Emits event on the transfer to the first receiver", async () => { await expect(splitter.split({ value: 50 })) @@ -181,7 +175,6 @@ it("Emits event on the transfer to the second receiver", async () => { L'abbinatore `emit` ci consente di verificare se un contratto ha emesso un evento alla chiamata di un metodo. Come parametri all'abbinatore `emit`, forniamo il contratto fittizio che prevediamo emetterà l'evento, insieme al nome di tale evento. Nel nostro caso, il contratto fittizio è `splitter` e il nome dell'evento è `Trasferimento`. Inoltre, possiamo verificare i valori precisi degli argomenti con cui è stato emesso l'evento; passiamo altrettanti argomenti all'abbinatore `withArgs`, come previsto dalla dichiarazione del nostro evento. Nel caso del contratto EtherSplitter, passiamo gli indirizzi del mittente e del destinatario insieme all'importo trasferito di wei. ### revertedWith {#revertedwith} - Come ultimo esempio verificheremo se la transazione è stata ripristinata, nel caso di un numero dispari di wei. Utilizzeremo l'abbinatore `revertedWith`: ```ts diff --git a/public/content/translations/it/ethereum-forks/index.md b/public/content/translations/it/ethereum-forks/index.md index d5f6252e37c..b3a41fd3001 100644 --- a/public/content/translations/it/ethereum-forks/index.md +++ b/public/content/translations/it/ethereum-forks/index.md @@ -16,7 +16,6 @@ Le diramazioni si verificano quando è necessario apportare importanti aggiornam Quando sono necessari aggiornamenti in software tradizionali controllati centralmente, l'azienda pubblica una nuova versione per l'utente finale. Le blockchain funzionano diversamente perché non esiste una proprietà centrale. I [client di Ethereum](/developers/docs/nodes-and-clients/) devono aggiornare il proprio software e implementare le regole della nuova diramazione. Inoltre i creatori dei blocchi (miner in contesto Proof of Work e validatori in contesto Proof of Stake) e i nodi devono creare blocchi e convalidarli in base alle nuove regole. [Maggiori informazioni sui meccanismi di consenso](/developers/docs/consensus-mechanisms/) Queste modifiche alle regole potrebbero creare una divisione temporanea nella rete. I nuovi blocchi potrebbero essere creati in base alle nuove regole o a quelle vecchie. Le diramazioni di solito sono concordate in anticipo in modo che i client adottino le modifiche all'unisono e la diramazione legata agli upgrade diventi la catena principale. Tuttavia, in rari casi, disaccordi sulle diramazioni possono causare una divisione permanente della rete, come è successo con la creazione di Ethereum Classic con la diramazione DAO. - @@ -59,7 +58,6 @@ Gli aggiornamenti dei livelli di esecuzione e di consenso erano inizialmente dis | ----------------- | ----------------- | ---------- | | Shanghai | Capella | "Shapella" | | Cancun | Deneb | "Dencun" | - Salta direttamente alle informazioni su alcuni degli ultimi aggiornamenti particolarmente importanti: [La Beacon Chain](/roadmap/beacon-chain/); [La Fusione](/roadmap/merge/) ed [EIP-1559](#london) @@ -68,13 +66,13 @@ Stai cercando i prossimi aggiornamenti di protocollo? [Scopri di più sui prossi -## 2024 {#2024} +## 2024 {#2025} -### Cancun-Deneb ("Dencun") {#dencun} +### Cancun-Deneb ("Dencun") {#fusaka} -#### Riepilogo di Cancun {#cancun-summary} +#### Riepilogo di Cancun {#pectra} L'aggiornamento di Cancun contiene una serie di miglioramenti all'_esecuzione_ di Ethereum, mirati a migliorarne la scalabilità, in tandem con gli aggiornamenti al consenso di Deneb. @@ -90,7 +88,6 @@ Notevolmente, include l'EIP-4844, nota come **Proto-Danksharding**, che riduce s
  • EIP-6780: SELFDESTRUCT soltanto nella stessa transazione
  • EIP-7516: Codice operativo BLOBBASEFEE
  • - - [Rollup del Livello 2](/layer-2/) @@ -98,7 +95,7 @@ Notevolmente, include l'EIP-4844, nota come **Proto-Danksharding**, che riduce s - [Danksharding](/roadmap/danksharding/) - [Leggi le specifiche dell'aggiornamento di Cancun](https://github.com/ethereum/execution-specs/blob/master/network-upgrades/mainnet-upgrades/cancun.md) -#### Riepilogo di Deneb {#deneb-summary} +#### Riepilogo di Deneb {#2024} L'aggiornamento di Deneb contiene una serie di miglioramenti al _consenso_ di Ethereum, mirati a migliorarne la scalabilità. Questo aggiornamento è in tandem con gli aggiornamenti del livello di esecuzione Cancun per consentire il Proto-Danksharding (EIP-4844), insieme ad altri miglioramenti alla Beacon Chain. @@ -115,7 +112,6 @@ EIP-7514 comporta un rafforzamento dell'emissione di ETH, limitando il tasso di
  • EIP-7045: Aumento degli slot massimi di inclusione dell'attestazione
  • EIP-7514: Aggiunta del limite massimo di churn per epoca
  • - - [Leggi le specifiche dell'aggiornamento di Deneb](https://github.com/ethereum/consensus-specs/blob/dev/specs/deneb/) @@ -123,13 +119,13 @@ EIP-7514 comporta un rafforzamento dell'emissione di ETH, limitando il tasso di -## 2023 {#2023} +## 2023 {#dencun} -### Shanghai-Capella ("Shapella") {#shapella} +### Shanghai-Capella ("Shapella") {#cancun-summary} -#### Riepilogo di Shanghai {#shanghai-summary} +#### Riepilogo di Shanghai {#deneb-summary} L'aggiornamento di Shanghai ha portato i prelievi di staking al livello d'esecuzione. Insieme all'aggiornamento Capella, questo abiliterà i blocchi ad accettare le operazioni di prelievo, che consentono agli staker di prelevare i propri ETH dalla Beacon Chain al livello d'esecuzione. @@ -142,12 +138,11 @@ L'aggiornamento di Shanghai ha portato i prelievi di staking al livello d'esecuz
  • EIP-4895La Beacon Chain lancia i prelievi come operazioni
  • EIP-6049 - Depreca SELFDESTRUCT
  • - - [Leggi le specifiche dell'aggiornamento Shanghai](https://github.com/ethereum/execution-specs/blob/master/network-upgrades/mainnet-upgrades/shanghai.md) -#### Riepilogo di Capella {#capella-summary} +#### Riepilogo di Capella {#2023} L'aggiornamento di Capella è il terzo aggiornamento principale al livello del consenso (Beacon Chain) e ha abilitato i prelievi di staking. Capella è avvenuto contemporaneamente all'aggiornamento del livello di esecuzione di Shanghai, e ha reso disponibili le funzioni di prelievo da staking. @@ -160,13 +155,13 @@ L'aggiornamento, inoltre, ha fornito la funzionalità di pulizia automatica dei -## 2022 {#2022} +## 2022 {#shapella} -### Paris (la Fusione) {#paris} +### Paris (la Fusione) {#shanghai-summary} -#### Riepilogo {#paris-summary} +#### Riepilogo {#capella-summary} L'aggiornamento Paris è stato attivato dal passaggio da una blockchain proof-of-work di una [difficoltà totale terminale](/glossary/#terminal-total-difficulty) di 58750000000000000000000. Questo è avvenuto al blocco 15537393 il 15 settembre 2022, innescando l'aggiornamento Paris dal blocco successivo. Paris è stata la transizione [alla Fusione](/roadmap/merge/): la sua caratteristica principale è lo spegnimento dell'algoritmo di mining [proof-of-work](/developers/docs/consensus-mechanisms/pow) e della relativa logica di consenso, e l'attivazione della [proof-of-stake](/developers/docs/consensus-mechanisms/pos). Paris è stata un aggiornamento ai [client di esecuzione](/developers/docs/nodes-and-clients/#execution-clients) (equivalente a Bellatrix a livello di consenso) che ha permesso loro di ricevere istruzioni dai loro [client di consenso](/developers/docs/nodes-and-clients/#consensus-clients) collegati. Questo ha richiesto l'attivazione di una nuova serie di metodi API interni, collettivamente noti come l'[API Engine](https://github.com/ethereum/execution-apis/blob/main/src/engine/common.md). Questo è stato probabilmente l'aggiornamento più significativo nella storia di Ethereum dopo [Homestead](#homestead)! @@ -178,16 +173,15 @@ L'aggiornamento Paris è stato attivato dal passaggio da una blockchain proof-of
  • EIP-3675Aggiorna il consenso al Proof-of-Stake
  • EIP-4399Sostituisce l'opcode DIFFICULTY con PREVRANDAO
  • - --- -### Bellatrix {#bellatrix} +### Bellatrix {#2022} -#### Riepilogo {#bellatrix-summary} +#### Riepilogo {#paris} L'aggiornamento Bellatrix è stato il secondo aggiornamento programmato per la [Beacon Chain](/roadmap/beacon-chain), preparando la catena per [la Fusione](/roadmap/merge/). Porta le penalità dei validatori al valore pieno per inattività e azioni sanzionabili (slashing). Bellatrix include anche un aggiornamento alle regole di scelta della diramazione per preparare la catena per la Fusione e la transizione dall'ultimo blocco di proof-of-work al primo blocco proof-of-stake. A tale scopo occorre far sì che i client di consenso siano consapevoli della [difficoltà terminale totale](/glossary/#terminal-total-difficulty) di 58750000000000000000000. @@ -195,11 +189,11 @@ L'aggiornamento Bellatrix è stato il secondo aggiornamento programmato per la [ --- -### Gray Glacier {#gray-glacier} +### Gray Glacier {#paris-summary} -#### Riepilogo {#gray-glacier-summary} +#### Riepilogo {#bellatrix} L'aggiornamento della rete di Gray Glacier ha rimandato di tre mesi la [bomba di difficoltà](/glossary/#difficulty-bomb). Questa è l'unica modifica introdotta in questo aggiornamento ed è simile per natura agli aggiornamenti di [Arrow Glacier](#arrow-glacier) e [Muir Glacier](#muir-glacier). Modifiche simili sono state effettuate sugli aggiornamenti di rete [Byzantium](#byzantium), [Constantinople](#constantinople) e [London](#london). @@ -210,18 +204,17 @@ L'aggiornamento della rete di Gray Glacier ha rimandato di tre mesi la [bomba di
    • EIP-5133ritarda la bomba di difficoltà fino a settembre 2022
    - -## 2021 {#2021} +## 2021 {#bellatrix-summary} -### Arrow Glacier {#arrow-glacier} +### Arrow Glacier {#gray-glacier} -#### Riepilogo {#arrow-glacier-summary} +#### Riepilogo {#gray-glacier-summary} L'aggiornamento di rete Arrow Glacier ha rimandato la [bomba di difficoltà](/glossary/#difficulty-bomb) di diversi mesi. Questo è l'unico cambiamento introdotto in questo aggiornamento, ed è simile nella sostanza all'aggiornamento [Muir Glacier](#muir-glacier). Modifiche simili sono state effettuate sugli aggiornamenti di rete [Byzantium](#byzantium), [Constantinople](#constantinople) e [London](#london). @@ -233,22 +226,21 @@ L'aggiornamento di rete Arrow Glacier ha rimandato la [bomba di difficoltà](/gl
    • EIP-4345ritarda la bomba di difficoltà fino a giugno 2022
    - --- -### Altair {#altair} +### Altair {#2021} -#### Riepilogo {#altair-summary} +#### Riepilogo {#arrow-glacier} L'aggiornamento Altair è stato il primo aggiornamento pianificato per la [Beacon Chain](/roadmap/beacon-chain). Ha aggiunto il supporto per le "commissioni di sincronizzazione", abilitando i "client leggeri", aumentando le penalità per inattività e slashing per i validatori man mano che lo sviluppo procedeva verso la Fusione. - [Leggi le specifiche dell'aggiornamento di Altair](https://github.com/ethereum/consensus-specs/tree/dev/specs/altair) -#### Curiosità! {#altair-fun-fact} +#### Curiosità! {#arrow-glacier-summary} Altair è stato il primo importante aggiornamento di rete che ha avuto un tempo di rollout esatto. Tutti gli aggiornamenti precedenti erano basati su un numero di blocco dichiarato su una catena proof-of-work, dove i tempi del blocco variavano. La Beacon Chain non richiede la risoluzione del proof-of-work e funziona invece su un sistema di epoche basato sul tempo che consiste in 32 "slot" di dodici secondi in cui i validatori possono proporre dei blocchi. Questo è il motivo per cui sapevamo esattamente quando avremmo raggiunto l'epoca 74.240 e Altair sarebbe diventato operativo! @@ -256,15 +248,15 @@ Altair è stato il primo importante aggiornamento di rete che ha avuto un tempo --- -### London {#london} +### London {#altair} -#### Riepilogo {#london-summary} +#### Riepilogo {#altair-summary} L'aggiornamento London ha introdotto l'[EIP-1559](https://eips.ethereum.org/EIPS/eip-1559), che ha riformato il mercato delle commissioni sulle transazioni, oltre a modificare come sono gestiti i rimborsi di carburante e la pianificazione di [Ice Age](/glossary/#ice-age). -#### Cos'è l'Aggiornamento di Londra / EIP-1559? {#eip-1559} +#### Cos'è l'Aggiornamento di Londra / EIP-1559? {#altair-fun-fact} Prima dell'Aggiornamento di Londra, Ethereum disponeva di blocchi di dimensioni fisse. Nei momenti di elevata domanda di rete, questi blocchi operavano a piena capacità. Di conseguenza, gli utenti devono spesso attendere che la domanda si riduca per essere inclusi in un blocco, il che ha portato a una scadente esperienza degli utenti. L'Aggiornamento di Londra ha introdotto blocchi di dimensioni variabili a Ethereum. @@ -291,16 +283,15 @@ Questo video spiega l'EIP-1559 e i benefici che comporta: [EIP-1559 Explained](h
  • EIP-3541 - impedisce la distribuzione dei contratti che iniziano con 0xEF
  • EIP-3554ritarda l'Era Glaciale fino a dicembre 2021
  • - --- -### Berlin {#berlin} +### Berlin {#london} -#### Riepilogo {#berlin-summary} +#### Riepilogo {#london-summary} L'aggiornamento Berlin ha ottimizzato i costi del carburante per certe azioni dell'EVM e ha aumentato il supporto per vari tipi di transazioni. @@ -315,18 +306,17 @@ L'aggiornamento Berlin ha ottimizzato i costi del carburante per certe azioni de
  • EIP-2929il costo del carburante aumenta per gli opcode d'accesso allo stato
  • EIP-2930aggiunge elenchi d'accesso facoltativi
  • - -## 2020 {#2020} +## 2020 {#eip-1559} -### Genesi della Beacon Chain {#beacon-chain-genesis} +### Genesi della Beacon Chain {#berlin} -#### Riepilogo {#beacon-chain-genesis-summary} +#### Riepilogo {#berlin-summary} La [Beacon Chain](/roadmap/beacon-chain/) necessita di 16384 depositi da 32 ETH di staking per poter funzionare in sicurezza. Questo è successo il 27 novembre, quindi la Beacon Chain ha iniziato a produrre blocchi il 1° dicembre 2020. Questa è una prima fase importante nel percorso per raggiungere la [visione di Ethereum](/roadmap/vision/). @@ -338,11 +328,11 @@ La [Beacon Chain](/roadmap/beacon-chain/) necessita di 16384 depositi da 32 ETH --- -### Distribuzione del contratto di deposito in staking {#staking-deposit-contract} +### Distribuzione del contratto di deposito in staking {#2020} -#### Riepilogo {#deposit-contract-summary} +#### Riepilogo {#beacon-chain-genesis} Il contratto di deposito in staking ha introdotto lo [staking](/glossary/#staking) all'ecosistema di Ethereum. Nonostante fosse un contratto della [Rete principale](/glossary/#mainnet), ha avuto un impatto diretto sulla linea temporale per il lancio della [Beacon Chain](/roadmap/beacon-chain/), un importante [aggiornamento di Ethereum](/roadmap/). @@ -354,11 +344,11 @@ Il contratto di deposito in staking ha introdotto lo [staking](/glossary/#stakin --- -### Muir Glacier {#muir-glacier} +### Muir Glacier {#beacon-chain-genesis-summary} -#### Riepilogo {#muir-glacier-summary} +#### Riepilogo {#staking-deposit-contract} La diramazione Muir Glacier ha introdotto un ritardo nella [bomba di difficoltà](/glossary/#difficulty-bomb). Aumenta la difficoltà del blocco del meccanismo di consenso [Proof-of-Work](/developers/docs/consensus-mechanisms/pow/), che rischiava di peggiorare l'utilizzabilità di Ethereum, aumentando i tempi d'attesa per l'invio delle transazioni e l'uso delle dapp. @@ -370,18 +360,17 @@ La diramazione Muir Glacier ha introdotto un ritardo nella [bomba di difficoltà
    • EIP-2384ritarda la bomba di difficoltà per altri 4.000.000 blocchi, o circa 611 giorni.
    - -## 2019 {#2019} +## 2019 {#deposit-contract-summary} -### Istanbul {#istanbul} +### Istanbul {#muir-glacier} -#### Riepilogo {#istanbul-summary} +#### Riepilogo {#muir-glacier-summary} La diramazione Instanbul: @@ -403,16 +392,15 @@ La diramazione Instanbul:
  • EIP-2028riduce il costo di CallData per consentire più dati nei blocchi, buono per il [ridimensionamento del Livello 2](/developers/docs/scaling/#layer-2-scaling).
  • EIP-2200altre alterazioni del prezzo del carburante dell'opcode.
  • - --- -### Constantinople {#constantinople} +### Constantinople {#2019} -#### Riepilogo {#constantinople-summary} +#### Riepilogo {#istanbul} La diramazione Constantinople: @@ -431,18 +419,17 @@ La diramazione Constantinople:
  • EIP-1052: Introduce l'istruzione EXTCODEHASH per recuperare l'hash del codice di un altro contratto.
  • EIP-1234assicura che la blockchain non si congeli prima del proof-of-stake e riduce la ricompensa per blocco da 3 a 2 ETH.
  • - -## 2017 {#2017} +## 2017 {#istanbul-summary} -### Byzantium {#byzantium} +### Byzantium {#constantinople} -#### Riepilogo {#byzantium-summary} +#### Riepilogo {#constantinople-summary} La diramazione Byzantium: @@ -466,18 +453,17 @@ La diramazione Byzantium:
  • EIP-100modifica la formula di regolazione della difficoltà.
  • EIP-649ritarda la [bomba di difficoltà](/glossary/#difficulty-bomb) di 1 anno e riduce la ricompensa del blocco da 5 a 3 ETH.
  • - -## 2016 {#2016} +## 2016 {#2017} -### Spurious Dragon {#spurious-dragon} +### Spurious Dragon {#byzantium} -#### Riepilogo {#spurious-dragon-summary} +#### Riepilogo {#byzantium-summary} La diramazione Spurious Dragon è stata la seconda risposta agli attacchi denial of service (DoS) sulla rete (settembre/ottobre 2016) e ha reso possibile, tra l'altro: @@ -495,16 +481,15 @@ La diramazione Spurious Dragon è stata la seconda risposta agli attacchi denial
  • EIP-161consente la rimozione dei conti vuoti aggiunti tramite attacchi DoS.
  • EIP-170modifica la dimensione massima del codice che un contratto sulla blockchain può avere, a 24576 byte.
  • - --- -### Tangerine Whistle {#tangerine-whistle} +### Tangerine Whistle {#2016} -#### Riepilogo {#tangerine-whistle-summary} +#### Riepilogo {#spurious-dragon} La diramazione Tangerine Whistle è stata la prima risposta agli attacchi di denial of service (DoS) alla rete (settembre/ottobre 2016) e ha incluso: @@ -518,16 +503,15 @@ La diramazione Tangerine Whistle è stata la prima risposta agli attacchi di den
  • EIP-150aumenta i costi del carburante degli opcode utilizzabili negli attacchi di spam.
  • EIP-158riduce le dimensioni di stato rimuovendo un gran numero di conti vuoti messi nello stato a costo bassissimo a causa di bug nelle versioni precedenti del protocollo di Ethereum.
  • - --- -### Diramazione OAD {#dao-fork} +### Diramazione OAD {#spurious-dragon-summary} -#### Riepilogo {#dao-fork-summary} +#### Riepilogo {#tangerine-whistle} La diramazione OAD è stata pensata come risposta all'[attacco OAD del 2016](https://www.coindesk.com/learn/understanding-the-dao-attack/), durante il quale un contratto [OAD](/glossary/#dao) non protetto è stato privato di oltre 3,6 milioni di ETH in un solo attacco. La diramazione ha spostato i fondi dal contratto difettoso a un [nuovo contratto](https://etherscan.io/address/0xbf4ed7b27f1d666546e30d74d50d173d20bca754) con una sola funzione: il prelievo. Chi aveva perso fondi ha potuto prelevare 1 ETH per ogni 100 token OAD nel proprio portafoglio. @@ -539,11 +523,11 @@ Alcuni miner rifiutarono di creare la diramazione perché l'incidente DAO non er --- -### Homestead {#homestead} +### Homestead {#tangerine-whistle-summary} -#### Riepilogo {#homestead-summary} +#### Riepilogo {#dao-fork} La diramazione Homestead guardava al futuro. Includeva diverse modifiche al protocollo e un cambiamento che ha dato a Ethereum la possibilità di eseguire ulteriori aggiornamenti della rete. @@ -556,18 +540,17 @@ La diramazione Homestead guardava al futuro. Includeva diverse modifiche al prot
  • EIP-7aggiunge il nuovo opcode: DELEGATECALL
  • EIP-8introduce i requisiti di compatibilità progressiva a devp2p
  • - -## 2015 {#2015} +## 2015 {#dao-fork-summary} -### Frontier thawing {#frontier-thawing} +### Frontier thawing {#homestead} -#### Riepilogo {#frontier-thawing-summary} +#### Riepilogo {#homestead-summary} La diramazione Frontier Thawing ha innalzato il limite di 5.000 [gas](/glossary/#gas) per [blocco](/glossary/#block) e ha impostato il prezzo predefinito del gas a 51 [gwei](/glossary/#gwei). Ciò ha reso possibili le transazioni, che richiedono 21.000 gas. La [bomba di difficoltà](/glossary/#difficulty-bomb) è stata introdotta per assicurare una hard-fork futura verso il [proof-of-stake](/glossary/#pos). @@ -576,11 +559,11 @@ La diramazione Frontier Thawing ha innalzato il limite di 5.000 [gas](/glossary/ --- -### Frontier {#frontier} +### Frontier {#2015} -#### Riepilogo {#frontier-summary} +#### Riepilogo {#frontier-thawing} Frontier è stata un'implementazione operativa ma rudimentale del progetto Ethereum. È seguita alla positiva fase di test Olympic. Era destinata agli utenti tecnici, in particolare gli sviluppatori. I [blocchi](/glossary/#block) avevano un limite di 5.000 [gas](/glossary/#gas). Questo periodo di "disgelo" (dall'inglese thawing) ha consentito ai miner di iniziare la propria operatività e ai primi utilizzatori di installare i client senza fretta. @@ -588,9 +571,9 @@ Frontier è stata un'implementazione operativa ma rudimentale del progetto Ether -## 2014 {#2014} +## 2014 {#frontier-thawing-summary} -### Vendita di Ether {#ether-sale} +### Vendita di Ether {#frontier} @@ -600,7 +583,7 @@ Ether fu ufficialmente messo in vendita per 42 giorni. Lo potresti acquistare in --- -### Pubblicazione dello yellowpaper {#yellowpaper} +### Pubblicazione dello yellowpaper {#frontier-summary} @@ -610,9 +593,9 @@ Lo Yellow Paper, redatto dal dott. Gavin Wood, è una definizione tecnica del pr -## 2013 {#2013} +## 2013 {#2014} -### Pubblicazione del whitepaper {#whitepaper} +### Pubblicazione del whitepaper {#ether-sale} diff --git a/public/content/translations/it/foundation/index.md b/public/content/translations/it/foundation/index.md index c742def2847..d1560ff071c 100644 --- a/public/content/translations/it/foundation/index.md +++ b/public/content/translations/it/foundation/index.md @@ -1,11 +1,11 @@ --- title: Ethereum Foundation -description: Scopri di più sulla Ethereum Foundation (EF), un'organizzazione no-profit dedita al supporto di Ethereum e delle tecnologie correlate. +description: "Scopri di più sulla Ethereum Foundation (EF), un'organizzazione no-profit dedita al supporto di Ethereum e delle tecnologie correlate." hideEditButton: true lang: it --- -# Informazioni sulla Ethereum Foundation {#about-the-ethereum-foundation} +# Informazioni sulla Ethereum Foundation {#ethereum-foundation} @@ -13,16 +13,14 @@ La [Ethereum Foundation](http://ethereum.foundation/) (EF) è un'organizzazione Non è un'azienda, né una no-profit tradizionale. Il suo ruolo non è quello di controllare o guidare Ethereum, e non è l'unica organizzazione che finanzia lo sviluppo critico delle tecnologie correlate a Ethereum. L'EF fa parte di un [ecosistema](/community/) molto più ampio. -## Iniziative dell'Ethereum Foundation {#ethereum-foundation-initiatives} - -### Programma di supporto dell'ecosistema {#ecosystem-support-program} +## Iniziative dell'Ethereum Foundation {#what-the-ef-does} +### Programma di supporto dell'ecosistema {#programs-and-initiatives} Il [programma di supporto dell'ecosistema](https://esp.ethereum.foundation/) esiste per dare sostegno sia finanziario che non a progetti ed entità all'interno di tutta la community Ethereum, con lo scopo di accelerare la crescita dell'ecosistema. È un'espansione dell'originario Ethereum Grants Program, che si concentrava soprattutto sul supporto finanziario. Scopri di più sul programma di supporto dell'ecosistema, sui destinatari delle sovvenzioni passati e sul processo di candidatura per le sovvenzioni su [esp.ethereum.foundation](https://esp.ethereum.foundation/). Puoi anche consultare l'[Ecosystem Support Program Blog](https://blog.ethereum.org/category/ecosystem-support-program/) o seguire [@EF_ESP](https://twitter.com/EF_ESP) per rimanere al passo con gli ultimi annunci e le notizie più recenti. -### Devcon {#devcon} - +### Devcon {#learn-more} Fin dal 2014, Ethereum Foundation ha organizzato Devcon, la conferenza annuale per tutti gli sviluppatori Ethereum, i ricercatori, i creatori e i pensatori. Puoi accedere ai contenuti video o alle conferenze di ogni anno, a partire da quello di creazione, su [archive.devcon.org](https://archive.devcon.org/). diff --git a/public/content/translations/it/governance/index.md b/public/content/translations/it/governance/index.md index 21a0a339cf5..fc1dff16672 100644 --- a/public/content/translations/it/governance/index.md +++ b/public/content/translations/it/governance/index.md @@ -22,7 +22,7 @@ Nessuna persona possiede o controlla il protocollo Ethereum, ma è comunque nece La governance di Ethereum è il processo attraverso il quale vengono apportate modifiche al protocollo. È importante sottolineare che questo processo non ha a che fare con il modo in cui le persone e le applicazioni utilizzano il protocollo, infatti Ethereum è senza autorizzazioni. Chiunque da qualsiasi parte del mondo può partecipare ad attività on-chain. Non ci sono regole fisse su chi può o non può creare un'applicazione o inviare una transazione. Tuttavia, esiste un processo per proporre modifiche al protocollo principale, su cui vengono eseguite queste applicazioni. Poiché molte persone dipendono dalla stabilità di Ethereum, esiste una soglia di coordinamento davvero elevata per i cambiamenti principali, inclusi i processi sociali e tecnici, per garantire che ogni modifica a Ethereum sia sicura e ampiamente supportata dalla community. -### Governance on-chain e off-chain {#on-chain-vs-off-chain} +### Governance on-chain e off-chain {#onchain-vs-offchain} La tecnologia blockchain rende possibili nuove modalità di governance, conosciute come governance on-chain. Per governance on-chain si intende che le proposte di modifica al protocollo sono decise tramite il voto degli stakeholder, che in genere detengono un governance token, e la votazione avviene sulla blockchain. In alcune forme di governance on-chain, le modifiche proposte al protocollo sono già scritte nel codice e vengono implementate automaticamente nel caso in cui vengano approvate dagli stakeholder tramite la sottoscrizione di una transazione. diff --git a/public/content/translations/it/guides/how-to-create-an-ethereum-account/index.md b/public/content/translations/it/guides/how-to-create-an-ethereum-account/index.md index b171b3ceb04..245478be491 100644 --- a/public/content/translations/it/guides/how-to-create-an-ethereum-account/index.md +++ b/public/content/translations/it/guides/how-to-create-an-ethereum-account/index.md @@ -47,7 +47,7 @@ Alcune applicazioni chiederanno di salvare una "frase di recupero" segreta (a vo Come utilizzare un portafoglio - + diff --git a/public/content/translations/it/guides/how-to-id-scam-tokens/index.md b/public/content/translations/it/guides/how-to-id-scam-tokens/index.md index 3af9b81af23..ad4b9dc7072 100644 --- a/public/content/translations/it/guides/how-to-id-scam-tokens/index.md +++ b/public/content/translations/it/guides/how-to-id-scam-tokens/index.md @@ -20,7 +20,6 @@ title="Cosa è ARB?" contentPreview=''> Arbitrum è un'organizzazione che sviluppa e gestisce [rollup ottimistici](/developers/docs/scaling/optimistic-rollups/). Inizialmente Arbitrum era organizzata come società a scopo di lucro, ma poi ha preso provvedimenti per decentralizzarsi. Nell'ambito di questo processo, hanno emesso un [token di governance](/dao/#token-based-membership) negoziabile. - In Ethereum esiste una convenzione per cui, quando una risorsa non è conforme a ERC-20, ne viene creata una versione "wrapped" con il nome che inizia con "w". Quindi, ad esempio, abbiamo wBTC per bitcoin e wETH per ether. Non ha senso creare una versione wrapped di un token ERC-20 già presente su Ethereum, ma i truffatori si basano sull'apparenza di legittimità piuttosto che sulla realtà sottostante. - ## Come funzionano i token truffa? {#how-do-scam-tokens-work} @@ -42,7 +40,6 @@ title="Cosa sono i contratti intelligenti?" contentPreview=''> [I contratti intelligenti](/developers/docs/smart-contracts/) sono i programmi che vengono eseguiti sulla blockchain di Ethereum. Ogni token ERC-20, ad esempio, è implementato come un contratto intelligente. - In particolare, Arbitrum ha distribuito un contratto che utilizza il simbolo `ARB`. Ma questo non impedisce ad altre persone di distribuire un contratto che utilizza lo stesso simbolo o uno simile. Chiunque scriva il contratto può stabilire ciò che il contratto farà. diff --git a/public/content/translations/it/nft/index.md b/public/content/translations/it/nft/index.md index 3279ce0720f..a9ad889f49d 100644 --- a/public/content/translations/it/nft/index.md +++ b/public/content/translations/it/nft/index.md @@ -5,11 +5,11 @@ description: Una panoramica dei NFT su Ethereum lang: it template: use-cases emoji: ":frame_with_picture:" -sidebarDepth: 3 +sidebarDepth: 2 image: /images/infrastructure_transparent.png alt: Un logo Eth visualizzato tramite ologramma. summaryPoint1: Un modo pe rappresentare qualsiasi cosa sia univoca, come una risorsa basata su Ethereum. -summaryPoint2: I NFT stanno dando ai creatori di contenuti più potere che mai. +summaryPoint2: "I NFT stanno dando ai creatori di contenuti più potere che mai." summaryPoint3: Basati sui contratti intelligenti, sulla blockchain di Ethereum. --- diff --git a/public/content/translations/it/roadmap/account-abstraction/index.md b/public/content/translations/it/roadmap/account-abstraction/index.md index 8695d3cd058..11786ab121e 100644 --- a/public/content/translations/it/roadmap/account-abstraction/index.md +++ b/public/content/translations/it/roadmap/account-abstraction/index.md @@ -1,6 +1,6 @@ --- title: Astrazione account -description: Una panoramica dei piani di Ethereum per rendere i conti degli utenti più semplici e sicuri +description: "Una panoramica dei piani di Ethereum per rendere i conti degli utenti più semplici e sicuri" lang: it summaryPoints: - L'astrazione del conto semplifica molto la creazione di portafogli di contratti intelligenti @@ -61,7 +61,6 @@ La gestione del gas, inoltre, è di molto migliorata con l'astrazione del conto. La gestione del gas è una delle frizioni principali per gli utenti di Ethereum, principalmente perché gli ETH sono la sola risorsa utilizzabile per pagare le transazioni. Immagina di avere un portafoglio con un saldo di USDC, ma nessun ETH. Non puoi spostare o scambiare quei token USDC, poiché non puoi pagare il gas. Non puoi nemmeno scambiare gli USDC per ETH, poiché anche questo costa del gas. Dovresti inviare altri ETH al tuo conto da una piattaforma di scambio o da un altro indirizzo per risolvere il problema. Con i portafogli di contratti intelligenti, invece, puoi semplicemente pagare il gas in USDC, liberando il tuo conto. Non devi più mantenere un saldo di ETH in tutti i tuoi conti. L'astrazione del conto, inoltre, consente agli sviluppatori di dapp di essere creativi con la gestione del gas. Ad esempio, potresti riuscire a iniziare a pagare una commissione fissa mensile alla tua DEX preferita, per delle transazioni illimitate. Le Dapp potrebbero offrire di pagare tutte le tue commissioni di gas per conto tuo, come ricompensa per aver utilizzato la loro piattaforma, o come offerta di inserimento. Per gli sviluppatori, sarebbe molto più facile innovare sul gas, quando i portafogli di contratti intelligenti sono supportati al livello del protocollo. - Le sessioni fidate, inoltre, sono potenzialmente trasformative per le esperienze degli utenti, specialmente per applicazioni come il gaming, in cui grandi numeri di piccole transazioni, potrebbero necessitare dell'approvazione in un breve tempo. Approvare individualmente ogni transazione spezzerebbe l'esperienza di gioco, ma l'approvazione permanente non è sicura. Il portafoglio di un contratto intelligente potrebbe approvare certe transazioni per un dato tempo, fino a un valore specifico o solo per certi indirizzi. @@ -77,7 +76,6 @@ I portafogli di contratti intelligenti, ad oggi, esistono, ma implementarli è i EIP-2771 introduce il concetto delle meta-transazioni, che consentono a terze parti di pagare i costi del gas degli utenti senza apportare modifiche al protocollo di Ethereum. L'idea è che le transazioni firmate da un utente sono inviate a un contratto `Corriere`. Il corriere è un'entità fidata che verifica che le transazioni siano valide, prima di inviarle a un ripetitore di gas. Ciò avviene all'esterno della catena, evitando il bisogno di pagare il gas. Il ripetitore di gas passa la transazione a un contratto `Destinatario`, pagando il gas necessario per rendere la transazione eseguibile su Ethereum. La transazione è eseguita se il `Corriere` è noto ed è ritenuto attendibile dal `Destinatario`. Questo modello semplifica, per gli sviluppatori, l'implementazione di transazioni a gas zero per gli utenti. - @@ -87,7 +85,6 @@ L'EIP-4337 è il primo passo verso il supporto dei portafogli di contratti intel Anche il funzionamento dei portafogli cambierà sotto EIP-4337. Invece di far reimplementare da ogni portafoglio una logica di sicurezza complessa ma comune, queste funzioni saranno affidate a un contratto del portafoglio globale, noto come "punto d'accesso". Questo, gestirebbe le operazioni come il pagamento delle commissioni e l'esecuzione del codice dell'EVM, così che gli sviluppatori di portafogli possano concentrarsi sul fornire eccellenti esperienze agli utenti. Nota: il contratto del punto d'accesso dell'EIP-4337, è stato distribuito alla Rete Principale di Ethereum l'1 marzo 2023. Puoi visualizzare il contratto su Etherscan. - @@ -95,7 +92,6 @@ Anche il funzionamento dei portafogli cambierà sotto EIP-4337. Invece di far re L'EIP-2938 mira ad aggiornare il protocollo di Ethereum introducendo un nuovo tipo di transazione, AA_TX_TYPE che include tre campi: nonce, target e data, dove nonce è un contatore di transazioni, target è l'indirizzo del contratto del punto d'accesso, e data è il bytecode dell'EVM. Per eseguire queste transazioni, devono essere aggiunte due nuove istruzioni (note come codici operativi) all'EVM: NONCE e PAYGAS. Il codice operativo NONCE traccia la sequenza della transazione e PAYGAS calcola e preleva il gas necessario per eseguire la transazione dal saldo del contratto. Queste nuove funzionalità consentono a Ethereum di supportare nativamente i portafogli di contratti intelligenti, poiché l'infrastruttura necessaria è integrata nel protocollo di Ethereum. Nota che l'EIP-2938 non è correntemente attiva. La community, al momento, preferisce EIP-4337 poiché non richiede modifiche al protocollo. - @@ -103,7 +99,6 @@ Nota che l'EIP-2938 non è correntemente attiva. La community, al momento, prefe L'EIP-3074 mira ad aggiornare i conti posseduti esternamente di Ethereum, consentendo loro di delegare il controllo a un contratto intelligente. Ciò significa che la logica dei contratti intelligenti potrebbe approvare le transazioni originate da un EOA. Questo consentirebbe funzionalità come la sponsorizzazione del gas e le transazioni raggruppate. Perché funzioni, devono essere aggiunti due nuovi codici operativi all'EVM: AUTH e AUTHCALL. Con l'EIP-3074, i benefici del portafoglio di un contratto intelligente sono resi disponibili senza la necessità di un contratto, invece un tipo specifico di contratto privo di stato, privo di fiducia e non ggiornabile, noto come "invocatore", gestisce le transazioni. Nota che EIP-3074 non è correntemente attivo. La community, al momento, preferisce EIP-4337 poiché non richiede modifiche al protocollo. - ## Stato attuale {#current-progress} diff --git a/public/content/translations/it/roadmap/beacon-chain/index.md b/public/content/translations/it/roadmap/beacon-chain/index.md index fdfafae0a45..d4529c6a841 100644 --- a/public/content/translations/it/roadmap/beacon-chain/index.md +++ b/public/content/translations/it/roadmap/beacon-chain/index.md @@ -6,7 +6,7 @@ template: upgrade image: /images/upgrades/core.png alt: summaryPoint1: La Beacon Chain ha introdotto il proof-of-stake all'ecosistema di Ethereum. -summaryPoint2: Si è unita alla catena di proof-of-work originale di Ethereum a settembre 2022. +summaryPoint2: "Si è unita alla catena di proof-of-work originale di Ethereum a settembre 2022." summaryPoint3: La Beacon Chain ha introdotto la logica del consenso e il protocollo di gossip dei blocchi, che ora protegge Ethereum. --- @@ -32,7 +32,7 @@ Lo staking ha un ruolo simile a quello che aveva il [mining](/developers/docs/co La transizione al proof of stake ha reso Ethereum significativamente più sicura e decentralizzata rispetto al proof of work. Più persone parteciperanno alla rete, più questa diventerà decentralizzata e protetta dagli attacchi. -E l'utilizzo del proof of stake come meccanismo di consenso è un componente fondamentale per [l'Ethereum sicuro, ecosostenibile e scalabile che conosciamo ora](/roadmap/vision/). +E l'utilizzo del proof of stake come meccanismo di consenso è un componente fondamentale per [l'Ethereum sicuro, ecosostenibile e scalabile che conosciamo ora](/staking/). diff --git a/public/content/translations/it/roadmap/danksharding/index.md b/public/content/translations/it/roadmap/danksharding/index.md index 59099359eac..6a853f4f77e 100644 --- a/public/content/translations/it/roadmap/danksharding/index.md +++ b/public/content/translations/it/roadmap/danksharding/index.md @@ -22,13 +22,11 @@ Ciò è costoso perché elaborato da tutti i nodi di Ethereum e risiede per semp I rollup sono un metodo per scalare Ethereum raggruppando le transazioni all'esterno della catena e, in seguito, pubblicando i risultati su Ethereum. Un rollup, essenzialmente, si compone di due parti: dati e controllo dell'esecuzione. I dati sono la sequenza completa delle transazioni elaborate da un rollup per produrre il cambiamento di stato pubblicato su Ethereum. Il controllo d'esecuzione è la ri-esecuzione di tali transazioni da un utente onesto (dimostratore) per aassicurarsi che il cambiamento di stato proposto sia corretto. Per effettuare il controllo d'esecuzione, i dati della transazione devono essere disponibili per un tempo sufficiente perché chiunque possa scaricarli e controllarli. Ciò significa che qualsiasi comportamento disonesto dal sequenziatore del rollup puà essere identificato e sfidato dal dimostratore. Tuttavia, non è necessario che sia disponibile per sempre. - I rollup pubblicano gli impegni ai dati delle proprie transazioni on chain e, inoltre, rendono disponibili i dati effettivi nei blob di dati. Ciò significa che i dimostratori possono verificare che gli impegni siano validi o sfidare i dati che ritengono siano errati. Al livello del nodo, i blob di dati sono conservati nel client del consenso. I client del consenso attestano di aver visto i dati e che sono stati propagati per la rete. Se i dati fossero conservati per sempre, tali client si allargherebberò, determinando grandi requisiti hardware per l'esecuzione di nodi. Invece, i dati sono eliminati automaticamente dal nodo ogni 18 giorni. Le attestazioni del client del consenso dimostrano che vi è stata un'opportunità sufficiente, affinché i dimostratori potessero verificare i dati. I dati effettivi possono essere memorizzati off-chain dagli operatori di rollup, dagli utenti o da terzi. - ### Come sono verificati i dati dei blob? {#how-are-blobs-verified} @@ -48,13 +46,11 @@ La cerimonia KZG dell'EIP-4844 era aperta al pubblico e decine di migliaia di pe Quando un rollup pubblica dati in un blob, fornisce un "impegno" che viene pubblicato sulla catena. Questo, è il risultato della valutazione di un adattamento polinomiale ai dati, in certi punti. Questi punti sono definiti dai numeri casuali generati nella cerimonia KZG. I dimostratori, quindi, possono valutare la polinomiale agli stessi punti, per poter verificare i dati; se arrivano agli stessi valori, allora i dati sono corretti. - Se qualcuno conoscesse le posizioni casuali utilizzate per l'impegno, sarebbe facile, per loro, generare una nuova polinomiaale che si adatti a quei punti specifici (cioè, una "collisione"). Ciò significa che potrebbero aggiungere o rimuovere i dati dal blob e, comunque, fornire una prova valida. Per impedirlo, invece di dare ai dimostratori le posizioni segrete effettive, ricevono in realtà le posizioni, avvolte in una "scatola nera" crittografica, utilizzando le curve ellittiche. Questi, infatti, rimescolano i valori in modo tale che i valori originali non siano decodificabili, ma con dimostratori e verificatori capaci in algebra, le polinomiali sono ancora valutabili ai punti rappresentati. - @@ -70,13 +66,11 @@ Funziona espandendo i blob collegati ai blocchi da sei (6) nel proto-dankshardin La separazione di propositori e costruttori è necessaria per impedire ai singoli validatori di dover generare costosi impegni e prove, per 32 MB di dati del blob. Questo metterebbe a dura prova gli staker domestici e richiederebbe loro di investire in hardware più potenti, danneggiando la decentralizzazione. Invece, i costruttori di blocchi specializzati si prendono la responsabilità di questo costoso lavoro di calcolo. Poi, mettono a disposizione i propri blocchi ai propositori di blocchi per la trasmissione. Il propositore di blocchi, semplicemente, sceglie il blocco più redditizio. Chiunque può verificare i blob in modo economico e rapido, a significare che ogni normale validatore può verificare che i costruttori di blocchi si stiano comportando onestamente. Questo permette di elaborare i blob di grandi dimensioni senza sacrificare la decentralizzazione. I costruttori di blocchi malevoli potrebbero semplicemente essere esplusi dalla rete e tagliati; altri arriverebbero al loro posto, poiché la costruzione di blocchi è un'attività redditizia. - Il campionamento della disponibilità dei dati è necessario perché i validatori verifichino in modo rapido ed efficace i dati dei blob. Utilizzando il campionmento della disponibilità dei dati, i validatori possono essere davvero certi che i blob di dati fossero disponibili e che siano stati inviati correttamente. Ogni validatore può campionare casualmente alcuni punti di dati e creare una prova, a significare che nessun validatore deve verificare l'intero blob. Se mancano dei dati, saranno identificati rapidamente e il blob sarà respinto. - ### Stato attuale {#current-progress} diff --git a/public/content/translations/it/roadmap/future-proofing/index.md b/public/content/translations/it/roadmap/future-proofing/index.md index 9166a97866d..6047829e3d4 100644 --- a/public/content/translations/it/roadmap/future-proofing/index.md +++ b/public/content/translations/it/roadmap/future-proofing/index.md @@ -1,6 +1,6 @@ --- title: Rendere Ethereum a prova di futuro -description: Questi aggiornamenti cementano Ethereum come lo strato fondamentale, resiliente e decentralizzato per il futuro, indipendentemente da ciò che conterrà. +description: "Questi aggiornamenti cementano Ethereum come lo strato fondamentale, resiliente e decentralizzato per il futuro, indipendentemente da ciò che conterrà." lang: it image: /images/roadmap/roadmap-future.png alt: "Roadmap di Ethereum" diff --git a/public/content/translations/it/roadmap/merge/index.md b/public/content/translations/it/roadmap/merge/index.md index 06cded798a0..eed70dddc1f 100644 --- a/public/content/translations/it/roadmap/merge/index.md +++ b/public/content/translations/it/roadmap/merge/index.md @@ -5,8 +5,8 @@ lang: it template: upgrade image: /images/upgrades/merge.png alt: -summaryPoint1: La Rete Principale di Ethereum utilizza il proof-of-stake, ma non è sempre stato così. -summaryPoint2: L'aggiornamento dal meccanismo originale di proof-of-work al proof-of-stake, è stato detto La Fusione. +summaryPoint1: "La Rete Principale di Ethereum utilizza il proof-of-stake, ma non è sempre stato così." +summaryPoint2: "L'aggiornamento dal meccanismo originale di proof-of-work al proof-of-stake, è stato detto La Fusione." summaryPoint3: La Fusione si riferisce all'unione della Rete Principale di Ethereum con una blockchain di proof-of-stake separata, detta Beacon Chain, ora coesistenti come un'unica catena. summaryPoint4: La Fusione ha ridotto il consumo energetico di Ethereum di circa il 99,95%. --- @@ -88,7 +88,6 @@ Gli elementi d'azione chiave includono: - Autenticare i client di esecuzione e di consenso con un segreto JWT condiviso, così che possano comunicare in sicurezza tra loro. Non completare i suddetti elementi farà sì che il tuo nodo risulti "offline", finché entrambi i livelli non saranno sincronizzati e autenticati. - Per ulteriori informazioni, consulta questo post del blog di Tim Beiko su Come La Fusione Influenza il Livello d'Applicazione di Ethereum. - ## La Fusione e il consumo energetico {#merge-and-energy} @@ -116,7 +114,7 @@ La Fusione ha segnato la fine del proof-of-work per Ethereum e ha dato inizio al ## La Fusione e il ridimensionamento {#merge-and-scaling} -La Fusione ha inoltre gettato le basi per ulteriori aggiornamenti di scalabilità, impossibili sotto il Poof of Work, portando Ethereum un po' più vicina al raggiungimento della completa scalabilità, sicurezza e sostenibilità delinate nella [visione di Ethereum](/roadmap/vision/). +La Fusione ha inoltre gettato le basi per ulteriori aggiornamenti di scalabilità, impossibili sotto il Poof of Work, portando Ethereum un po' più vicina al raggiungimento della completa scalabilità, sicurezza e sostenibilità delinate nella [visione di Ethereum](/energy-consumption/). ## Equivoci su La Fusione {#misconceptions} @@ -135,7 +133,6 @@ Eseguire un nodo che non produce blocchi è possibile per chiunque, in entrambi L'abilità per chiunque di gestire il proprio nodo è assolutamente essenziale per mantenere la decentralizzazione della rete di Ethereum. [Ulteriori informazioni sull'esecuzione di un proprio nodo](/run-a-node/) - tabella di marcia incentrata sui rollup, gli sforzi si concentrano sul ridimensionamento delle attività degli utenti al [livello 2](/layer-2/), consentendo alla Rete Principale di Livello 1 di essere un livello di accordo decentralizzato e sicuro, ottimizzato per l'archiviazione dei dati dei rollup, per aiutare a rendere esponenzialmente più economiche le transazioni dei rollup. La transizione al Proof of stake è un precursore essenziale per realizzarlo. [Ulteriori informazioni su gas e commissioni.](/developers/docs/gas/) - indirizzo di prelievo per iniziare a ricevere pagamenti automatici di qualsiasi saldo di staking in eccesso (ETH superiori a 32, da ricompense del protocollo). Questo aggiornamento, inoltre, ha consentito la capacità di un validatore di sbloccare e rivendicare l'intero saldo all'uscita dalla rete. [Maggiori informazioni sui prelievi in staking](/staking/withdrawals/) - - L'emissione di staking esatta fluttua a seconda dell'importo totale di ETH in staking - **Da La Fusione, restano approssimativamnte soltanto 1.700 ETH/giorno, riducendo la nuova emissione totale di ETH di circa l'88%** - La bruciatura: questa, fluttua secondo la domanda di rete. _Se_ per un dato giorno si osserva un prezzo di gas medio di almeno 16 gwei, questo compensa effettivamente i circa 1.700 ETH emessi ai validatori e porta l'inflazione netta di ETH a zero, o meno, per quel giorno. - ## Pre-Fusione (storico) {#pre-merge} @@ -63,7 +62,9 @@ Offerta totale di ETH: **circa 120.520.000 ETH** (al momento della Fusione a set **Circa l'11,3%** era emesso agli staker sul livello del consenso (0,52 / 4,61 * 100) + + ## Post-Fusione (oggi) {#post-merge} @@ -97,7 +98,9 @@ Tasso di emissione annualizzato totale: **circa 0,52%** Riduzione netta nell'emissione annuale di ETH: **circa 88,7%** ((4,61%-0,52%) / 4,61% * 100) + + ## La bruciatura {#the-burn} @@ -109,7 +112,9 @@ La forza opposta all'emissione di ETH è il tasso a cui gli ETH sono bruciati. P La bruciatura delle commissioni è divenuta attiva con l'[aggiornamento di Londra](/ethereum-forks/#london) ad agosto 2021 e resta immutata da La Fusione. + + Oltre alla bruciatura della commissione, implementata dall'aggiornamento di Londra, i validatori, inoltre, possono incorrere in sanzioni per essere online o, peggio, possono ricevere tagli per l'infrazione di regole specifiche che minacciano la sicurezza della rete. Queste, risultano in una riduzione degli ETH dal saldo di quel validatore, che non è ricompensato direttamente a nessun altro conto, bruciandoli/rimuovendoli effettivamente dalla circolazione. diff --git a/public/content/translations/it/roadmap/pbs/index.md b/public/content/translations/it/roadmap/pbs/index.md index 4b0b292c707..be168336e77 100644 --- a/public/content/translations/it/roadmap/pbs/index.md +++ b/public/content/translations/it/roadmap/pbs/index.md @@ -1,6 +1,6 @@ --- title: Separazione proponente-sviluppatore -description: Scopri come e perché i validatori di Ethereum divideranno le proprie responsabilità di costruzione e trasmissione dei blocchi. +description: "Scopri come e perché i validatori di Ethereum divideranno le proprie responsabilità di costruzione e trasmissione dei blocchi." lang: it --- @@ -21,7 +21,6 @@ I [mempool crittografati](https://www.youtube.com/watch?v=fHDjgFcha0M&list=PLpkt Potenti organizzazioni possono spingere i validatori a censurare le transazioni da o verso certi indirizzi. I validatori si conformano a tale pressione rilevando gli indirizzi nella lista nera del proprio gruppo di transazioni e omettendoli dai blocchi che propongono. Dopo la PBS, non sarà più possibile poiché i propositori di blocchi non sapranno quali transazioni stanno trasmettendo nei propri blocchi. Potrebbe essere importante, per certi individui o app, conformarsi alle regole di censura, ad esempio, quando è emanata una legge nella loro regione. In tali casi, la conformità si verifica a livello di applicazione, mentre il protocolo rimane privo di permessi e di censura. - ## PBS e MEV {#pbs-and-mev} diff --git a/public/content/translations/it/roadmap/scaling/index.md b/public/content/translations/it/roadmap/scaling/index.md index 54d6c3f2ac9..2d511aa85e6 100644 --- a/public/content/translations/it/roadmap/scaling/index.md +++ b/public/content/translations/it/roadmap/scaling/index.md @@ -1,6 +1,6 @@ --- title: Ridimensionare Ethereum -description: I rollup raggruppano le transazioni al di fuori della catena, riducendo i costi per l'utente. Tuttavia, il modo in cui i rollup utilizzano i dati al momento è troppo costoso, il che limita l'economicità delle transazioni. Il Proto-Danksharding lo corregge. +description: "I rollup raggruppano le transazioni al di fuori della catena, riducendo i costi per l'utente. Tuttavia, il modo in cui i rollup utilizzano i dati al momento è troppo costoso, il che limita l'economicità delle transazioni. Il Proto-Danksharding lo corregge." lang: it image: /images/roadmap/roadmap-transactions.png alt: "Roadmap di Ethereum" diff --git a/public/content/translations/it/roadmap/security/index.md b/public/content/translations/it/roadmap/security/index.md index 11dfbd8b335..8526aae04e7 100644 --- a/public/content/translations/it/roadmap/security/index.md +++ b/public/content/translations/it/roadmap/security/index.md @@ -1,6 +1,6 @@ --- -title: Un Ethereum più sicuro -description: Ethereum è la piattaforma di contratti intelligenti più sicura e decentralizzata che esista. Tuttavia, restano ancora da implementare alcuni miglioramenti in modo che Ethereum resti resiliente a qualsiasi livello di attacco anche in un futuro lontano. +title: "Un Ethereum più sicuro" +description: "Ethereum è la piattaforma di contratti intelligenti più sicura e decentralizzata che esista. Tuttavia, restano ancora da implementare alcuni miglioramenti in modo che Ethereum resti resiliente a qualsiasi livello di attacco anche in un futuro lontano." lang: it image: /images/roadmap/roadmap-security.png alt: "Roadmap di Ethereum" diff --git a/public/content/translations/it/roadmap/single-slot-finality/index.md b/public/content/translations/it/roadmap/single-slot-finality/index.md index d8e0bc0c4a6..02ba9bcc682 100644 --- a/public/content/translations/it/roadmap/single-slot-finality/index.md +++ b/public/content/translations/it/roadmap/single-slot-finality/index.md @@ -1,6 +1,6 @@ --- -title: Finalità dello spazio singolo -description: Spiegazione della finalità dello spazio singolo +title: "Finalità dello spazio singolo" +description: "Spiegazione della finalità dello spazio singolo" lang: it --- diff --git a/public/content/translations/it/roadmap/user-experience/index.md b/public/content/translations/it/roadmap/user-experience/index.md index 2748d708027..3713de6141f 100644 --- a/public/content/translations/it/roadmap/user-experience/index.md +++ b/public/content/translations/it/roadmap/user-experience/index.md @@ -1,6 +1,6 @@ --- title: Migliorare l'esperienza degli utenti -description: Per molti, è ancora troppo complesso utilizzare Ethereum. Per incoraggiare l'adozione di massa, Ethereum deve ridurre drasticamente le proprie barriere d'accesso; gli utenti devono ricevere i benefici dell'accesso decentralizzato, privo di permessi e resistente alla censura a Ethereum, ma dev'essere privo di frizione, tanto quanto utilizzare una tradizionale app del web2. +description: "Per molti, è ancora troppo complesso utilizzare Ethereum. Per incoraggiare l'adozione di massa, Ethereum deve ridurre drasticamente le proprie barriere d'accesso; gli utenti devono ricevere i benefici dell'accesso decentralizzato, privo di permessi e resistente alla censura a Ethereum, ma dev'essere privo di frizione, tanto quanto utilizzare una tradizionale app del web2." lang: it image: /images/roadmap/roadmap-ux.png alt: "Roadmap di Ethereum" diff --git a/public/content/translations/it/roadmap/verkle-trees/index.md b/public/content/translations/it/roadmap/verkle-trees/index.md index 59cae3a2e7c..02bb4b09d23 100644 --- a/public/content/translations/it/roadmap/verkle-trees/index.md +++ b/public/content/translations/it/roadmap/verkle-trees/index.md @@ -18,7 +18,6 @@ Gli alberi di Verkle sono un passaggio fondamentale sul percorso per i client di I client di Ethereum, al momento, utilizzano una struttura di dati nota come Albero di Patricia di Merkle per memorizzarne i dati di stato. Le informazioni sui singoli conti sono memorizzati come foglie su un albero e, le coppie di foglie, ricevono ripetutamente un hash finché non ne resta soltanto uno. Questo hash finale è noto come la "radice". Per verficare i blocchi, i client di Ethereum eseguono tutte le transazioni in un blocco e aggiornano il proprio albero di stato locale. Il blocco è considerato valido se la radice dell'albero locale è identica a quella fornita dal propositore di blocchi, poiché qualsiasi differenza nel calcolo effettuato dal propositore del blocco e dal nodo di convalida, formerebbe un hash di radice completamente differente. Il problema è che la verifica della blockchain richiede che ogni client memorizzi l'intero albero di stato per il blocco di testa e per diversi blocchi storici (di default, su Geth, sono mantenuti i dati di stato per 128 blocchi oltre la testa). Ciò richiede che i client abbiano accesso a una grande quantità di spazio su disco, limitando l'esecuzione dei nodi completi su hardware economici e poco potenti. Una soluzione è aggiornare l'albero di stato a una struttura più efficiente (l'albero di Verkle), riepilogabile utilizzando un piccolo "testimone" ai dati, condivisibile invece dei dati di stato completi. Riformattare i dati di stato in un albero di Verkle è una pietra miliare per spostarsi verso i client privi di stato. - ## Cos'è un testimone e perché è necessario? {#what-is-a-witness} @@ -34,7 +33,6 @@ Sotto lo schema di impegno polinomiale, i testimoni hanno dimensioni gestibili, Le dimensioni dei testimoni variano a seconda del numero di foglie che include. Supponendo che il testimone copra 1000 foglie, un testimone per un albero di Merkle occuperebbe all'incirca 3,5 MB (ipotizzando 7 livelli all'albero). Un testimone per gli stessi dati in un albero di Verkle (ipotizzando 4 livelli all'albero) occuperebbe circa 150 kB; **circa 23 volte più piccolo**. Questa riduzione delle dimensioni del testimone consentirà ai testimoni del client di essere accettabilmente piccoli. I testimoni polinomiali variano da 0,128 a 1 kB a seconda dello specifico impegno polinomiale utilizzato. - ## Qual è la struttura di un albero di Verkle? {#what-is-the-structure-of-a-verkle-tree} diff --git a/public/content/translations/it/social-networks/index.md b/public/content/translations/it/social-networks/index.md index 47d7099ccb2..2c62d2f1d3f 100644 --- a/public/content/translations/it/social-networks/index.md +++ b/public/content/translations/it/social-networks/index.md @@ -65,18 +65,18 @@ I post pubblicati su Mirror sono memorizzati permanentemente su Arweave, una pia Gli utenti utilizzano il token [ERC-20](/glossary/#erc-20) nativo della piattaforma $MIND per pagare gli articoli. Inoltre, gli utenti, possono anche guadagnare token $MIND, pubblicando contenuti popolari, contribuendo all'ecosistema e riferendo altri alla piattaforma. -## Utilizzare i social decentralizzati {#use-decentralized-social-networks} +## Utilizzare i social decentralizzati {#farcaster} - **[Status.im](https://status.im/)**: _Status è un'app di messaggistica sicura che utilizza un protocollo open source e tra pari, nonché la crittografia end-to-end per proteggere i tuoi messaggi dalle terze parti._ - **[Mirror.xyz](https://mirror.xyz/)**: _Mirror è una piattaforma di pubblicazione decentralizzata e posseduta dagli utenti basata su Ethereum, per il crowdfunding delle idee, la monetizzazione dei contenuti e la creazione di community dal valore elevato._ - **[Lens Protocol](https://lens.xyz/)**: _Lens Protocol è un grafico sociale componibile e decentralizzato che aiuta i creatori a prendere possesso dei propri contenuti, ovunque vadano nel proprio giardino digitale dell'Intenet decentralizzato._ - **[Farcaster](https://farcaster.xyz/)**: _Farcaster è un social sufficientemente decentralizzato. È un protocollo aperto che supporta molti client, proprio come l'email._ -## Social network Web2 su Ethereum {#web2-social-networks-and-ethereum} +## Social network Web2 su Ethereum {#use-decentralized-social-networks} Le piattaforme social native del [Web3](/glossary/#web3) non sono le sole che stanno tentando di incorporare la tecnologia della blockchain nei social. Anche molte piattaforme centralizzate stanno pianificando di integrare Ethereum nella propria infrastruttura: -### Reddit {#reddit} +### Reddit {#web2-social-networks-and-ethereum} Reddit ha [pubblicizzato i Punti della Community](https://cointelegraph.com/news/reddit-to-reportedly-tokenize-karma-points-and-onboard-500m-new-users): token ERC-20 che gli utenti possono guadagnare pubblicando contenuti di qualità e contribuendo alle community online (subreddit). Puoi riscattare tali token in una subreddit per ottenere privilegi e vantaggi esclusivi. Per questo progetto, Reddit sta lavorando con Arbitrum, una rete di [livello 2](/glossary/#layer-2) progettata per ridimensionare le transazioni di Ethereum. @@ -84,9 +84,9 @@ Il programma è già attivo: la subreddit r/CryptoCurrency [adopera la propria v Oltre a utilizzare i Punti della Community per sbloccare funzionalità speciali, gli utenti possono anche scambiarli per valuta legale nelle piattaforme di scambio. Inoltre, l'importo di Punti della Community posseduto da un utente ne determina l'influenza sul processo decisionale all'interno della community. -## Lettura consigliate {#further-reading} +## Lettura consigliate {#brave} -### Articoli {#articles} +### Articoli {#audius} - [Decentralizzare i social: una guida allo stack dei social di Web3](https://www.coinbase.com/blog/decentralizing-social-media-a-guide-to-the-web3-social-stack) - _Coinbase Ventures_ - [I social sono la prossima grande opportunità per la decentralizzazione](https://www.coindesk.com/tech/2021/01/22/social-networks-are-the-next-big-decentralization-opportunity/) - _Ben Goertzel_ @@ -95,12 +95,12 @@ Oltre a utilizzare i Punti della Community per sbloccare funzionalità speciali, - [In che modo la blockchain può risolvere la privacy dei social](https://www.investopedia.com/news/ethereum-blockchain-social-media-privacy-problem-linkedin-indorse/) - _Prableen Bajpai_ - [Decentralizzazione sufficiente per i social](https://www.varunsrinivasan.com/2022/01/11/sufficient-decentralization-for-social-networks) - _Varun Srinivasan_ -### Video {#videos} +### Video {#sorare} - [Social decentralizzati spiegati](https://www.youtube.com/watch?v=UdT2lpcGvcQ) - _Coinmarketcap_ - [La blockchain DeSo vuole decentralizzare i social](https://www.youtube.com/watch?v=SG2HUiVp0rE) - _Bloomberg Technology_ - [Il futuro dei social decentralizzati, con Balaji Srinivasan, Vitalik Buterin e Juan Benet](https://www.youtube.com/watch?v=DTxE9KV3YrE) - _ETHGlobal_ -### Community {#communities} +### Community {#twitter} - [Subreddit r/CryptoCurrency](https://www.reddit.com/r/CryptoCurrency/) diff --git a/public/content/translations/it/staking/dvt/index.md b/public/content/translations/it/staking/dvt/index.md index d2f9a11efe2..b719b9c0de7 100644 --- a/public/content/translations/it/staking/dvt/index.md +++ b/public/content/translations/it/staking/dvt/index.md @@ -1,6 +1,6 @@ --- title: Tecnologia del validatore distribuito -description: La tecnologia del validatore distribuito consente l'operazione distribuita di un validatore di Ethereum da più parti. +description: "La tecnologia del validatore distribuito consente l'operazione distribuita di un validatore di Ethereum da più parti." lang: it --- diff --git a/public/content/translations/it/staking/solo/index.md b/public/content/translations/it/staking/solo/index.md index d1460e62efc..629e55fc205 100644 --- a/public/content/translations/it/staking/solo/index.md +++ b/public/content/translations/it/staking/solo/index.md @@ -71,6 +71,7 @@ Differente dalle sanzioni di inattività per esser offline, il taglio Ulteriori informazioni sullo slashing e sul ciclo di vita dei validatori + @@ -130,7 +131,6 @@ Esistono alcune domande molto comuni sullo staking che meritano di essere affron Un validatore è un'entità virtuale che risiede su Ethereum e partecipa al consenso del protocollo di Ethereum. I validatori sono rappresentati da un saldo, una chiave pubblica e altre proprietà. Un client del validatore è il software che agisce per conto del validatore detenendone e usandone la chiave privata. Un singolo client del validatore può detenere molte coppie di chiavi, controllando molti validatori. - diff --git a/public/content/translations/it/staking/withdrawals/index.md b/public/content/translations/it/staking/withdrawals/index.md index da48375cdc0..e0317c01898 100644 --- a/public/content/translations/it/staking/withdrawals/index.md +++ b/public/content/translations/it/staking/withdrawals/index.md @@ -166,7 +166,6 @@ eventName="read more"> Se fai parte di un [pool di staking](/staking/pools/) o detieni token di staking, dovresti chiedere al tuo fornitore ulteriori dettagli su come vengono gestiti i prelievi dallo staking, poiché ogni servizio opera in modo diverso. In generale, gli utenti dovrebbero essere liberi di rivendicare i propri ETH in staking sottostanti, o di modificare il fornitore di staking che utilizzano. Se un pool in particolare sta diventando troppo grande, è possibile uscire, riscattare i fondi e rimetterli in staking con un fornitore di dimensioni minori. O, se hai accumulato abbastanza ETH, potresti [fare staking da casa](/staking/solo/). - No, se il tuo validatore è ancora attivo sulla rete, un prelievo completo non si verificherà automaticamente. Questo richiede l'avvio manuale di un'uscita volontaria. Una volta che un validatore ha completato il procedimento di uscita e supponendo che il conto abbia le credenziali di prelievo, il saldo rimanente sarà then prelevato durante la successivapulizia del validatore. - Gli operatori del validatore dovrebbero visitare la pagina dei Prelievi del Launchpad di Staking, dove troveranno ulteriori dettagli su come preparare il proprio validatore ai prelievi, le tempistiche degli eventi e ulteriori dettagli sul funzionamento dei prelievi. Per testare la tua configurazione su una rete di prova, visita il Launchpad di Staking della rete di prova di Holesky per iniziare. -