Изпълнение на публични и частни транзакции в блокчейна JPMorgan Quorum с използване на Web3

Изпълнение на публични и частни транзакции в блокчейна JPMorgan Quorum с използване на Web3

Quorum — блокчейн, базиран на Ethereum, разработен от JPMorgan и наскоро стана първата платформа за разпределени регистри, която предлага Microsoft Azure.

Quorum поддържа частни и публични транзакции и има много търговски сценарии за използване.

В тази статия ще разгледаме един от тези сценарии — разгръщането на мрежа за разпределен регистър между супермаркет и собственик на склад за осигуряване на актуална информация за температурата в складовото помещение.

Кодът, използван в това ръководство, е репозитория на GitHub.

Статията обхваща:

  • създаване на смарт-контракт;
  • разгръщане на мрежа Quorum с помощта на Chainstack;
  • публични транзакции в Quorum;
  • частни транзакции в Quorum.

За илюстрация се използва сценарий за мониторинг на температурата в складовите помещения на участниците в мрежата Quorum в рамките на Internet of Things (IoT).

Контекст

Група складови компании се обединява в консорциум, за да съхранява информация и автоматизира процеси на блокчейн. За целта компаниите решили да използват Quorum. В тази статия ще покрием два сценария: публични транзакции и частни транзакции.

Транзакции се създават от различни участници, за да взаимодействат с консорциума, към който принадлежат. Всяка транзакция или разгръща контракт, или извиква функция в контракта за зареждане на данни в мрежата. Тези действия се репликират на всички възли в мрежата.

Публичните транзакции са достъпни за всички участници в консорциума. Частните транзакции добавят слой на поверителност и са достъпни само за тези участници, които имат права за това.

За двата сценария ще използваме един и същи контракт за илюстрация.

Смарт-контракт

По-долу е прост смарт-контракт, създаден за нашия сценарий. Той има публична променлива temperature, която може да бъде променяна чрез метода set и получавана чрез метода 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;
  }
}

За да работи контрактът с web3.js, той трябва да бъде преобразуван в формат ABI и байткод. Използването на функцията formatContract, посочена по-долу, компилира контракта с помощта на solc-js.

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

Готовият контракт изглежда по следния начин:

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

Сега, когато договора е готов, ще разположим мрежата и ще разположим договора.

Разполагане на нодове

Изпълнение на публични и частни транзакции в блокчейна JPMorgan Quorum с използване на Web3

Разполагането на нода може да бъде доста трудоемко и този процес може да бъде заменен с използването на услуга. Chainstack.

По-долу е представен процесът на разполагане на мрежата Quorum с консенсус Raft и три нода.

Първо, ще създадем проект и ще го наречем Quorum Project:

Изпълнение на публични и частни транзакции в блокчейна JPMorgan Quorum с използване на Web3

Ще създадем мрежа Quorum с консенсус Raft в Google Cloud Platform:

Изпълнение на публични и частни транзакции в блокчейна JPMorgan Quorum с използване на Web3

Към вече създадения по подразбиране нод ще добавим още два нода:

Изпълнение на публични и частни транзакции в блокчейна JPMorgan Quorum с използване на Web3

Три активни нода:

Изпълнение на публични и частни транзакции в блокчейна JPMorgan Quorum с използване на Web3

Страница с детайли на нода показва RPC endpoint, публичен ключ и т.н.

Изпълнение на публични и частни транзакции в блокчейна JPMorgan Quorum с използване на Web3

Мрежата е разположена. Сега ще се заемем с деплойването на смарт-договори и изпълнението на транзакции с помощта на web3.js.

Публични транзакции

Контекст

Температурата на складовото помещение има голямо значение за намаляване на разходите, особено за продукти, които трябва да се съхраняват при отрицателни температури.

Предоставяйки на компаниите възможността да споделят стойностите на външната температура на географското си местоположение в реално време и да записват в неизменим регистър, участниците в мрежата намаляват разходите и времето.

Изпълнение на публични и частни транзакции в блокчейна JPMorgan Quorum с използване на Web3

Ще извършим три задачи, илюстрирани в диаграмата:

  1. Ще разположим договора чрез Node 1:

    const contractAddress = await deployContract(raft1Node);
    console.log(`Адрес на договора след разполагането: ${contractAddress}`);

  2. Ще зададем температурата чрез Node 2 с 3 градуса:

    const status = await setTemperature(raft2Node, contractAddress, 3);
    console.log(`Статус на транзакцията: ${status}`);

  3. Node 3 ще получи информация от смарт-договора. Договорът ще върне стойност 3 градуса:

    const temp = await getTemperature(raft3Node, contractAddress);
    console.log('Получена температура от договора', temp);

    Нека разгледаме как да изпълним публична транзакция в мрежата Quorum, използвайки web3.js.

Инициираме инстанция чрез RPC за трите нода:

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

Ще разположим смарт-договора:

// 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 осигурява два метода за взаимодействие с договора: call и send.

Актуализираме температурата на договора, като изпълняваме set използвайки метода 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;
  });
}

След това използваме метода web3 call за получаване на температурата на договора. Обърнете внимание, че методът call се изпълнява на локалния нод и транзакцията няма да бъде създадена в блокчейна.

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

Сега можем да стартираме public.js за получаване на следния резултат:

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

Следва да разгледаме записките в експлорера Quorum в панела на Chainstack, както е показано по-долу.

Всички три ноди взаимодействат и транзакциите се обновяват:

  1. Първата транзакция деплоизира контракта.
  2. Втората транзакция зададе температурата на контракта на 3 градуса.
  3. Получаването на температурата се извършва през локалната нода, затова транзакция не е създадена.

Изпълнение на публични и частни транзакции в блокчейна JPMorgan Quorum с използване на Web3

Приватни транзакции

Контекст

Често изискване на организациите е защита на данните. Като пример разглеждаме сценарий, в който Супермаркет наема складово помещение за съхранение на морски дарове от отделен Доставчик:

  • Доставчик чрез IoT-сензори счита температурните стойности на всеки 30 секунди и ги предава на Супермаркета;
  • тези стойности трябва да бъдат достъпни само за Доставчика и Супермаркета, обединен в мрежа консорциум.

Изпълнение на публични и частни транзакции в блокчейна JPMorgan Quorum с използване на Web3

Ще изпълним четири задачи, илюстрирани на схематичното представяне по-горе.

  • Използваме същите три ноди от предишния сценарий за демонстрация на приватни транзакции:
  • Супермаркет деплоизира смарт-контракт, който е приватен за Супермаркета и Доставчик.
  • Третата страна няма достъп до смарт-контракта.

Ще извикаме методите get и set от името на Супермаркета и Доставчик за демонстрация на приватна транзакция Quorum.

  1. Деплоизиране на приватен контракт за участниците Супермаркет и Доставчик чрез участник Супермаркет:

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

  2. Зададете температурата от Третата страна (външна нода) и получаваме стойността на температурата:

    // 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. Зададете температурата от Доставчик (вътрешна нода) и получаваме стойността на температурата:

    Температурата в този сценарий трябва да върне от смарт-контракта стойността 12. Обърнете внимание, че Доставчик тук има разрешен достъп до смарт-контракта.

    // 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. Ще получим температурата от Третата страна (външна нода):

    На стъпка 3 температурата беше зададена със стойност 12, но Третата страна няма достъп до смарт-контракта. Следователно връщането на стойността трябва да бъде null.

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

    Следва да разгледаме по-подробно изпълнението на приватни транзакции в мрежата Quorum с web3.js. Понеже голяма част от кода съвпада с публичните транзакции, ще подчертаем само онези части, които се различават за приватни транзакции.

Обърнете внимание, че договорът, качен в мрежата, е неизменяем, така че достъп с разрешение трябва да бъде предоставен на съответните възли, като се включи публичният договор в момента на деплой на договора, а не след това.

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

По подобен начин се извършват частни транзакции — чрез включване на публичния ключ на участниците в момента на изпълнението.

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

Сега можем да стартираме private.js с следните резултати:

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

Explorer Quorum в Chainstack ще покаже следното:

  • деплой на договора от участник Супермаркет;
  • Изпълнение SetTemperature от Третата страна;
  • Изпълнение SetTemperature от участник Доставчик.

Изпълнение на публични и частни транзакции в блокчейна JPMorgan Quorum с използване на Web3

Както виждате, и двете транзакции са изпълнени, но само транзакцията от участника Доставчик обнови температурата в договора. По този начин частните транзакции осигуряват неизменяемост, но също така не разкриват данни на трети страни.

Заключение

Ние разгледахме търговски сценарий за използване на Quorum за осигуряване на актуална информация за температурата в складово помещение чрез разгръщане на мрежа между две страни — хипермаркет и собственик на склад.

Показахме как актуалната информация за температурата може да се поддържа както чрез публични, така и чрез частни транзакции.

Приложенията може да са много и, както виждате, това не е никак сложно.

Експериментирайте, опитайте се да разположите своя сценарий. Особено, тъй като индустрията на блокчейн технологиите до 2024 година може да нарасне почти десетократно.

Източник: habr.com

Купете надежден хостинг за сайтове със защита от DDoS, VPS и VDS сървъри 🔥 Купете надежден хостинг за сайтове със защита от DDoS, VPS и VDS сървъри | ProHoster