
â blockchain based on Ethereum, developed by JPMorgan and recently becoming the first distributed ledger platform offered by Microsoft Azure.
Quorum supports private and public transactions and has many commercial use cases.
In this article, we will examine one such scenario â deploying a distributed ledger network between a supermarket and a warehouse owner to ensure up-to-date information about the temperature of the storage space.
The code used in this guide can be found in .
The article covers:
- creating a smart contract;
- deploying a Quorum network using ;
- public Quorum transactions;
- private Quorum transactions.
The scenario illustrates temperature monitoring in the storage spaces of Quorum network participants within the Internet of Things (IoT).
Kontekst
A group of warehouse companies joins a consortium to collaboratively store information and automate processes on the blockchain. To achieve this, the companies chose to use Quorum. In this article, we will cover two scenarios: public transactions and private transactions.
Transactions are created by different participants to interact with the consortium they belong to. Each transaction either deploys a contract or calls a function in the contract to upload data to the network. These actions are replicated across all nodes in the network.
Public transactions are available for viewing by all consortium participants. Private transactions add a layer of confidentiality and are only accessible to those participants who have the necessary permissions.
For both scenarios, we use the same contract for clarity.
smart-contract
Below is a simple smart contract created for our scenario. It has a public variable temperature, which can be modified by the method set and accessed by the method pridobi.
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;
}
}For the contract to work with , it needs to be converted to ABI and bytecode format. Using the function formatContract, shown below, compiles the contract using .
function formatContract() {
const path = '.\/contracts\/temperatureMonitor.sol';
const source = fs.readFileSync(path,'UTF8');
return solc.compile(source, 1).contracts[':TemperatureMonitor'];
}The final contract looks like this:
// 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
0x608060405234801561001057600080fd5b50610104806100206000396000f30060806040526004361060525763ffffffff7c01000000000000000000000000000000000000000000000000000000006000350416636d4ce63c81146057578063adccea12146082578063faee13b9146094575b600080fd5b348015606257600080fd5b50606960ae565b60408051600092830b90920b8252519081900360200190f35b348015608d57600080fd5b50606960b7565b348015609f57600080fd5b5060ac60043560000b60c0565b005b60008054900b90565b60008054900b81565b6000805491810b60ff1660ff199092169190911790555600a165627a7a72305820af0086d55a9a4e6d52cb6b3967afd764ca89df91b2f42d7bf3b30098d222e5c50029Zdaj, ko je pogodba pripravljena, bomo razporedili omreĆŸje in namestili pogodbo.
Razvijanje vozliĆĄÄ

Namestitev vozliĆĄÄa je lahko precej zamudna in ta postopek lahko nadomestimo z uporabo storitve. .
Spodaj je prikazan postopek namestitve omreĆŸja Quorum s konsenzom Raft in tremi vozliĆĄÄi.
Najprej bomo ustvarili projekt in ga poimenovali Quorum Project:

Ustvarili bomo omreĆŸje Quorum s konsenzom Raft na Google Cloud Platform:

ObstojeÄemu privzetemu vozliĆĄÄu dodajmo ĆĄe dve vozli.

Tri zagnana vozliĆĄÄa:

Stran podrobnosti vozliĆĄÄa prikazuje RPC endpoint, javni kljuÄ itd.

OmreĆŸje je razporejeno. Zdaj se bomo ukvarjali z nameĆĄÄanjem pametnih pogodb in izvajanjem transakcij s pomoÄjo .
Javne transakcije
Kontekst
Temperatura skladiĆĄÄnega prostora ima velik pomen za zniĆŸanje stroĆĄkov, ĆĄe posebej za izdelke, ki jih je treba shranjevati pri negativnih temperaturah.
S tem, da podjetjem omogoÄimo deljenje vrednosti zunanje temperature njihove geografske lokacije v realnem Äasu in zapisovanje v nespremenljiv register, Älani omreĆŸja zmanjĆĄujejo stroĆĄke in Äas.

Izvedli bomo tri naloge, prikazane na diagramu:
Namestili bomo pogodbo preko Node 1:
const contractAddress = await deployContract(raft1Node); console.log(`Naslov pogodbe po namestitvi: ${contractAddress}`);Nastavili bomo temperaturo preko Node 2 na 3 stopinje:
const status = await setTemperature(raft2Node, contractAddress, 3); console.log(`Status transakcije: ${status}`);Node 3 bo pridobil informacije iz pametne pogodbe. Pogodba bo vrnila vrednost 3 stopinje:
const temp = await getTemperature(raft3Node, contractAddress); console.log(âPridobljena temperatura pogodbeâ, temp);Nato bomo preuÄili, kako izvesti javno transakcijo v omreĆŸju Quorum z uporabo .
Inicializiramo instanco preko RPC za tri vozliĆĄÄa:
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,
},
);Namestimo pametno pogodbo:
// 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;
});
} ponuja dve metodi za interakcijo s pogodbo: call in send.
Posodobimo temperaturo pogodbe z izvajanjem set z uporabo metode 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;
});
}Nato uporabimo metodo web3 call za pridobitev temperature pogodbe. UpoĆĄtevajte, da se metoda call izvaja na lokalnem vozliĆĄÄu in transakcija na blockchainu ne bo ustvarjena.
// 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);
}Zdaj lahko zagnamo za pridobitev naslednjega rezultata:
// Execute public script
node public.js
Contract address after deployment: 0xf46141Ac7D6D6E986eFb2321756b5d1e8a25008F
Transaction status: true
Retrieved contract Temperature 3Nato lahko v Quorum Explorerju v nadzorni ploĆĄÄi Chainstack pogledamo zapise, kot je prikazano spodaj.
Vse tri vozliĆĄÄa so medsebojno delovala in transakcije so bile posodobljene:
- Prva transakcija je implementirala pogodbo.
- Druga transakcija je nastavila temperaturo pogodbe na 3 stopinje.
- Pridobitev temperature se izvede preko lokalnega vozliĆĄÄa, zato transakcija ni bila ustvarjena.

Zasebne transakcije
Kontekst
Pogosta zahteva organizacij je zaĆĄÄita podatkov. Kot primer razmislimo o scenariju, v katerem supermarket najemajo skladiĆĄÄni prostor za shranjevanje morskih sadeĆŸev pri posebnem dobavitelju:
- Dobavitelj s pomoÄjo IoT senzorjev beleĆŸijo temperaturne vrednosti vsakih 30 sekund in jih posredujejo supermarketu.;
- Te vrednosti morajo biti dostopne samo dobavitelju. in Supermarketu, zdruĆŸenemu v konzorcij.

Izvedli bomo ĆĄtiri naloge, ki so ilustrirane na zgornjem diagramu.
- Uporabimo ista tri vozliĆĄÄa iz prejĆĄnjega scenarija za demonstracijo zasebnih transakcij:
- Supermarket implementira pametno pogodbo, ki je privatna za supermarket. in dobavitelju.
- Tretja stran nima pravice do dostopa do pametne pogodbe.
Poklicali bomo metode pridobi in set v imenu supermarket. in dobavitelju za demonstracijo zasebne transakcije Quorum.
Implementirali bomo zasebno pogodbo za udeleĆŸence Supermarket in Dobavitelj preko udeleĆŸenca Supermarket:
const contractAddress = await deployContract( raft1Node, process.env.PK2, ); console.log(`Naslov pogodbe po implementaciji: ${contractAddress}`);Nastavimo temperaturo od Tretje strani (zunanje vozliĆĄÄe) in dobimo temperaturno vrednost:
// 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}`);Nastavimo temperaturo od dobavitelju (notranje vozliĆĄÄe) in dobimo temperaturno vrednost:
Temperatura v tem scenariju bi morala vrniti iz pametne pogodbe vrednost 12. UpoĆĄtevajte, da Dobavitelj tu ima dovoljen dostop do pametne pogodbe.
// 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}`);Pridobimo temperaturo od Tretje strani (zunanje vozliĆĄÄe):
Na 3. koraku je bila temperatura nastavljena na 12, vendar Tretja stran nima dostopa do pametne pogodbe. Zato bi morala vrniti vrednost null.
// This returns null const temp3 = await getTemperature(raft3Node, contractAddress); console.log(`[Node3] temp retrieved from external nodes after update ${temp}`);Nato bomo podrobneje preuÄili izvajanje zasebnih transakcij v mreĆŸi Quorum z . Ker se veÄina kode ujema s javnimi transakcijami, bomo izpostavili le tiste dele, ki se razlikujejo za zasebne transakcije.
UpoĆĄtevajte, da je pogodba, naloĆŸena v omreĆŸje, nespremenljiva, zato morajo biti dostopi z dovoljenjem (permissioned) dodeljeni ustreznim vozliĆĄÄem z vkljuÄitvijo javne pogodbe ob trenutku namestitve pogodbe, in ne pozneje.
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',
// Dodelite dovoljenje pogodbi z vkljuÄitvijo javnih kljuÄev vozliĆĄÄ
privateFor: [publicKey],
})
.then((contract) => {
return contract.options.address;
});
}Na podoben naÄin se izvajajo zasebne transakcije â z vkljuÄitvijo javnega kljuÄa udeleĆŸencev ob izvajanju.
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,
// Dodelite dovoljenje z vkljuÄitvijo javnih kljuÄev vozliĆĄÄ
privateFor: [publicKey],
}).then((receipt) => {
return receipt.status;
});
}Zdaj lahko zaÄnemo z naslednjimi rezultati:
node private.js
Naslov pogodbe po namestitvi: 0x85dBF88B4dfa47e73608b33454E4e3BA2812B21D
[Node3] temperatura pridobljena po posodobitvi pogodbe z zunanjih vozliĆĄÄ: null
[Node2] temperatura pridobljena po posodobitvi pogodbe z notranjih vozliĆĄÄ: 12
[Node3] temperatura pridobljena z zunanjih vozliĆĄÄ po posodobitvi: nullQuorum explorer v Chainstack bo prikazal naslednje:
- namestitev pogodbe s strani udeleĆŸenca Supermarket;
- IzvrĆĄevanje
SetTemperatureod Tretje strani; - IzvrĆĄevanje
SetTemperatures strani udeleĆŸenca Dobavitelj.

Kot vidite, sta bili obe transakciji izvedeni, vendar je le transakcija s strani udeleĆŸenca Dobavitelj posodobila temperaturo v pogodbi. Tako zasebne transakcije zagotavljajo nespremenljivost, a ne razkrivajo podatkov tretji strani.
ZakljuÄek
Obravnvali smo poslovni scenarij uporabe Quorum za zagotavljanje aktualnih informacij o temperaturi v skladiĆĄÄu z razporeditvijo omreĆŸja med dvema stranema â supermarketom in lastnikom skladiĆĄÄa.
Pokazali smo, kako lahko aktualne informacije o temperaturi ohranjamo tako s prek javnih kot tudi s prek zasebnih transakcij.
MoĆŸnosti uporabe je lahko zelo veliko in, kot vidite, to ni nikakor zapleteno.
Eksperimentirajte, poskusite z razporeditvijo svojega scenarija. Ć e posebej, ker se lahko industrija blockchain tehnologij .
Izvor: habr.com
