プログラマブル コントラクトをデプロイする

Universal Ledger は、ネットワークにデプロイして、関係する参加者間の合意を自動化して適用できる、プログラム可能な契約をサポートしています。

このチュートリアルでは、Universal Ledger ネットワークでプログラム可能な契約を開発、デプロイ、操作するために必要な手順について説明します。

始める前に

このチュートリアルを完了するには、次のものが必要です。

  • Google Cloud コンソールで Cloud Shell をアクティブにします。

    Cloud Shell をアクティブにする

  • ROLE_CONTRACT_CREATOR を持つ Universal Ledger ユーザー アカウント。このアカウントが契約所有者になります。

  • ROLE_CONTRACT_PARTICIPANT を持つ 1 つ以上の Universal Ledger ユーザー アカウント。契約所有者と同じアカウントにすることもできます。

  • 必要に応じて、Universal Ledger CLI を設定して、これらのユーザー アカウントに代わってトランザクションに署名して送信できるようにします。

Universal Ledger のロールは、アカウント マネージャーがユーザー アカウントを作成するときに、CreateAccount トランザクションが送信されたときに割り当てることができます。アカウントがすでに存在する場合は、AddRoles トランザクションを使用して後で変更できます。テスト目的で、Universal Ledger CLI を使用してアカウントを管理することもできます。

環境の設定

設定を簡素化するため、このチュートリアルは Cloud Shell セッションで提供されるデフォルトの環境を対象としています。別の環境を使用している場合は、これらのコマンドを変更する必要があります。

gculpyc コンパイラは、GCULpy 言語で記述されたソースコードを受け取り、Universal Ledger のバイトコードを生成します。

次の各コマンドを実行して、gculpyc Docker イメージを pull し、バイナリを実行するためのエイリアスを定義して、バイナリが動作することを確認します。

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

契約書を作成する

GCULpy は、Universal Ledger の契約を記述するために使用される言語です。これは、明確で監査可能、かつ理解しやすいコントラクト ロジック用に最適化された、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 環境内で Universal Ledger ネットワークをネイティブにシミュレートするために必要な機能を提供するように設計されています。そのため、コントラクトをローカルで実行し、任意のテスト フレームワークを使用して単体テストを作成できるため、デプロイ前にコントラクトの信頼性と正確性を確保できます。

契約をコンパイルする

次の gculpyc コマンドを使用して、上記のコントラクト ソースコードをバイトコードにコンパイルします。

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

コントラクトをデプロイする

ROLE_CONTRACT_CREATOR を保持するユーザー アカウントによって署名された CreateContract トランザクションを送信して、コントラクトを Universal Ledger ネットワークにデプロイします。

Universal Ledger 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 トランザクションを送信して、コントラクト内の任意のパブリック メソッドを呼び出すことができます。

Universal Ledger CLI を使用している場合は、次のコマンドを実行します。

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

次のように置き換えます。

  • PARTICIPANT_ALIAS: ROLE_CONTRACT_PARTICIPANT を持つユーザー アカウントのエイリアス。

契約の状態を読み取る

このチュートリアルを完了するには、QueryAccount リクエストを送信して、台帳に保存されている契約の状態を読み取り、確認します。これは、Universal Ledger アカウントの詳細をクエリして取得するために使用される 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

次のステップ