تراکنش های عمومی و خصوصی را در بلاک چین JPMorgan Quorum با استفاده از Web3 انجام دهید

تراکنش های عمومی و خصوصی را در بلاک چین JPMorgan Quorum با استفاده از Web3 انجام دهید

کوروم یک بلاک چین مبتنی بر اتریوم است که توسط JPMorgan توسعه یافته است و اخیراً اولین پلتفرم دفتر کل توزیع شده است که توسط Microsoft Azure ارائه شده است.

Quorum از معاملات خصوصی و عمومی پشتیبانی می کند و موارد استفاده تجاری زیادی دارد.

در این مقاله، یکی از این سناریوها را بررسی خواهیم کرد - استقرار یک شبکه دفتر کل توزیع شده بین یک سوپرمارکت و یک صاحب انبار برای ارائه اطلاعات به روز در مورد دمای انبار.

کد استفاده شده در این آموزش به صورت in است مخازن در GitHub.

مقاله شامل موارد زیر است:

  • ایجاد یک قرارداد هوشمند؛
  • استقرار شبکه Quorum با استفاده از زنجیر چرخ;
  • حد نصاب معاملات عمومی؛
  • حد نصاب معاملات خصوصی

برای نشان دادن، ما از سناریویی برای نظارت بر دما در انبارهای اعضای شبکه Quorum در اینترنت اشیا (IoT) استفاده می کنیم.

متن نوشته

گروهی از شرکت‌های انبار در حال متحد شدن در کنسرسیومی هستند تا به طور مشترک اطلاعات را ذخیره کنند و فرآیندها را روی بلاک چین خودکار کنند. برای این کار، شرکت ها تصمیم گرفتند از Quorum استفاده کنند. در این مقاله به دو سناریو خواهیم پرداخت: معاملات عمومی و معاملات خصوصی.

تراکنش ها توسط شرکت کنندگان مختلف برای تعامل با کنسرسیومی که به آن تعلق دارند ایجاد می شوند. هر تراکنش یا قراردادی را مستقر می کند یا تابعی را در قرارداد برای آپلود داده ها در شبکه فراخوانی می کند. این اقدامات در تمام گره های شبکه تکرار می شود.

معاملات عمومی برای مشاهده توسط همه شرکت کنندگان کنسرسیوم در دسترس است. تراکنش‌های خصوصی لایه‌ای از محرمانگی را اضافه می‌کنند و فقط برای شرکت‌کنندگانی در دسترس است که حق انجام این کار را دارند.

برای هر دو سناریو، ما از یک قرارداد برای وضوح استفاده می کنیم.

قرارداد هوشمند

در زیر یک قرارداد هوشمند ساده برای سناریوی ما ایجاد شده است. یک متغیر عمومی دارد 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 و بایت کد ترجمه شود. با استفاده از تابع 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
0x608060405234801561001057600080fd5b50610104806100206000396000f30060806040526004361060525763ffffffff7c01000000000000000000000000000000000000000000000000000000006000350416636d4ce63c81146057578063adccea12146082578063faee13b9146094575b600080fd5b348015606257600080fd5b50606960ae565b60408051600092830b90920b8252519081900360200190f35b348015608d57600080fd5b50606960b7565b348015609f57600080fd5b5060ac60043560000b60c0565b005b60008054900b90565b60008054900b81565b6000805491810b60ff1660ff199092169190911790555600a165627a7a72305820af0086d55a9a4e6d52cb6b3967afd764ca89df91b2f42d7bf3b30098d222e5c50029

اکنون که قرارداد آماده است، شبکه را مستقر کرده و قرارداد را مستقر می کنیم.

استقرار گره

تراکنش های عمومی و خصوصی را در بلاک چین JPMorgan Quorum با استفاده از Web3 انجام دهید

استقرار یک گره می تواند کاملاً کار فشرده باشد و این فرآیند را می توان با استفاده از یک سرویس جایگزین کرد زنجیر چرخ.

در زیر فرآیند استقرار شبکه Quorum با اجماع Raft و سه گره آورده شده است.

ابتدا بیایید یک پروژه ایجاد کنیم و آن را Quorum Project بنامیم:

تراکنش های عمومی و خصوصی را در بلاک چین JPMorgan Quorum با استفاده از Web3 انجام دهید

بیایید یک شبکه Quorum با اجماع Raft در Google Cloud Platform ایجاد کنیم:

تراکنش های عمومی و خصوصی را در بلاک چین JPMorgan Quorum با استفاده از Web3 انجام دهید

بیایید دو گره دیگر به گره ای که قبلاً به طور پیش فرض ایجاد شده است اضافه کنیم:

تراکنش های عمومی و خصوصی را در بلاک چین JPMorgan Quorum با استفاده از Web3 انجام دهید

سه گره در حال اجرا:

تراکنش های عمومی و خصوصی را در بلاک چین JPMorgan Quorum با استفاده از Web3 انجام دهید

صفحه جزئیات گره، نقطه پایانی RPC، کلید عمومی و غیره را نشان می دهد.

تراکنش های عمومی و خصوصی را در بلاک چین JPMorgan Quorum با استفاده از Web3 انجام دهید

شبکه مستقر شده است. اکنون بیایید قراردادهای هوشمند را مستقر کنیم و با استفاده از آن تراکنش ها را انجام دهیم web3.js.

معاملات عمومی

متن نوشته

دمای انبار در کاهش هزینه ها به ویژه برای محصولاتی که قرار است در دمای زیر صفر نگهداری شوند اهمیت زیادی دارد.

شرکت‌کنندگان شبکه با اجازه دادن به شرکت‌ها برای به اشتراک گذاشتن دمای بیرونی موقعیت جغرافیایی خود در زمان واقعی و ثبت آن در یک دفتر کل غیرقابل تغییر، هزینه‌ها و زمان را کاهش می‌دهند.

تراکنش های عمومی و خصوصی را در بلاک چین JPMorgan Quorum با استفاده از Web3 انجام دهید

ما سه کار را انجام خواهیم داد که در نمودار نشان داده شده است:

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

    در مرحله بعد، نحوه اجرای تراکنش عمومی در شبکه Quorum را بررسی خواهیم کرد 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 и send.

اجازه دهید دمای قرارداد را با اجرا به روز کنیم set با استفاده از روش 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;
  });
}

در ادامه از روش web3 استفاده می کنیم call برای بدست آوردن دمای قرارداد لطفا توجه داشته باشید که روش call روی یک گره محلی اجرا می شود و تراکنش روی بلاک چین ایجاد نمی شود.

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

در مرحله بعد، همانطور که در زیر نشان داده شده است، می توانیم ورودی های Quorum explorer را در پانل Chainstack مشاهده کنیم.

هر سه گره با هم تعامل کردند و تراکنش ها به روز شدند:

  1. اولین معامله قرارداد را گسترش داد.
  2. معامله دوم دمای قرارداد را روی 3 درجه تنظیم کرد.
  3. دما از طریق یک گره محلی دریافت می شود، بنابراین هیچ تراکنشی ایجاد نمی شود.

تراکنش های عمومی و خصوصی را در بلاک چین JPMorgan Quorum با استفاده از Web3 انجام دهید

معاملات خصوصی

متن نوشته

یکی از الزامات رایج سازمان ها حفاظت از داده ها است. به عنوان مثال، سناریویی را در نظر بگیرید که در آن سوپر مارکت یک فضای انباری برای نگهداری غذاهای دریایی از یک مجزا اجاره می کند فروشنده:

  • فروشنده با استفاده از حسگرهای اینترنت اشیا، مقادیر دما را هر 30 ثانیه یک بار خوانده و ارسال می کند به سوپرمارکت;
  • این مقادیر فقط باید در دسترس باشند به فروشنده и به سوپرمارکت، شبکه ای توسط کنسرسیوم.

تراکنش های عمومی و خصوصی را در بلاک چین JPMorgan Quorum با استفاده از Web3 انجام دهید

ما چهار وظیفه نشان داده شده در نمودار بالا را تکمیل خواهیم کرد.

  • ما از همان سه گره سناریوی قبلی برای نشان دادن تراکنش های خصوصی استفاده می کنیم:
  • سوپر مارکت قرارداد هوشمندی را مستقر می کند که خصوصی است سوپر مارکت и فروشنده.
  • طرف سوم حق دسترسی به قرارداد هوشمند را ندارد.

روش ها را فراخوانی خواهیم کرد get и set از طرف سوپر مارکت и فروشنده برای نشان دادن یک معامله Quorum خصوصی.

  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 تنظیم شد، اما طرف سوم به قرارداد هوشمند دسترسی ندارد. بنابراین مقدار بازگشتی باید null باشد.

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

    در ادامه، نگاهی دقیق تر به انجام تراکنش های خصوصی در شبکه Quorum با خواهیم داشت 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

کاوشگر Quorum در Chainstack موارد زیر را نشان می دهد:

  • استقرار قرارداد از طرف شرکت کننده سوپر مارکت;
  • کارایی SetTemperature از شخص ثالث;
  • کارایی SetTemperature از یک شرکت کننده فروشنده.

تراکنش های عمومی و خصوصی را در بلاک چین JPMorgan Quorum با استفاده از Web3 انجام دهید

همانطور که می بینید، هر دو تراکنش تکمیل شده است، اما فقط تراکنش از طرف شرکت کننده انجام می شود فروشنده دما را در قرارداد به روز کرد. بنابراین، تراکنش های خصوصی تغییر ناپذیری را فراهم می کنند، اما در عین حال داده ها را برای شخص ثالث آشکار نمی کنند.

نتیجه

ما به یک مورد استفاده تجاری برای Quorum نگاه کردیم تا با استقرار شبکه ای بین دو طرف - یک سوپرمارکت و یک صاحب انبار - اطلاعات دمای به روز را در یک انبار ارائه دهیم.

ما نشان دادیم که چگونه می‌توان اطلاعات دمایی به‌روز را از طریق تراکنش‌های عمومی و خصوصی حفظ کرد.

سناریوهای کاربردی زیادی می تواند وجود داشته باشد و همانطور که می بینید اصلاً سخت نیست.

آزمایش کنید، سعی کنید اسکریپت خود را گسترش دهید. علاوه بر این، صنعت فناوری بلاک چین می تواند تا سال 2024 تقریباً ده برابر شود.

منبع: www.habr.com

اضافه کردن نظر