كيفية التعامل مع الأصول الرقمية باستخدام عمليات حوسبة متعددة الأطراف والمساحة السرية

1. نظرة عامة

قبل البدء، على الرغم من أنّ المعرفة العملية بالميزات والمفاهيم التالية ليست ضرورية تمامًا، إلا أنّها ستكون مفيدة في هذا الدرس التطبيقي حول الترميز.

4670cd5427aa39a6.png

أهداف الدورة التعليمية

يوفّر هذا التمرين المعملي تنفيذًا مرجعيًا لإجراء توقيع متوافق مع الحوسبة المتعددة الأطراف (MPC) على سلسلة الكتل باستخدام Confidential Space. لتوضيح المفاهيم، سنشرح سيناريو تريد فيه شركة Primus نقل أصول رقمية إلى شركة Secundus. في هذا السيناريو، تستخدم شركة Primus نموذجًا متوافقًا مع الحوسبة المتعددة الأطراف الآمنة، ما يعني أنّها تستخدم أجزاء مفاتيح موزّعة بدلاً من استخدام مفاتيح خاصة فردية. يحتفظ عدة أطراف بهذه الأجزاء من المفتاح، وهم في هذه الحالة نبيلة ويوسف. يوفّر هذا النهج لشركة Company Primus العديد من المزايا، بما في ذلك تجربة مستخدم مبسطة وكفاءة تشغيلية وتحكّم في مفاتيحها الخاصة.

لتوضيح الجوانب الأساسية لهذه العملية، سنشرح الإعداد الفني وسنرشدك خلال عملية الموافقة والتوقيع التي تبدأ نقل الأصول الرقمية من شركة Primus إلى شركة Secundus. يُرجى العِلم أنّ يوسف ونبيلة، وهما موظفان في شركة Primus، يجب أن يوافقا على المعاملة.

على الرغم من أنّ هذا التنفيذ المرجعي يوضّح عمليات التوقيع، إلا أنّه لا يغطّي جميع جوانب إدارة مفاتيح الحوسبة المتعددة الأطراف. على سبيل المثال، لا نناقش عملية إنشاء المفاتيح. بالإضافة إلى ذلك، هناك طرق بديلة وتكميلية، مثل استخدام خدمات غير Google Cloud لإنشاء توقيعات مشتركة أو أن يضع الموقّعون المشاركون توقيعات سلسلة الكتل في بيئاتهم الخاصة، وهي بنية أكثر لا مركزية. نأمل أن يلهم هذا المختبر أساليب مختلفة للحوسبة المتعددة الأطراف الآمنة على Google Cloud.

ستعمل على عبء عمل بسيط يوقّع على معاملة Ethereum في Confidential Space باستخدام مواد مفاتيح الموقّع المشترك. توقيع معاملات Ethereum هو عملية يمكن للمستخدم من خلالها السماح بإجراء معاملة على سلسلة Ethereum. لإرسال معاملة Ethereum، عليك توقيعها باستخدام مفتاحك الخاص. ويثبت ذلك أنّك مالك الحساب وأنّك تفوّض بإجراء المعاملة. تكون عملية التوقيع على النحو التالي:

  1. ينشئ المرسِل عنصر معاملة يحدّد عنوان المستلِم ومقدار عملة ETH المطلوب إرسالها وأي بيانات أخرى ذات صلة.
  2. يتم استخدام المفتاح الخاص للمرسِل لتجزئة بيانات المعاملة.
  3. بعد ذلك، يتم توقيع التجزئة باستخدام المفتاح الخاص.
  4. يتم إرفاق التوقيع بكائن المعاملة.
  5. يتم بث المعاملة إلى شبكة Ethereum.

عندما تتلقّى إحدى العُقد على الشبكة معاملة، فإنّها تتحقّق من التوقيع للتأكّد من أنّ صاحب الحساب هو من وقّعها. إذا كان التوقيع صالحًا، ستضيف العقدة المعاملة إلى سلسلة الكتل.

للبدء، عليك إعداد موارد السحابة الإلكترونية اللازمة. بعد ذلك، شغِّل عبء العمل في Confidential Space. سيرشدك هذا الدرس التطبيقي حول الترميز خلال الخطوات العالية المستوى التالية:

  • كيفية إعداد موارد السحابة الإلكترونية اللازمة لتشغيل Confidential Space
  • كيفية منح إذن الوصول إلى الموارد المحمية استنادًا إلى سمات ما يلي:
  • ما هي: حاوية وحدة العمل
  • المكان: بيئة "مساحة للبيانات السرية" (صورة "مساحة للبيانات السرية" على Confidential VM)
  • المستخدم: الحساب الذي يشغّل عبء العمل
  • كيفية تشغيل عبء العمل في جهاز Confidential VM يعمل بصورة الجهاز Confidential Space VM

واجهات برمجة التطبيقات المطلوبة

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

اسم واجهة برمجة التطبيقات

عنوان واجهة برمجة التطبيقات

cloudkms.googleapis.com

Cloud KMS

compute.googleapis.com

Compute Engine

confidentialcomputing.googleapis.com

الحوسبة السرية

iamcredentials.googleapis.com

إدارة الهوية وإمكانية الوصول

artifactregistry.googleapis.com

Artifact Registry

2. إعداد موارد السحابة

قبل البدء

  • استنسِخ هذا المستودع باستخدام الأمر أدناه للحصول على النصوص البرمجية المطلوبة التي يتم استخدامها كجزء من هذا الدرس التطبيقي.
git clone https://github.com/GoogleCloudPlatform/confidential-space.git
  • غيِّر الدليل الخاص بهذا الدرس البرمجي.
cd confidential-space/codelabs/digital_asset_transaction_codelab/scripts
  • تأكَّد من ضبط متغيرات بيئة المشروع المطلوبة كما هو موضّح أدناه. لمزيد من المعلومات حول إعداد مشروع على Google Cloud Platform، يُرجى الاطّلاع على هذا الدرس العملي. يمكنك الرجوع إلى هذه الصفحة للحصول على تفاصيل حول كيفية استرداد رقم تعريف المشروع وكيفية اختلافه عن اسم المشروع ورقمه. .
export PRIMUS_PROJECT_ID=<GCP project id>
  • فعِّل الفوترة لمشاريعك.
  • فعِّل واجهة Confidential Computing API وواجهات برمجة التطبيقات التالية لكلا المشروعَين.
gcloud services enable \
   cloudapis.googleapis.com \
    cloudkms.googleapis.com \
    cloudresourcemanager.googleapis.com \
    cloudshell.googleapis.com \
    container.googleapis.com \
    containerregistry.googleapis.com \
    iam.googleapis.com \
    confidentialcomputing.googleapis.com
  • لضبط المتغيرات لأسماء الموارد، يمكنك استخدام الأمر التالي. يُرجى العِلم أنّ هذا الإجراء سيؤدي إلى إلغاء أسماء الموارد الخاصة بمشروعك على Google Cloud Platform للشركة (أ)، مثل export PRIMUS_INPUT_STORAGE_BUCKET='primus-input-bucket'
  • يمكن ضبط المتغيّرات التالية لمشروعك على GCP في "الشركة أ":

$PRIMUS_INPUT_STORAGE_BUCKET

الحزمة التي تخزِّن المفاتيح المشفّرة

$PRIMUS_RESULT_STORAGE_BUCKET

الحزمة التي تخزِّن نتيجة معاملة الحوسبة المتعددة الأطراف.

$PRIMUS_KEY

مفتاح KMS المستخدَم لتشفير البيانات المخزَّنة في $PRIMUS_INPUT_STORAGE_BUCKET لصالح Primus Bank

$PRIMUS_KEYRING

سلسلة مفاتيح KMS التي سيتم استخدامها لإنشاء مفتاح التشفير $PRIMUS_KEY لبنك Primus

$PRIMUS_WIP_PROVIDER

موفِّر مجموعة معرّفات أعباء العمل الذي يتضمّن شرط السمة المطلوب استخدامه للرموز المميزة الموقَّعة من خلال خدمة أعباء العمل في MPC

$PRIMUS_SERVICEACCOUNT

حساب الخدمة الذي يستخدمه المتغيّر $PRIMUS_WORKLOAD_IDENTITY_POOL للوصول إلى الموارد المحمية سيحصل حساب الخدمة هذا على إذن بالاطّلاع على المفاتيح المشفّرة المخزّنة في الحزمة $PRIMUS_INPUT_STORAGE_BUCKET.

$PRIMUS_ARTIFACT_REPOSITORY

مستودع العناصر لتخزين صورة حاوية عبء العمل

$WORKLOAD_SERVICEACCOUNT

حساب الخدمة الذي لديه إذن بالوصول إلى Confidential VM الذي يشغّل عبء العمل

$WORKLOAD_CONTAINER

حاوية Docker التي تنفّذ عبء العمل

$WORKLOAD_IMAGE_NAME

تمثّل هذه السمة اسم صورة حاوية عبء العمل.

$WORKLOAD_IMAGE_TAG

علامة صورة حاوية وحدة العمل

  • نفِّذ البرنامج النصي التالي لضبط أسماء المتغيرات المتبقية على قيم استنادًا إلى رقم تعريف مشروعك لأسماء الموارد.
source config_env.sh

إعداد موارد السحابة الإلكترونية

كجزء من هذه الخطوة، عليك إعداد موارد السحابة الإلكترونية المطلوبة لإجراء الحسابات المتعددة الأطراف. في هذا الدرس العملي، ستستخدم المفتاح الخاص التالي: 0000000000000000000000000000000000000000000000000000000000000001

في بيئة الإنتاج، عليك إنشاء مفتاحك الخاص. ومع ذلك، لأغراض هذا الدرس التطبيقي، سنقسّم هذا المفتاح الخاص إلى جزأين ونشفّر كل جزء. في سيناريو الإنتاج، يجب ألا يتم تخزين المفاتيح في ملفات نصية عادية. بدلاً من ذلك، يمكن إنشاء المفتاح الخاص خارج Google Cloud (أو تخطّيه بالكامل واستبداله بإنشاء أجزاء مفتاح MPC مخصّصة)، ثم تشفيره حتى لا يتمكّن أحد من الوصول إلى المفتاح الخاص أو أجزاء المفتاح. لأغراض هذا الدرس التطبيقي، سنستخدم Gcloud CLI.

شغِّل النص البرمجي التالي لإعداد موارد السحابة الإلكترونية المطلوبة. كجزء من هذه الخطوات، سيتم إنشاء الموارد المذكورة أدناه:

  • حزمة Cloud Storage ($PRIMUS_INPUT_STORAGE_BUCKET) لتخزين أجزاء المفتاح الخاص المشفّر
  • حزمة Cloud Storage ($PRIMUS_RESULT_STORAGE_BUCKET) لتخزين نتيجة معاملة الأصول الرقمية
  • مفتاح تشفير ($PRIMUS_KEY) وسلسلة مفاتيح ($PRIMUS_KEYRING) في خدمة إدارة المفاتيح (KMS) لتشفير أجزاء المفتاح الخاص
  • مجموعة معلومات تعريفية للمعالجة ($PRIMUS_WORKLOAD_IDENTITY_POOL) للتحقّق من صحة المطالبات استنادًا إلى شروط السمات التي تم ضبطها ضمن الموفّر
  • حساب خدمة ($PRIMUS_SERVICEACCOUNT) مرتبط بمجموعة مصادر الهوية المذكورة أعلاه ($PRIMUS_WORKLOAD_IDENTITY_POOL) مع إذن الوصول التالي في "إدارة الهوية وإمكانية الوصول":
  • roles/cloudkms.cryptoKeyDecrypter لفك تشفير البيانات باستخدام مفتاح KMS.
  • objectViewer لقراءة البيانات من حزمة Cloud Storage
  • استبدِل roles/iam.workloadIdentityUser برقم تعريف مجموعة المعلومات التعريفية لربط حساب الخدمة هذا بها.
./setup_resources.sh

3- إنشاء حمل عمل

إنشاء حساب خدمة خاص بعبء العمل

عليك الآن إنشاء حساب خدمة لعبء العمل مع الأدوار والأذونات المطلوبة. لإجراء ذلك، شغِّل النص البرمجي التالي الذي سينشئ حساب خدمة لحمل العمل خاصًا بالشركة (أ). سيتم استخدام حساب الخدمة هذا من قِبل الجهاز الظاهري الذي يشغّل عبء العمل.

سيكون لحساب الخدمة الخاص بعبء العمل ($WORKLOAD_SERVICEACCOUNT) الأدوار التالية:

  • confidentialcomputing.workloadUser للحصول على رمز مميّز للتصديق
  • logging.logWriter لكتابة السجلّات في Cloud Logging
  • objectViewer لقراءة البيانات من حزمة $PRIMUS_INPUT_STORAGE_BUCKET Cloud Storage
  • objectUser لكتابة نتيجة عبء العمل في حزمة $PRIMUS_RESULT_STORAGE_BUCKET Cloud Storage.
./create_workload_service_account.sh

إنشاء حمل عمل

تتضمّن هذه الخطوة إنشاء صورة Docker لعبء العمل. حِمل العمل في هذا الدرس التطبيقي عبارة عن تطبيق بسيط متعدد الأطراف (MPC) يستند إلى Node.js ويوقّع المعاملات الرقمية لنقل الأصول باستخدام حصص المفتاح الخاص المشفّرة. هنا رمز مشروع وحدة العمل. يتضمّن مشروع عبء العمل الملفات التالية.

package.json: يحتوي هذا الملف على قائمة بالحِزم التي يجب استخدامها لتطبيق MPC الخاص بعبء العمل. في هذه الحالة، نستخدم المكتبات ‎ @google-cloud/kms و‎@google-cloud/storage وethers وfast-crc32c. هنا ملف package.json الذي سنستخدمه في هذا الدرس التطبيقي.

index.js: هذه هي نقطة دخول تطبيق عبء العمل، وتحدّد الأوامر التي يجب تنفيذها عند بدء تشغيل حاوية عبء العمل. لقد أدرجنا أيضًا نموذجًا لمعاملة غير موقَّعة من المفترض أن يقدّمه تطبيق غير موثوق به يطلب من المستخدمين توقيعهم. يستورد ملف index.js أيضًا دوال من mpc.js، وسننشئها في الخطوة التالية. في ما يلي محتوى ملف index.js، ويمكنك أيضًا العثور عليه هنا.

import {signTransaction, submitTransaction, uploadFromMemory} from './mpc.js';

const signAndSubmitTransaction = async () => {
  try {
    // Create the unsigned transaction object
    const unsignedTransaction = {
      nonce: 0,
      gasLimit: 21000,
      gasPrice: '0x09184e72a000',
      to: '0x0000000000000000000000000000000000000000',
      value: '0x00',
      data: '0x',
    };

    // Sign the transaction
    const signedTransaction = await signTransaction(unsignedTransaction);

    // Submit the transaction to Ganache
    const transaction = await submitTransaction(signedTransaction);

    // Write the transaction receipt
    uploadFromMemory(transaction);

    return transaction;
  } catch (e) {
    console.log(e);
    uploadFromMemory(e);
  }
};

await signAndSubmitTransaction();

mpc.js: هذا هو المكان الذي يتم فيه توقيع المعاملة. يستورد هذا الملف دوالاً من kms-decrypt وcredential-config، وسنتناولها في الفقرة التالية. في ما يلي محتوى ملف mpc.js، ويمكنك أيضًا العثور عليه هنا.

import {Storage} from '@google-cloud/storage';
import {ethers} from 'ethers';

import {credentialConfig} from './credential-config.js';
import {decryptSymmetric} from './kms-decrypt.js';

const providers = ethers.providers;
const Wallet = ethers.Wallet;

// The ID of the GCS bucket holding the encrypted keys
const bucketName = process.env.KEY_BUCKET;

// Name of the encrypted key files.
const encryptedKeyFile1 = 'alice_encrypted_key_share';
const encryptedKeyFile2 = 'bob_encrypted_key_share';

// Create a new storage client with the credentials
const storageWithCreds = new Storage({
  credentials: credentialConfig,
});

// Create a new storage client without the credentials
const storage = new Storage();

const downloadIntoMemory = async (keyFile) => {
  // Downloads the file into a buffer in memory.
  const contents =
      await storageWithCreds.bucket(bucketName).file(keyFile).download();

  return contents;
};

const provider =
    new providers.JsonRpcProvider(`http://${process.env.NODE_URL}:80`);

export const signTransaction = async (unsignedTransaction) => {
  /* Check if Alice and Bob have both approved the transaction
  For this example, we're checking if their encrypted keys are available. */
  const encryptedKey1 =
      await downloadIntoMemory(encryptedKeyFile1).catch(console.error);
  const encryptedKey2 =
      await downloadIntoMemory(encryptedKeyFile2).catch(console.error);

  // For each key share, make a call to KMS to decrypt the key
  const privateKeyshare1 = await decryptSymmetric(encryptedKey1[0]);
  const privateKeyshare2 = await decryptSymmetric(encryptedKey2[0]);

  /* Perform the MPC calculations
  In this example, we're combining the private key shares
  Alternatively, you could import your mpc calculations here */
  const wallet = new Wallet(privateKeyshare1 + privateKeyshare2);

  // Sign the transaction
  const signedTransaction = await wallet.signTransaction(unsignedTransaction);

  return signedTransaction;
};

export const submitTransaction = async (signedTransaction) => {
  // This can now be sent to Ganache
  const hash = await provider.sendTransaction(signedTransaction);
  return hash;
};

export const uploadFromMemory = async (contents) => {
  // Upload the results to the bucket without service account impersonation
  await storage.bucket(process.env.RESULTS_BUCKET)
      .file('transaction_receipt_' + Date.now())
      .save(JSON.stringify(contents));
};

kms-decrypt.js: يحتوي هذا الملف على رمز فك التشفير باستخدام المفاتيح المُدارة في KMS. في ما يلي محتوى ملف kms-decrypt.js، ويمكنك أيضًا العثور عليه هنا.

import {KeyManagementServiceClient} from '@google-cloud/kms';
import crc32c from 'fast-crc32c';

import {credentialConfig} from './credential-config.js';

const projectId = process.env.PRIMUS_PROJECT_ID;
const locationId = process.env.PRIMUS_LOCATION;
const keyRingId = process.env.PRIMUS_ENC_KEYRING;
const keyId = process.env.PRIMUS_ENC_KEY;

// Instantiates a client
const client = new KeyManagementServiceClient({
  credentials: credentialConfig,
});

// Build the key name
const keyName = client.cryptoKeyPath(projectId, locationId, keyRingId, keyId);

export const decryptSymmetric = async (ciphertext) => {
  const ciphertextCrc32c = crc32c.calculate(ciphertext);
  const [decryptResponse] = await client.decrypt({
    name: keyName,
    ciphertext,
    ciphertextCrc32c: {
      value: ciphertextCrc32c,
    },
  });

  // Optional, but recommended: perform integrity verification on
  // decryptResponse. For more details on ensuring E2E in-transit integrity to
  // and from Cloud KMS visit:
  // https://cloud.google.com/kms/docs/data-integrity-guidelines
  if (crc32c.calculate(decryptResponse.plaintext) !==
      Number(decryptResponse.plaintextCrc32c.value)) {
    throw new Error('Decrypt: response corrupted in-transit');
  }

  const plaintext = decryptResponse.plaintext.toString();

  return plaintext;
};

credential-config.js: يخزّن الملف مسارات مجموعة المعلومات التعريفية الخاصة بعبء العمل وتفاصيل انتحال هوية حساب الخدمة. إليك ملف credential-config.js الذي سنستخدمه في هذا الدرس التطبيقي.

ملف Dockerfile: أخيرًا، سننشئ ملف Dockerfile الذي سيتم استخدامه لإنشاء صورة Docker الخاصة بعبء العمل. يحدّد ملف Dockerfile كما هو موضّح هنا.

FROM node:16.18.0

ENV NODE_ENV=production

WORKDIR /app

COPY ["package.json", "package-lock.json*", "./"]

RUN npm install --production

COPY . .

LABEL "tee.launch_policy.allow_cmd_override"="true"
LABEL "tee.launch_policy.allow_env_override"="NODE_URL,RESULTS_BUCKET,KEY_BUCKET,PRIMUS_PROJECT_NUMBER,PRIMUS_PROJECT_ID,PRIMUS_WORKLOAD_IDENTITY_POOL,PRIMUS_WIP_PROVIDER,PRIMUS_SERVICEACCOUNT,PRIMUS_ENC_KEYRING,PRIMUS_ENC_KEY"

CMD [ "node", "index.js" ]

ملاحظة: LABEL "tee.launch_policy.allow_cmd_override"="true" في Dockerfile هي سياسة تشغيل يضبطها مؤلف الصورة. تسمح هذه السمة للمشغّل بتجاوز CMD عند تنفيذ عبء العمل. يتم ضبط allow_cmd_override تلقائيًا على false. يخبر التصنيف "tee.launch_policy.allow_env_override" ميزة "المساحة الآمنة" بمتغيّرات البيئة التي يمكن لمستخدمي الصور استخدامها .

نفِّذ البرنامج النصي التالي لإنشاء عبء عمل يتم فيه تنفيذ الخطوات التالية:

  • أنشئ Artifact Registry($PRIMUS_ARTIFACT_REPOSITORY) لتخزين صورة Docker الخاصة بحمل العمل.
  • عدِّل رمز عبء العمل باستخدام أسماء الموارد المطلوبة. إليك رمز وحدة العمل المستخدَم في هذا الدرس التطبيقي.
  • أنشِئ ملف Dockerfile لإنشاء صورة Docker لرمز وحدة العمل. يمكنك العثور على ملف Dockerfile هنا.
  • أنشئ صورة Docker وانشرها في Artifact Registry ($PRIMUS_ARTIFACT_REPOSITORY) الذي تم إنشاؤه في الخطوة السابقة.
  • امنح $WORKLOAD_SERVICEACCOUNT إذن القراءة لـ $PRIMUS_ARTIFACT_REPOSITORY. هذا الإجراء ضروري لكي يسحب حاوي تحميل عبء العمل صورة Docker الخاصة بعبء العمل من Artifact Registry.
./create_workload.sh

إنشاء عقدة Blockchain

Ganache Ethereum Node

قبل السماح بحِمل العمل، علينا إنشاء مثيل Ethereum Ganache. سيتم إرسال المعاملة الموقّعة إلى مثيل Ganache هذا. يُرجى تدوين عنوان IP لهذه الآلة الافتراضية. بعد تنفيذ الأمر أدناه، قد تحتاج إلى إدخال y لتفعيل واجهة برمجة التطبيقات.

gcloud compute instances create-with-container ${ETHEREUM_NODE} \
  --zone=${PRIMUS_PROJECT_ZONE} \
  --tags=http-server \
  --project=${PRIMUS_PROJECT_ID} \
  --shielded-secure-boot \
  --shielded-vtpm \
  --shielded-integrity-monitoring \
  --container-image=docker.io/trufflesuite/ganache:v7.7.3 \
--container-arg=--wallet.accounts=\"0x0000000000000000000000000000000000000000000000000000000000000001,0x21E19E0C9BAB2400000\" \
  --container-arg=--port=80

4. منح الإذن بتشغيل حمل العمل

منح الإذن لحمل العمل

كجزء من هذه الخطوة، سنعمل على إعداد موفِّر مجموعة المعلومات التعريفية ضمن مجموعة المعلومات التعريفية ($PRIMUS_WORKLOAD_IDENTITY_POOL). تم ضبط شروط السمات الخاصة بالمعلومات التعريفية على النحو الموضّح أدناه. أحد الشروط هو التحقّق من أنّ صورة عبء العمل يتم سحبها من مستودع العناصر المتوقّع.

gcloud config set project $PRIMUS_PROJECT_ID
gcloud iam workload-identity-pools providers create-oidc ${PRIMUS_WIP_PROVIDER} \
 --location="${PRIMUS_PROJECT_LOCATION}" \
 --workload-identity-pool="$PRIMUS_WORKLOAD_IDENTITY_POOL" \
 --issuer-uri="https://confidentialcomputing.googleapis.com/" \
 --allowed-audiences="https://sts.googleapis.com" \
 --attribute-mapping="google.subject='assertion.sub'" \
 --attribute-condition="assertion.swname == 'CONFIDENTIAL_SPACE' && 'STABLE' in assertion.submods.confidential_space.support_attributes && assertion.submods.container.image_reference == '${PRIMUS_PROJECT_REPOSITORY_REGION}-docker.pkg.dev/$PRIMUS_PROJECT_ID/$PRIMUS_ARTIFACT_REPOSITORY/$WORKLOAD_IMAGE_NAME:$WORKLOAD_IMAGE_TAG' && '$WORKLOAD_SERVICEACCOUNT@$PRIMUS_PROJECT_ID.iam.gserviceaccount.com' in assertion.google_service_accounts"

تشغيل حجم المعالجة

يوضّح هذا القسم كيفية تشغيل عبء العمل على Confidential VM. لإجراء ذلك، سنمرّر وسيطات TEE المطلوبة باستخدام علامة البيانات الوصفية. بالإضافة إلى ذلك، سنضبط متغيرات البيئة لحاوية عبء العمل باستخدام العلامة "tee-env-*". تحتوي الصورة على المتغيّرات التالية:

  • NODE_URL: عنوان URL لعقدة Ethereum التي ستعالج المعاملة الموقّعة.
  • RESULTS_BUCKET: الحزمة التي تخزّن نتيجة معاملة الحوسبة المتعددة الأطراف.
  • KEY_BUCKET: الحزمة التي تخزّن المفاتيح المشفّرة باستخدام الحوسبة المتعددة الأطراف.
  • PRIMUS_PROJECT_NUMBER: رقم المشروع المستخدَم في ملف إعداد بيانات الاعتماد.
  • PRIMUS_PROJECT_ID: معرّف المشروع المستخدَم لملف إعداد بيانات الاعتماد سيتم نشر نتيجة تنفيذ عبء العمل في $PRIMUS_RESULT_STORAGE_BUCKET.
  • PRIMUS_WORKLOAD_IDENTITY_POOL: مجموعة المعلومات التعريفية المستخدَمة للتحقّق من صحة المطالبات.
  • استبدِل PRIMUS_WIP_POROVIDER بموفِّر مجموعة المعلومات التعريفية الذي يتضمّن شروط السمات التي سيتم استخدامها للتحقّق من صحة الرموز المميزة التي تقدّمها أعباء العمل.
  • WORKLOAD_SERVICEACCOUNT: حساب الخدمة الخاص بعبء العمل
gcloud compute instances create $WORKLOAD_VM \
 --confidential-compute-type=SEV \
 --shielded-secure-boot \
 --maintenance-policy=TERMINATE \
 --scopes=cloud-platform \
 --zone=${PRIMUS_PROJECT_ZONE} \
 --project=${PRIMUS_PROJECT_ID} \
 --image-project=confidential-space-images \
 --image-family=confidential-space \
 --service-account=$WORKLOAD_SERVICEACCOUNT@$PRIMUS_PROJECT_ID.iam.gserviceaccount.com \
 --metadata "^~^tee-image-reference=${PRIMUS_PROJECT_REPOSITORY_REGION}-docker.pkg.dev/$PRIMUS_PROJECT_ID/$PRIMUS_ARTIFACT_REPOSITORY/$WORKLOAD_IMAGE_NAME:$WORKLOAD_IMAGE_TAG~tee-restart-policy=Never~tee-env-NODE_URL=$(gcloud compute instances describe ${ETHEREUM_NODE} --format='get(networkInterfaces[0].networkIP)' --zone=${PRIMUS_PROJECT_ZONE})~tee-env-RESULTS_BUCKET=$PRIMUS_RESULT_STORAGE_BUCKET~tee-env-KEY_BUCKET=$PRIMUS_INPUT_STORAGE_BUCKET~tee-env-PRIMUS_PROJECT_ID=$PRIMUS_PROJECT_ID~tee-env-PRIMUS_PROJECT_NUMBER=$(gcloud projects describe $PRIMUS_PROJECT_ID --format="value(projectNumber)")~tee-env-PRIMUS_WORKLOAD_IDENTITY_POOL=$PRIMUS_WORKLOAD_IDENTITY_POOL~tee-env-PRIMUS_PROJECT_LOCATION=${PRIMUS_PROJECT_LOCATION}~tee-env-PRIMUS_WIP_PROVIDER=$PRIMUS_WIP_PROVIDER~tee-env-PRIMUS_SERVICEACCOUNT=$PRIMUS_SERVICEACCOUNT~tee-env-PRIMUS_KEY=${PRIMUS_KEY}~tee-env-PRIMUS_KEYRING=${PRIMUS_KEYRING}"

الاطّلاع على نتائج Cloud Storage

يمكنك الاطّلاع على إيصال المعاملة في Cloud Storage. قد يستغرق تشغيل "المساحة الآمنة" وظهور النتائج بضع دقائق. ستعرف أنّ الحاوية قد اكتملت عندما تكون الآلة الافتراضية في حالة الإيقاف.

  1. انتقِل إلى صفحة متصفّح Cloud Storage.
  2. انقر على $PRIMUS_RESULT_STORAGE_BUCKET.
  3. انقر على الملف transaction_receipt.
  4. انقر على "تنزيل" لتنزيل ردّ المعاملة وعرضه.

بدلاً من ذلك، يمكنك تنفيذ الأوامر التالية لعرض النتيجة.

gcloud config set project $PRIMUS_PROJECT_ID
gsutil cat gs://$PRIMUS_RESULT_STORAGE_BUCKET/transaction_receipt

ملاحظة: إذا لم تظهر النتائج، يمكنك الانتقال إلى $WORKLOAD_VM في صفحة Compute Engine Cloud Console والنقر على "المنفذ التسلسلي 1 (وحدة التحكّم)" لعرض السجلات.

التحقّق من معاملة سلسلة الكتل في Ganache

يمكنك أيضًا الاطّلاع على المعاملة في سجلّ سلسلة الكتل.

  1. انتقِل إلى صفحة Cloud Compute Engine.
  2. انقر على ${ETHEREUM_NODE} VM.
  3. انقر على SSH لفتح نافذة SSH في المتصفّح.
  4. في نافذة SSH، أدخِل sudo docker ps للاطّلاع على حاوية Ganache قيد التشغيل.
  5. العثور على رقم تعريف الحاوية لـ trufflesuite/ganache:v7.7.3
  6. أدخِل sudo docker logs CONTAINER_ID مع استبدال CONTAINER_ID بمعرّف trufflesuite/ganache:v7.7.3.
  7. اطّلِع على سجلّات Ganache وتأكَّد من إدراج عملية في السجلّات.

5- تَنظيم

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

  • حاوية التخزين التي يتم إدخالها والمستخدَمة لتخزين أجزاء المفتاح المشفّرة ($PRIMUS_INPUT_STORAGE_BUCKET)
  • مفتاح التشفير ($PRIMUS_KEY)
  • حساب الخدمة المستخدَم للوصول إلى الموارد المحمية ($PRIMUS_SERVICEACCOUNT)
  • مجموعة Workload Identity ($PRIMUS_WORKLOAD_IDENTITY_POOL)
  • حساب خدمة عبء العمل ($WORKLOAD_SERVICEACCOUNT)
  • آلات Compute المخصّصة لأحمال العمل ($WORKLOAD_VM و$ETHEREUM_NODE)
  • حزمة تخزين النتائج المستخدَمة لتخزين نتيجة المعاملة ($PRIMUS_RESULT_STORAGE_BUCKET).
  • مستودع القطع الأثرية المستخدَم لتخزين صورة عبء العمل ($PRIMUS_ARTIFACT_REPOSITORY)
./cleanup.sh

إذا انتهيت من استكشاف المشروع، يُرجى التفكير في حذفه.

  • انتقِل إلى وحدة تحكّم Cloud Platform
  • اختَر المشروع الذي تريد إيقافه، ثم انقر على "حذف" في أعلى الصفحة. يؤدي ذلك إلى تحديد موعد لحذف المشروع.

ما هي الخطوات التالية؟

يمكنك الاطّلاع على بعض الدروس التطبيقية المشابهة حول الترميز...

Further reading