Realiza transaccións públicas e privadas na cadea de bloques de JPMorgan Quorum usando Web3

Realiza transaccións públicas e privadas na cadea de bloques de JPMorgan Quorum usando Web3

quorum é unha cadea de bloques baseada en Ethereum desenvolvida por JPMorgan e, máis recentemente, converteuse na primeira plataforma de contabilidade distribuída que ofrece Microsoft Azure.

Quorum admite transaccións públicas e privadas e ten moitos casos de uso comercial.

Neste artigo, examinaremos un destes escenarios: a implantación dunha rede de libros de contas distribuídas entre un supermercado e o propietario dun almacén para proporcionar información actualizada sobre a temperatura do almacén.

O código usado neste tutorial está en repositorios en GitHub.

O artigo abrangue:

  • creación dun contrato intelixente;
  • implantación da rede Quorum usando Chainstack;
  • Quórum transaccións públicas;
  • Quórum transaccións privadas.

Para ilustralo, utilizamos un escenario para controlar a temperatura nos almacéns dos membros da rede Quorum dentro da Internet das cousas (IoT).

Contexto

Un grupo de empresas de almacén únense nun consorcio para almacenar conxuntamente información e automatizar procesos na cadea de bloques. Para iso, as empresas decidiron utilizar Quorum. Neste artigo abordaremos dous escenarios: transaccións públicas e transaccións privadas.

As transaccións son creadas por diferentes participantes para interactuar co consorcio ao que pertencen. Cada transacción desprega un contrato ou chama a unha función do contrato para cargar datos á rede. Estas accións replícanse en todos os nodos da rede.

As transaccións públicas están dispoñibles para a súa visualización por todos os participantes do consorcio. As transaccións privadas engaden unha capa de confidencialidade e só están dispoñibles para aqueles participantes que teñan dereitos para facelo.

Para os dous escenarios, usamos o mesmo contrato para claridade.

Contrato intelixente

A continuación móstrase un contrato intelixente sinxelo creado para o noso escenario. Ten unha variable pública temperature, que se pode cambiar usando set e recibir por método 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;
  }
}

Para que o contrato funcione web3.js, debe traducirse ao formato ABI e ao bytecode. Usando a función formatContracta continuación compila o contrato utilizando solc-js.

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

O contrato concluído ten o seguinte aspecto:

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

Agora que o contrato está listo, implementaremos a rede e o contrato.

Implantación de nodos

Realiza transaccións públicas e privadas na cadea de bloques de JPMorgan Quorum usando Web3

A implantación dun nodo pode ser moi laboriosa e este proceso pódese substituír mediante un servizo Chainstack.

A continuación móstrase o proceso para a implantación da rede Quorum co consenso de Raft e tres nodos.

Primeiro, imos crear un proxecto e chamalo Proxecto Quórum:

Realiza transaccións públicas e privadas na cadea de bloques de JPMorgan Quorum usando Web3

Imos crear unha rede Quorum co consenso de Raft en Google Cloud Platform:

Realiza transaccións públicas e privadas na cadea de bloques de JPMorgan Quorum usando Web3

Engadimos dous nodos máis ao nodo xa creado por defecto:

Realiza transaccións públicas e privadas na cadea de bloques de JPMorgan Quorum usando Web3

Tres nodos en execución:

Realiza transaccións públicas e privadas na cadea de bloques de JPMorgan Quorum usando Web3

A páxina de detalles do nodo mostra o punto final RPC, a chave pública, etc.

Realiza transaccións públicas e privadas na cadea de bloques de JPMorgan Quorum usando Web3

A rede está implantada. Agora imos implementar contratos intelixentes e realizar transaccións usando web3.js.

Transaccións públicas

Contexto

A temperatura do almacén é de gran importancia para reducir os custos, especialmente para os produtos destinados a almacenarse a temperaturas baixo cero.

Ao permitir ás empresas compartir a temperatura exterior da súa localización xeográfica en tempo real e rexistrala nun libro inmutable, os participantes da rede reducen custos e tempo.

Realiza transaccións públicas e privadas na cadea de bloques de JPMorgan Quorum usando Web3

Realizaremos tres tarefas, ilustradas no diagrama:

  1. Implementaremos o contrato vía Nodo 1:

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

  2. Establece a temperatura mediante Nodo 2 en 3 graos:

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

  3. Nodo 3 recibirá información do contrato intelixente. O contrato devolverá o valor de 3 graos:

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

    A continuación, veremos como executar unha transacción pública na rede Quorum usando web3.js.

Iniciamos unha instancia a través de RPC para 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,
 },
);

Implementemos o contrato intelixente:

// 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 ofrece dous métodos para interactuar co contrato: call и send.

Actualicemos a temperatura do contrato executando set utilizando o 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 usamos o método web3 call para obter a temperatura do contrato. Teña en conta que o método call execútase nun nodo local e a transacción non se creará na cadea de bloques.

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

Agora podes correr público.js para obter o seguinte resultado:

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

A continuación, podemos ver as entradas no explorador de Quórum no panel Chainstack, como se mostra a continuación.

Os tres nodos interactuaron e actualizáronse as transaccións:

  1. A primeira transacción despregou o contrato.
  2. A segunda transacción fixou a temperatura do contrato en 3 graos.
  3. A temperatura recíbese a través dun nodo local, polo que non se crea ningunha transacción.

Realiza transaccións públicas e privadas na cadea de bloques de JPMorgan Quorum usando Web3

Transaccións privadas

Contexto

Un requisito común das organizacións é a protección de datos. Como exemplo, considere un escenario no que Supermercado aluga un espazo de almacén para almacenar produtos do mar dun separado Vendedor:

  • Vendedor usando sensores IoT, le os valores de temperatura cada 30 segundos e os transmite Ao supermercado;
  • estes valores só deberían estar dispoñibles Ao vendedor и Ao supermercado, en rede por un consorcio.

Realiza transaccións públicas e privadas na cadea de bloques de JPMorgan Quorum usando Web3

Realizaremos as catro tarefas ilustradas no diagrama anterior.

  • Usamos os mesmos tres nodos do escenario anterior para demostrar transaccións privadas:
  • Supermercado implementa un contrato intelixente que é privado para Supermercado и Vendedor.
  • O terceiro lado non ten dereito a acceder ao contrato intelixente.

Chamaremos os métodos get и set en nome de Supermercado и Vendedor para demostrar unha transacción privada de Quórum.

  1. Implementaremos un contrato privado para os participantes Supermercado и Vendedor a través dun participante Supermercado:

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

  2. Imos configurar a temperatura desde Terceiro (nodo externo) e obtén o valor da 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. Imos configurar a temperatura desde Vendedor (nodo interno) e obtén o valor da temperatura:

    A temperatura neste escenario debería devolver o valor 12 do contrato intelixente. Teña en conta que Vendedor aquí ten acceso autorizado ao contrato intelixente.

    // 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. Tomamos a temperatura de Terceiro (nodo externo):

    No paso 3 a temperatura estableceuse en 12, pero O terceiro lado non ten acceso ao contrato intelixente. Polo tanto, o valor de retorno debe 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, analizaremos con máis detalle a realización de transaccións privadas na rede Quorum web3.js. Dado que a maior parte do código é o mesmo para as transaccións públicas, só destacaremos aquelas partes que son diferentes para as transaccións privadas.

Teña en conta que o contrato cargado na rede é inmutable, polo que o acceso con permiso debe concederse aos nodos apropiados habilitando o contrato público no momento en que se despregue o contrato, non despois.

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

As transaccións privadas realízanse dun xeito similar, incluíndo a clave pública dos participantes no momento da execució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;
  });
}

Agora podemos correr privado.js cos seguintes 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

O explorador de Quórum en Chainstack mostrará o seguinte:

  • despregamento do contrato do participante Supermercado;
  • Actuación SetTemperature de Terceiro;
  • Actuación SetTemperature dun participante Vendedor.

Realiza transaccións públicas e privadas na cadea de bloques de JPMorgan Quorum usando Web3

Como podes ver, complétanse ambas as transaccións, pero só a transacción do participante Vendedor actualizou a temperatura no contrato. Así, as transaccións privadas proporcionan inmutabilidade, pero ao mesmo tempo non revelan datos a un terceiro.

Conclusión

Analizamos un caso de uso comercial de Quorum para proporcionar información actualizada sobre a temperatura nun almacén mediante a implantación dunha rede entre dúas partes: un supermercado e o propietario dun almacén.

Amosamos como se pode manter a información actualizada sobre a temperatura mediante transaccións públicas e privadas.

Pode haber moitos escenarios de aplicación e, como podes ver, non é nada difícil.

Experimenta, tenta ampliar o teu guión. Ademais, a industria da tecnoloxía blockchain podería crecer case dez veces en 2024.

Fonte: www.habr.com

Engadir un comentario