이 Codelab 정보
1. 개요
시작하기 전에 다음 기능과 개념에 대한 지식을 알고 있으면 이 Codelab을 진행하는 데 도움이 됩니다.
학습할 내용
이 실습에서는 Confidential Space를 사용하여 MPC 규격 블록체인 서명을 실행하기 위한 참조 구현을 제공합니다. 이 개념을 설명하기 위해 Primus 회사가 Secundus 회사에 디지털 애셋을 이전하려는 시나리오를 살펴보겠습니다. 이 시나리오에서 Primus 회사는 MPC 준수 모델을 사용합니다. 즉, 개별 비공개 키를 사용하는 대신 분산 키 공유를 사용합니다. 이러한 키 공유는 여러 당사자(여기서는 앨리스와 밥)가 보유합니다. 이 접근 방식을 통해 Primus는 간소화된 사용자 환경, 운영 효율성, 비공개 키 제어 등 여러 이점을 얻을 수 있습니다.
이 절차의 기본적인 측면을 설명하기 위해 기술 설정을 자세히 설명하고 Primus 회사에서 Secundus 회사로 디지털 저작물 이전을 시작하는 승인 및 서명 절차를 안내합니다. Primus 회사의 직원인 밥과 앨리스가 모두 거래를 승인해야 합니다.
이 참조 구현은 서명 작업을 보여 주지만 MPC 키 관리의 모든 측면을 다루지는 않습니다. 예를 들어 키 생성은 다루지 않습니다. 또한 Google Cloud 이외의 서비스를 사용하여 공동 서명을 생성하거나 공동 서명자가 자체 환경에서 블록체인 서명을 생성하도록 하는 등 대체 및 보완적인 접근 방식도 있습니다. 이는 보다 분산된 아키텍처입니다. 이 실습이 Google Cloud에서 MPC에 대한 다양한 접근 방식을 고안하는 데 도움이 되기를 바랍니다.
공동 서명자 키 재료를 사용하여 Confidential Space에서 이더리움 거래에 서명하는 간단한 워크로드를 사용합니다. 이더리움 거래 서명은 사용자가 이더리움 블록체인에서 거래를 승인할 수 있는 프로세스입니다. 이더리움 거래를 보내려면 비공개 키로 서명해야 합니다. 이렇게 하면 본인이 계정 소유자임을 증명하고 거래를 승인할 수 있습니다. 서명 프로세스는 다음과 같습니다.
- 발신자는 수신자 주소, 전송할 ETH 금액, 기타 관련 데이터를 지정하는 거래 객체를 만듭니다.
- 발신자의 비공개 키는 트랜잭션 데이터를 해싱하는 데 사용됩니다.
- 그런 다음 해시에 비공개 키로 서명합니다.
- 서명이 거래 객체에 첨부됩니다.
- 거래가 이더리움 네트워크로 브로드캐스트됩니다.
네트워크의 노드가 거래를 수신하면 서명을 확인하여 계정 소유자가 서명했는지 확인합니다. 서명이 유효하면 노드가 블록체인에 트랜잭션을 추가합니다.
먼저 필요한 Cloud 리소스를 구성합니다. 그런 다음 Confidential Space에서 워크로드를 실행합니다. 이 Codelab에서는 다음과 같은 대략적인 단계를 안내합니다.
- Confidential Space 실행에 필요한 Cloud 리소스를 구성하는 방법
- 다음 속성을 기반으로 보호된 리소스에 대한 액세스를 승인하는 방법
- 내용: 워크로드 컨테이너
- 위치: Confidential Space 환경 (Confidential VM의 Confidential Space 이미지)
- Who: 워크로드를 실행하는 계정
- Confidential Space VM 이미지를 실행하는 컨피덴셜 VM에서 워크로드를 실행하는 방법
필수 API
이 가이드를 완료하려면 지정된 프로젝트에서 다음 API를 사용 설정해야 합니다.
API 이름 | API 제목 |
cloudkms.googleapis.com | Cloud KMS |
compute.googleapis.com | Compute Engine |
confidentialcomputing.googleapis.com | 컨피덴셜 컴퓨팅 |
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 워크로드 서비스에서 서명한 토큰에 사용할 속성 조건이 포함된 워크로드 아이덴티티 풀 제공업체입니다. |
$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
프로덕션 환경에서는 자체 비공개 키를 생성합니다. 하지만 이 실습에서는 이 비공개 키를 두 개의 공유로 분할하고 각각을 암호화하겠습니다. 프로덕션 시나리오에서는 키를 일반 텍스트 파일에 저장해서는 안 됩니다. 대신 비공개 키를 Google Cloud 외부에서 생성하거나 (또는 완전히 건너뛰고 맞춤 MPC 키 샤드 생성으로 대체) 암호화하여 아무도 비공개 키 또는 키 셰어에 액세스할 수 없도록 할 수 있습니다. 이 실습에서는 Gcloud CLI를 사용합니다.
다음 스크립트를 실행하여 필요한 클라우드 리소스를 설정합니다. 이 단계의 일환으로 다음 리소스가 생성됩니다.
- 암호화된 비공개 키 공유를 저장할 Cloud Storage 버킷 (
$PRIMUS_INPUT_STORAGE_BUCKET
) - 디지털 애셋 거래의 결과를 저장할 Cloud Storage 버킷 (
$PRIMUS_RESULT_STORAGE_BUCKET
) - 비공개 키 공유를 암호화하는 KMS의 암호화 키 (
$PRIMUS_KEY
) 및 키링 ($PRIMUS_KEYRING
)입니다. - 공급업체에 구성된 속성 조건에 따라 클레임을 확인하는 워크로드 ID 풀 (
$PRIMUS_WORKLOAD_IDENTITY_POOL
)입니다. - 위에서 언급한 워크로드 ID 풀 (
$PRIMUS_WORKLOAD_IDENTITY_POOL
)에 연결된 서비스 계정 ($PRIMUS_SERVICEACCOUNT
)으로 다음 IAM 액세스 권한이 있습니다. roles/cloudkms.cryptoKeyDecrypter
를 사용하여 데이터를 복호화합니다.objectViewer
: Cloud Storage 버킷에서 데이터를 읽습니다.roles/iam.workloadIdentityUser
: 이 서비스 계정을 워크로드 아이덴티티 풀에 연결합니다.
./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: 이 파일에는 서비스 계정 명의 도용에 대한 워크로드 ID 풀 경로와 세부정보가 저장됩니다. 다음은 이 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로 설정됩니다. 라벨 '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 이미지를 가져올 수 있도록 하기 위해 필요합니다.
./create_workload.sh
블록체인 노드 만들기
Ganache 이더리움 노드
워크로드를 승인하기 전에 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. 워크로드 승인 및 실행
워크로드 승인
이 단계에서는 워크로드 아이덴티티 풀 ($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"
워크로드 실행
이 섹션에서는 컨피덴셜 VM에서 워크로드를 실행하는 방법을 설명합니다. 이렇게 하려면 메타데이터 플래그를 사용하여 필요한 TEE 인수를 전달합니다. 또한 'tee-env-*' 플래그를 사용하여 워크로드 컨테이너의 환경 변수를 설정합니다. 이미지에는 다음과 같은 변수가 있습니다.
NODE_URL
: 서명된 트랜잭션을 처리할 이더리움 노드의 URL입니다.RESULTS_BUCKET
: mpc 트랜잭션 결과를 저장하는 버킷입니다.KEY_BUCKET
: mpc 암호화 키를 저장하는 버킷입니다.PRIMUS_PROJECT_NUMBER
: 사용자 인증 정보 구성 파일에 사용되는 프로젝트 번호입니다.PRIMUS_PROJECT_ID
: 사용자 인증 정보 구성 파일에 사용된 프로젝트 ID입니다. 워크로드 실행 결과가$PRIMUS_RESULT_STORAGE_BUCKET
에 게시됩니다.PRIMUS_WORKLOAD_IDENTITY_POOL
: 사용자 인증 정보의 유효성을 검사하는 데 사용되는 워크로드 ID 풀입니다.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에서 거래 영수증을 볼 수 있습니다. 비공개 공간이 부팅되고 결과가 표시되기까지 몇 분 정도 걸릴 수 있습니다. VM이 중지 상태가 되면 컨테이너가 완료된 것입니다.
- Cloud Storage 브라우저 페이지로 이동합니다.
$PRIMUS_RESULT_STORAGE_BUCKET
을 클릭합니다.transaction_receipt
파일을 클릭합니다.- '다운로드'를 클릭하여 거래 응답을 다운로드하고 확인합니다.
또는 다음 명령어를 실행하여 결과를 확인할 수 있습니다.
gcloud config set project $PRIMUS_PROJECT_ID
gsutil cat gs://$PRIMUS_RESULT_STORAGE_BUCKET/transaction_receipt
참고: 결과가 표시되지 않으면 Compute Engine Cloud 콘솔 페이지의 $WORKLOAD_VM으로 이동하여 'Serial port 1 (console)(시리얼 포트 1(콘솔))'을 클릭하여 로그를 볼 수 있습니다.
Ganache 블록체인 거래 확인
블록체인 로그에서도 거래를 확인할 수 있습니다.
- Cloud Compute Engine 페이지로 이동합니다.
${ETHEREUM_NODE}
VM
아이콘을 클릭합니다.SSH
아이콘을 클릭하여 브라우저에서 SSH를 통해 연결 창을 엽니다.- SSH 창에서
sudo docker ps
를 입력하여 실행 중인 Ganache 컨테이너를 확인합니다. trufflesuite/ganache:v7.7.3
의 컨테이너 ID 찾기sudo docker logs CONTAINER_ID
를 입력하고 CONTAINER_ID를trufflesuite/ganache:v7.7.3
의 ID로 바꿉니다.- Ganache의 로그를 확인하고 로그에 트랜잭션이 표시되는지 확인합니다.
5. 삭제
다음은 이 Codelab의 일부로 만든 리소스를 정리하는 데 사용할 수 있는 스크립트입니다. 이번 정리 작업의 일환으로 다음 리소스가 삭제됩니다.
- 암호화된 키 공유를 저장하는 데 사용되는 입력 스토리지 버킷 (
$PRIMUS_INPUT_STORAGE_BUCKET)
. - 암호화 키 (
$PRIMUS_KEY
) - 보호된 리소스에 액세스하는 데 사용되는 서비스 계정 (
$PRIMUS_SERVICEACCOUNT
) - 워크로드 ID 풀 (
$PRIMUS_WORKLOAD_IDENTITY_POOL
) - 워크로드 서비스 계정 (
$WORKLOAD_SERVICEACCOUNT
) - 워크로드 컴퓨팅 인스턴스 (
$WORKLOAD_VM
및$ETHEREUM_NODE
) - 트랜잭션 결과를 저장하는 데 사용되는 결과 저장소 버킷입니다.(
$PRIMUS_RESULT_STORAGE_BUCKET
) - 워크로드 이미지를 저장하는 데 사용되는 아티팩트 저장소 (
$PRIMUS_ARTIFACT_REPOSITORY
)
./cleanup.sh
탐색이 완료되면 프로젝트를 삭제하는 것이 좋습니다.
- Cloud Platform Console로 이동합니다.
- 종료하려는 프로젝트를 선택한 다음 상단의 '삭제'를 클릭합니다. 그러면 프로젝트 삭제 일정이 예약됩니다.
다음 단계
다음과 같은 유사한 Codelab을 확인해 보세요.