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

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

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

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

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

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

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

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

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

Контекст

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

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

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

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

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

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

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

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
Договорен адрес след разгръщането: 0x85dBF88B4dfa47e73608b33454E4e3BA2812B21D
[Node3] температура получена след актуализиране на договора от външни възли: null
[Node2] температура получена след актуализиране на договора от вътрешни възли: 12
[Node3] температура получена от външни възли след актуализация null

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

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

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

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

Заключение

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

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

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

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

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

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