تنفيذ المعاملات العامة والخاصة على JPMorgan Quorum blockchain باستخدام Web3



Quorum هي عبارة عن blockchain قائمة على Ethereum تم تطويرها بواسطة JPMorgan وأصبحت مؤخرًا أول منصة تسجيل موزعة توفرها Microsoft Azure.


النصاب يدعم المعاملات الخاصة والعامة وله العديد من حالات الاستخدام التجاري.


في هذه المقالة ، سنقوم بتحليل أحد هذه السيناريوهات - نشر شبكة تسجيل موزعة بين سوبر ماركت ومالك المستودع لتوفير المعلومات ذات الصلة حول درجة حرارة المستودع.


الكود المستخدم في هذا الدليل يكمن في المستودع على جيثب .


يغطي المقال:


  • إنشاء عقد ذكي ؛
  • نشر شبكة النصاب باستخدام Chainstack
  • النصاب القانوني للمعاملات العامة
  • النصاب القانوني للمعاملات الخاصة.

لتوضيح ذلك ، نستخدم سيناريو مراقبة درجة الحرارة في غرف التخزين للمشاركين في شبكة النصاب كجزء من إنترنت الأشياء (IoT).


السياق


تتحد مجموعة من شركات المستودعات في كونسورتيوم للتخزين المشترك للمعلومات وأتمتة العمليات على blockchain. لهذا ، قررت الشركات استخدام النصاب القانوني. في هذه المقالة ، سنغطي سيناريوهين: المعاملات العامة والمعاملات الخاصة.


يتم إنشاء المعاملات من قبل مشاركين مختلفين للتفاعل مع الاتحاد الذي ينتمون إليه. كل معاملة تنشر عقدًا أو تستدعي وظيفة في عقد لتحميل البيانات إلى الشبكة. يتم نسخ هذه الإجراءات إلى جميع العقد في الشبكة.


المعاملات العامة متاحة للعرض من قبل جميع أعضاء الكونسورتيوم. تضيف المعاملات الخاصة طبقة من السرية وهي متاحة فقط لأولئك المشاركين الذين لديهم حقوق في ذلك.


لكلا السيناريوهين ، نستخدم نفس العقد للتوضيح.


عقد ذكي


يوجد أدناه عقد ذكي بسيط تم إنشاؤه لسيناريونا. يحتوي على temperature متغيرة عامة ، والتي يمكن تغييرها باستخدام طريقة set واسترجاعها بواسطة طريقة 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; } } 

لكي يعمل العقد مع web3.js ، يجب تحويله إلى تنسيق ABI و bytecode. يؤدي استخدام دالة formatContract أدناه إلى ترجمة العقد باستخدام solc-js .


 function formatContract() { const path = './contracts/temperatureMonitor.sol'; const source = fs.readFileSync(path,'UTF8'); return solc.compile(source, 1).contracts[':TemperatureMonitor']; } 

العقد النهائي على النحو التالي:


 // 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 

الآن بعد أن أصبح العقد جاهزًا ، سنقوم بنشر الشبكة ونشر العقد.


نشر العقدة


صورة


يمكن أن يستغرق نشر العقدة وقتًا طويلاً ويمكن استبدال هذه العملية باستخدام خدمة Chainstack .


التالي هو عملية نشر شبكة حصة مع إجماع رافت وثلاث عقد.


للبدء ، دعونا نبدأ مشروعًا ونطلق عليه مشروع النصاب:


صورة


إنشاء شبكة حصة مع إجماع Raft على Google Cloud Platform:


صورة


إلى العقدة الافتراضية التي تم إنشاؤها بالفعل ، أضف عقدتين أخريين:


صورة


ثلاثة العقد قيد التشغيل:


صورة


تعرض صفحة تفاصيل العقدة نقطة نهاية RPC أو المفتاح العمومي ، إلخ.


صورة


تم نشر الشبكة. سنقوم الآن بنشر العقود الذكية وتنفيذ المعاملات باستخدام web3.js.


المعاملات العامة


السياق


تتسم درجة حرارة المستودع بأهمية كبيرة لخفض التكاليف ، خاصة بالنسبة للمنتجات المخصصة للتخزين في درجات حرارة دون الصفر.


من خلال منح الشركات القدرة على مشاركة قيم الوقت الفعلي لدرجة الحرارة الخارجية لموقعها الجغرافي وتسجيلها في سجل ثابت ، يعمل أعضاء الشبكة على تقليل التكاليف والوقت.


صورة


سنكمل المهام الثلاث الموضحة في المخطط:


  1. سننهي العقد من خلال العقدة 1 :


     const contractAddress = await deployContract(raft1Node); console.log(`Contract address after deployment: ${contractAddress}`); 

  2. ضبط درجة الحرارة من خلال العقدة 2 إلى 3 درجات:


     const status = await setTemperature(raft2Node, contractAddress, 3); console.log(`Transaction status: ${status}`); 

  3. ستتلقى العقدة 3 معلومات من العقد الذكي. سيعود العقد بقيمة 3 درجات:


     const temp = await getTemperature(raft3Node, contractAddress); console.log('Retrieved contract Temperature', temp); 

    بعد ذلك ، سننظر في كيفية تنفيذ معاملة عامة على شبكة النصاب باستخدام web3.js.



نبدأ مثيل عبر RPC لثلاث عقد:


 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, }, ); 

تدمير العقد الذكي:


 // 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 طريقتين للتفاعل مع العقد: call والإرسال .


قم بتحديث درجة حرارة العقد عن طريق تنفيذ set باستخدام طريقة send web3.


 // 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; }); } 

بعد ذلك ، نستخدم طريقة call web3 للحصول على درجة حرارة العقد. يرجى ملاحظة أنه يتم تنفيذ طريقة call على العقدة المحلية ولن يتم إنشاء المعاملة على 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); } 

يمكنك الآن تشغيل public.js للحصول على النتيجة التالية:


 // Execute public script node public.js Contract address after deployment: 0xf46141Ac7D6D6E986eFb2321756b5d1e8a25008F Transaction status: true Retrieved contract Temperature 3 

بعد ذلك ، يمكننا أن نرى الإدخالات في مستكشف الحصة في لوحة Chainstack ، كما هو موضح أدناه.


تفاعلت العقد الثلاثة وتم تحديث المعاملات:


  1. الصفقة الأولى حصلت على عقد.
  2. الصفقة الثانية ضبط درجة حرارة العقد إلى 3 درجات.
  3. يتم الحصول على درجة الحرارة من خلال العقدة المحلية ، لذلك لم يتم إنشاء المعاملة.

صورة


المعاملات الخاصة


السياق


من المتطلبات الشائعة للمنظمات حماية البيانات. على سبيل المثال ، ضع في الاعتبار سيناريو يستأجر فيه سوبر ماركت مستودعًا لتخزين المأكولات البحرية من بائع منفصل:


  • يقوم البائع بمساعدة مستشعر إنترنت الأشياء بقراءة قيم درجة الحرارة كل 30 ثانية ويمررها إلى السوبر ماركت ؛
  • يجب أن تكون هذه القيم متاحة فقط للبائعين والسوبر ماركت ، وهو اتحاد متصل بالشبكة.

صورة


سنكمل المهام الأربع الموضحة في الرسم البياني أعلاه.


  • نستخدم نفس العقد الثلاثة من السيناريو السابق لإظهار المعاملات الخاصة:
  • يقوم السوبر ماركت بنشر عقد ذكي خاص بالسوبر ماركت والبائع .
  • لا يملك طرف ثالث الوصول إلى العقد الذكي.

سوف ندعو إلى get set أساليب نيابة عن السوبر ماركت والمورد لإظهار معاملة النصاب الخاصة.


  1. سننهي العقد الخاص للمشاركين في السوبر ماركت والبائعين من خلال المشارك في السوبر ماركت :


     const contractAddress = await deployContract( raft1Node, process.env.PK2, ); console.log(`Contract address after deployment: ${contractAddress}`); 

  2. اضبط درجة الحرارة من الطرف الثالث (العقدة الخارجية) واحصل على قيمة درجة الحرارة:


     // 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}`); 

  3. اضبط درجة الحرارة من المورد (العقدة الداخلية) واحصل على قيمة درجة الحرارة:


    يجب أن تُرجع درجة الحرارة في هذا السيناريو قيمة 12 من العقد الذكي. يرجى ملاحظة أن البائع هنا قد سمح بالوصول إلى العقد الذكي.


     // 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}`); 

  4. الحصول على درجة الحرارة من الطرف الثالث (العقدة الخارجية):


    في الخطوة 3 ، تم ضبط درجة الحرارة على 12 ، لكن الطرف الثالث لا يستطيع الوصول إلى العقد الذكي. لذلك ، يجب أن تكون قيمة الإرجاع خالية.


     // This returns null const temp3 = await getTemperature(raft3Node, contractAddress); console.log(`[Node3] temp retrieved from external nodes after update ${temp}`); 

    بعد ذلك ، سننظر بتفصيل أكبر في تنفيذ المعاملات الخاصة على شبكة النصاب باستخدام web3.js. نظرًا لأن معظم الكود يتزامن مع المعاملات العامة ، فإننا نختار فقط الأجزاء المختلفة للمعاملات الخاصة.



يرجى ملاحظة أن العقد الذي تم تحميله على الشبكة غير قابل للتغيير ، وبالتالي يجب منح الوصول بإذن إلى العقد المقابلة عن طريق تضمين العقد العام في وقت نشر العقد ، وليس بعده.


 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; }); } 

تتم المعاملات الخاصة بنفس الطريقة - من خلال تضمين المفتاح العمومي للمشاركين في وقت التنفيذ.


 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; }); } 

الآن يمكننا تشغيل private.js بالنتائج التالية:


 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 

يعرض مستكشف النصاب في Chainstack ما يلي:


  • نشر عقد من أحد المشاركين في سوبر ماركت ؛
  • أداء SetTemperature من طرف ثالث ؛
  • تنفيذ SetTemperature من مشارك بائع .

صورة


كما ترى ، تم إكمال كلتا المعاملتين ، لكن المعاملة من البائع المشارك فقط هي التي قامت بتحديث درجة الحرارة في العقد. وبالتالي ، توفر المعاملات الخاصة ثباتًا ، لكنها في الوقت نفسه لا توفر بيانات لطرف ثالث.


استنتاج


درسنا السيناريو التجاري لاستخدام النصاب القانوني لتوفير معلومات محدثة عن درجة الحرارة في أحد المستودعات عن طريق نشر شبكة بين طرفين - سوبر ماركت ومالك المستودع.


لقد أظهرنا كيف يمكن الحفاظ على معلومات درجة الحرارة الحالية من خلال المعاملات العامة والخاصة.


يمكن أن يكون هناك الكثير من سيناريوهات التطبيق ، وكما ترى ، هذا ليس بالأمر الصعب على الإطلاق.


التجربة ، حاول نشر البرنامج النصي الخاص بك. علاوة على ذلك ، يمكن أن تنمو صناعة تكنولوجيا blockchain ما يقرب من عشر مرات بحلول عام 2024

Source: https://habr.com/ru/post/ar456368/


All Articles