Esegui transazioni pubbliche e private sulla blockchain JPMorgan Quorum utilizzando Web3

Esegui transazioni pubbliche e private sulla blockchain JPMorgan Quorum utilizzando Web3

Quorum è una blockchain basata su Ethereum sviluppata da JPMorgan e recentemente diventata la prima piattaforma di registro distribuito offerta da Microsoft Azure.

Quorum supporta transazioni private e pubbliche e ha molti casi d'uso commerciali.

In questo articolo esamineremo uno di questi scenari: l'implementazione di una rete di registri distribuiti tra un supermercato e il proprietario di un magazzino per fornire informazioni aggiornate sulla temperatura del magazzino.

Il codice utilizzato in questo tutorial è in repository su GitHub.

L'articolo tratta:

  • creazione di un contratto intelligente;
  • distribuzione della rete Quorum utilizzando Catenella;
  • Transazioni pubbliche del quorum;
  • Transazioni private del quorum.

Per illustrare, utilizziamo uno scenario per il monitoraggio della temperatura nei magazzini dei membri della rete Quorum all'interno dell'Internet delle cose (IoT).

Contesto

Un gruppo di società di magazzini si sta unendo in un consorzio per archiviare congiuntamente informazioni e automatizzare i processi sulla blockchain. Per questo, le aziende hanno deciso di utilizzare Quorum. In questo articolo tratteremo due scenari: transazioni pubbliche e transazioni private.

Le transazioni vengono create da diversi partecipanti per interagire con il consorzio a cui appartengono. Ogni transazione distribuisce un contratto o richiama una funzione nel contratto per caricare i dati sulla rete. Queste azioni vengono replicate su tutti i nodi della rete.

Le transazioni pubbliche possono essere visualizzate da tutti i partecipanti al consorzio. Le transazioni private aggiungono un livello di riservatezza e sono disponibili solo per i partecipanti che hanno il diritto di farlo.

Per entrambi gli scenari, utilizziamo lo stesso contratto per chiarezza.

Contratto intelligente

Di seguito è riportato un semplice contratto intelligente creato per il nostro scenario. Ha una variabile pubblica temperature, che può essere modificato utilizzando set e ricevere con metodo get.

pragma solidity ^0.4.25;
contract TemperatureMonitor {
  int8 public temperature;
function set(int8 temp) public {
    temperature = temp;
  }
function get() view public returns (int8) {
    return temperature;
  }
}

Affinché il contratto possa funzionare web3.js, deve essere tradotto in formato ABI e bytecode. Utilizzando la funzione formatContractdi seguito compila il contratto utilizzando solc-js.

function formatContract() {
  const path = './contracts/temperatureMonitor.sol';
  const source = fs.readFileSync(path,'UTF8');
return solc.compile(source, 1).contracts[':TemperatureMonitor'];
}

Il contratto completato si presenta così:

// interface
[ 
  { 
    constant: true,
    inputs: [],
    name: ‘get’,
    outputs: [Array],
    payable: false,
    stateMutability: ‘view’,
    type: ‘function’ 
  },
  { 
    constant: true,
    inputs: [],
    name: ‘temperature’,
    outputs: [Array],
    payable: false,
    stateMutability: ‘view’,
    type: ‘function’ 
  },
  {
    constant: false,
    inputs: [Array],
    name: ‘set’,
    outputs: [],
    payable: false,
    stateMutability: ‘nonpayable’,
    type: ‘function’ 
  }
]

// bytecode
0x608060405234801561001057600080fd5b50610104806100206000396000f30060806040526004361060525763ffffffff7c01000000000000000000000000000000000000000000000000000000006000350416636d4ce63c81146057578063adccea12146082578063faee13b9146094575b600080fd5b348015606257600080fd5b50606960ae565b60408051600092830b90920b8252519081900360200190f35b348015608d57600080fd5b50606960b7565b348015609f57600080fd5b5060ac60043560000b60c0565b005b60008054900b90565b60008054900b81565b6000805491810b60ff1660ff199092169190911790555600a165627a7a72305820af0086d55a9a4e6d52cb6b3967afd764ca89df91b2f42d7bf3b30098d222e5c50029

Ora che il contratto è pronto, implementeremo la rete e implementeremo il contratto.

Distribuzione del nodo

Esegui transazioni pubbliche e private sulla blockchain JPMorgan Quorum utilizzando Web3

La distribuzione di un nodo può richiedere molto lavoro e questo processo può essere sostituito utilizzando un servizio Catenella.

Di seguito è riportato il processo per l'implementazione della rete Quorum con consenso Raft e tre nodi.

Per prima cosa creiamo un progetto e chiamiamolo Progetto Quorum:

Esegui transazioni pubbliche e private sulla blockchain JPMorgan Quorum utilizzando Web3

Creiamo una rete Quorum con il consenso Raft su Google Cloud Platform:

Esegui transazioni pubbliche e private sulla blockchain JPMorgan Quorum utilizzando Web3

Aggiungiamo altri due nodi al nodo già creato di default:

Esegui transazioni pubbliche e private sulla blockchain JPMorgan Quorum utilizzando Web3

Tre nodi in esecuzione:

Esegui transazioni pubbliche e private sulla blockchain JPMorgan Quorum utilizzando Web3

La pagina dei dettagli del nodo mostra l'endpoint RPC, la chiave pubblica, ecc.

Esegui transazioni pubbliche e private sulla blockchain JPMorgan Quorum utilizzando Web3

La rete è distribuita. Ora implementiamo i contratti intelligenti ed eseguiamo le transazioni utilizzando web3.js.

Transazioni pubbliche

Contesto

La temperatura del magazzino è di grande importanza per ridurre i costi, soprattutto per i prodotti destinati ad essere conservati a temperature inferiori allo zero.

Consentendo alle aziende di condividere la temperatura esterna della propria posizione geografica in tempo reale e di registrarla in un registro immutabile, i partecipanti alla rete riducono costi e tempi.

Esegui transazioni pubbliche e private sulla blockchain JPMorgan Quorum utilizzando Web3

Eseguiremo tre attività, illustrate nel diagramma:

  1. Distribuiremo il contratto tramite Nodo 1:

    const contractAddress = await deployContract(raft1Node);
    console.log(`Contract address after deployment: ${contractAddress}`);

  2. Impostare la temperatura tramite Nodo 2 di 3 gradi:

    const status = await setTemperature(raft2Node, contractAddress, 3);
    console.log(`Transaction status: ${status}`);

  3. Nodo 3 riceverà informazioni dal contratto intelligente. Il contratto restituirà il valore 3 gradi:

    const temp = await getTemperature(raft3Node, contractAddress);
    console.log(‘Retrieved contract Temperature’, temp);

    Successivamente, vedremo come eseguire una transazione pubblica sulla rete Quorum utilizzando web3.js.

Avviamo un'istanza tramite RPC per tre nodi:

const raft1Node = new Web3(
 new Web3.providers.HttpProvider(process.env.RPC1), null, {
   transactionConfirmationBlocks: 1,
 },
);
const raft2Node = new Web3(
 new Web3.providers.HttpProvider(process.env.RPC2), null, {
   transactionConfirmationBlocks: 1,
 },
);
const raft3Node = new Web3(
 new Web3.providers.HttpProvider(process.env.RPC3), null, {
   transactionConfirmationBlocks: 1,
 },
);

Implementiamo il contratto intelligente:

// returns the default account from the Web3 instance initiated previously
function getAddress(web3) {
  return web3.eth.getAccounts().then(accounts => accounts[0]);
}
// Deploys the contract using contract's interface and node's default address
async function deployContract(web3) {
  const address = await getAddress(web3);
// initiate contract with contract's interface
  const contract = new web3.eth.Contract(
    temperatureMonitor.interface
  );
return contract.deploy({
    // deploy contract with contract's bytecode
    data: temperatureMonitor.bytecode,
  })
  .send({
    from: address,
    gas: '0x2CD29C0',
  })
  .on('error', console.error)
  .then((newContractInstance) => {
    // returns deployed contract address
    return newContractInstance.options.address;
  });
}

web3.js prevede due modalità per interagire con il contratto: call и send.

Aggiorniamo la temperatura del contratto eseguendo set utilizzando il metodo web3 send.

// get contract deployed previously
async function getContract(web3, contractAddress) {
  const address = await getAddress(web3);
return web3.eth.Contract(
    temperatureMonitor.interface,
    contractAddress, {
      defaultAccount: address,
    }
  );
}
// calls contract set method to update contract's temperature
async function setTemperature(web3, contractAddress, temp) {
  const myContract = await getContract(web3, contractAddress);
return myContract.methods.set(temp).send({}).then((receipt) => {
    return receipt.status;
  });
}

Successivamente utilizziamo il metodo web3 call per ottenere la temperatura contrattuale. Si prega di notare che il metodo call viene eseguito su un nodo locale e la transazione non verrà creata sulla blockchain.

// calls contract get method to retrieve contract's temperature
async function getTemperature(web3, contractAddress) {
  const myContract = await getContract(web3, contractAddress);
return myContract.methods.get().call().then(result => result);
}

Ora puoi correre public.js per ottenere il seguente risultato:

// Execute public script
node public.js
Contract address after deployment: 0xf46141Ac7D6D6E986eFb2321756b5d1e8a25008F
Transaction status: true
Retrieved contract Temperature 3

Successivamente, possiamo visualizzare le voci nel Quorum Explorer nel pannello Chainstack, come mostrato di seguito.

Tutti e tre i nodi hanno interagito e le transazioni sono state aggiornate:

  1. La prima transazione ha implementato il contratto.
  2. La seconda transazione ha fissato la temperatura del contratto a 3 gradi.
  3. La temperatura viene ricevuta tramite un nodo locale, quindi non viene creata alcuna transazione.

Esegui transazioni pubbliche e private sulla blockchain JPMorgan Quorum utilizzando Web3

Transazioni private

Contesto

Un requisito comune delle organizzazioni è la protezione dei dati. Ad esempio, considera uno scenario in cui Supermercato affitta uno spazio magazzino per la conservazione dei frutti di mare da un magazzino separato Venditore:

  • Venditore utilizzando sensori IoT, legge i valori di temperatura ogni 30 secondi e li trasmette Al supermercato;
  • solo questi valori dovrebbero essere disponibili Al venditore и Al supermercato, collegati in rete da un consorzio.

Esegui transazioni pubbliche e private sulla blockchain JPMorgan Quorum utilizzando Web3

Completeremo le quattro attività illustrate nel diagramma sopra.

  • Utilizziamo gli stessi tre nodi dello scenario precedente per dimostrare le transazioni private:
  • supermercato distribuisce un contratto intelligente a cui è privato Supermercato и Venditore.
  • Il terzo lato non ha il diritto di accedere allo smart contract.

Chiameremo i metodi get и set per conto di Supermercato и Venditore per dimostrare una transazione del Quorum privato.

  1. Distribuiremo un contratto privato per i partecipanti supermercato и Venditore tramite un partecipante supermercato:

    const contractAddress = await deployContract(
    raft1Node,
    process.env.PK2,
    );
    console.log(`Contract address after deployment: ${contractAddress}`);

  2. Impostiamo la temperatura da Terzo (nodo esterno) e ottieni il valore della temperatura:

    // Attempts to set Contract temperature to 10, this will not mutate contract's temperature
    await setTemperature(
    raft3Node,
    contractAddress,
    process.env.PK1,
    10,
    );
    // This returns null
    const temp = await getTemperature(raft3Node, contractAddress);
    console.log(`[Node3] temp retrieved after updating contract from external nodes: ${temp}`);

  3. Impostiamo la temperatura da Venditore (nodo interno) e ottieni il valore della temperatura:

    La temperatura in questo scenario dovrebbe restituire il valore 12 dal contratto intelligente. Tienilo presente Venditore qui ha autorizzato l'accesso allo smart contract.

    // Updated Contract temperature to 12 degrees
    await setTemperature(
    raft2Node,
    contractAddress,
    process.env.PK1,
    12,
    );
    // This returns 12
    const temp2 = await getTemperature(raft2Node, contractAddress);
    console.log(`[Node2] temp retrieved after updating contract from internal nodes: ${temp2}`);

  4. Otteniamo la temperatura da Terzo (nodo esterno):

    Al punto 3 la temperatura era impostata su 12, ma Il terzo lato non ha accesso allo smart contract. Pertanto il valore restituito deve essere nullo.

    // This returns null
    const temp3 = await getTemperature(raft3Node, contractAddress);
    console.log(`[Node3] temp retrieved from external nodes after update ${temp}`);

    Successivamente, daremo uno sguardo più da vicino all'esecuzione di transazioni private sulla rete Quorum con web3.js. Poiché la maggior parte del codice è la stessa per le transazioni pubbliche, evidenzieremo solo le parti che differiscono per le transazioni private.

Tieni presente che il contratto caricato sulla rete è immutabile, quindi l'accesso autorizzato deve essere concesso ai nodi appropriati abilitando il contratto pubblico al momento della distribuzione del contratto, non dopo.

async function deployContract(web3, publicKey) {
  const address = await getAddress(web3);
  const contract = new web3.eth.Contract(
    temperatureMonitor.interface,
  );
return contract.deploy({
    data: temperatureMonitor.bytecode,
  })
  .send({
    from: address,
    gas: ‘0x2CD29C0’, 
    // Grant Permission to Contract by including nodes public keys
    privateFor: [publicKey],
  })
  .then((contract) => {
    return contract.options.address;
  });
}

Le transazioni private vengono eseguite in modo simile, includendo la chiave pubblica dei partecipanti al momento dell'esecuzione.

async function setTemperature(web3, contractAddress, publicKey, temp) {
  const address = await getAddress(web3);
  const myContract = await getContract(web3, contractAddress);
return myContract.methods.set(temp).send({
    from: address,
    // Grant Permission by including nodes public  keys
    privateFor: [publicKey],
  }).then((receipt) => {
    return receipt.status;
  });
}

Ora possiamo correre private.js con i seguenti risultati:

node private.js
Contract address after deployment: 0x85dBF88B4dfa47e73608b33454E4e3BA2812B21D
[Node3] temp retrieved after updating contract from external nodes: null
[Node2] temp retrieved after updating contract from internal nodes: 12
[Node3] temp retrieved from external nodes after update null

L'esploratore Quorum in Chainstack mostrerà quanto segue:

  • attuazione del contratto da parte del partecipante supermercato;
  • esecuzione SetTemperature от Terzo;
  • esecuzione SetTemperature da un partecipante Venditore.

Esegui transazioni pubbliche e private sulla blockchain JPMorgan Quorum utilizzando Web3

Come puoi vedere, entrambe le transazioni sono state completate, ma solo la transazione del partecipante Venditore aggiornata la temperatura nel contratto. Pertanto, le transazioni private garantiscono l’immutabilità, ma allo stesso tempo non rivelano i dati a terzi.

conclusione

Abbiamo esaminato un caso d'uso commerciale di Quorum per fornire informazioni aggiornate sulla temperatura in un magazzino implementando una rete tra due parti: un supermercato e il proprietario del magazzino.

Abbiamo mostrato come è possibile mantenere informazioni aggiornate sulla temperatura attraverso transazioni sia pubbliche che private.

Gli scenari applicativi possono essere moltissimi e, come puoi vedere, non è affatto difficile.

Sperimenta, prova ad espandere il tuo script. Inoltre, l’industria della tecnologia blockchain potrebbe crescere quasi dieci volte entro il 2024.

Fonte: habr.com

Aggiungi un commento