1. Descripción general
Antes de comenzar, aunque no es del todo necesario, tener conocimientos prácticos sobre las siguientes funciones y conceptos será útil en este codelab.
- Cloud Storage, específicamente buckets
- Compute Engine, específicamente Confidential VM
- Cuentas de servicio
- Contenedores y repositorios remotos
- Federación de identidades para cargas de trabajo y condiciones de atributos

Qué aprenderás
En este lab, se proporciona una implementación de referencia para realizar la firma de cadenas de bloques que cumpla con los requisitos de MPC con Confidential Space. Para ilustrar los conceptos, analizaremos una situación en la que la empresa Primus desea transferir activos digitales a la empresa Secundus. En esta situación, la empresa Primus usa un modelo que cumple con los requisitos de MPC, lo que significa que, en lugar de usar claves privadas individuales, usa claves compartidas distribuidas. Estas claves se encuentran en poder de varias partes, en este caso, Alicia y Roberto. Este enfoque le proporciona a Company Primus varios beneficios, como una experiencia del usuario simplificada, eficiencia operativa y control sobre sus claves privadas.
Para explicar los aspectos fundamentales de este proceso, detallaremos la configuración técnica y te guiaremos por el proceso de aprobación y firma que inicia la transferencia de activos digitales de la Empresa Primus a la Empresa Secundus. Ten en cuenta que tanto Bob como Alice, que son empleados de la empresa Primus, deben aprobar la transacción.
Si bien esta implementación de referencia demuestra las operaciones de firma, no abarca todos los aspectos de la administración de claves de MPC. Por ejemplo, no analizamos la generación de claves. Además, existen enfoques alternativos y complementarios, como usar servicios que no son de Google Cloud para generar firmas conjuntas o hacer que los cofirmantes construyan firmas de blockchain en sus propios entornos, lo que constituye una arquitectura más descentralizada. Esperamos que este lab inspire diferentes enfoques para el MPC en Google Cloud.
Trabajarás con una carga de trabajo simple que firma una transacción de Ethereum en Confidential Space con materiales de claves de cofirmante. La firma de transacciones de Ethereum es un proceso por el cual un usuario puede autorizar una transacción en la cadena de bloques de Ethereum. Para enviar una transacción de Ethereum, debes firmarla con tu clave privada. Esto demuestra que eres el propietario de la cuenta y que autorizas la transacción. El proceso de firma es el siguiente:
- El remitente crea un objeto de transacción que especifica la dirección del destinatario, la cantidad de ETH que se enviará y cualquier otro dato pertinente.
- La clave privada del remitente se usa para generar un hash de los datos de la transacción.
- Luego, el hash se firma con la clave privada.
- La firma se adjunta al objeto de transacción.
- La transacción se transmite a la red de Ethereum.
Cuando un nodo de la red recibe una transacción, verifica la firma para asegurarse de que la haya firmado el propietario de la cuenta. Si la firma es válida, el nodo agregará la transacción a la cadena de bloques.
Para comenzar, configurarás los recursos de Cloud necesarios. Luego, ejecutarás la carga de trabajo en Confidential Space. En este codelab, se te guiará a través de los siguientes pasos de alto nivel:
- Cómo configurar los recursos de Cloud necesarios para ejecutar Confidential Space
- Cómo autorizar el acceso a recursos protegidos según los atributos de los siguientes elementos:
- Qué: El contenedor de la carga de trabajo
- Dónde: El entorno de Confidential Space (la imagen de Confidential Space en la Confidential VM)
- Quién: La cuenta que ejecuta la carga de trabajo
- Cómo ejecutar la carga de trabajo en una Confidential VM que ejecuta la imagen de VM de Confidential Space
APIs requeridas
Debes habilitar las siguientes APIs en los proyectos especificados para poder completar esta guía.
Nombre de la API | Título de la 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. Configura recursos de Cloud
Antes de comenzar
- Clona este repositorio con el siguiente comando para obtener las secuencias de comandos necesarias que se usan como parte de este codelab.
git clone https://github.com/GoogleCloudPlatform/confidential-space.git
- Cambia el directorio de este codelab.
cd confidential-space/codelabs/digital_asset_transaction_codelab/scripts
- Asegúrate de haber configurado las variables de entorno del proyecto necesarias como se muestra a continuación. Para obtener más información sobre cómo configurar un proyecto de GCP, consulta este codelab. Puedes consultar este vínculo para obtener detalles sobre cómo recuperar el ID del proyecto y en qué se diferencia del nombre y el número del proyecto. .
export PRIMUS_PROJECT_ID=<GCP project id>
- Habilita la facturación para tus proyectos.
- Habilita la API de Confidential Computing y las siguientes APIs para ambos proyectos.
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
- Para establecer las variables de los nombres de los recursos, puedes usar el siguiente comando. Ten en cuenta que esto anulará los nombres de recursos específicos de tu proyecto de GCP para la empresa A, por ejemplo,
export PRIMUS_INPUT_STORAGE_BUCKET='primus-input-bucket'. - Se pueden configurar las siguientes variables para tu proyecto de GCP en la empresa A:
$PRIMUS_INPUT_STORAGE_BUCKET | Es el bucket que almacena las claves encriptadas. |
$PRIMUS_RESULT_STORAGE_BUCKET | Es el bucket que almacena el resultado de la transacción de MPC. |
$PRIMUS_KEY | Es la clave de KMS que se usa para encriptar los datos almacenados en $PRIMUS_INPUT_STORAGE_BUCKET para Primus Bank. |
$PRIMUS_KEYRING | El llavero de claves de KMS que se usará para crear la clave de encriptación $PRIMUS_KEY para Primus Bank. |
$PRIMUS_WIP_PROVIDER | Es el proveedor del grupo de identidades para cargas de trabajo que incluye la condición del atributo que se usará para los tokens firmados por el servicio de carga de trabajo de MPC. |
$PRIMUS_SERVICEACCOUNT | Es la cuenta de servicio que usa $PRIMUS_WORKLOAD_IDENTITY_POOL para acceder a los recursos protegidos. Esta cuenta de servicio tendrá permiso para ver las claves encriptadas que se almacenan en el bucket $PRIMUS_INPUT_STORAGE_BUCKET. |
$PRIMUS_ARTIFACT_REPOSITORY | Es el repositorio de artefactos para almacenar la imagen de contenedor de la carga de trabajo. |
$WORKLOAD_SERVICEACCOUNT | Es la cuenta de servicio que tiene permiso para acceder a la VM confidencial que ejecuta la carga de trabajo. |
$WORKLOAD_CONTAINER | Contenedor de Docker que ejecuta la carga de trabajo. |
$WORKLOAD_IMAGE_NAME | Nombre de la imagen del contenedor de la carga de trabajo. |
$WORKLOAD_IMAGE_TAG | Es la etiqueta de la imagen del contenedor de la carga de trabajo. |
- Ejecuta la siguiente secuencia de comandos para establecer los nombres de las variables restantes en valores basados en el ID de tu proyecto para los nombres de los recursos.
source config_env.sh
Configura recursos de Cloud
Como parte de este paso, configurarás los recursos de Cloud necesarios para la computación multipartidaria. Para este lab, usarás la siguiente clave privada: 0000000000000000000000000000000000000000000000000000000000000001
En un entorno de producción, generarás tu propia clave privada. Sin embargo, para los fines de este lab, dividiremos esta clave privada en dos partes y encriptaremos cada una. En una situación de producción, las claves nunca deben almacenarse en archivos de texto sin formato. En cambio, la clave privada se puede generar fuera de Google Cloud (o se puede omitir por completo y reemplazar por la creación personalizada de fragmentos de claves de MPC) y, luego, encriptar para que nadie tenga acceso a la clave privada ni a los fragmentos de claves. Para los fines de este lab, usaremos la CLI de gcloud.
Ejecuta la siguiente secuencia de comandos para configurar los recursos de Cloud necesarios. Como parte de estos pasos, se crearán los recursos que se mencionan a continuación:
- Un bucket de Cloud Storage (
$PRIMUS_INPUT_STORAGE_BUCKET) para almacenar los fragmentos de la clave privada encriptada. - Un bucket de Cloud Storage (
$PRIMUS_RESULT_STORAGE_BUCKET) para almacenar el resultado de la transacción de activos digitales - Una clave de encriptación (
$PRIMUS_KEY) y un llavero de claves ($PRIMUS_KEYRING) en KMS para encriptar los fragmentos de la clave privada - Un grupo de Workload Identity (
$PRIMUS_WORKLOAD_IDENTITY_POOL) para validar reclamos según las condiciones de atributos configuradas en su proveedor - Una cuenta de servicio (
$PRIMUS_SERVICEACCOUNT) adjunta al grupo de identidades para cargas de trabajo mencionado anteriormente ($PRIMUS_WORKLOAD_IDENTITY_POOL) con el siguiente acceso a IAM: roles/cloudkms.cryptoKeyDecrypterpara desencriptar los datos con la clave de KMSobjectViewerpara leer datos del bucket de Cloud Storageroles/iam.workloadIdentityUserpara conectar esta cuenta de servicio al grupo de identidades para cargas de trabajo
./setup_resources.sh
3. Crear carga de trabajo
Crea una cuenta de servicio de carga de trabajo
Ahora crearás una cuenta de servicio para la carga de trabajo con los roles y permisos necesarios. Para ello, ejecuta la siguiente secuencia de comandos, que creará una cuenta de servicio de carga de trabajo para la empresa A. La VM que ejecuta la carga de trabajo usará esta cuenta de servicio.
La cuenta de servicio de la carga de trabajo ($WORKLOAD_SERVICEACCOUNT) tendrá los siguientes roles:
confidentialcomputing.workloadUserpara obtener un token de certificaciónlogging.logWriterpara escribir registros en Cloud Logging.objectViewerpara leer datos del bucket de Cloud Storage$PRIMUS_INPUT_STORAGE_BUCKETobjectUserpara escribir el resultado de la carga de trabajo en el bucket$PRIMUS_RESULT_STORAGE_BUCKETde Cloud Storage
./create_workload_service_account.sh
Crear carga de trabajo
En este paso, se crea una imagen de Docker de la carga de trabajo. La carga de trabajo de este codelab es una aplicación de MPC simple de Node.js que firma transacciones digitales para transferir activos con partes de claves privadas encriptadas. Aquí se encuentra el código del proyecto de la carga de trabajo. El proyecto de carga de trabajo incluye los siguientes archivos.
package.json: Este archivo contiene la lista de paquetes que se deben usar para la aplicación de MPC de la carga de trabajo. En este caso, usamos las bibliotecas @google-cloud/kms, @google-cloud/storage, ethers y fast-crc32c. Aquí se encuentra el archivo package.json que usaremos para este codelab.
index.js: Es un punto de entrada de la aplicación de carga de trabajo y especifica qué comandos se deben ejecutar cuando se inicia el contenedor de carga de trabajo. También incluimos una muestra de transacción sin firmar que normalmente proporcionaría una aplicación no confiable que les pide a los usuarios su firma. Este archivo index.js también importa funciones de mpc.js, que crearemos a continuación. A continuación, se muestra el contenido del archivo index.js, que también puedes encontrar aquí.
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: Aquí es donde se firma la transacción. Importa funciones de kms-decrypt y credential-config, que abordaremos a continuación. A continuación, se muestra el contenido del archivo mpc.js, que también puedes encontrar aquí.
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: Este archivo contiene el código para la desencriptación con claves administradas en KMS. A continuación, se muestra el contenido del archivo kms-decrypt.js, que también puedes encontrar aquí.
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: El archivo almacena las rutas de acceso y los detalles del grupo de identidades para cargas de trabajo para la suplantación de la cuenta de servicio. Aquí se encuentra el archivo credential-config.js que usaremos para este codelab.
Dockerfile: Por último, crearemos nuestro Dockerfile que se usará para compilar la imagen de Docker de la carga de trabajo. Define el Dockerfile como se especifica aquí.
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" ]
Nota: LABEL "tee.launch_policy.allow_cmd_override"="true" en el Dockerfile es una política de lanzamiento establecida por el autor de la imagen. Permite que el operador anule el CMD cuando ejecuta la carga de trabajo. De forma predeterminada, allow_cmd_override se establece como falso. La etiqueta "tee.launch_policy.allow_env_override" le indica a Confidential Space qué variables de entorno pueden usar los usuarios de la imagen .
Ejecuta la siguiente secuencia de comandos para crear una carga de trabajo en la que se realizan los siguientes pasos:
- Crea Artifact Registry(
$PRIMUS_ARTIFACT_REPOSITORY) para almacenar la imagen de Docker de la carga de trabajo. - Actualiza el código de la carga de trabajo con los nombres de los recursos requeridos. Aquí se encuentra el código de la carga de trabajo que se usa para este codelab.
- Crea un Dockerfile para compilar una imagen de Docker del código de la carga de trabajo. Puedes encontrar el Dockerfile aquí.
- Compila y publica la imagen de Docker en Artifact Registry (
$PRIMUS_ARTIFACT_REPOSITORY) que creaste en el paso anterior. - Otorga permiso de lectura de
$WORKLOAD_SERVICEACCOUNTpara$PRIMUS_ARTIFACT_REPOSITORY. Esto es necesario para que el contenedor de la carga de trabajo extraiga la imagen de Docker de la carga de trabajo de Artifact Registry.
./create_workload.sh
Crea el nodo de cadena de bloques
Nodo de Ethereum de Ganache
Antes de autorizar la carga de trabajo, debemos crear la instancia de Ethereum Ganache. La transacción firmada se enviará a esta instancia de Ganache. Toma nota de la dirección IP de esta instancia. Después de ejecutar el siguiente comando, es posible que debas ingresar y para habilitar la 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. Autoriza y ejecuta la carga de trabajo
Autoriza la carga de trabajo
Como parte de este paso, configuraremos el proveedor del grupo de identidades para cargas de trabajo en el grupo de identidades para cargas de trabajo ($PRIMUS_WORKLOAD_IDENTITY_POOL). Hay condiciones de atributos configuradas para la identidad de carga de trabajo, como se muestra a continuación. Una de las condiciones es validar que la imagen de la carga de trabajo se extrae del repositorio de artefactos esperado.
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"
Ejecutar carga de trabajo
En esta sección, se explica cómo ejecutar la carga de trabajo en una Confidential VM. Para ello, pasaremos los argumentos de TEE necesarios con la marca de metadatos. Además, estableceremos variables de entorno para el contenedor de carga de trabajo con la marca "tee-env-*". La imagen tiene las siguientes variables:
NODE_URL: Es la URL del nodo de Ethereum que procesará la transacción firmada.RESULTS_BUCKET: Es el bucket que almacena el resultado de la transacción de MPC.KEY_BUCKET: Es el bucket que almacena las claves encriptadas de MPC.PRIMUS_PROJECT_NUMBER: Es el número de proyecto que se usa para el archivo de configuración de credenciales.PRIMUS_PROJECT_ID: Es el ID del proyecto que se usa para el archivo de configuración de credenciales. El resultado de la ejecución de la carga de trabajo se publicará en$PRIMUS_RESULT_STORAGE_BUCKET.PRIMUS_WORKLOAD_IDENTITY_POOL: Es el grupo de identidades para cargas de trabajo que se usa para validar las reivindicaciones.PRIMUS_WIP_POROVIDER: Es el proveedor de grupos de identidades para cargas de trabajo que incluye las condiciones de atributo que se usarán para validar los tokens que presenta la carga de trabajo.WORKLOAD_SERVICEACCOUNT: Es la cuenta de servicio de la carga de trabajo.
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}"
Verifica los resultados de Cloud Storage
Puedes ver el recibo de la transacción en Cloud Storage. Es posible que el Espacio Confidencial tarde unos minutos en iniciarse y en mostrar los resultados. Sabrás que el contenedor terminó cuando la VM esté en estado detenido.
- Ve a la página Navegador de Cloud Storage.
- Haz clic en
$PRIMUS_RESULT_STORAGE_BUCKET. - Haz clic en el archivo
transaction_receipt. - Haz clic en Descargar para descargar y ver la respuesta de la transacción.
Como alternativa, puedes ejecutar los siguientes comandos para ver el resultado.
gcloud config set project $PRIMUS_PROJECT_ID
gsutil cat gs://$PRIMUS_RESULT_STORAGE_BUCKET/transaction_receipt
Nota: Si no aparecen resultados, puedes ir a la VM de $WORKLOAD_VM en la página de la consola de Cloud de Compute Engine y hacer clic en "Puerto serie 1 (consola)" para ver los registros.
Verifica la transacción de la cadena de bloques de Ganache
También puedes ver la transacción en el registro de la cadena de bloques.
- Ve a la página de Cloud Compute Engine.
- Haz clic en
${ETHEREUM_NODE}VM. - Haz clic en
SSHpara abrir la ventana de SSH en el navegador. - En la ventana de SSH, ingresa
sudo docker pspara ver el contenedor de Ganache en ejecución. - Busca el ID del contenedor de
trufflesuite/ganache:v7.7.3. - Ingresa
sudo docker logs CONTAINER_IDy reemplaza CONTAINER_ID por el ID detrufflesuite/ganache:v7.7.3. - Consulta los registros de Ganache y confirma que haya una transacción en ellos.
5. Limpia
Aquí tienes la secuencia de comandos que se puede usar para limpiar los recursos que creamos como parte de este codelab. Como parte de esta limpieza, se borrarán los siguientes recursos:
- Es el bucket de almacenamiento de entrada que se usa para almacenar los recursos compartidos de claves encriptadas (
$PRIMUS_INPUT_STORAGE_BUCKET)). - Clave de encriptación (
$PRIMUS_KEY). - Es la cuenta de servicio que se usa para acceder a recursos protegidos (
$PRIMUS_SERVICEACCOUNT). - Grupo de identidades para cargas de trabajo (
$PRIMUS_WORKLOAD_IDENTITY_POOL). - Cuenta de servicio de la carga de trabajo (
$WORKLOAD_SERVICEACCOUNT) - Instancias de procesamiento de cargas de trabajo (
$WORKLOAD_VMy$ETHEREUM_NODE) - Bucket de almacenamiento de resultados que se usa para almacenar el resultado de la transacción (
$PRIMUS_RESULT_STORAGE_BUCKET). - Registro de artefactos que se usa para almacenar la imagen de la carga de trabajo (
$PRIMUS_ARTIFACT_REPOSITORY).
./cleanup.sh
Si terminaste de explorar, considera borrar tu proyecto.
- Ve a Cloud Platform Console.
- Selecciona el proyecto que deseas cerrar y, luego, haz clic en “Borrar” en la parte superior. Con esta acción, se programa la eliminación del proyecto.
¿Qué sigue?
Consulta algunos de estos codelabs similares…
- Datos compartidos protegidos en uso con Confidential Space
- Codelab de imágenes de contenedor firmadas
- Analiza datos confidenciales con Confidential Space
Lecturas adicionales
- ¿Te sientes aislado? Confidential Computing al rescate
- Confidential Computing en GCP
- Confidential Space: El futuro de la colaboración que preserva la privacidad
- Cómo Google e Intel hacen que Confidential Computing sea más seguro
- Privacidad vs. Progreso: Avance de la seguridad con la computación confidencial de Google Cloud