프로그래밍 가능한 계약 배포

유니버설 원장은 네트워크에 배포하여 관심 있는 참여자 간의 계약을 자동화하고 시행할 수 있는 프로그래밍 가능한 계약을 지원합니다.

이 튜토리얼에서는 개발자가 범용 원장 네트워크에서 프로그래밍 가능한 계약을 개발, 배포, 상호작용하는 데 필요한 단계를 보여줍니다.

시작하기 전에

이 튜토리얼을 완료하려면 다음이 필요합니다.

  • Google Cloud 콘솔에서 Cloud Shell을 활성화합니다.

    Cloud Shell 활성화

  • ROLE_CONTRACT_CREATOR이 있는 Universal Ledger 사용자 계정 이 계정이 계약 소유자가 됩니다.

  • ROLE_CONTRACT_PARTICIPANT이 있는 하나 이상의 범용 원장 사용자 계정 계약 소유자와 동일한 계정일 수 있습니다.

  • 선택적으로 이러한 사용자 계정을 대신하여 트랜잭션을 서명하고 제출할 수 있도록 범용 원장 CLI를 설정합니다.

범용 원장 역할은 계정 관리자가 생성한 사용자 계정에 할당할 수 있으며, CreateAccount 트랜잭션이 제출될 때 또는 계정이 이미 있는 경우 AddRoles 트랜잭션을 통해 나중에 수정할 수 있습니다. 실험 목적으로 Universal Ledger CLI를 사용하여 계정을 관리할 수도 있습니다.

환경 설정

설정을 간소화하기 위해 이 튜토리얼은 Cloud Shell 세션에서 제공되는 기본 환경을 대상으로 작성되었습니다. 다른 환경을 사용하는 경우 이러한 명령어를 수정해야 할 수 있습니다.

gculpyc 컴파일러는 GCULpy 언어로 작성된 소스 코드를 가져와 Universal Ledger의 바이트 코드를 생성합니다.

다음 명령어를 각각 실행하여 gculpyc Docker 이미지를 가져오고, 바이너리 실행을 위한 별칭을 정의하고, 바이너리가 작동하는지 확인합니다.

docker pull us-docker.pkg.dev/gcul-artifacts/images/client/gculpyc:preview
alias gculpyc="docker run --rm -i --user $(id -u):$(id -g) \
    --volume .:/workspace --workdir /workspace \
    us-docker.pkg.dev/gcul-artifacts/images/client/gculpyc:preview"
gculpyc --help

계약서 작성

GCULpy는 범용 원장의 계약을 작성하는 데 사용되는 언어입니다. 명확하고 감사 가능하며 이해하기 쉬운 계약 로직에 최적화된 Python의 정적 유형 하위 집합입니다. 이 설계는 안전한 코드 작성을 우선시하고 예기치 않거나 안전하지 않은 동작을 제한합니다. 자세한 내용은 GCULpy 언어 참조를 확인하세요.

GCULpy는 Python의 엄격한 하위 집합이므로 기존 워크플로 및 개발 관행과 함께 선호하는 통합 개발 환경 (IDE)을 계속 사용할 수 있습니다.

예를 들어 코드는 다음과 같을 수 있습니다.

import gcul

class Counter(gcul.Contract):
    """Example contract implementing a counter."""

    value: int

    def increment(self) -> None:
        """Increments the counter value by 1."""
        self.value += 1

이 샘플 코드를 복사하여 counter.py 파일에 저장합니다.

로컬에서 테스트

조만간 개발자는 로컬 시뮬레이션 환경에 액세스할 수 있게 됩니다. gcul Python 모듈의 일부로 제공되며 Python 환경 내에서 범용 원장 네트워크를 기본적으로 시뮬레이션하는 데 필요한 기능을 제공하도록 설계되었습니다. 따라서 로컬에서 계약을 실행하고 원하는 테스트 프레임워크를 사용하여 단위 테스트를 작성하여 배포 전에 계약의 신뢰성과 정확성을 보장할 수 있습니다.

계약서 컴파일

다음 gculpyc 명령어를 사용하여 앞의 계약 소스 코드를 바이트 코드로 컴파일합니다.

gculpyc --source_file counter.py --output_file counter.bin

계약 배포

ROLE_CONTRACT_CREATOR를 보유한 사용자 계정으로 서명된 CreateContract 트랜잭션을 제출하여 범용 원장 네트워크에 계약을 배포합니다.

범용 원장 CLI를 사용하는 경우 다음 명령어를 실행하여 이를 수행할 수 있습니다.

ul-cli contracts create \
    --alias counter-contract \
    --sender OWNER_ALIAS \
    counter.bin

다음을 바꿉니다.

  • OWNER_ALIAS: ROLE_CONTRACT_CREATOR이 있는 사용자 계정의 별칭입니다.

거래가 완료되면 이 명령어의 출력에 새로 배포된 계약의 ID가 포함됩니다. 예를 들면 다음과 같습니다.

Contract created: 1:CTR:005XvYfiSm3913Jwv4y8HVQucStJ2Ev15Sar6A1kNNX10

계약 메서드 호출

계약이 배포되면 ROLE_CONTRACT_PARTICIPANT 권한이 있는 사용자 계정은 InvokeContractMethod 트랜잭션을 제출하여 계약의 공개 메서드를 호출할 수 있습니다.

범용 원장 CLI를 사용하는 경우 다음 명령어를 실행하여 이를 수행할 수 있습니다.

ul-cli contracts invoke \
    --alias counter-contract \
    --method-name increment \
    --sender PARTICIPANT_ALIAS

다음을 바꿉니다.

  • PARTICIPANT_ALIAS: ROLE_CONTRACT_PARTICIPANT이 있는 사용자 계정의 별칭입니다.

계약 상태 읽기

이 튜토리얼을 마치려면 QueryAccount 요청을 제출하여 원장에 저장된 계약의 상태를 읽고 확인할 수 있습니다. 이는 범용 원장 계정의 세부정보를 쿼리하고 검색하는 데 사용되는 API 메서드와 동일합니다.

Universal Ledger CLI를 사용하여 다음을 실행할 수 있습니다.

ul-cli accounts describe --alias counter-contract

이제 카운터 값이 1로 설정되어 다음과 같은 출력이 생성됩니다.

Account: 1:CTR:005XvYfiSm3913Jwv4y8HVQucStJ2Ev15Sar6A1kNNX10
Contract account details:
  Owner: 1:USR:XCL:022uF6cVkTJBaa6pViqTuYqP4455jnRbRc4bWannZGg0b
  Contract fields:
    value: int64_value:1

  Balances:
    None

다음 단계