Vai al contenuto principale

Interagire con altri contratti da Solidity

smart contract
Solidity
Remix
distribuzione
componibilità
Avanzato
jdourlens
5 aprile 2020
4 minuti di lettura

Nei tutorial precedenti abbiamo imparato molto su come distribuire il tuo primo smart contract e aggiungervi alcune funzionalità come controllare l'accesso con i modificatori (opens in a new tab) o gestire gli errori in Solidity (opens in a new tab). In questo tutorial impareremo come distribuire uno smart contract da un contratto esistente e interagirvi.

Creeremo un contratto che consenta a chiunque di avere il proprio smart contract Counter creandone una factory, il cui nome sarà CounterFactory. Innanzitutto, ecco il codice del nostro smart contract Counter iniziale:

Nota che abbiamo modificato leggermente il codice del contratto per tenere traccia dell'indirizzo della factory e dell'indirizzo del proprietario del contratto. Quando chiami il codice di un contratto da un altro contratto, msg.sender si riferirà all'indirizzo della nostra factory di contratti. Questo è un punto davvero importante da comprendere, poiché usare un contratto per interagire con altri contratti è una pratica comune. Dovresti quindi prestare attenzione a chi sia il mittente nei casi complessi.

Per questo abbiamo anche aggiunto un modificatore onlyFactory che si assicura che la funzione che modifica lo stato possa essere chiamata solo dalla factory, la quale passerà il chiamante originale come parametro.

All'interno del nostro nuovo CounterFactory che gestirà tutti gli altri Counter, aggiungeremo una mappatura che assocerà un proprietario all'indirizzo del suo contratto counter:

mapping(address => Counter) _counters;

In Ethereum, le mappature (mapping) sono l'equivalente degli oggetti in JavaScript; consentono 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.

L'istanziazione di un nuovo Counter per qualcuno avrà questo aspetto:

  function createCounter() public {
      require (_counters[msg.sender] == Counter(0));
      _counters[msg.sender] = new Counter(msg.sender);
  }

Per prima cosa controlliamo se la persona possiede già un counter. Se non possiede un counter, istanziamo un nuovo counter passando il suo indirizzo al costruttore di Counter e assegniamo l'istanza appena creata alla mappatura.

Per ottenere il conteggio di un Counter specifico, l'aspetto sarà questo:

function getCount(address account) public view returns (uint256) {
    require (_counters[account] != Counter(0));
    return (_counters[account].getCount());
}

function getMyCount() public view returns (uint256) {
    return (getCount(msg.sender));
}

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 originale della transazione al contratto Counter:

function increment() public {
      require (_counters[msg.sender] != Counter(0));
      Counter(_counters[msg.sender]).increment(msg.sender);
  }

Nota che se chiamato troppe volte, il nostro counter potrebbe essere vittima di un overflow. Dovresti usare la libreria SafeMath (opens in a new tab) il più possibile per proteggerti da questo possibile caso.

Per distribuire il nostro contratto, dovrai fornire sia il codice di CounterFactory che di Counter. Quando distribuisci, ad esempio in Remix, dovrai selezionare CounterFactory.

Ecco il codice completo:

Dopo la compilazione, nella sezione di distribuzione di Remix selezionerai la factory da distribuire:

Selecting the factory to be deployed in Remix

Quindi puoi giocare con la tua factory di contratti e controllare il cambiamento del valore. Se desideri chiamare lo smart contract da un indirizzo diverso, dovrai cambiare l'indirizzo nella selezione Account di Remix.

Ultimo aggiornamento della pagina: 3 marzo 2026