GCULpy は、安全性、読みやすさ、監査可能性を重視して設計された、Python の厳密な静的型付けサブセットです。その設計では、一般的なスマート コントラクトの脆弱性を防ぎ、コントラクトの動作が常に予測可能になるように、Python の特定の動的機能を意図的に制限しています。
このページでは、GCULpy 言語仕様のリファレンスを提供します。これには、Universal Ledger ネットワーク上の契約のコアコンセプトとライフサイクルが含まれます。
基本コンセプト
次のコントラクトは、GCULpy でサンプル ERC20 トークンを定義しています。
import gcul
class ERC20Token(gcul.Contract):
"""Sample ERC20 implementation for the Universal Ledger."""
symbol: str
total_supply: int
balance: gcul.AccountField[int]
def __init__(self, symbol: str):
self.symbol = symbol
self.total_supply = 0
def mint(self, beneficiary: gcul.Account, value: int) -> int:
"""Mints tokens to the given beneficiary."""
assert self.is_owner(gcul.sender), "Only the owner can mint"
assert value >= 0, "Mint amount must be non-negative"
self.total_supply += value
self.balance[beneficiary] += value
return value
def transfer(self, beneficiary: gcul.Account, value: int) -> int:
"""Transfers tokens from the sender to the given beneficiary."""
assert value >= 0, "Transfer amount must be non-negative"
assert (
value <= self.balance[gcul.sender]
), "Sender does not have enough balance"
self.balance[gcul.sender] -= value
self.balance[beneficiary] += value
return value
GCULpy 契約は、gcul.Contract から継承するクラスです。これには、フィールド(状態を保存)とメソッド(フィールドを操作する処理ロジック)が含まれます。
フィールド
GCULpy 契約の状態はフィールドに保存されます。すべてのフィールドは、クラスレベルで静的型で宣言する必要があります。フィールドには次の 2 種類があります。
契約フィールドには、契約自体に保存されている単一の値が格納されます。
ERC20Tokenの例では、symbol: strとtotal_supply: intは契約フィールドです。アカウント フィールドには、コントラクトを操作するアカウントごとに個別の値が保持されます。これらは
gcul.AccountField[T]で宣言されます。ここで、Tはアカウントごとの値のタイプです。ERC20Tokenの例では、balance: gcul.AccountField[int]はアカウント フィールドです。コントラクトがそのアカウント用に予約されたストレージ スペースに書き込むには、ストレージ権限を明示的にコントラクトに付与する必要があります。データが保存されると、コントラクト インスタンスのみがデータを変更できます。アカウントは変更できません。
制限 フィールドには次のストレージ上限があります。いずれかの上限を超えるトランザクションは失敗します。
- コントラクトのすべてのコントラクト フィールドは、1 つのストレージ エントリを共有します。このエントリには、合計で約 5 MiB のシリアル化されたデータを保持できます。
- コントラクトが個々のアカウントに保存するすべてのアカウント フィールドは、合計で最大 1 MiB のシリアル化されたデータを保持できます。
メソッド
メソッドは、コントラクトの実行可能なロジックを定義します。これらは Python メソッドのように動作し、コントラクトのフィールドを読み取りまたは変更できます。
__init__: コンストラクタは、コントラクトが最初にデプロイされたときに 1 回だけ呼び出されます。すべてのコントラクト フィールドに、コンストラクタで値を割り当てる必要があります。コンストラクタはアカウント フィールドを初期化しません。各アカウントの値は、そのアカウントがストレージ権限を付与したときに作成されます。プライベート メソッド: アンダースコアで始まるメソッド(
_internal_logicなど)はプライベートであり、同じコントラクト内の他のメソッドからのみ呼び出すことができます。Universal Ledger インタープリタは、この制約を適用します。パブリック メソッド: アンダースコア(
_)で始まらないメソッドはすべてパブリックです。ROLE_CONTRACT_PARTICIPANTを持つユーザーは、InvokeContractMethod トランザクションを送信することで、パブリック メソッドを呼び出すことができます。
制限 パブリック メソッドとすべての @gcul.readonly メソッドは、シグネチャで可変型(list や dict など)を使用できません。代わりに、Sequence や Mapping などの読み取り専用の型宣言を使用します。
制限 実行中、メソッドはネットワーク全体でのコンピューティング使用量の上限に制限されます。この上限を超えると、トランザクションが失敗します。
契約ライフサイクル
以降のセクションでは、GCULpy 契約のライフサイクルに関連する一般的なオペレーションについて説明します。
コントラクトをデプロイする
まず、gculpyc コンパイラを使用して GCULpy ソースコードをコンパイルします。次に、ROLE_CONTRACT_CREATOR を持つユーザーが CreateContract トランザクションを送信して、コンパイルされたバイトコードを Universal Ledger ネットワークにデプロイします。詳細な手順については、プログラム可能な契約をデプロイするチュートリアルをご覧ください。
このようなトランザクションは次のようになります。
client_transaction {
sender_id: "OWNER_ACCOUNT_ID"
create_contract_transaction {
contract_bytes: "COMPILED_BYTECODE"
init_arguments {
key: "symbol"
value: { string_value: "US02079K1079" }
}
}
}
ネットワークがこの取引を処理すると、次のようになります。
- コンストラクタ(
__init__メソッド)が、指定された引数を使用して実行され、新しいコントラクト インスタンスが作成されます。 - トランザクションの送信者がコントラクトのオーナーになります。
- コントラクト インスタンスは台帳に永続的に保存され、一意のコントラクト ID が割り当てられます。この ID は、トランザクション出力の一部として返されます。
権限を付与する
コントラクトがアカウント(ユーザーのアカウントまたは別のコントラクト)に代わってアカウント フィールドにデータを保存するには、データを保存するコントラクトにストレージ権限を付与する必要があります。これは重要なセキュリティ手順です。
ユーザー アカウントに権限を付与する
ROLE_CONTRACT_PARTICIPANT を持つユーザーは、特定のコントラクト ID の GrantContractPermissions トランザクションを送信できます。
client_transaction {
sender_id: "PARTICIPANT_ACCOUNT_ID"
grant_contract_permissions_transaction {
contract_id: "CONTRACT_ID"
permissions: CONTRACT_PERMISSION_STORAGE
}
}
ネットワークがこの取引を処理すると、次のようになります。
- コントラクトでアカウント フィールドが定義されていない場合、トランザクションは拒否されます。
- コントラクトでアカウント フィールドが定義されている場合、それらのフィールドはすべてデフォルト値(
contract.balance[gcul.sender] = 0など)で入力されます。これらの値は、アカウントのデータの一部としてワールド状態に保存されます。
委任契約の権限を付与する
ROLE_CONTRACT_PARTICIPANT を持つユーザーは、GrantContractPermissions トランザクションを送信して、1 つのコントラクトが所有する別のコントラクトに代わってデータを保存できるようにすることができます。
client_transaction {
sender_id: "OWNER_ACCOUNT_ID"
grant_contract_permissions_transaction {
contract_id: "TARGET_CONTRACT_ID"
delegate_contract_id: "DELEGATE_CONTRACT_ID"
permissions: CONTRACT_PERMISSION_STORAGE
}
}
ネットワークがこの取引を処理すると、次のようになります。
- トランザクションの送信者(
sender_id)は、delegate_contract_idで識別される契約の所有者である必要があります。 - コントラクトは自身にストレージ権限を付与できないため、
delegate_contract_idはcontract_idと異なる必要があります。 - ストレージ権限は、トランザクションの送信者ではなく、
delegate_contract_idで指定されたコントラクトにのみ付与されます。 - ターゲット コントラクト
contract_idで定義されたアカウント フィールドは、デリゲート コントラクトdelegate_contract_id用に初期化されます。これにより、ターゲット コントラクトのメソッドは、クロス コントラクト呼び出し中にgcul.callerまたはgcul.senderをキーとするアカウント フィールドに安全にアクセスできます。
コントラクト メソッドを呼び出す
コントラクトがデプロイされ、必要な権限が付与されると、ユーザーはパブリック メソッドを呼び出してコントラクトを操作できます。ROLE_CONTRACT_PARTICIPANT を持つユーザーは、コントラクト ID、メソッド名、メソッド引数値を指定して InvokeContractMethod トランザクションを送信できます。
client_transaction {
sender_id: "PARTICIPANT_ACCOUNT_ID"
invoke_contract_method_transaction {
contract_id: "CONTRACT_ID"
method_name: "mint"
method_arguments {
key: "beneficiary"
value: { account_id: "BENEFICIARY_ID" }
}
method_arguments {
key: "value"
value: { int64_value: 10 }
}
}
}
ネットワークがこの取引を処理すると、次のようになります。
- 指定された
CONTRACT_IDに関連付けられている契約インスタンスが取得されます。 mint(beneficiary=Account("BENEFICIARY_ID"), value=10)メソッドが実行されます。受益者のAccountオブジェクトは、ランタイムによってビルドされ、検証されます。このメソッドのロジックでは、指定された ID が有効であり、台帳上の既存のアカウントを参照していると想定しても問題ありません。- なんらかの理由でメソッドが失敗すると、トランザクションは失敗し、コントラクトの状態は更新されません。
- メソッドが成功すると、更新された契約の状態がワールド状態に記録されます。
言語仕様
GCULpy は安全性と予測可能性を考慮して設計されているため、いくつかの Python 機能が許可されていません。これらは制限ラベルで示されます。これらの制限は、コントラクト ロジックを読みやすく、監査しやすく、静的に分析しやすくするために導入された、永続的な言語機能であり、予期しない動作や安全でない動作を制限することを目的としています。
その他の機能には、ロードマップ ラベルが付いています。これらは実装ロードマップにありますが、gculpyc コンパイラではまだサポートされていません。
型
GCULpy は、静的型付けを重視した、さまざまな一般的な変数型をサポートしています。
コアバリューのタイプ:
int、bool、str、Noneはすでにサポートされています。- ロードマップ
Decimal、bytes、Enumはロードマップにあります。 - 制限
floatとcomplexは使用できません。 - 制限
int値は、-263 から 263 - 1 までの符号付き 64 ビット整数です。この範囲外の整数リテラルはコンパイル時エラーになり、この範囲外の結果になるオペレーションはランタイム エラーになります。 - 制限
str値は最大 1,000,000 文字です。これより長い文字列リテラルを使用すると、コンパイル時にエラーが発生します。メソッドの引数として長い文字列を渡したり、オペレーションの結果として長い文字列を生成したりすると、ランタイム エラーが発生します。
コンテナタイプ:
listとdict:list[T]: 変更可能なシーケンス。インデックス登録(my_list[0]など)とappend()メソッドをサポートします。dict[K, V]: 変更可能なマッピング。インデックス登録(my_dict[key]など)とpop()メソッドをサポートします。
collections.abc.Sequenceとcollections.abc.Mapping:collections.abc.Sequence[T]: シーケンスへの読み取り専用参照。インデックス(my_seq[0]など)による要素の読み取りをサポートしていますが、要素の変更や削除はできません。list[T]はSequence[T]のサブタイプであるため、list[T]値またはリストリテラルをSequence[T]型のターゲットに渡す、返す、または割り当てることができますが、Sequence[T]をlist[T]に割り当てることはできません。collections.abc.Mapping[K, V]: マッピングへの読み取り専用参照。キー(my_map[key]など)によるエントリの読み取りをサポートしますが、エントリの変更や削除はできません。dict[K, V]はMapping[K, V]のサブタイプであるため、dict[K, V]値または辞書リテラルをMapping[K, V]型のターゲットに渡す、返す、または割り当てることができますが、Mapping[K, V]をdict[K, V]に割り当てることはできません。
- ロードマップ
tuple、set、dataclassはロードマップにあります。 - 制限 コンテナ内の値には、具体的な型を指定する必要があります。たとえば、
dict[str, int]は許可されますが、プレーンなdictやdict[str, Any]は許可されません。 - ロードマップ リストのスライス(例:
my_list[1:3])。 - ロードマップ
.get()、.keys()、.values()、.items()、.clear()、.extend()などの他のメソッド。
制限 すべての変数(コントラクト フィールド、アカウント フィールド、関数パラメータ、戻り値の型など)は、静的に定義して型指定する必要があります。実行時に型を変更することはできず、具象型のみがサポートされます。型を値として使用することはできません。たとえば、変数に格納したり、引数として関数に渡したりすることはできません。宣言されていないフィールドに値を割り当てようとすると、コンパイル時にエラーが発生します。
制限 ローカル変数は、読み取る前に割り当てる必要があります。ローカル変数にはデフォルト値がないため、割り当てられる前に読み取ると、ランタイム エラーが発生します。
クラスと継承
定義できるのは、gcul.Contract または gcul.ContractInterface の直接のサブクラスであるクラスのみです。この厳格なルールにより、Python の完全な継承の複雑さを回避できます。これにより、見つけにくいバグが発生し、コードの推論が困難になる可能性があります。セキュリティ上の理由から、親クラスのプロパティまたはメソッドをオーバーライドしようとするとエラーが発生し、予期しない動作に対する明確な保護が提供されます。
ロードマップ GCULpy は、基本原則を維持しながら、より柔軟な機能を提供します。ロードマップには、@override デコレータで明示的に管理されるメソッド オーバーライドを使用した、ユーザー定義クラスの単一継承のサポートが含まれています。さらに、super() 組み込みは、直接的で予測可能なオペレーションを保証するために、引数なしの形式でのみサポートされます。
gcul モジュール
GCULpy には、コントラクト開発に不可欠な型、デコレータ、変数を備えた組み込みの gcul モジュールが用意されています。
クラス gcul.Contract
すべての契約の基本クラス。インスタンスを直接作成することはできません。契約は、CreateContract トランザクションを介してのみインスタンス化されます。基本 gcul.Contract クラスのメソッドとプロパティは、サブクラスでオーバーライドできません。
Contract.is_owner(account: Account) -> bool指定されたアカウントが契約所有者の場合は
Trueを返します。Contract.call(target: ContractInterface, payment: Amount | None = None) -> ContractMethodstargetとのクロス契約インタラクションを開始します。ターゲットのメソッドを直接呼び出す(例:target.foo())代わりに、self.call()を使用して、台帳ランタイムを介して呼び出しを明示的にルーティングする必要があります。このメカニズムは、ターゲット コントラクトで対応するパブリック メソッドを呼び出すために使用される安全なプロキシ オブジェクトを返します。これにより、実行境界が厳密に適用され、paymentが安全に配信されます。詳しくは、ContractInterface をご覧ください。@gcul.payableで修飾されたメソッドを呼び出す場合は、paymentを指定する必要があります。支払い不可のメソッドの場合は省略する必要があります。targetは別の契約である必要があります。self.call()を介して現在のコントラクトを呼び出すと、ランタイム エラーが発生します。同じコントラクトで別のメソッドを呼び出すには、self.foo()などのメソッドを直接呼び出します。Contract.native_transfer(beneficiary: Account, amount: Amount) -> None契約の残高から
beneficiaryに台帳上の金額を直接転送します。Contract.id: str契約の一意の文字列 ID。
クラス gcul.Account
台帳上のユーザー アカウントまたは契約アカウントを表す組み込み型。gcul.Account オブジェクトを直接作成することはできません。ランタイム環境によって作成され、関数またはメソッドの引数として提供されます。アカウントをトランザクション引数として渡すには、アカウント ID を保持する AccountValue を指定します。ランタイムは ID を検証し、完全なアカウント オブジェクトに変換します。ID が登録済みのアカウントに属していない場合、トランザクションは失敗します。これにより、有効なアカウントのみを操作できるようになります。
このクラスの定義は、おおよそ次のようになります。
@dataclasses.dataclass(frozen=True)
class Account:
"""A valid account on the ledger."""
id: str # The ID of the account as a string.
Account.id: strアカウントの一意の文字列 ID。
クラス gcul.Amount
特定の元帳通貨で表される金銭的価値を表します。gcul.Amount(value: int, currency: gcul.Currency) を使用して金額をインスタンス化します。このクラスの定義は、おおよそ次のようになります。
@dataclasses.dataclass(frozen=True)
class Amount:
"""Represents an amount denominated in a ledger currency."""
value: int
currency: Currency
クラス gcul.Currency
台帳上の完全修飾通貨を表します。このクラスの定義は、おおよそ次のようになります。
@dataclasses.dataclass(frozen=True)
class Currency:
"""Represents a fully qualified currency on the ledger."""
code: str
operator_id: str
クラス gcul.ContractInterface
コントラクトの公開インターフェースを宣言するための基本クラス。基本 gcul.ContractInterface クラスのメソッドとプロパティは、サブクラスでオーバーライドできません。また、インターフェース宣言のメソッドにコードを含めることはできません。... のみを使用できます。
台帳にデプロイされた別のコントラクトのメソッドを呼び出すには、gcul.ContractInterface を継承するインターフェース クラスを宣言します。メソッド スタブは、ターゲット コントラクト内の対応する宣言と一致する必要があります。これには、引数、戻り値の型、デコレータ アノテーション(@gcul.readonly や @gcul.payable など)が含まれます。
コントラクト コード内で self.call(target, payment) を使用して、別のコントラクトからメソッドを呼び出します。
次の例は、TokenVendor コントラクトが ERC20Interface を実装する別のコントラクトとどのようにやり取りするかを示しています。self.call() を使用して、台帳上の通貨支払いと引き換えにトークンを購入者に転送します。
class ERC20Interface(gcul.ContractInterface):
"""Interface for an external ERC20 token contract."""
def transfer(self, beneficiary: gcul.Account, value: int) -> int:
...
class TokenVendor(gcul.Contract):
"""A vendor contract that distributes ERC20 tokens."""
price_per_token: int
def __init__(self, price_per_token: int) -> None:
self.price_per_token = price_per_token
@gcul.payable
def purchase_tokens(self, token: ERC20Interface, quantity: int) -> int:
"""Accepts on-ledger currency for a specific quantity of ERC20 tokens."""
# Enforce positive quantity.
assert quantity > 0, "Quantity must be positive"
# Calculate the required payment.
required_payment = quantity * self.price_per_token
assert gcul.payment.value == required_payment, "Incorrect payment amount"
# Invokes `transfer` on the external ERC20 token contract
# to move tokens from the vendor's own balance to the caller.
return self.call(token).transfer(gcul.caller, quantity)
インターフェース タイプは、メソッド パラメータとしてだけでなく、コントラクト フィールドとしても使用できます。インターフェースをフィールドに保存すると、コントラクトはトランザクション間で別のコントラクトへの参照を保持し、後でその参照を置き換えることができます。次のコントラクトの例では、前述の ERC20Interface を使用しています。
class Router(gcul.Contract):
"""Holds a replaceable reference to an ERC20 token contract."""
target: ERC20Interface
def __init__(self, target: ERC20Interface) -> None:
self.target = target
def set_target(self, new_target: ERC20Interface) -> None:
assert self.is_owner(gcul.sender), "Only the owner can set the target"
self.target = new_target
クラス gcul.AccountField
アカウント フィールドを宣言するための組み込みの汎用型。gcul.AccountField[T] は、コントラクトにストレージ権限を付与したアカウントごとに、T 型の個別の値を保持します。これは gcul.Account キーを使用したマッピングとして動作し、特定のアカウントごとに値を読み書きするために使用できます。次に例を示します。
class Token(gcul.Contract):
balance: gcul.AccountField[int]
def deposit(self, account: gcul.Account, value: int) -> None:
self.balance[account] = value # Writes the value for one account.
def get_balance(self, account: gcul.Account) -> int:
return self.balance[account] # Reads the value for one account.
T はデフォルト値を持つ型である必要があります。そのため、gcul.Account、gcul.Amount、gcul.Currency、インターフェース型はアカウント フィールドの値として使用できません。アカウントがコントラクトにストレージ権限を付与すると、すべてのアカウント フィールドに、そのアカウントのタイプのデフォルト値が入力されます。
制限 アカウント フィールドでサポートされているオペレーションは、アカウントを使用したインデックス登録のみです。フィールド自体を変数に割り当てたり、引数として渡したり、関数から返したり、反復処理したりすることはできません。
制限事項: アカウント フィールドのエントリは削除できません。保存された値は上書きできますが、エントリ自体は永続的です。
制限 gcul.sender、gcul.caller、およびメソッド引数として渡された gcul.Account(リストまたは他のコンテナ内を含む)のアカウント フィールドは、メソッドの実行前に読み込まれます。他のアカウントの場合、1 つのトランザクションで最大 15 個の異なる (contract, account) ペアのアカウント フィールドを遅延読み込みできます。トランザクションで同じペアのアカウント フィールドに複数回アクセスしても、1 回としてカウントされます。この上限を超えるトランザクションは失敗します。
@gcul.readonly
コントラクト メソッドを読み取り専用としてアノテーションします。このデコレータを使用したメソッド宣言では、契約状態を変更したり、台帳上の通貨転送を行ったりすることはできません。また、シグネチャで可変コンテナ型(list や dict など)を使用することはできません。代わりに、Sequence や Mapping などの読み取り専用型の宣言を使用する必要があります。
@gcul.payable
コントラクト メソッドに、実行に支払いが必要であることを示すアノテーションを付けます。メソッドが gcul.payment を使用してオンレジャー通貨の支払いを受け取ることを想定している場合は、このデコレータでマークする必要があります。そうしないと、トランザクションは失敗します。
gcul.sender: gcul.Account
現在の InvokeContractMethod トランザクションに署名して送信したアカウントへの参照を保持します。gcul.sender の値は、クロス契約呼び出しが含まれている場合でも、トランザクションの実行中に変更されることはありません。これは、直前の呼び出し元を参照する gcul.caller とは異なります。
gcul.caller: gcul.Account
現在のメソッドの直接の呼び出し元への参照を保持します。直接ユーザー トランザクションの場合、gcul.caller は、トランザクションを送信したユーザーを指す gcul.sender と一致します。クロス契約呼び出しの場合、gcul.caller は呼び出し元契約のアカウント ID に対応します。コントラクト内の内部呼び出しでは、gcul.caller の値は変更されません。
gcul.payment: gcul.Amount
@gcul.payable で修飾されたメソッドに転送された支払いを保持します。支払い不可のメソッド内で gcul.payment にアクセスすると、コンパイル時エラーが発生します。
演算子
Python で使用可能なほとんどの演算子は GCULpy でサポートされており、想定どおりに動作します。
- 加算(
+)と減算(-)(単項形式と二項形式を含む)。 - 乗算(
*)、切り捨て除算(//)、剰余(%)。 - 正の指数に対するべき乗(
**)。 - 比較(
<、<=、>、>=、==、!=)。 - ビット演算 AND(
&)、OR(|)、XOR(^)、左シフト(<<)、右シフト(>>)、否定(~)。 - ブール演算子(
and、or、not)。 - ロードマップ オブジェクト ID(
is)。 - 制限 負の指数は使用できません。ランタイム エラーが発生します。
- 制限 戻り値の型が
floatであるため、真の除算(/)は許可されず、コンパイル時エラーが発生します。
制御フロー
Python のほとんどの制御フロー ステートメントは、GCULpy で同じセマンティクスで動作します。
passステートメント。- 内部関数呼び出し(同じコントラクト、非再帰)。
assertステートメント。if ... then .. else ...ステートメント。for VAR in CONTAINERステートメント。- 外部関数呼び出し(他のコントラクトへの呼び出し、非再帰的)。
breakステートメントとcontinueステートメント。raiseステートメント。- ロードマップ
try ... exceptステートメント。 - ロードマップ
matchステートメント。 - ロードマップ
generatorsおよびyieldステートメント。 - ロードマップ: コンテキスト マネージャーと
withステートメント。
制限 GCULpy は、無限ループを防ぎ、静的分析を容易にするために、意図的にチューリング不完全になっています。この適用方法は次のとおりです。
- 無限ループなし: 反復処理は、
range(...)を使用した有限コンテナまたは有界シーケンスに対するforループでのみ許可されます。whileループは許可されません。リストへの要素の追加や削除、辞書へのキーの追加など、一部のコンテナの更新は、反復処理中には許可されません。 - 再帰なし: 関数は、直接的または間接的に自身を呼び出すことはできません。ランタイム環境は、静的チェックとランタイム チェックの両方を実行して、再帰の使用を検出して拒否します。
- 非同期制御フローなし: 予測可能性、セキュリティ、決定論的実行というコア設計原則を維持するため、
asyncプリミティブの使用は許可されていません。非同期オペレーションでは、プログラムの制御フローを推論することが難しく、脆弱性や競合状態につながることがよくあります。
組み込みの関数
GCULpy は、次の組み込み関数をサポートしています。
abs(x)整数
xの絶対値を返します。引数はint型にする必要があります。len(s)文字列または有限コンテナの長さ(アイテム数)を返します。
max(iterable)
max(arg1, arg2, *args)イテラブル内の最大の項目、または 2 つ以上の引数のうち最大のものを返します。空のイテラブルで
max()を呼び出すと、ランタイム エラーが発生します。min(iterable)
min(arg1, arg2, *args)イテラブル内の最小のアイテム、または 2 つ以上の引数のうち最小の引数を返します。空のイテラブルで
min()を呼び出すと、ランタイム エラーが発生します。range(stop)
range(start, stop[, step=1])ゼロ以外の整数
stepを使用して、整数の等差数列を生成します。制限
forループ(for i in range(10): ...など)でのみインラインで使用できます。Range オブジェクトは、変数に割り当てたり、フィールドに保存したり、関数に引数として渡したり、len()でクエリしたりすることはできません。
ロードマップ 次の組み込み関数は、実装ロードマップにあります。
|
A
B
C
D |
E
F
H
I
L |
O
P
R |
S
T
Z |
リリースノート
2026 年 11 月 3 日
gculpycコンパイラ(v0.2.0)の GA 版をリリースしました。これには、クロス コントラクト呼び出し、台帳上の通貨の送金と支払い、@gcul.readonlyメソッド、list、追加の制御フロー ステートメント、組み込み関数のサポートが含まれます。2026 年 1 月 28 日。
gculpycコンパイラの初期バージョンが、Universal Ledger の限定公開プレビューの参加者に提供されました。コンパイラを使用したチュートリアルについては、プログラム可能なコントラクトをデプロイするをご覧ください。