ProHoster > Blogs > AdministrÄcija > Veiciet publiskos un privÄtos darÄ«jumus JPMorgan Quorum blokÄ·ÄdÄ, izmantojot Web3
Veiciet publiskos un privÄtos darÄ«jumus JPMorgan Quorum blokÄ·ÄdÄ, izmantojot Web3
Kvorums ir uz Ethereum balstÄ«ta blokÄ·Äde, ko izstrÄdÄjusi JPMorgan, un pavisam nesen tÄ kļuva par pirmo izplatÄ«to virsgrÄmatu platformu, ko piedÄvÄ Microsoft Azure.
Quorum atbalsta privÄtus un publiskus darÄ«jumus, un tam ir daudz komerciÄlas lietoÅ”anas gadÄ«jumu.
Å ajÄ rakstÄ mÄs apskatÄ«sim vienu Å”Ädu scenÄriju - izkliedÄtÄ virsgrÄmatas tÄ«kla izvietoÅ”anu starp lielveikalu un noliktavas Ä«paÅ”nieku, lai nodroÅ”inÄtu aktuÄlu informÄciju par noliktavas temperatÅ«ru.
Å ajÄ apmÄcÄ«bÄ izmantotais kods ir iekÅ”Ä GitHub krÄtuves.
Lai ilustrÄtu, mÄs izmantojam scenÄriju temperatÅ«ras uzraudzÄ«bai Quorum tÄ«kla dalÄ«bnieku noliktavÄs lietiskajÄ internetÄ (IoT).
Konteksts
Noliktavas uzÅÄmumu grupa apvienojas konsorcijÄ, lai kopÄ«gi uzglabÄtu informÄciju un automatizÄtu procesus blokÄ·ÄdÄ. Å im nolÅ«kam uzÅÄmumi nolÄma izmantot Quorum. Å ajÄ rakstÄ mÄs apskatÄ«sim divus scenÄrijus: publiskus darÄ«jumus un privÄtus darÄ«jumus.
DarÄ«jumus veido dažÄdi dalÄ«bnieki, lai mijiedarbotos ar konsorciju, kuram tie pieder. Katrs darÄ«jums vai nu izvieto lÄ«gumu, vai izsauc kÄdu funkciju lÄ«gumÄ, lai augÅ”upielÄdÄtu datus tÄ«klÄ. Å Ä«s darbÄ«bas tiek atkÄrtotas visos tÄ«kla mezglos.
Publiskie darÄ«jumi ir pieejami apskatei visiem konsorcija dalÄ«bniekiem. PrivÄtie darÄ«jumi palielina konfidencialitÄtes lÄ«meni un ir pieejami tikai tiem dalÄ«bniekiem, kuriem ir tiesÄ«bas to darÄ«t.
Abiem scenÄrijiem skaidrÄ«bas labad mÄs izmantojam vienu un to paÅ”u lÄ«gumu.
Gudrs līgums
ZemÄk ir vienkÄrÅ”s viedais lÄ«gums, kas izveidots mÅ«su scenÄrijam. Tam ir publisks mainÄ«gais temperature, ko var mainÄ«t, izmantojot set un saÅemt pÄc metodes 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;
}
}
Lai lÄ«gums darbotos ar web3.js, tas ir jÄtulko ABI formÄtÄ un baitkodÄ. Izmantojot funkciju formatContractzemÄk apkopo lÄ«gumu, izmantojot solc-js.
Tagad, kad lÄ«gums ir gatavs, mÄs izvietosim tÄ«klu un izvietosim lÄ«gumu.
Mezglu izvietoŔana
Mezgla izvietoÅ”ana var bÅ«t diezgan darbietilpÄ«ga, un Å”o procesu var aizstÄt, izmantojot pakalpojumu ĶÄdes spieÄ·is.
TÄlÄk ir aprakstÄ«ts Quorum tÄ«kla izvietoÅ”anas process ar Raft konsensu un trim mezgliem.
Vispirms izveidosim projektu un nosauksim to par Kvoruma projektu:
Izveidosim Quorum tīklu ar Raft konsensu Google Cloud Platform:
Pievienosim vÄl divus mezglus mezglam, kas jau ir izveidots pÄc noklusÄjuma:
Trīs darbības mezgli:
Mezgla informÄcijas lapÄ tiek parÄdÄ«ts RPC galapunkts, publiskÄ atslÄga utt.
Tīkls ir izvietots. Tagad izvietosim viedos līgumus un veiksim darījumus, izmantojot web3.js.
Publiskie darījumi
Konteksts
Noliktavas temperatÅ«rai ir liela nozÄ«me izmaksu samazinÄÅ”anÄ, Ä«paÅ”i produktiem, kas paredzÄti uzglabÄÅ”anai mÄ«nusÄ temperatÅ«rÄ.
Ä»aujot uzÅÄmumiem dalÄ«ties ar savas Ä£eogrÄfiskÄs atraÅ”anÄs vietas ÄrÄjo temperatÅ«ru reÄllaikÄ un reÄ£istrÄt to nemainÄ«gÄ virsgrÄmatÄ, tÄ«kla dalÄ«bnieki samazina izmaksas un laiku.
MÄs veiksim trÄ«s uzdevumus, kas parÄdÄ«ti diagrammÄ:
MÄs izvietosim lÄ«gumu caur Node 1:
const contractAddress = await deployContract(raft1Node);
console.log(`Contract address after deployment: ${contractAddress}`);
Iestatiet temperatÅ«ru, izmantojot Node 2 par 3 grÄdiem:
const status = await setTemperature(raft2Node, contractAddress, 3);
console.log(`Transaction status: ${status}`);
Node 3 saÅems informÄciju no viedÄ lÄ«guma. LÄ«gumÄ tiks atgriezta vÄrtÄ«ba 3 grÄdi:
TÄlÄk mÄs apskatÄ«sim, kÄ veikt publisku darÄ«jumu Quorum tÄ«klÄ, izmantojot web3.js.
MÄs uzsÄkam instanci, izmantojot RPC, trim mezgliem:
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,
},
);
Izvietosim viedo līgumu:
// 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 nodroÅ”ina divas metodes mijiedarbÄ«bai ar lÄ«gumu: call Šø send.
AtjauninÄsim lÄ«guma temperatÅ«ru, izpildot set izmantojot web3 metodi 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;
});
}
TÄlÄk mÄs izmantojam web3 metodi call lai iegÅ«tu lÄ«guma temperatÅ«ru. LÅ«dzu, Åemiet vÄrÄ, ka metode call tiek izpildÄ«ts vietÄjÄ mezglÄ, un darÄ«jums netiks izveidots blokÄ·ÄdÄ.
// 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);
}
Tagad jÅ«s varat skriet public.js lai iegÅ«tu Å”Ädu rezultÄtu:
// Execute public script
node public.js
Contract address after deployment: 0xf46141Ac7D6D6E986eFb2321756b5d1e8a25008F
Transaction status: true
Retrieved contract Temperature 3
TÄlÄk mÄs varam skatÄ«t ierakstus Quorum Explorer panelÄ« Chainstack, kÄ parÄdÄ«ts zemÄk.
Visi trÄ«s mezgli mijiedarbojÄs, un darÄ«jumi tika atjauninÄti:
Pirmais darījums izvietoja līgumu.
OtrajÄ darÄ«jumÄ lÄ«guma temperatÅ«ra tika noteikta uz 3 grÄdiem.
TemperatÅ«ra tiek saÅemta caur lokÄlo mezglu, tÄpÄc transakcija netiek izveidota.
PrivÄtie darÄ«jumi
Konteksts
IzplatÄ«ta organizÄciju prasÄ«ba ir datu aizsardzÄ«ba. KÄ piemÄru apsveriet scenÄriju, kurÄ Lielveikals Ä«rÄ noliktavas telpu jÅ«ras velÅ”u uzglabÄÅ”anai no atseviŔķas PÄrdevÄjs:
PÄrdevÄjs izmantojot IoT sensorus, nolasa temperatÅ«ras vÄrtÄ«bas ik pÄc 30 sekundÄm un pÄrraida tÄs Uz lielveikalu;
Ŕīm vÄrtÄ«bÄm jÄbÅ«t tikai pieejamÄm PÄrdevÄjam Šø Uz lielveikalu, ko tÄ«klÄ izveidojis konsorcijs.
MÄs izpildÄ«sim Äetrus uzdevumus, kas parÄdÄ«ti diagrammÄ iepriekÅ”.
MÄs izmantojam tos paÅ”us trÄ«s mezglus no iepriekÅ”ÄjÄ scenÄrija, lai demonstrÄtu privÄtos darÄ«jumus:
Lielveikals izvieto viedo lÄ«gumu, kas ir privÄts Lielveikals Šø PÄrdevÄjs.
TreÅ”Ä puse nav tiesÄ«bu piekļūt viedajam lÄ«gumam.
MÄs sauksim metodes get Šø set vÄrdÄ Lielveikals Šø PÄrdevÄjs lai demonstrÄtu privÄtu Quorum darÄ«jumu.
IestatÄ«sim temperatÅ«ru no TreÅ”Ä ballÄ«te (ÄrÄjais mezgls) un iegÅ«stiet temperatÅ«ras vÄrtÄ«bu:
// 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}`);
IestatÄ«sim temperatÅ«ru no PÄrdevÄjs (iekÅ”Äjais mezgls) un iegÅ«stiet temperatÅ«ras vÄrtÄ«bu:
TemperatÅ«rai Å”ajÄ scenÄrijÄ ir jÄatgriež vÄrtÄ«ba 12 no viedÄ lÄ«guma. LÅ«dzu, Åemiet vÄrÄ to PÄrdevÄjs Å”eit ir autorizÄta piekļuve viedajam lÄ«gumam.
// 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}`);
MÄs iegÅ«stam temperatÅ«ru no TreÅ”Ä ballÄ«te (ÄrÄjais mezgls):
3. solÄ« temperatÅ«ra tika iestatÄ«ta uz 12, bet TreÅ”Ä puse nav piekļuves viedajam lÄ«gumam. TÄpÄc atgrieÅ”anas vÄrtÄ«bai jÄbÅ«t nullei.
// This returns null
const temp3 = await getTemperature(raft3Node, contractAddress);
console.log(`[Node3] temp retrieved from external nodes after update ${temp}`);
TÄlÄk mÄs sÄ«kÄk aplÅ«kosim privÄto darÄ«jumu veikÅ”anu Quorum tÄ«klÄ ar web3.js. TÄ kÄ publiskajiem darÄ«jumiem koda lielÄkÄ daļa ir vienÄda, mÄs izcelsim tikai tÄs daļas, kas atŔķiras privÄtajiem darÄ«jumiem.
Å emiet vÄrÄ, ka tÄ«klÄ augÅ”upielÄdÄtais lÄ«gums ir nemainÄ«gs, tÄpÄc attiecÄ«gajiem mezgliem ir jÄpieŔķir atļauta piekļuve, iespÄjojot publisko lÄ«gumu lÄ«guma izvietoÅ”anas laikÄ, nevis pÄc tÄ.
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;
});
}
PrivÄtie darÄ«jumi tiek veikti lÄ«dzÄ«gi ā izpildes brÄ«dÄ« iekļaujot dalÄ«bnieku publisko atslÄgu.
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;
});
}
Tagad mÄs varam skriet private.js ar Å”Ädiem rezultÄtiem:
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
Quorum Explorer programmÄ Chainstack parÄdÄ«s tÄlÄk norÄdÄ«to.
līguma izvietoŔana no dalībnieka Lielveikals;
PiepildÄ«jums SetTemperature no TreÅ”Ä ballÄ«te;
PiepildÄ«jums SetTemperature no dalÄ«bnieka PÄrdevÄjs.
KÄ redzat, abi darÄ«jumi ir pabeigti, bet tikai darÄ«jums no dalÄ«bnieka PÄrdevÄjs atjauninÄja temperatÅ«ru lÄ«gumÄ. TÄdÄjÄdi privÄtie darÄ«jumi nodroÅ”ina nemainÄ«gumu, bet tajÄ paÅ”Ä laikÄ neatklÄj datus treÅ”ajai personai.
SecinÄjums
MÄs izskatÄ«jÄm Quorum komerciÄlas izmantoÅ”anas gadÄ«jumu, lai nodroÅ”inÄtu jaunÄko informÄciju par temperatÅ«ru noliktavÄ, izvietojot tÄ«klu starp divÄm pusÄm ā lielveikalu un noliktavas Ä«paÅ”nieku.
MÄs parÄdÄ«jÄm, kÄ atjauninÄtu informÄciju par temperatÅ«ru var uzturÄt gan publiskos, gan privÄtos darÄ«jumos.
Lietojumprogrammu scenÄriju var bÅ«t daudz, un, kÄ redzat, tas nepavisam nav grÅ«ti.