Réaliser des transactions sur des actifs numériques avec le calcul multipartite et Confidential Space

Réaliser des transactions sur des actifs numériques avec le calcul multipartite et Confidential Space

À propos de cet atelier de programmation

subjectDernière mise à jour : janv. 9, 2025
account_circleRédigé par Devon Yarbrough, Bertrand Portier, Chris Diya, Meetrajsinh Vala

1. Présentation

Avant de commencer, bien que ce ne soit pas entièrement nécessaire, une connaissance pratique des fonctionnalités et concepts suivants vous sera utile dans cet atelier de programmation.

4670cd5427aa39a6.png

Points abordés

Cet atelier fournit une implémentation de référence pour effectuer la signature de blockchain conforme à la MPC à l'aide de l'espace confidentiel. Pour illustrer ces concepts, nous allons passer en revue un scénario dans lequel l'entreprise Primus souhaite transférer des éléments numériques à l'entreprise Secundus. Dans ce scénario, l'entreprise Primus utilise un modèle conforme à la MPC, ce qui signifie qu'au lieu d'utiliser des clés privées individuelles, elle utilise des parts de clés distribuées. Ces parts de clé sont détenues par plusieurs parties, en l'occurrence Alice et Bob. Cette approche offre à l'entreprise Primus plusieurs avantages, dont une expérience utilisateur simplifiée, une efficacité opérationnelle et un contrôle de ses clés privées.

Pour vous expliquer les aspects fondamentaux de ce processus, nous allons détailler la configuration technique et vous guider tout au long du processus d'approbation et de signature qui lance le transfert d'actifs numériques de l'entreprise Primus vers l'entreprise Secundus. Veuillez noter que Bob et Alice, qui sont tous deux employés de l'entreprise Primus, doivent approuver la transaction.

Bien que cette implémentation de référence illustre les opérations de signature, elle ne couvre pas tous les aspects de la gestion des clés MPC. Par exemple, nous ne discutons pas de la génération de clés. En outre, il existe d'autres approches complémentaires, telles que l'utilisation de services autres que Google Cloud pour générer des cosignatures ou demander aux cosignataires de créer des signatures blockchain dans leurs propres environnements, ce qui constitue une architecture plus décentralisée. Nous espérons que cet atelier vous inspirera différentes approches de la MPC sur Google Cloud.

Vous allez utiliser une charge de travail simple qui signe une transaction Ethereum dans Confidential Space à l'aide de matériaux de clé de cosignataire. La signature de transactions Ethereum est un processus par lequel un utilisateur peut autoriser une transaction sur la blockchain Ethereum. Pour envoyer une transaction Ethereum, vous devez la signer avec votre clé privée. Cela prouve que vous êtes le propriétaire du compte et que vous autorisez la transaction. Le processus de signature est le suivant:

  1. L'expéditeur crée un objet de transaction qui spécifie l'adresse du destinataire, la quantité d'ETH à envoyer et toute autre donnée pertinente.
  2. La clé privée de l'émetteur est utilisée pour hacher les données de transaction.
  3. Le hachage est ensuite signé avec la clé privée.
  4. La signature est jointe à l'objet de la transaction.
  5. La transaction est diffusée sur le réseau Ethereum.

Lorsqu'un nœud du réseau reçoit une transaction, il vérifie la signature pour s'assurer qu'elle a été signée par le titulaire du compte. Si la signature est valide, le nœud ajoute la transaction à la blockchain.

Pour commencer, vous allez configurer les ressources Cloud nécessaires. Vous exécuterez ensuite la charge de travail dans Confidential Space. Cet atelier de programmation vous guidera tout au long des étapes générales suivantes:

  • Configurer les ressources Cloud nécessaires pour exécuter Confidential Space
  • Autoriser l'accès aux ressources protégées en fonction des attributs des éléments suivants:
  • Quoi: le conteneur de charge de travail
  • : environnement Confidential Space (image Confidential Space sur Confidential VM)
  • Qui: compte qui exécute la charge de travail
  • Exécuter la charge de travail dans une VM Confidential exécutant l'image de VM Confidential Space

API requises

Pour pouvoir suivre ce guide, vous devez activer les API suivantes dans les projets spécifiés.

Nom de l'API

Titre de l'API

cloudkms.googleapis.com

Cloud KMS

compute.googleapis.com

Compute Engine

confidentialcomputing.googleapis.com

Informatique confidentielle

iamcredentials.googleapis.com

IAM

artifactregistry.googleapis.com

Artifact Registry

2. Configurer des ressources Cloud

Avant de commencer

  • Clonez ce dépôt à l'aide de la commande ci-dessous pour obtenir les scripts requis utilisés dans cet atelier de programmation.
git clone https://github.com/GoogleCloudPlatform/confidential-space.git
  • Accédez au répertoire de cet atelier de programmation.
cd confidential-space/codelabs/digital_asset_transaction_codelab/scripts
  • Assurez-vous d'avoir défini les variables d'environnement de projet requises, comme indiqué ci-dessous. Pour en savoir plus sur la configuration d'un projet GCP, consultez cet atelier de programmation. Pour savoir comment récupérer l'ID de projet et en quoi il diffère du nom et du numéro de projet, consultez cette page. .
export PRIMUS_PROJECT_ID=<GCP project id>
  • Activez la facturation pour vos projets.
  • Activez l'API Confidential Computing et les API suivantes pour les deux projets.
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
  • Pour définir les variables pour les noms de ressources, vous pouvez utiliser la commande suivante. Notez que cela remplacera les noms de ressources spécifiques à votre projet GCP pour l'entreprise A, par exemple export PRIMUS_INPUT_STORAGE_BUCKET='primus-input-bucket'.
  • Les variables suivantes peuvent être définies pour votre projet GCP dans l'entreprise A:

$PRIMUS_INPUT_STORAGE_BUCKET

Bucket dans lequel les clés chiffrées sont stockées.

$PRIMUS_RESULT_STORAGE_BUCKET

Bucket qui stocke le résultat de la transaction MPC.

$PRIMUS_KEY

Clé KMS utilisée pour chiffrer les données stockées dans $PRIMUS_INPUT_STORAGE_BUCKET pour Primus Bank.

$PRIMUS_KEYRING

Trousseau de clés KMS qui sera utilisé pour créer la clé de chiffrement $PRIMUS_KEY pour Primus Bank.

$PRIMUS_WIP_PROVIDER

Le fournisseur de pool d'identités de charge de travail, qui inclut la condition d'attribut à utiliser pour les jetons signés par le service de charge de travail MPC.

$PRIMUS_SERVICEACCOUNT

Compte de service utilisé par $PRIMUS_WORKLOAD_IDENTITY_POOL pour accéder aux ressources protégées. Ce compte de service sera autorisé à afficher les clés chiffrées stockées dans le bucket $PRIMUS_INPUT_STORAGE_BUCKET.

$PRIMUS_ARTIFACT_REPOSITORY

Dépôt d'artefacts pour stocker l'image du conteneur de charge de travail.

$WORKLOAD_SERVICEACCOUNT

Compte de service autorisé à accéder à la VM Confidential qui exécute la charge de travail.

$WORKLOAD_CONTAINER

Conteneur Docker qui exécute la charge de travail.

$WORKLOAD_IMAGE_NAME

Nom de l'image du conteneur de charge de travail.

$WORKLOAD_IMAGE_TAG

Tag de l'image du conteneur de charge de travail.

  • Exécutez le script suivant pour définir les noms de variable restants sur des valeurs basées sur votre ID de projet pour les noms de ressources.
source config_env.sh

Configurer des ressources Cloud

Au cours de cette étape, vous allez configurer les ressources cloud requises pour le calcul multiparti. Pour cet atelier, vous allez utiliser la clé privée suivante: 0000000000000000000000000000000000000000000000000000000000000001

Dans un environnement de production, vous générerez votre propre clé privée. Toutefois, pour les besoins de cet atelier, nous allons diviser cette clé privée en deux parts et chiffrer chacune d'elles. Dans un scénario de production, les clés ne doivent jamais être stockées dans des fichiers en texte brut. Au lieu de cela, la clé privée peut être générée en dehors de Google Cloud (ou complètement ignorée et remplacée par la création de fragments de clé MPC personnalisés), puis chiffrée afin que personne n'ait accès à la clé privée ni aux fragments de clé. Pour cet atelier, nous allons utiliser la gcloud CLI.

Exécutez le script suivant pour configurer les ressources cloud requises. Au cours de ces étapes, les ressources ci-dessous seront créées:

  • Un bucket Cloud Storage ($PRIMUS_INPUT_STORAGE_BUCKET) pour stocker les partages de clé privée chiffrés.
  • Un bucket Cloud Storage ($PRIMUS_RESULT_STORAGE_BUCKET) pour stocker le résultat de la transaction d'actifs numériques.
  • Une clé de chiffrement ($PRIMUS_KEY) et un trousseau ($PRIMUS_KEYRING) dans KMS pour chiffrer les partages de clés privées.
  • Un pool d'identités de charge de travail ($PRIMUS_WORKLOAD_IDENTITY_POOL) pour valider les revendications en fonction des conditions d'attributs configurées dans son fournisseur.
  • Un compte de service ($PRIMUS_SERVICEACCOUNT) associé au pool d'identités de charge de travail ($PRIMUS_WORKLOAD_IDENTITY_POOL) mentionné ci-dessus avec l'accès IAM suivant:
  • roles/cloudkms.cryptoKeyDecrypter pour déchiffrer les données à l'aide de la clé KMS.
  • objectViewer pour lire les données du bucket Cloud Storage ;
  • roles/iam.workloadIdentityUser pour connecter ce compte de service au pool d'identités de charge de travail.
./setup_resources.sh

3. Créer une charge de travail

Créer un compte de service de charge de travail

Vous allez maintenant créer un compte de service pour la charge de travail avec les rôles et les autorisations requis. Pour ce faire, exécutez le script suivant, qui créera un compte de service de charge de travail pour l'entreprise A. Ce compte de service sera utilisé par la VM qui exécute la charge de travail.

Le compte de service de la charge de travail ($WORKLOAD_SERVICEACCOUNT) disposera des rôles suivants:

  • confidentialcomputing.workloadUser pour obtenir un jeton d'attestation
  • logging.logWriter pour écrire des journaux dans Cloud Logging.
  • objectViewer pour lire les données du bucket Cloud Storage $PRIMUS_INPUT_STORAGE_BUCKET ;
  • objectUser pour écrire le résultat de la charge de travail dans le bucket Cloud Storage $PRIMUS_RESULT_STORAGE_BUCKET.
./create_workload_service_account.sh

Créer une charge de travail

Cette étape consiste à créer une image Docker de charge de travail. La charge de travail de cet atelier de programmation est une application MPC Node.js simple qui signe les transactions numériques pour le transfert d'actifs à l'aide de parts de clés privées chiffrées. Voici le code du projet de charge de travail. Le projet de charge de travail inclut les fichiers suivants.

package.json::ce fichier contient la liste des packages à utiliser pour l'application MPC de la charge de travail. Dans ce cas, nous utilisons les bibliothèques @google-cloud/kms, @google-cloud/storage, ethers et fast-crc32c. Voici le fichier package.json que nous utiliserons pour cet atelier de programmation.

index.js::point d'entrée de l'application de charge de travail. Spécifie les commandes à exécuter au démarrage du conteneur de charge de travail. Nous avons également inclus un exemple de transaction non signée qui serait normalement fournie par une application non approuvée qui demande aux utilisateurs de signer. Ce fichier index.js importe également des fonctions de mpc.js, que nous allons créer ensuite. Vous trouverez ci-dessous le contenu du fichier index.js, qui est également disponible sur cette page.

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::c'est là que la signature de la transaction a lieu. Il importe des fonctions de kms-decrypt et credential-config, que nous verrons ensuite. Vous trouverez ci-dessous le contenu du fichier mpc.js, qui est également disponible sur cette page.

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:ce fichier contient le code de déchiffrement à l'aide de clés gérées dans KMS. Vous trouverez ci-dessous le contenu du fichier kms-decrypt.js, que vous pouvez également consulter sur cette page.

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:ce fichier stocke les chemins et les informations du pool d'identités de charge de travail pour l'usurpation d'identité du compte de service. Voici le fichier credential-config.js que nous utiliserons pour cet atelier de programmation.

Dockerfile:enfin, nous allons créer notre Dockerfile qui servira à créer l'image Docker de la charge de travail. définit le Dockerfile comme indiqué ici.

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" ]

Remarque:La LABEL "tee.launch_policy.allow_cmd_override"="true" dans le Dockerfile est une stratégie de lancement définie par l'auteur de l'image. Il permet à l'opérateur de remplacer le CMD lors de l'exécution de la charge de travail. Par défaut, allow_cmd_override est défini sur "false". Le libellé "tee.launch_policy.allow_env_override" indique à Confidential Space les variables d'environnement que les utilisateurs de l'image peuvent utiliser .

Exécutez le script suivant pour créer une charge de travail dans laquelle les étapes suivantes sont effectuées:

  • Créez Artifact Registry($PRIMUS_ARTIFACT_REPOSITORY) pour stocker l'image Docker de la charge de travail.
  • Remplacez le code de la charge de travail par les noms des ressources requises. Voici le code de la charge de travail utilisé pour cet atelier de programmation.
  • Créez un Dockerfile pour créer une image Docker du code de la charge de travail. Vous trouverez le Dockerfile sur cette page.
  • Créez et publiez l'image Docker dans Artifact Registry ($PRIMUS_ARTIFACT_REPOSITORY) créé à l'étape précédente.
  • Accordez à $WORKLOAD_SERVICEACCOUNT l'autorisation de lecture pour $PRIMUS_ARTIFACT_REPOSITORY. Cela est nécessaire pour que le conteneur de la charge de travail puisse extraire l'image Docker de la charge de travail à partir d'Artifact Registry.
./create_workload.sh

Créer le nœud blockchain

Nœud Ethereum Ganache

Avant d'autoriser la charge de travail, nous devons créer l'instance Ethereum Ganache. La transaction signée sera envoyée à cette instance Ganache. Veuillez noter l'adresse IP de cette instance. Après avoir exécuté la commande ci-dessous, vous devrez peut-être saisir y pour activer l'API.

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. Autoriser et exécuter la charge de travail

Autoriser la charge de travail

Au cours de cette étape, nous allons configurer le fournisseur de pool d'identités de charge de travail sous le pool d'identités de charge de travail ($PRIMUS_WORKLOAD_IDENTITY_POOL). Des conditions d'attributs sont configurées pour l'identité de charge de travail, comme indiqué ci-dessous. L'une des conditions consiste à valider que l'image de la charge de travail est extraite du dépôt d'artefacts attendu.

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"

Exécuter la charge de travail

Cette section explique comment exécuter la charge de travail sur Confidential VM. Pour ce faire, nous transmettons les arguments TEE requis à l'aide de l'indicateur de métadonnées. De plus, nous allons définir des variables d'environnement pour le conteneur de charge de travail à l'aide de l'indicateur "tee-env-*". L'image contient les variables suivantes:

  • NODE_URL: URL du nœud Ethereum qui traitera la transaction signée.
  • RESULTS_BUCKET: bucket qui stocke le résultat de la transaction mpc.
  • KEY_BUCKET: bucket qui stocke les clés chiffrées MPC.
  • PRIMUS_PROJECT_NUMBER: numéro de projet utilisé pour le fichier de configuration des identifiants.
  • PRIMUS_PROJECT_ID: ID du projet utilisé pour le fichier de configuration des identifiants. Le résultat de l'exécution de la charge de travail sera publié dans $PRIMUS_RESULT_STORAGE_BUCKET.
  • PRIMUS_WORKLOAD_IDENTITY_POOL: Pool d'identités de charge de travail utilisé pour valider les revendications.
  • PRIMUS_WIP_POROVIDER: fournisseur du pool d'identités de charge de travail, qui inclut les conditions d'attribut à utiliser pour valider les jetons présentés par la charge de travail.
  • WORKLOAD_SERVICEACCOUNT: compte de service de la charge de travail.
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}"

Vérifier les résultats Cloud Storage

Vous pouvez consulter le reçu de la transaction dans Cloud Storage. L'espace confidentiel peut mettre quelques minutes à démarrer et les résultats peuvent mettre un certain temps à s'afficher. Vous saurez que le conteneur est terminé lorsque la VM est à l'état "Arrêtée".

  1. Accédez à la page du navigateur Cloud Storage.
  2. Cliquez sur $PRIMUS_RESULT_STORAGE_BUCKET.
  3. Cliquez sur le fichier transaction_receipt.
  4. Cliquez sur "Télécharger" pour télécharger et afficher la réponse de la transaction.

Vous pouvez également exécuter les commandes suivantes pour afficher le résultat.

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

Remarque:Si les résultats ne s'affichent pas, vous pouvez accéder à $WORKLOAD_VM sur la page de la console Cloud Compute Engine, puis cliquer sur "Port série 1 (console)" pour afficher les journaux.

Vérifier la transaction de la blockchain Ganache

Vous pouvez également consulter la transaction dans le journal de la blockchain.

  1. Accédez à la page Cloud Compute Engine.
  2. Cliquez sur ${ETHEREUM_NODE} VM.
  3. Cliquez sur SSH pour ouvrir la fenêtre SSH dans le navigateur.
  4. Dans la fenêtre SSH, saisissez sudo docker ps pour afficher le conteneur Ganache en cours d'exécution.
  5. Rechercher l'ID du conteneur pour trufflesuite/ganache:v7.7.3
  6. Saisissez sudo docker logs CONTAINER_ID en remplaçant CONTAINER_ID par l'ID de trufflesuite/ganache:v7.7.3.
  7. Affichez les journaux de Ganache et vérifiez qu'une transaction y est listée.

5. Effectuer un nettoyage

Voici le script que vous pouvez utiliser pour nettoyer les ressources que nous avons créées dans cet atelier de programmation. Dans le cadre de ce nettoyage, les ressources suivantes seront supprimées:

  • Bucket de stockage d'entrée utilisé pour stocker des parts de clé chiffrées ($PRIMUS_INPUT_STORAGE_BUCKET).
  • Clé de chiffrement ($PRIMUS_KEY)
  • Compte de service utilisé pour accéder aux ressources protégées ($PRIMUS_SERVICEACCOUNT).
  • Pool d'identités de charge de travail ($PRIMUS_WORKLOAD_IDENTITY_POOL)
  • Compte de service de la charge de travail ($WORKLOAD_SERVICEACCOUNT)
  • Instances Compute de charge de travail ($WORKLOAD_VM et $ETHEREUM_NODE)
  • Bucket de stockage des résultats utilisé pour stocker le résultat de la transaction ($PRIMUS_RESULT_STORAGE_BUCKET).
  • Répertoire d'artefacts utilisé pour stocker l'image de la charge de travail ($PRIMUS_ARTIFACT_REPOSITORY).
./cleanup.sh

Si vous avez terminé votre exploration, envisagez de supprimer votre projet.

  • Accédez à la console Cloud Platform.
  • Sélectionnez le projet que vous souhaitez arrêter, puis cliquez sur "Supprimer" en haut de la page. La suppression du projet est planifiée.

Et ensuite ?

Découvrez ces ateliers de programmation similaires :

Complément d'informations