
â njĂ« blockchain i bazuar nĂ« Ethereum, i zhvilluar nga JPMorgan dhe sĂ« fundmi bĂ«ri tĂ« parĂ«n platformĂ« tĂ« regjistrit tĂ« shpĂ«rndarĂ« qĂ« ofron Microsoft Azure.
Quorum mbështet transaksione private dhe publike dhe ka shumë skenarë komercialë përdorimi.
NĂ« kĂ«tĂ« artikull, do tĂ« shqyrtojmĂ« njĂ« nga kĂ«ta skenarĂ« â krijimin e njĂ« rrjeti tĂ« regjistrit tĂ« shpĂ«rndarĂ« midis njĂ« supermarketi dhe pronarit tĂ« njĂ« depoje pĂ«r tĂ« siguruar informacionin aktual mbi temperaturĂ«n e ambientit tĂ« depozitĂ«s.
Kodi i përdorur në këtë udhëzim është i përcaktuar në .
Artikulli mbulon:
- krijimin e një kontrate inteligjente;
- krijimin e një rrjeti Quorum me ndihmën e ;
- transaksionet publike në Quorum;
- transaksionet private në Quorum.
Për ilustrim, përdorim skenarin e monitorimit të temperaturës në ambientet e depozitave të anëtarëve të rrjetit Quorum në kuadër të Internet of Things (IoT).
Konteksti
Një grup kompanish depozitoresh bashkohet në një konsorcium për të ndarë informacionin dhe për të automatizuar proceset në blockchain. Për këtë, kompanitë vendosën të përdorin Quorum. Në këtë artikull do të mbulojmë dy skenarë: transaksione publike dhe transaksione private.
Transaksionet krijohen nga pjesĂ«marrĂ«s tĂ« ndryshĂ«m pĂ«r tĂ« bashkĂ«vepruar me konsorciumin nĂ« tĂ« cilin janĂ« pjesĂ«. Ădo transaksion ose krijon njĂ« kontratĂ«, ose thĂ«rret njĂ« funksion nĂ« kontratĂ« pĂ«r tĂ« ngarkuar tĂ« dhĂ«nat nĂ« rrjet. KĂ«to veprime riprodhohen nĂ« tĂ« gjitha nodet nĂ« rrjet.
Transaksionet publike janë të aksesueshme për t'u parë nga të gjithë anëtarët e konsorciumit. Transaksionet private, nga ana tjetër, shtojnë një shtresë konfidencialiteti dhe janë të aksesueshme vetëm për ata pjesëmarrës që kanë të drejta për to.
Për të dy skenarët, për qartësi, përdorim të njëjtën kontratë.
Kontrata e mençur
Më poshtë është një kontratë inteligjente e thjeshtë e krijuar për skenarin tonë. Ajo ka një variabël publike temperature, e cila mund të ndryshohet me metodën set dhe të merret me metodën merr.
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;
}
}Për të bërë që kontrata të funksionojë me , ajo duhet të konvertohet në formatin ABI dhe bytecode. Përdorimi i funksionit formatContract, i dhënë më poshtë, kompilon kontratën duke përdorur .
function formatContract() {
const path = './contracts/temperatureMonitor.sol';
const source = fs.readFileSync(path,'UTF8');
return solc.compile(source, 1).contracts[':TemperatureMonitor'];
}Kontrata e përfunduar duket kështu:
// 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
0x608060405234801561001057600080fd5b50610104806100206000396000f30060806040526004361060525763ffffffff7c01000000000000000000000000000000000000000000000000000000006000350416636d4ce63c81146057578063adccea12146082578063faee13b9146094575b600080fd5b348015606257600080fd5b50606960ae565b60408051600092830b90920b8252519081900360200190f35b348015608d57600080fd5b50606960b7565b348015609f57600080fd5b5060ac60043560000b60c0565b005b60008054900b90565b60008054900b81565b6000805491810b60ff1660ff199092169190911790555600a165627a7a72305820af0086d55a9a4e6d52cb6b3967afd764ca89df91b2f42d7bf3b30098d222e5c50029Tani, kur kontrata është gati, do të krijojmë rrjetin dhe do ta vendosim kontratën.
Shpërndarja e nodëve

Krijimi i një nodi mund të jetë mjaft i punës, dhe ky proces mund të zëvendësohet duke përdorur shërbimin .
Më poshtë është procesi i krijimit të rrjetit Quorum me konsensus Raft dhe tre node.
Së pari, do të krijojmë një projekt dhe ta quajmë Quorum Project:

Do të krijojmë një rrjet Quorum me konsensus Raft në Google Cloud Platform:

Do të shtojmë dy node shtesë në nodin e krijuar më parë:

Tre nodet e aktivizuara:

Faqja e detajeve të nodit tregon pikën e fundit RPC, çelësin publik, etj.

Rrjeti është krijuar. Tani do të merremi me vendosjen e kontratave inteligjente dhe ekzekutimin e transaksioneve me ndihmën e .
Transaksioneve publike
Konteksti
Temperatura e ambientit të depozitave ka rëndësi të madhe për uljen e kostove, veçanërisht për produktet që kanë nevojë të ruhet në temperatura nën zero.
Duke iu dhënë kompanive mundësinë për të ndarë vlerat e temperaturës së jashtme të vendndodhjes së tyre në kohë reale dhe për t'i regjistruar ato në një regjistër të pandryshueshëm, pjesëmarrësit e rrjetit reduktojnë shpenzimet dhe kohën.

Ne do të realizojmë tre detyra të ilustruara në diagram:
Do ta vendosim kontratën përmes Node 1:
const contractAddress = await deployContract(raft1Node); console.log(`Adresa e kontratës pas vendosjes: ${contractAddress}`);Do të vendosim temperaturën përmes Node 2 në 3 gradë:
const status = await setTemperature(raft2Node, contractAddress, 3); console.log(`Statusi i transaksionit: ${status}`);Node 3 do të marrë informacionin nga kontrata inteligjente. Kontrata do të kthejë vlerën 3 gradë:
const temp = await getTemperature(raft3Node, contractAddress); console.log(âTemperatura e marrĂ« nga kontrataâ, temp);MĂ« pas do tĂ« shohim se si tĂ« ekzekutojmĂ« njĂ« transaksion publik nĂ« rrjetin Quorum duke pĂ«rdorur .
Ngremë një instancë përmes RPC për tre nodet:
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,
},
);Do ta vendosim kontratën inteligjente:
// 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;
});
} siguron dy metoda për të komunikuar me kontratën: call dhe dërgo.
Do ta përditësojmë temperaturën e kontratës duke kryer set duke përdorur metodën web3 dërgo.
// 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;
});
}Më vonë, do të përdorim metodën web3 call për të marrë temperaturën e kontratës. Vini re se metoda call ekzekutohet në nodin lokal dhe në blockchain nuk do të krijohet asnjë transaksion.
// 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);
}Tani mund të ekzekutojmë për të marrë rezultatin e mëposhtëm:
// Execute public script
node public.js
Contract address after deployment: 0xf46141Ac7D6D6E986eFb2321756b5d1e8a25008F
Transaction status: true
Retrieved contract Temperature 3Më pas, ne mund të shohim regjistrimet në eksploruesin Quorum në panelin Chainstack, siç është treguar më poshtë.
Të tre nodet ndërsjellë dhanë kontribut dhe transaksionet u përditësuan:
- Transaksioni i parë vendosi kontratën.
- Transaksioni i dytë vendosi temperaturën e kontratës në 3 gradë.
- Marrja e temperaturës bëhet përmes nodit lokal, ndaj transaksioni nuk është krijuar.

Transaksionet e privatisë
Konteksti
Një kërkesë e zakonshme nga organizatat është mbrojtja e të dhënave. Siç është treguar, le të shqyrtojmë një skenar ku supermarketi marr me qira një hapësirë magazinimi për ruajtjen e produkteve detare nga një shkëputës:
- Shitesi përdor pajisje IoT për të lexuar vlerat e temperaturës çdo 30 sekonda dhe për t'i dërguar ato supermarketit;
- këto vlera duhet të jenë të disponueshme vetëm për shkëputësin dhe supermarketin, të lidhur në një rrjet konsorciumi.

Ne do të kryejmë katër detyra, të ilustruara në diagramin më sipër.
- Përdorim të njëjtat tri node nga skenari i mëparshëm për të demonstruar transaksionet private:
- supermarketi deplojon një kontratë inteligjente, e cila është private për supermarketin. dhe shkëputës.
- Një palë e tretë nuk ka të drejtë akses në kontratën intelligente.
Ne do të thërrasim metodat merr dhe set në emër supermarketin. dhe shkëputës për të demonstruar një transaksion privat Quorum.
Të deplohet një kontratë private për pjesëmarrësit supermarketi dhe Shitesi nëpërmjet pjesëmarrësit supermarketi:
const contractAddress = await deployContract( raft1Node, process.env.PK2, ); console.log(`Adresa e kontratës pas deponimit: ${contractAddress}`);Vendosim temperaturën nga pala e tretë (nodi i jashtëm) dhe marrim vlerën e temperaturës:
// 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}`);Vendosim temperaturën nga shkëputës (nodi i brendshëm) dhe marrim vlerën e temperaturës:
Temperatura në këtë skenar duhet të kthejë vlerën 12 nga kontrata inteligjente. Vini re se Shitesi këtu ka akses të lejuar në kontratën inteligjente.
// 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}`);Marrim temperaturën nga pala e tretë (nodi i jashtëm):
Në hapat e 3-të, temperatura u vendos me vlerën 12, por Një palë e tretë nuk ka akses në kontratën inteligjente. Prandaj, kthimi i vlerës duhet të jetë null.
// This returns null const temp3 = await getTemperature(raft3Node, contractAddress); console.log(`[Node3] temp retrieved from external nodes after update ${temp}`);Më pas ne do të shqyrtojmë në detaje ekzekutimin e transaksioneve private në rrjetin Quorum me . Duke pasur parasysh se pjesa më e madhe e kodit është e njëjtë me transaksionet publike, do të nxjerrim vetëm ato pjesë që dallojnë për transaksionet private.
Vini re se kontrata e ngarkuar në rrjet është e pandryshueshme, prandaj qasja me leje duhet të jepet për nodet përkatëse duke përfshirë kontratën publike në momentin e deponimit, dhe jo pas.
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â,
// Jepni leje për kontratën duke përfshirë çelësat publikë të nodave
privateFor: [publicKey],
})
.then((contract) => {
return contract.options.address;
});
}Po ashtu kryhen transaksionet private - duke përfshirë çelësin publik të pjesëmarrësve në momentin e ekzekutimit.
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,
// Jepni leje duke përfshirë çelësat publikë të nodave
privateFor: [publicKey],
}).then((receipt) => {
return receipt.status;
});
}Tani ne mund të nisim me rezultatet si më poshtë:
node private.js
Adresa e kontratës pas deponimit: 0x85dBF88B4dfa47e73608b33454E4e3BA2812B21D
[Node3] temperatura e rimarrë pas përditësimit të kontratës nga nodet e jashtme: null
[Node2] temperatura e rimarrë pas përditësimit të kontratës nga nodet e brendshme: 12
[Node3] temperatura e rimarrë nga nodet e jashtme pas përditësimit: nullEksploruesi Quorum në Chainstack do të tregojë si më poshtë:
- depolimi i kontratës nga pjesëmarrësi supermarketi;
- Ekzekutimi
SetTemperaturenga pala e tretë; - Ekzekutimi
SetTemperaturenga pjesëmarrësi Shitesi.

Siç e shihni, të dy transaksionet janë ekzekutuar, por vetëm transaksioni nga pjesëmarrësi Shitesi përditësoi temperaturën në kontratë. Në këtë mënyrë, transaksionet private sigurojnë pandryshueshmëri, por gjithashtu nuk ndjellin të dhëna për një palë të tretë.
Përfundimi
Ne shqyrtuam një skenar komercial të përdorimit të Quorum për sigurimin e informacionit të saktë mbi temperaturën në hapësirën magazinuese duke vendosur një rrjet mes dy palëve - supermarketit dhe pronarit të magazinës.
Ne treguam se si informacioni i saktë mbi temperaturën mund të mbahen si përmes transaksioneve publike ashtu edhe ato private.
Ka shumë skenarë përdorimi dhe, siç e shihni, nuk është aspak e ndërlikuar.
Eksperimentoni, provoni të zhvilloni skenarin tuaj. Veçanërisht nëse merrni parasysh se industria e teknologjive blockchain .
Burimi: habr.com
