
â njĂ« blockchain i bazuar nĂ« Ethereum, i zhvilluar nga JPMorgan dhe qĂ« nĂ« mĂ«nyrĂ« tĂ« fundit u bĂ« platforma e parĂ« e regjistrit tĂ« shpĂ«rndarĂ« qĂ« ofrohet nga Microsoft Azure.
Quorum mbështet transaksionet private dhe publike dhe ka shumë skenarë tregtarë përdorimi.
NĂ« kĂ«tĂ« artikull ne do tĂ« shqyrtojmĂ« njĂ« nga kĂ«ta skenarĂ« â vendosjen e njĂ« rrjeti tĂ« regjistrit tĂ« shpĂ«rndarĂ« midis njĂ« supermarketi dhe pronarit tĂ« magazinĂ«s pĂ«r tĂ« siguruar informacion tĂ« pĂ«rditĂ«suar pĂ«r temperaturĂ«n nĂ« ambientet e magazinimit.
Kodi i përdorur në këtë udhëzues ndodhet në .
Artikulli mbulon:
- krijimin e një smart contract;
- vendosjen e një rrjeti Quorum përmes ;
- transaksionet publike Quorum;
- transaksionet private Quorum.
Për ilustruese, përdoret një skenar për monitorimin e temperaturës në ambientet e magazinimit të anëtarëve të rrjetit Quorum brenda Internet of Things (IoT).
Konteksti
Grupi i kompanive të magazinimit bashkohet në një konsorcium për të ruajtur së bashku 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ë: transaksionet publike dhe transaksionet private.
Transaksionet krijohen nga anĂ«tarĂ« tĂ« ndryshĂ«m pĂ«r tĂ« bashkĂ«vepruar me konsorciumin tĂ« cilit i pĂ«rkasin. Ădo transaksion ose vendos njĂ« kontratĂ«, ose thĂ«rret njĂ« funksion nĂ« kontratĂ« pĂ«r tĂ« ngarkuar tĂ« dhĂ«na nĂ« rrjet. KĂ«to veprime riprodhohen nĂ« tĂ« gjitha nodet nĂ« rrjet.
Transaksionet publike janë të disponueshme për t'u parë nga të gjithë anëtarët e konsorciumit. Ndërsa transaksionet private shtojnë një nivel privatësie dhe janë të disponueshme vetëm për ata anëtarë që kanë të drejta për këtë.
Për të dy skenarët ne për ilustruese përdorim të njëjtën kontratë.
Kontrata inteligjente
Më poshtë është një smart contract i thjeshtë, krijuar për skenarin tonë. Ajo ka një variabël publike temperature, e cila mund të ndryshohet përmes metodës set dhe të merret përmes metodës 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ë siguruar që kontrata të funksionojë me , ajo duhet të përkthehet në formatin ABI dhe bytecode. Përdorimi i funksionit formatContract, i dhënë më poshtë, kompilon kontratën përmes .
function formatContract() {
const path = '.\/contracts\/temperatureMonitor.sol';
const source = fs.readFileSync(path,'UTF8');
return solc.compile(source, 1).contracts[':TemperatureMonitor'];
}Kontrata përfundimtare duket si më poshtë:
// 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 që kontrata është përgatitur, do ta zbatojmë rrjetin dhe do ta dislokojmë kontratën.
Zhvillimi i nodave

Dislokimi i nodës mund të jetë mjaft i punës, dhe ky proces mund të zëvendësohet me përdorimin e një shërbimi .
Më poshtë është procesi i dislokimit të rrjetit Quorum me konsensus Raft dhe tre nodë.
Për të filluar, do të krijojmë një projekt dhe do ta quajmë Projketin Quorum:

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

Së bashku me nodën e krijuar me default, do të shtojmë edhe dy nodë:

TĂ« tre nodat e nisura:

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

Rrjeti është dislokuar. Tani do të merremi me dislokimin e kontratave të mençura dhe ekzekutimin e transaksioneve përmes .
Transaksioneve publike
Konteksti
Temperatura e magazinimit ka rëndësi të madhe për uljen e kostove, veçanërisht për produktet e destinuara për ruajtje në temperatura negative.
Duke i dhënë kompanive mundësinë që të ndajnë vlerat e temperaturës së jashtme të vendndodhjes së tyre në kohë reale dhe të regjistrojnë në një regjistër të pandryshuar, pjesëmarrësit e rrjetit reduktojnë shpenzimet dhe kohën.

Do të kryejmë tre detyra të ilustruara në diagram:
Do ta dislojmë kontratën përmes Node 1:
const contractAddress = await deployContract(raft1Node); console.log(`Adresa e kontratës pas dislokimit: ${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ë informacion nga kontrata e mençur. Kontrata do të kthejë vlerën 3 gradë:
const temp = await getTemperature(raft3Node, contractAddress); console.log(âTemperatura e kontratĂ«s e marrĂ«â, temp);MĂ« pas do tĂ« shqyrtojmĂ« se si tĂ« ekzekutojmĂ« njĂ« transaksion publik nĂ« rrjetin Quorum duke pĂ«rdorur .
Inicojmë një instancë përmes RPC për tre nodat:
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 dislojmë kontratën e mençur:
// 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;
});
} ofron dy metoda për të ndërvepruar me kontratën: thirr 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ë pas do të përdorim metodën web3 thirr për të marrë temperaturën e kontratës. Vini re se metoda thirr ekzekutohet në nodën lokale dhe në bllokadin 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ë filloni për të marrë rezultatin e ardhshëm:
// Execute public script
node public.js
Contract address after deployment: 0xf46141Ac7D6D6E986eFb2321756b5d1e8a25008F
Transaction status: true
Retrieved contract Temperature 3Më pas, mund të shohim regjistrimet në eksploruesin Quorum në panelin Chainstack, siç tregohet më poshtë.
Të tre nodet kanë bashkëvepruar dhe transaksionet janë përditësuar:
- Transaksioni i parë ka depozituar kontratën.
- Transaksioni i dytë ka vendosur temperaturën e kontratës në 3 gradë.
- Marrja e temperaturës ndodh përmes nodës lokale, kështu që transaksioni nuk është krijuar.

Transaksione private
Konteksti
Një kërkesë e zakonshme për organizatat është mbrojtja e të dhënave. Si një shembull, le të shqyrtojmë një skenar ku Supermarketi merr me qira një magazinë për të ruajtur ushqimet detare nga një Furnizues:
- Furnizuesi me ndihmën e sensorëve IoT lexon vlerat e temperaturës çdo 30 sekonda dhe i dërgon ato Supermarketit;
- vlerat e tilla duhet të jenë të aksesueshme vetëm për Furnizuesin dhe Supermarketin, të bashkuar në një rrjet konsorciumi.

Ne do të realizojmë katër detyra që ilustrohen në diagramin më sipër.
- Përdorim të njëjtat tre node nga skenari i mëparshëm për të demonstruar transaksionet private:
- Supermarketi depozon një kontratë inteligjente, e cila është private për Supermarketingun dhe Furnizues.
- Pjesa e tretë nuk ka të drejtë qasje në kontratën inteligjente.
Ne do të thërrasim metodat merr dhe set në emër Supermarketingun dhe Furnizues për të demonstruar transaksionin privat në Quorum.
Do të depozojmë një kontratë private për pjesëmarrësit Supermarketi dhe Furnizuesi përmes pjesëmarrësit Supermarketi:
const contractAddress = await deployContract( raft1Node, process.env.PK2, ); console.log(`Adresa e kontratës pas depozitimit: ${contractAddress}`);Do të vendosim temperaturën nga Pjesa e tretë (noda e jashtme) dhe do të 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}`);Do të vendosim temperaturën nga Furnizues (noda e brendshme) dhe do të marrim vlerën e temperaturës:
Temperatura në këtë skenar duhet të kthejë nga kontrata inteligjente vlerën 12. Vëreni se Furnizuesi këtu ka qasje 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}`);Do të marrim temperaturën nga Pjesa e tretë (noda e jashtme):
Në hapin 3, temperatura ishte vendosur me vlerën 12, por Pjesa e tretë nuk ka qasje në kontratën inteligjente. Prandaj, vlera e kthyer 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, do të shqyrtojmë në detaje ekzekutimin e transaksioneve private në rrjetin Quorum me . Duke qenë se pjesa më e madhe e kodit është identike me transaksionet publike, do të theksojmë vetëm ato pjesë që ndryshojnë për transaksionet private.
Vini re në konsideratë se kontrata e ngarkuar në rrjet është e paprekshme, prandaj qasja me leje duhet të jepet nodëve përkatës duke përfshirë kontratën publike në momentin e depozitimit të kontratës, e jo pas saj.
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;
});
}Po ashtu, transaksionet private realizohen 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,
// Grant Permission by including nodes public keys
privateFor: [publicKey],
}).then((receipt) => {
return receipt.status;
});
}Tani mund të fillojmë me rezultatet e mëposhtme:
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 nullEksploruesi Quorum në Chainstack do të tregojë si më poshtë:
- depozitimi i kontratës nga një pjesëmarrës Supermarketi;
- Execution
SetTemperaturenga Pjesa e tretë; - Execution
SetTemperaturenga një pjesëmarrës Furnizuesi.

Siç e shihni, të dyja transaksionet janë realizuar, por vetëm transaksioni nga pjesëmarrësi Furnizuesi përditësoi temperaturën në kontratë. Kështu, transaksionet private sigurojnë paprekshmërinë, por gjithashtu nuk zbulojnë të dhëna për palët e treta.
Përfundim
Ne shqyrtuam njĂ« skenar komercial tĂ« pĂ«rdorimit tĂ« Quorum pĂ«r tĂ« siguruar informacionin e saktĂ« mbi temperaturĂ«n nĂ« magazinĂ« pĂ«rmes krijimit tĂ« njĂ« rrjeti midis dy palĂ«ve â supermarketit dhe pronarit tĂ« magazinĂ«s.
Ne treguam si informacioni aktual mbi temperaturën mund të mbahet si përmes transaksioneve publike ashtu edhe përmes atyre private.
Skenarët e aplikimit mund të jenë shumë dhe, siç e shihni, nuk është aspak e vështirë.
Eksperimentoni, provoni të implementoni skenarin tuaj. Sidomos që industria e teknologjive blockchain .
Burimi: habr.com
