
â une blockchain basĂ©e sur Ethereum, dĂ©veloppĂ©e par JPMorgan et rĂ©cemment devenue la premiĂšre plateforme de registre distribuĂ© proposĂ©e par Microsoft Azure.
Quorum prend en charge les transactions privées et publiques et possÚde de nombreux scénarios commerciaux d'utilisation.
Dans cet article, nous examinerons l'un de ces scénarios : le déploiement d'un réseau de registre distribué entre un supermarché et un propriétaire d'entrepÎt pour garantir des informations actualisées sur la température de l'entrepÎt.
Le code utilisé dans ce guide se trouve dans .
L'article couvre :
- la création d'un contrat intelligent ;
- le déploiement d'un réseau Quorum à l'aide de ;
- les transactions publiques de Quorum ;
- les transactions privées de Quorum.
Pour illustrer, nous utilisons un scénario de surveillance de la température dans les entrepÎts des membres du réseau Quorum dans le cadre de l'Internet des Objets (IoT).
Contexte
Un groupe d'entreprises de stockage se regroupe en consortium pour partager des informations et automatiser des processus sur la blockchain. Pour cela, les entreprises ont décidé d'utiliser Quorum. Dans cet article, nous couvrirons deux scénarios : les transactions publiques et les transactions privées.
Les transactions sont créées par diffĂ©rents participants pour interagir avec le consortium auquel ils appartiennent. Chaque transaction dĂ©ploie soit un contrat, soit appelle une fonction dans le contrat pour charger des donnĂ©es sur le rĂ©seau. Ces actions sont rĂ©pliquĂ©es sur tous les nĆuds du rĂ©seau.
Les transactions publiques sont accessibles à tous les membres du consortium. En revanche, les transactions privées ajoutent une couche de confidentialité et ne sont accessibles qu'aux participants ayant les droits appropriés.
Pour les deux scĂ©narios, nous utilisons le mĂȘme contrat pour plus de clartĂ©.
Contrat intelligent
Voici un simple contrat intelligent créé pour notre scénario. Il contient une variable publique temperature, que l'on peut modifier avec la méthode set et obtenir avec la méthode obtenir.
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;
}
}Pour que le contrat fonctionne avec , il doit ĂȘtre converti en format ABI et bytecode. L'utilisation de la fonction formatContract, ci-dessous, compile le contrat Ă l'aide de .
function formatContract() {
const path = '.\/contracts\/temperatureMonitor.sol';
const source = fs.readFileSync(path,'UTF8');
return solc.compile(source, 1).contracts[':TemperatureMonitor'];
}Le contrat final ressemble Ă ceci :
// 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
0x608060405234801561001057600080fd5b50610104806100206000396000f30060806040526004361060525763ffffffff7c01000000000000000000000000000000000000000000000000000000006000350416636d4ce63c81146057578063adccea12146082578063faee13b9146094575b600080fd5b348015606257600080fd5b50606960ae565b60408051600092830b90920b8252519081900360200190f35b348015608d57600080fd5b50606960b7565b348015609f57600080fd5b5060ac60043560000b60c0565b005b60008054900b90565b60008054900b81565b6000805491810b60ff1660ff199092169190911790555600a165627a7a72305820af0086d55a9a4e6d52cb6b3967afd764ca89df91b2f42d7bf3b30098d222e5c50029Maintenant que le contrat est prĂȘt, nous allons dĂ©ployer le rĂ©seau et dĂ©ployer le contrat.
DĂ©ploiement de nĆuds

Le dĂ©ploiement d'un nĆud peut ĂȘtre assez laborieux et ce processus peut ĂȘtre remplacĂ© par l'utilisation d'un service .
Voici le processus de dĂ©ploiement du rĂ©seau Quorum avec le consensus Raft et trois nĆuds.
Pour commencer, créons un projet et nommons-le Projet Quorum :

Créons un réseau Quorum avec le consensus Raft sur Google Cloud Platform :

Nous ajouterons deux nĆuds supplĂ©mentaires au nĆud par dĂ©faut dĂ©jĂ créé :

Trois nĆuds en cours d'exĂ©cution :

La page de dĂ©tails du nĆud affiche le point de terminaison RPC, la clĂ© publique, etc.

Le réseau est déployé. Passons maintenant au déploiement des contrats intelligents et à l'exécution des transactions avec .
Transactions publiques
Contexte
La tempĂ©rature de l'entrepĂŽt est essentielle pour rĂ©duire les coĂ»ts, en particulier pour les produits devant ĂȘtre conservĂ©s Ă des tempĂ©ratures infĂ©rieures Ă zĂ©ro.
En permettant aux entreprises de partager les valeurs de température externe de leur localisation géographique en temps réel et de les enregistrer dans un registre immuable, les participants au réseau réduisent les coûts et le temps.

Nous allons accomplir trois tùches illustrées sur le diagramme :
Nous dĂ©ploierons le contrat via NĆud 1:
const contractAddress = await deployContract(raft1Node); console.log(`Adresse du contrat aprĂšs dĂ©ploiement : ${contractAddress}`);Nous Ă©tablirons la tempĂ©rature via NĆud 2 Ă 3 degrĂ©s :
const status = await setTemperature(raft2Node, contractAddress, 3); console.log(`Statut de la transaction : ${status}`);NĆud 3 obtiendra des informations du contrat intelligent. Le contrat renverra la valeur de 3 degrĂ©s :
const temp = await getTemperature(raft3Node, contractAddress); console.log('Température récupérée du contrat', temp);Voyons maintenant comment exécuter une transaction publique sur le réseau Quorum en utilisant .
Nous initierons une instance via RPC pour trois nĆuds :
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,
},
);Déployons le smart contract :
// 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;
});
} fournit deux méthodes pour interagir avec le contrat : call et send.
Nous mettrons à jour la température du contrat en exécutant set en utilisant la méthode 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;
});
}Ensuite, nous utiliserons la mĂ©thode web3 call pour obtenir la tempĂ©rature du contrat. Notez que la mĂ©thode call s'exĂ©cute sur le nĆud local et qu'aucune transaction ne sera créée sur la 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);
}Vous pouvez maintenant exécuter pour obtenir le résultat suivant :
// Execute public script
node public.js
Contract address after deployment: 0xf46141Ac7D6D6E986eFb2321756b5d1e8a25008F
Transaction status: true
Retrieved contract Temperature 3Nous pouvons ensuite examiner les enregistrements dans l'explorateur Quorum sur le panneau Chainstack, comme indiqué ci-dessous.
Les trois nĆuds ont interagi et les transactions ont Ă©tĂ© mises Ă jour :
- La premiÚre transaction a déployé le contrat.
- La deuxiÚme transaction a défini la température du contrat à 3 degrés.
- La rĂ©cupĂ©ration de la tempĂ©rature se fait via le nĆud local, donc aucune transaction n'est créée.

Transactions privées
Contexte
Une demande frĂ©quente des organisations est la protection des donnĂ©es. Prenons comme exemple un scĂ©nario oĂč un supermarchĂ© loue un espace d'entrepĂŽt pour stocker des fruits de mer auprĂšs d'un fournisseur:
- Nombre de blocs/enregistrements qui, à l'aide de capteurs IoT, lit les valeurs de température toutes les 30 secondes et les transmet au supermarché.;
- Ces valeurs doivent ĂȘtre accessibles uniquement au fournisseur. et au supermarchĂ©,qui est regroupĂ© en un consortium.

Nous allons accomplir quatre tùches, illustrées dans le diagramme ci-dessus.
- Nous utiliserons les mĂȘmes trois nĆuds que dans le scĂ©nario prĂ©cĂ©dent pour dĂ©montrer les transactions privĂ©es :
- Le supermarché déploie un contrat intelligent, qui est privé pour le supermarché. et fournisseur.
- Une tierce partie n'a pas accĂšs au contrat intelligent.
Nous appellerons des méthodes obtenir et set au nom de le supermarché. et fournisseur pour démontrer une transaction privée Quorum.
Nous allons déployer un contrat privé pour les participants Le supermarché et Nombre de blocs/enregistrements via le participant Le supermarché:
const contractAddress = await deployContract( raft1Node, process.env.PK2, ); console.log(`Adresse du contrat aprĂšs le dĂ©ploiement : ${contractAddress}`);Nous dĂ©finirons la tempĂ©rature de la tierce partie (nĆud externe) et obtiendrons la valeur de tempĂ©rature :
// 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}`);Nous dĂ©finirons la tempĂ©rature de fournisseur (nĆud interne) et obtiendrons la valeur de tempĂ©rature :
La température dans ce scénario devrait retourner une valeur de 12 du contrat intelligent. Notez que Nombre de blocs/enregistrements ici a un accÚs autorisé au contrat intelligent.
// 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}`);Nous obtiendrons la tempĂ©rature de la tierce partie (nĆud externe) :
Ă l'Ă©tape 3, la tempĂ©rature a Ă©tĂ© dĂ©finie Ă 12, mais Une tierce partie n'a pas accĂšs au contrat intelligent. Par consĂ©quent, la valeur retournĂ©e doit ĂȘtre null.
// This returns null const temp3 = await getTemperature(raft3Node, contractAddress); console.log(`[Node3] temp retrieved from external nodes after update ${temp}`);Nous examinerons plus en détail l'exécution des transactions privées sur le réseau Quorum avec . Comme la majeure partie du code correspond aux transactions publiques, mettons en évidence uniquement les parties qui diffÚrent pour les transactions privées.
Veuillez noter que le contrat tĂ©lĂ©chargĂ© sur la chaĂźne est immuable, de sorte que l'accĂšs avec autorisation (permissioned) doit ĂȘtre accordĂ© aux nĆuds correspondants en incluant le contrat public au moment du dĂ©ploiement du contrat, et non aprĂšs.
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',
// Accorder l'autorisation au contrat en incluant les clĂ©s publiques des nĆuds
privateFor: [publicKey],
})
.then((contract) => {
return contract.options.address;
});
}De la mĂȘme maniĂšre, les transactions privĂ©es sont exĂ©cutĂ©es â en incluant la clĂ© publique des participants au moment de l'exĂ©cution.
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,
// Accorder l'autorisation en incluant les clĂ©s publiques des nĆuds
privateFor: [publicKey],
}).then((receipt) => {
return receipt.status;
});
}Nous pouvons maintenant démarrer avec les résultats suivants :
node private.js
Adresse du contrat aprÚs déploiement : 0x85dBF88B4dfa47e73608b33454E4e3BA2812B21D
[NĆud3] temp rĂ©cupĂ©rĂ©e aprĂšs mise Ă jour du contrat depuis des nĆuds externes : null
[NĆud2] temp rĂ©cupĂ©rĂ©e aprĂšs mise Ă jour du contrat depuis des nĆuds internes : 12
[NĆud3] temp rĂ©cupĂ©rĂ©e depuis des nĆuds externes aprĂšs mise Ă jour nullL'explorateur Quorum dans Chainstack affichera ce qui suit :
- déploiement du contrat par un participant Le supermarché;
- Exécution
SetTemperatureà partir de la tierce partie; - Exécution
SetTemperaturepar un participant Nombre de blocs/enregistrements.

Comme vous pouvez le voir, les deux transactions ont été exécutées, mais seule la transaction d'un participant Nombre de blocs/enregistrements a mis à jour la température dans le contrat. Ainsi, les transactions privées garantissent l'immutabilité, mais ne divulguent pas les données à un tiers.
Conclusion
Nous avons examinĂ© un scĂ©nario commercial d'utilisation de Quorum pour garantir des informations actualisĂ©es sur la tempĂ©rature dans un entrepĂŽt en dĂ©ployant un rĂ©seau entre deux parties â un supermarchĂ© et un propriĂ©taire d'entrepĂŽt.
Nous avons montrĂ© comment des informations actualisĂ©es sur la tempĂ©rature peuvent ĂȘtre maintenues Ă la fois par des transactions publiques et privĂ©es.
Il peut y avoir de nombreux scénarios d'application et, comme vous pouvez le voir, ce n'est pas si compliqué.
Expérimentez, essayez de déployer votre scénario. D'autant plus que l'industrie des technologies blockchain .
Source : habr.com
