マルチパーティ コンピューティングと Confidential Space によってデジタル アセットをトランザクションする方法

1. 概要

開始前に、次の機能とコンセプトを理解しておくと、この Codelab で役立ちます。

4670cd5427aa39a6.png

学習内容

このラボでは、Confidential Space を使用して MPC 準拠のブロックチェーン署名を行うためのリファレンス実装について説明します。このコンセプトを説明するために、会社 Primus が会社 Secundus にデジタル アセットを転送するシナリオについて説明します。このシナリオでは、会社 Primus は MPC 準拠モデルを使用しています。つまり、個々の秘密鍵を使用する代わりに、分散鍵を使用しています。これらの鍵の共有は、複数の当事者(この場合は Alice と Bob)によって保持されます。このアプローチには、ユーザー エクスペリエンスの簡素化、運用効率の向上、秘密鍵の制御など、いくつかのメリットがあります。

このプロセスの基本的な側面を説明するために、技術的な設定について詳しく説明します。また、Company Primus から Company Secundus へのデジタル アセットの転送を開始する承認と署名のプロセスについても説明します。なお、両者とも Primus 社の社員である Bob と Alice が取引を承認する必要があります。

このリファレンス実装では署名オペレーションを示していますが、MPC 鍵管理のすべての側面を網羅しているわけではありません。たとえば、鍵の生成については説明しません。また、Google Cloud 以外のサービスを使用して共同署名を生成したり、共同署名者が交代で、それぞれの環境でブロックチェーン署名を作成したりするといった代替手段や補完的なアプローチもあります(より分散型のアーキテクチャ)。このラボが、Google Cloud での MPC に対するさまざまなアプローチの発想のきっかけとなることを願います。

共同署名者の鍵マテリアルを使用して Confidential Space で Ethereum トランザクションに署名するシンプルなワークロードを扱います。Ethereum トランザクションの署名は、ユーザーが Ethereum ブロックチェーンでトランザクションを承認できるプロセスです。Ethereum トランザクションを送信するには、秘密鍵で署名する必要があります。これにより、お客様がアカウントの所有者であり、取引を承認していることが証明されます。署名プロセスは次のとおりです。

  1. 送信者は、受信者のアドレス、送信する ETH の量、その他の関連データを指定するトランザクション オブジェクトを作成します。
  2. 送信者の秘密鍵を使用して、トランザクション データがハッシュ化されます。
  3. ハッシュは秘密鍵で署名されます。
  4. 署名はトランザクション オブジェクトに関連付けられます。
  5. トランザクションが Ethereum ネットワークにブロードキャストされます。

ネットワーク上のノードがトランザクションを受信すると、署名を検証して、アカウントの所有者によって署名されたことを確認します。署名が有効な場合、ノードはトランザクションをブロックチェーンに追加します。

まず、必要な Cloud リソースを構成します。次に、Confidential Space でワークロードを実行します。この Codelab では、次の手順について説明します。

  • Confidential Space の実行に必要な Cloud リソースを構成する方法
  • 次の属性に基づいて、保護されたリソースへのアクセスを承認する方法。
  • : ワークロード コンテナ
  • 場所: Confidential Space 環境(Confidential VM 上の Confidential Space イメージ)
  • Who: ワークロードを実行しているアカウント
  • Confidential Space VM イメージを実行している Confidential VM でワークロードを実行する方法

必要な API

このガイドを完了するには、指定されたプロジェクトで次の API を有効にする必要があります。

API 名

API タイトル

cloudkms.googleapis.com

Cloud KMS

compute.googleapis.com

Compute Engine

confidentialcomputing.googleapis.com

Confidential Computing

iamcredentials.googleapis.com

IAM

artifactregistry.googleapis.com

Artifact Registry

2. Cloud リソースを設定する

始める前に

  • 次のコマンドを使用して このリポジトリのクローンを作成し、この Codelab で使用する必要なスクリプトを取得します。
git clone https://github.com/GoogleCloudPlatform/confidential-space.git
  • この Codelab のディレクトリを変更します。
cd confidential-space/codelabs/digital_asset_transaction_codelab/scripts
  • 以下に示すように、必要なプロジェクト環境変数が設定されていることを確認します。GCP プロジェクトの設定の詳細については、 こちらの Codelab をご覧ください。プロジェクト ID の取得方法と、プロジェクト ID とプロジェクト名、プロジェクト番号の違いについては、こちらをご覧ください。.
export PRIMUS_PROJECT_ID=<GCP project id>
  • プロジェクトの課金を有効にします
  • 両方のプロジェクトで Confidential Computing API と次の 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
  • リソース名の変数を設定するには、次のコマンドを使用します。これにより、会社 A の GCP プロジェクトに固有のリソース名(export PRIMUS_INPUT_STORAGE_BUCKET='primus-input-bucket' など)がオーバーライドされます。
  • 会社 A の GCP プロジェクトには、次の変数を設定できます。

$PRIMUS_INPUT_STORAGE_BUCKET

暗号化された鍵を保存するバケット。

$PRIMUS_RESULT_STORAGE_BUCKET

MPC トランザクションの結果を保存するバケット。

$PRIMUS_KEY

Primus Bank の $PRIMUS_INPUT_STORAGE_BUCKET に保存されているデータを暗号化するために使用される KMS 鍵。

$PRIMUS_KEYRING

Primus Bank の暗号鍵 $PRIMUS_KEY の作成に使用される KMS キーリング。

$PRIMUS_WIP_PROVIDER

MPC ワークロード サービスによって署名されたトークンに使用する属性条件を含む Workload Identity プール プロバイダ。

$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

ワークロード コンテナ イメージのタグ。

  • 次のスクリプトを実行して、残りの変数名を、リソース名のプロジェクト ID に基づく値に設定します。
source config_env.sh

Cloud リソースを設定する

この手順では、マルチパーティ計算に必要なクラウド リソースを設定します。このラボでは、次の秘密鍵を使用します。0000000000000000000000000000000000000000000000000000000000000001

本番環境では、独自の秘密鍵を生成します。このラボでは、この秘密鍵を 2 つの共有鍵に分割し、それぞれを暗号化します。本番環境のシナリオでは、鍵を平文ファイルに保存しないでください。代わりに、秘密鍵を Google Cloud の外部で生成し(または完全にスキップしてカスタム MPC 鍵シャードの作成に置き換え)、暗号化して、秘密鍵や鍵共有に誰もアクセスできないようにします。このラボでは、Gcloud CLI を使用します。

次のスクリプトを実行して、必要なクラウド リソースを設定します。この手順の一環として、次のリソースが作成されます。

  • 暗号化された秘密鍵の共有を保存する Cloud Storage バケット($PRIMUS_INPUT_STORAGE_BUCKET)。
  • デジタル資産取引の結果を保存する Cloud Storage バケット($PRIMUS_RESULT_STORAGE_BUCKET)。
  • 秘密鍵の共有を暗号化するための KMS の暗号鍵($PRIMUS_KEY)とキーリング($PRIMUS_KEYRING)。
  • プロバイダで構成された属性条件に基づいてクレームを検証する Workload Identity プール($PRIMUS_WORKLOAD_IDENTITY_POOL)。
  • 上記の Workload Identity プール($PRIMUS_WORKLOAD_IDENTITY_POOL)に接続されたサービス アカウント($PRIMUS_SERVICEACCOUNT)で、次の IAM アクセス権を持つもの。
  • roles/cloudkms.cryptoKeyDecrypter: KMS 鍵を使用してデータを復号します。
  • objectViewer: Cloud Storage バケットからデータを読み取ります。
  • roles/iam.workloadIdentityUser: このサービス アカウントを Workload Identity プールに接続します。
./setup_resources.sh

3. ワークロードを作成する

ワークロード サービス アカウントを作成する

次に、必要なロールと権限を持つワークロードのサービス アカウントを作成します。これを行うには、次のスクリプトを実行します。これにより、Company A のワークロード サービス アカウントが作成されます。このサービス アカウントは、ワークロードを実行する VM によって使用されます。

ワークロード サービス アカウント($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 イメージを作成します。この Codelab のワークロードは、暗号化された秘密鍵の共有を使用してアセットを転送するデジタル トランザクションに署名する、単純な Node.js MPC アプリケーションです。ワークロード プロジェクト コードはこちらです。ワークロード プロジェクトには、次のファイルが含まれています。

package.json: このファイルには、ワークロード MPC アプリケーションに使用するパッケージのリストが含まれています。この例では、@google-cloud/kms、@google-cloud/storage、ethers、fast-crc32c ライブラリを使用しています。この Codelab で使用する 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: このファイルには、Workload Identity プールのパスと、サービス アカウントの権限借用に関する詳細情報が保存されます。こちらに、この Codelab で使用する credential-config.js ファイルがあります。

Dockerfile: 最後に、ワークロード Docker イメージのビルドに使用する Dockerfile を作成します。こちらで指定されているように 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" ]

注: Dockerfile の LABEL "tee.launch_policy.allow_cmd_override"="true" は、イメージ作成者が設定した起動ポリシーです。これにより、オペレーターはワークロードの実行時に CMD をオーバーライドできます。デフォルトでは、allow_cmd_override は false に設定されています。LABEL "tee.launch_policy.allow_env_override" は、イメージ ユーザーが使用できる環境変数を Confidential Space に指示します。

次のスクリプトを実行して、次の手順が実行されるワークロードを作成します。

  • ワークロード Docker イメージを保存する Artifact Registry($PRIMUS_ARTIFACT_REPOSITORY)を作成します。
  • 必要なリソース名でワークロード コードを更新します。この Codelab で使用するワークロード コードはこちらです。
  • ワークロード コードの Docker イメージをビルドするための Dockerfile を作成します。Dockerfile はこちらにあります。
  • 前の手順で作成した Artifact Registry($PRIMUS_ARTIFACT_REPOSITORY)に Docker イメージをビルドして公開します。
  • $WORKLOAD_SERVICEACCOUNT$PRIMUS_ARTIFACT_REPOSITORY の読み取り権限を付与します。これは、ワークロード コンテナが Artifact Registry からワークロード Docker イメージを pull できるようにするために必要です。
./create_workload.sh

ブロックチェーン ノードを作成する

Ganache Ethereum ノード

ワークロードを承認する前に、Ethereum Ganache インスタンスを作成する必要があります。署名されたトランザクションは、この Ganache インスタンスに送信されます。このインスタンスの IP アドレスをメモしてください。次のコマンドを実行した後、API を有効にするために 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. ワークロードを承認して実行する

ワークロードを承認する

この手順では、Workload Identity プール($PRIMUS_WORKLOAD_IDENTITY_POOL)の下に Workload Identity プール プロバイダを設定します。以下に示すように、Workload Identity に属性条件が構成されています。条件の 1 つは、ワークロード イメージが想定されるアーティファクト リポジトリから pull されていることを検証することです。

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: 署名付きトランザクションを処理する Ethereum ノードの URL。
  • RESULTS_BUCKET: mpc トランザクションの結果を保存するバケット。
  • KEY_BUCKET: mpc 暗号化鍵を保存するバケット。
  • PRIMUS_PROJECT_NUMBER: 認証情報構成ファイルに使用されるプロジェクト番号。
  • PRIMUS_PROJECT_ID: 認証情報構成ファイルに使用されるプロジェクト ID。ワークロードの実行結果は $PRIMUS_RESULT_STORAGE_BUCKET に公開されます。
  • PRIMUS_WORKLOAD_IDENTITY_POOL: クレームの検証に使用される Workload Identity プール。
  • PRIMUS_WIP_POROVIDER: ワークロードによって提示されたトークンの検証に使用する属性条件を含む Workload Identity プール プロバイダ。
  • 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 で確認できます。Confidential Space が起動して結果が表示されるまでに数分かかることがあります。VM が停止状態になったら、コンテナの処理が完了したことがわかります。

  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

注: 結果が表示されない場合は、Compute Engine Cloud コンソール ページの $WORKLOAD_VM に移動し、[シリアルポート 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 のコンテナ ID を確認する
  6. CONTAINER_ID を trufflesuite/ganache:v7.7.3 の ID に置き換えて、sudo docker logs CONTAINER_ID と入力します。
  7. Ganache のログを表示し、ログにトランザクションが含まれていることを確認します。

5. クリーンアップ

この Codelab で作成したリソースをクリーンアップするために使用できるスクリプトは、こちらにあります。このクリーンアップの一環として、次のリソースが削除されます。

  • 暗号化された鍵の共有を保存するために使用される入力ストレージ バケット($PRIMUS_INPUT_STORAGE_BUCKET))。
  • 暗号鍵($PRIMUS_KEY)。
  • 保護されたリソースへのアクセスに使用されるサービス アカウント($PRIMUS_SERVICEACCOUNT)。
  • Workload Identity プール($PRIMUS_WORKLOAD_IDENTITY_POOL)。
  • ワークロード サービス アカウント($WORKLOAD_SERVICEACCOUNT)。
  • ワークロード コンピューティング インスタンス($WORKLOAD_VM$ETHEREUM_NODE)。
  • トランザクションの結果の保存に使用される結果ストレージ バケット($PRIMUS_RESULT_STORAGE_BUCKET)。
  • ワークロード イメージの保存に使用される Artifact Registry($PRIMUS_ARTIFACT_REPOSITORY)。
./cleanup.sh

確認が完了したら、プロジェクトの削除を検討してください。

  • Cloud Platform Console に移動します。
  • シャットダウンするプロジェクトを選択し、上部の [削除] をクリックします。これにより、プロジェクトの削除スケジュールが設定されます。

次のステップ

以下の類似の Codelab をご覧ください。

参考資料