La ejecución de transacciones públicas y privadas en la blockchain de JPMorgan Quorum utilizando Web3

La ejecución de transacciones públicas y privadas en la blockchain de JPMorgan Quorum utilizando Web3

Quorum — una blockchain basada en Ethereum, desarrollada por JPMorgan y que recientemente se ha convertido en la primera plataforma de libro mayor distribuido disponible en Microsoft Azure.

Quorum admite transacciones públicas y privadas y tiene numerosos escenarios comerciales de uso.

En este artículo, analizaremos uno de esos escenarios: el despliegue de una red de libro mayor distribuido entre un supermercado y un operador de almacén para garantizar información actual sobre la temperatura del almacén.

El código utilizado en esta guía se encuentra en el repositorio en GitHub.

Este artículo cubre:

  • la creación de un contrato inteligente;
  • el despliegue de una red Quorum utilizando Chainstack;
  • transacciones públicas en Quorum;
  • transacciones privadas en Quorum.

Para ilustrar, se utiliza un escenario de monitoreo de temperatura en los almacenes de los participantes de la red Quorum dentro del Internet de las Cosas (IoT).

Contexto

Un grupo de empresas de almacenamiento se une en un consorcio para compartir información y automatizar procesos en la blockchain. Para esto, las empresas decidieron utilizar Quorum. En este artículo cubriremos dos escenarios: transacciones públicas y transacciones privadas.

Las transacciones son creadas por diferentes participantes para interactuar con el consorcio al que pertenecen. Cada transacción despliega un contrato o invoca una función en el contrato para cargar datos en la red. Estas acciones se replican en todos los nodos de la red.

Las transacciones públicas son accesibles para que todos los participantes del consorcio las vean. Las transacciones privadas, en cambio, añaden una capa de confidencialidad y solo son accesibles para aquellos participantes que tienen permisos para ello.

Para ambos escenarios, utilizamos el mismo contrato para mayor claridad.

Contrato inteligente

A continuación, se presenta un contrato inteligente simple creado para nuestro escenario. Tiene una variable pública temperature, que se puede modificar mediante el método set 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; } } get.

Para que el contrato funcione con

, debe ser traducido a formato ABI y bytecode. El uso de la función web3.jsformatContract , presentada a continuación, compila el contrato utilizandosolc-js solc-js.

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

El contrato listo se ve de la siguiente manera:

// 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

Ahora que el contrato está listo, desplegaremos la red y desplegaremos el contrato.

Despliegue de nodos

La ejecución de transacciones públicas y privadas en la blockchain de JPMorgan Quorum utilizando Web3

El despliegue de un nodo puede ser bastante laborioso y este proceso puede ser reemplazado por el uso de un servicio. Chainstack.

A continuación, se presenta el proceso de despliegue de la red Quorum con consenso Raft y tres nodos.

Primero, crearemos un proyecto y lo nombraremos Proyecto Quorum:

La ejecución de transacciones públicas y privadas en la blockchain de JPMorgan Quorum utilizando Web3

Crearemos una red Quorum con consenso Raft en Google Cloud Platform:

La ejecución de transacciones públicas y privadas en la blockchain de JPMorgan Quorum utilizando Web3

A la ya creada nodo por defecto, añadiremos dos nodos más:

La ejecución de transacciones públicas y privadas en la blockchain de JPMorgan Quorum utilizando Web3

Tres nodos en funcionamiento:

La ejecución de transacciones públicas y privadas en la blockchain de JPMorgan Quorum utilizando Web3

La página de detalles del nodo muestra el punto final RPC, la clave pública, etc.

La ejecución de transacciones públicas y privadas en la blockchain de JPMorgan Quorum utilizando Web3

La red está desplegada. Ahora nos ocuparemos del despliegue de contratos inteligentes y la ejecución de transacciones a través de web3.js.

Transacciones públicas

Contexto

La temperatura en el almacén es crucial para reducir costos, especialmente para productos que deben ser almacenados a temperaturas bajo cero.

Al permitir a las empresas compartir valores de temperatura externa de su ubicación geográfica en tiempo real y registrarlos en un libro mayor inmutable, los participantes de la red reducen costos y tiempos.

La ejecución de transacciones públicas y privadas en la blockchain de JPMorgan Quorum utilizando Web3

Realizaremos tres tareas ilustradas en el diagrama:

  1. Desplegaremos el contrato a través de Nodo 1:

    const contractAddress = await deployContract(raft1Node);
    console.log(`Dirección del contrato después del despliegue: ${contractAddress}`);

  2. Estableceremos la temperatura a través de Nodo 2 a 3 grados:

    const status = await setTemperature(raft2Node, contractAddress, 3);
    console.log(`Estado de la transacción: ${status}`);

  3. Nodo 3 obtendrá información del contrato inteligente. El contrato devolverá el valor de 3 grados:

    const temp = await getTemperature(raft3Node, contractAddress);
    console.log('Temperatura del contrato recuperada', temp);

    A continuación, veremos cómo ejecutar una transacción pública en la red Quorum utilizando web3.js.

Iniciaremos una instancia a través de RPC para los tres nodos:

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,
 },
);

Desplegaremos el contrato inteligente:

// 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 proporciona dos métodos para interactuar con el contrato: call y send.

Actualizaremos la temperatura del contrato realizando set utilizando el método 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;
  });
}

A continuación, utilizaremos el método web3 call para obtener la temperatura del contrato. Tenga en cuenta que el método call se ejecuta en un nodo local y no se generará una transacción en la 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);
}

Ahora podemos iniciar public.js para obtener el siguiente resultado:

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

A continuación, podemos ver los registros en el explorador Quorum en el panel de Chainstack, como se muestra a continuación.

Los tres nodos han interactuado y las transacciones se han actualizado:

  1. La primera transacción desplegó el contrato.
  2. La segunda transacción estableció la temperatura del contrato en 3 grados.
  3. La obtención de la temperatura se realiza a través del nodo local, por lo que no se ha creado una transacción.

La ejecución de transacciones públicas y privadas en la blockchain de JPMorgan Quorum utilizando Web3

Transacciones privadas

Contexto

Un requisito común de las organizaciones es la protección de datos. Tomemos como ejemplo el escenario en el que el supermercado arrienda un espacio de almacenamiento para productos del mar de un Proveedor:

  • Proveedor mediante sensores IoT que leen los valores de temperatura cada 30 segundos y los envían al supermercado;
  • esos valores deben estar disponibles solo para el proveedor y del supermercado, formando parte de una red de consorcio.

La ejecución de transacciones públicas y privadas en la blockchain de JPMorgan Quorum utilizando Web3

Realizaremos cuatro tareas, ilustradas en el diagrama anterior.

  • Usaremos los mismos tres nodos del escenario anterior para demostrar transacciones privadas:
  • el supermercado despliega un contrato inteligente que es privado para el supermercado y Proveedor.
  • Una tercera parte no tiene acceso al contrato inteligente.

Llamaremos a los métodos get y set en nombre de el supermercado y Proveedor para demostrar una transacción privada en Quorum.

  1. Desplegaremos un contrato privado para los participantes el supermercado y Proveedor a través del participante el supermercado:

    const contractAddress = await deployContract(
    raft1Node,
    process.env.PK2,
    );
    console.log(`Dirección del contrato después del despliegue: ${contractAddress}`);

  2. Estableceremos la temperatura desde la tercera parte (nodo externo) y obtendremos el valor de 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. Estableceremos la temperatura desde Proveedor (nodo interno) y obtendremos el valor de temperatura:

    La temperatura en este escenario debería devolver el valor 12 desde el contrato inteligente. Tenga en cuenta que Proveedor aquí se tiene acceso permitido al contrato inteligente.

    // 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. Obtendremos la temperatura desde la tercera parte (nodo externo):

    En el paso 3, la temperatura se estableció con un valor de 12, pero Una tercera parte no tiene acceso al contrato inteligente. Por lo tanto, el valor devuelto debería ser nulo.

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

    A continuación, examinaremos más de cerca la ejecución de transacciones privadas en la red Quorum con web3.js. Dado que la mayor parte del código coincide con las transacciones públicas, destacaremos solo aquellas partes que difieren para las transacciones privadas.

Tenga en cuenta que el contrato cargado en la red es inmutable, por lo que el acceso con permiso debe ser otorgado a los nodos correspondientes mediante la inclusión del contrato público en el momento de la implementación del contrato, y no después.

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;
  });
}

De manera similar se realizan transacciones privadas, incluida la clave pública de los participantes en el momento de la ejecución.

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;
  });
}

Ahora podemos ejecutar private.js con los siguientes resultados:

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

El explorador Quorum en Chainstack mostrará lo siguiente:

  • implementación del contrato por parte del participante el supermercado;
  • Ejecución SetTemperature desde la tercera parte;
  • Ejecución SetTemperature por el participante Proveedor.

La ejecución de transacciones públicas y privadas en la blockchain de JPMorgan Quorum utilizando Web3

Como pueden ver, ambas transacciones se ejecutaron, pero solo la transacción del participante Proveedor actualizó la temperatura en el contrato. Por lo tanto, las transacciones privadas garantizan la inmutabilidad, pero no divulgan datos a terceros.

Conclusión

Hemos explorado un escenario comercial que utiliza Quorum para proporcionar información actualizada sobre la temperatura en un almacén a través del despliegue de una red entre dos partes: un supermercado y el propietario del almacén.

Hemos demostrado cómo la información actualizada sobre la temperatura se puede mantener tanto a través de transacciones públicas como privadas.

Los escenarios de aplicación pueden ser muy numerosos y, como pueden ver, no es nada complicado.

Experimente, intente implementar su propio escenario. Más aún, dado que la industria de la tecnología blockchain podría crecer casi diez veces para 2024..

Fuente: habr.com

Compra un hosting fiable para sitios web con protección contra DDoS, servidores VPS VDS 🔥 Compra un hosting fiable para sitios web con protección contra DDoS, servidores VPS VDS | ProHoster