ProHoster > Blog > administration > Udfør offentlige og private transaktioner på JPMorgan Quorum blockchain ved hjælp af Web3
Udfør offentlige og private transaktioner på JPMorgan Quorum blockchain ved hjælp af Web3
Beslutningsdygtighed er en Ethereum-baseret blockchain udviklet af JPMorgan og blev senest den første distribuerede hovedbogsplatform, der tilbydes af Microsoft Azure.
Quorum understøtter private og offentlige transaktioner og har mange kommercielle brugssager.
I denne artikel vil vi undersøge et sådant scenarie - udrulningen af et distribueret hovedbogsnetværk mellem et supermarked og en lagerejer for at give ajourførte oplysninger om temperaturen på lageret.
For at illustrere bruger vi et scenarie til at overvåge temperaturen i lagre hos medlemmer af Quorum-netværket inden for tingenes internet (IoT).
kontekst
En gruppe lagervirksomheder går sammen i et konsortium for i fællesskab at lagre information og automatisere processer på blockchain. Til dette besluttede virksomheder at bruge Quorum. I denne artikel vil vi dække to scenarier: offentlige transaktioner og private transaktioner.
Transaktioner oprettes af forskellige deltagere for at interagere med det konsortium, de tilhører. Hver transaktion implementerer enten en kontrakt eller kalder en funktion i kontrakten for at uploade data til netværket. Disse handlinger replikeres til alle noder på netværket.
Offentlige transaktioner er tilgængelige for visning af alle konsortiets deltagere. Private transaktioner tilføjer et lag af fortrolighed og er kun tilgængelige for de deltagere, der har rettigheder til at gøre det.
For begge scenarier bruger vi den samme kontrakt for klarhedens skyld.
Smart kontrakt
Nedenfor er en simpel smart kontrakt oprettet til vores scenarie. Den har en offentlig variabel temperature, som kan ændres vha set og modtage efter metode 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;
}
}
For at kontrakten kan arbejde med web3.js, skal den oversættes til ABI-format og bytekode. Brug af funktionen formatContractnedenfor samler kontrakten vha solc-js.
Nu hvor kontrakten er klar, vil vi implementere netværket og implementere kontrakten.
Node-implementering
Implementering af en node kan være ret arbejdskrævende, og denne proces kan erstattes ved at bruge en tjeneste Chainstack.
Nedenfor er processen for implementering af Quorum-netværket med Raft-konsensus og tre noder.
Lad os først oprette et projekt og kalde det Quorum Project:
Lad os skabe et Quorum-netværk med Raft-konsensus på Google Cloud Platform:
Lad os tilføje yderligere to noder til den node, der allerede er oprettet som standard:
Tre kørende noder:
Siden med nodedetaljer viser RPC-slutpunktet, den offentlige nøgle osv.
Netværket er installeret. Lad os nu implementere smarte kontrakter og udføre transaktioner ved hjælp af web3.js.
Offentlige transaktioner
kontekst
Lagertemperaturen er af stor betydning for at reducere omkostningerne, især for produkter beregnet til at blive opbevaret ved minusgrader.
Ved at give virksomheder mulighed for at dele udetemperaturen på deres geografiske placering i realtid og registrere den i en uforanderlig hovedbog, reducerer netværksdeltagere omkostninger og tid.
Vi vil udføre tre opgaver, illustreret i diagrammet:
Vi vil implementere kontrakten via Node 1:
const contractAddress = await deployContract(raft1Node);
console.log(`Contract address after deployment: ${contractAddress}`);
Indstil temperaturen via Node 2 med 3 grader:
const status = await setTemperature(raft2Node, contractAddress, 3);
console.log(`Transaction status: ${status}`);
Node 3 vil modtage information fra den smarte kontrakt. Kontrakten vil returnere værdien 3 grader:
Dernæst vil vi se på, hvordan man udfører en offentlig transaktion på Quorum-netværket ved hjælp af web3.js.
Vi starter en instans via RPC for tre noder:
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,
},
);
Lad os implementere den smarte kontrakt:
// 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 giver to metoder til at interagere med kontrakten: call и send.
Lad os opdatere kontrakttemperaturen ved at udføre set ved hjælp af web3-metoden 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;
});
}
Dernæst bruger vi web3-metoden call for at opnå kontrakttemperaturen. Bemærk venligst, at metoden call udføres på en lokal node, og transaktionen vil ikke blive oprettet på blockchain.
// 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);
}
Nu kan du løbe public.js for at få følgende resultat:
// Execute public script
node public.js
Contract address after deployment: 0xf46141Ac7D6D6E986eFb2321756b5d1e8a25008F
Transaction status: true
Retrieved contract Temperature 3
Dernæst kan vi se posterne i Quorum Explorer i Chainstack-panelet, som vist nedenfor.
Alle tre noder interagerede, og transaktionerne blev opdateret:
Den første transaktion implementerede kontrakten.
Den anden transaktion satte kontrakttemperaturen til 3 grader.
Temperaturen modtages gennem en lokal node, så der oprettes ingen transaktion.
Private transaktioner
kontekst
Et almindeligt krav fra organisationer er databeskyttelse. Som et eksempel kan du overveje et scenarie, hvor Supermarked lejer en lagerplads til opbevaring af fisk og skaldyr fra en separat Sælger:
Sælger ved hjælp af IoT-sensorer, læser temperaturværdier hvert 30. sekund og sender dem Til supermarkedet;
disse værdier bør kun være tilgængelige Til sælgeren и Til supermarkedet, netværket af et konsortium.
Vi vil fuldføre de fire opgaver, der er illustreret i diagrammet ovenfor.
Vi bruger de samme tre noder fra det forrige scenario til at demonstrere private transaktioner:
Supermarked implementerer en smart kontrakt, der er privat til Supermarked и Sælger.
Den tredje side har ikke ret til at få adgang til den smarte kontrakt.
Vi vil kalde metoderne get и set på vegne af Supermarked и Sælger at demonstrere en privat Quorum-transaktion.
Vi vil implementere en privat kontrakt for deltagerne Supermarked и Sælger gennem en deltager Supermarked:
Lad os indstille temperaturen fra Tredje part (ekstern knude) og få temperaturværdien:
// 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}`);
Lad os indstille temperaturen fra Sælger (intern knude) og få temperaturværdien:
Temperaturen i dette scenarie skulle returnere værdien 12 fra den smarte kontrakt. Bemærk venligst at Sælger her har autoriseret adgang til den smarte kontrakt.
// 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}`);
Vi får temperaturen fra Tredje part (ekstern knude):
I trin 3 blev temperaturen sat til 12, men Den tredje side ikke har adgang til den smarte kontrakt. Derfor skal returværdien være null.
// This returns null
const temp3 = await getTemperature(raft3Node, contractAddress);
console.log(`[Node3] temp retrieved from external nodes after update ${temp}`);
Dernæst vil vi se nærmere på at udføre private transaktioner på Quorum-netværket med web3.js. Da det meste af koden er den samme for offentlige transaktioner, vil vi kun fremhæve de dele, der er forskellige for private transaktioner.
Bemærk, at kontrakten, der uploades til netværket, er uforanderlig, så der skal gives tilladelse til de relevante noder ved at aktivere den offentlige kontrakt på det tidspunkt, kontrakten implementeres, ikke efter.
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;
});
}
Private transaktioner udføres på lignende måde - ved at inkludere deltagernes offentlige nøgle på tidspunktet for udførelsen.
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;
});
}
Nu kan vi løbe private.js med følgende resultater:
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 i Chainstack vil vise følgende:
implementering af kontrakten fra deltageren Supermarked;
udførelse SetTemperature fra Tredje part;
udførelse SetTemperature fra en deltager Sælger.
Som du kan se, er begge transaktioner gennemført, men kun transaktionen fra deltageren Sælger opdateret temperaturen i kontrakten. Private transaktioner giver således uforanderlighed, men afslører samtidig ikke data til en tredjepart.
Konklusion
Vi så på en kommerciel brugssag for Quorum til at levere ajourførte temperaturoplysninger på et lager ved at implementere et netværk mellem to parter - et supermarked og en lagerejer.
Vi viste, hvordan opdaterede temperaturoplysninger kan opretholdes gennem både offentlige og private transaktioner.
Der kan være mange anvendelsesscenarier, og som du kan se, er det slet ikke svært.