現像 > AssemblyScript API > AssemblyScript API

AssemblyScript API

Reading time: 32 min

注意: graph-cli/graph-ts のバージョン 0.22.0 より前にサブグラフを作成した場合、古いバージョンのAssemblyScriptを使用しているので、マイグレーションガイド を参照することをお勧めします。

このページでは、サブグラフのマッピングを記述する際に、どのような組み込み API を使用できるかを説明します。 すぐに使える API は 2 種類あります:

  • the Graph TypeScript library (graph-ts) and
  • graph codegenによってサブグラフファイルから生成されたコードです。

また、AssemblyScriptとの互換性があれば、他のライブラリを依存関係に追加することも可能です。 マッピングはこの言語で書かれているので、言語や標準ライブラリの機能については、 AssemblyScript wikiが参考になります。

API リファレンス

このセクションへのリンク

@graphprotocol/graph-tsライブラリは、以下の API を提供しています:

  • Ethereum スマートコントラクト、イベント、ブロック、トランザクション、Ethereum の値を扱うためのethereumAPI
  • エンティティをグラフノードのストアからロードしたり、ストアに保存したりするstoreAPI
  • A log API to log messages to the Graph Node output and Graph Explorer.
  • IPFS からファイルをロードするipfsAPI
  • JSON データを解析するためのjsonAPI
  • 暗号機能を使用するためのcryptoAPI
  • Ethereum、JSON、GraphQL、AssemblyScript など、異なるタイプのシステム間で変換するための低レベルプリミティブ

サブグラフマニフェストapiVersionは、特定のサブグラフのマッピングAPIバージョンを指定します。このバージョンは、Graph Nodeによって実行されます。

バージョンリリースノート
0.0.9Adds new host functions eth_get_balance & hasCode
0.0.8Adds validation for existence of fields in the schema when saving an entity.
0.0.7Ethereum タイプに TransactionReceiptLog クラスを追加
Ethereum Event オブジェクトに receipt フィールドを追加。
0.0.6Ethereum Transactionオブジェクトにnonceフィールドを追加
Ethereum BlockオブジェクトにbaseFeePerGasを追加。
0.0.5AssemblyScriptはバージョン0.19.10にアップグレードされました(このバージョンアップには変更点が含まれていますので Migration Guide) をご覧ください)。
ethereum.transaction.gasUsedの名前がethereum.transaction.gasLimitに変更
0.0.4Ethereum SmartContractCall オブジェクトにfunctionSignatureフィールドを追加
0.0.3イーサリアムコールオブジェクトにfromフィールドを追加
etherem.call.addressethereum.call.toに変更。
0.0.2Ethereum Transaction オブジェクトに inputフィールドを追加

Documentation on the base types built into AssemblyScript can be found in the AssemblyScript wiki.

以下の追加型は@graphprotocol/graph-tsで提供されています。

'@graphprotocol/graph-ts'から{ ByteArray } をインポートします。

ByteArrayは、u8の配列を表します。

Construction

  • fromI32(x: i32): ByteArray - Decomposes x into bytes.
  • fromHexString(hex:: 文字列): ByteArray - 入力長は偶数でなければなりません。0xのプレフィックスはオプションとなります。

Type conversions

  • toHexString(): string - 0x を先頭に持つ 16 進文字列に変換します。
  • toString(): string - バイトを UTF-8 文字列として解釈します。
  • toBase58(): string - バイトをbase58の文字列にエンコードします。
  • toU32(): u32 - バイトをリトルエンディアンの u32 として解釈し、オーバーフローした場合にスローします。
  • toI32(): i32 - バイト配列をリトルエンディアンの i32 として解釈し、オーバーフローした場合にスローします。

Operators

  • equals(y: ByteArray): bool-x == y` と書くことができます。
  • concat(other: ByteArray) : ByteArray - thisother を直接続けた ByteArray を返します。
  • concatI32(other: i32) : ByteArray - thisother のバイト表現を直接続けた ByteArray を返します。
'@graphprotocol/graph-ts'から { BigDecimal } をインポートします。

BigDecimalは、任意の精度の小数を表現するために使用されます。

Note: Internally BigDecimal is stored in IEEE-754 decimal128 floating-point format, which supports 34 decimal digits of significand. This makes BigDecimal unsuitable for representing fixed-point types that can span wider than 34 digits, such as a Solidity ufixed256x18 or equivalent.

Construction

  • constructor(bigInt: BigInt) - BigInt から BigDecimal を生成します。
  • static fromString(s: string): BigDecimal - 10進数の文字列をパースします。

Type conversions

  • toString(): string` - 10進数の文字列を表示します。

Math

  • plus(y: BigDecimal): BigDecimal - x + y と書くことができます。
  • minus(y: BigDecimal): BigDecimal - x + y と書くことができます。
  • times(y: BigDecimal): BigDecimal - x + y と書くことができます。
  • div(y: BigDecimal): BigDecimal-x / y` と書くことができます。
  • equals(y: BigDecimal): bool-x == y` と書くことができます。
  • notEqual(y: BigDecimal): bool-x != y` と書くことができます。
  • lt(y: BigDecimal): bool-x < y` と書くことができます。
  • le(y: BigDecimal): bool - x <= y と書くことができます。
  • gt(y: BigDecimal): bool と書くことができます。
  • ge(y: BigDecimal): boolと書くことができます。
  • neg(): BigDecimal - -x と書くことができます。
'@graphprotocol/graph-ts'から { BigInt } をインポートします。

BigInt は大きな整数を表現するために使用されます。これには uint32 から uint256int64 から int256 型のイーサリアムの値が含まれます。uint32以下の値、例えばint32uint24int8は全てi32` として表現されます。

BigIntクラスの API は以下の通りです。

Construction

  • BigInt.fromI32(x: i32): BigInt - i32 から BigInt を作成すします。

  • BigInt.fromString(s: string): BigInt- 文字列から BigInt をパースします。

  • BigInt.fromUnsignedBytes(x: Bytes): BigInt - bytes を符号なし、リトルエンディアンの整数として解釈します。入力がビッグエンディアンの場合は、最初に .reverse() を呼び出します。

  • BigInt.fromSignedBytes(x: Bytes): BigInt - bytes を符号付きのリトルエンディアン整数として解釈します。入力がビッグエンディアンの場合は、最初に .reverse() を呼び出します。

    Type conversions

  • x.toHex(): string - BigInt を16進数の文字列に変換します。

  • x.toString(): string - BigInt を10進数の文字列に変換します。

  • x.toI32(): i32 - BigInti32 として返す。値が i32 に収まらない場合は失敗します。まず x.isI32() をチェックするのが良いでしょう。

  • x.toBigDecimal(): BigDecimal - 小数部のない10進数に変換します。

Math

  • x.plus(y: BigInt): BigInt - x + y と書くことができます。
  • x.minus(y: BigInt): BigInt - x - y と書くことができます。
  • x.times(y: BigInt): BigInt - x * y と書くことができます。
  • x.div(y: BigInt): BigInt - x / y と書くことができます。
  • x.mod(y: BigInt): BigInt - x % y と書くことができます。
  • x.equals(y: BigInt): bool - x == y と書くことができます。
  • x.notEqual(y: BigInt): bool - x = y と書くことができます。
  • x.lt(y: BigInt): bool - x < y と書くことができます。
  • x.le(y: BigInt): bool - x <= y と書くことができます。
  • x.gt(y: BigInt): bool - x > y と書くことができます。
  • x.ge(y: BigInt): bool - x >= y と書くことができます。
  • x.neg(): BigInt - -x と書くことができます。
  • x.divDecimal(y: BigDecimal): BigDecimal - 小数点で割り、10進数の結果を返します。
  • x.isZero(): bool - 数がゼロかどうかをチェックするための便利な関数です。
  • x.isI32(): bool - 数が i32 に収まるかどうかを調べます。
  • x.abs(): BigInt` - 絶対値。
  • x.pow(exp: u8): BigInt - 指数。
  • bitOr(x: BigInt, y: BigInt): BigInt - x | y と書くことができます。
  • bitAnd(x: BigInt, y: BigInt): BigInt - x & y と書くことができます。
  • leftShift(x: BigInt, bits: u8): BigInt - x << y と書くことができます。
  • rightShift(x: BigInt, bits: u8): BigInt - x >> y と書くことができます。
'@graphprotocol/graph-ts'から { TypedMap } をインポートします。

TypedMapはキーと値のペアを格納するために使用することができます。この例](https://github.com/graphprotocol/aragon-subgraph/blob/29dd38680c5e5104d9fdc2f90e740298c67e4a31/individual-dao-subgraph/mappings/constants.ts#L51)を参照してください。

TypedMapクラスは以下のAPIを持っています:

  • new TypedMap<K, V>() - K 型のキーと V 型の値を持つ空のマップを作成します。
  • map.set(key: K, value: V): void - key の値を value に設定します。
  • map.getEntry(key: K): TypedMapEntry<K, V> | null - key のキーと値のペアを返します。
  • map.get(key: K): V | null - key の値を返して、key がマップに存在しない場合は null を返します。
  • map.isSet(key: K): bool - key がマップに存在すれば true を返し、存在しなければ false を返します。
'@graphprotocol/graph-ts'から { Bytes } をインポートします。

Bytesは任意の長さのバイト配列を表現するために使用されます。これには bytesbytes32 型などのイーサリアム値が含まれます。

BytesクラスはAssemblyScriptのUint8Arrayを拡張したもので、Uint8Arrayのすべての機能に加え、以下の新しいメソッドをサポートしています:

Construction

  • fromHexString(hex: string) : Bytes - 偶数桁の16進数からなる文字列 hexByteArray に変換します。文字列 hex はオプションで 0x から始めることができます。
  • fromI32(i: i32): Bytes - i をバイト配列に変換します。

Type conversions

  • b.toHex() - 配列のバイト数を16進数で表した文字列を返します。
  • b.toString() - 配列のバイト列をユニコード文字列に変換します。
  • b.toBase58() - イーサリアムバイトの値を base58 エンコーディングに変換します (IPFS ハッシュに使用)

Operators

  • b.concat(other: Bytes): Bytes - - thisother を直接連結した Bytes を返します。
  • b.concatI32(other: i32) : ByteArray - thisother のバイト表現を直接続けた Bytes を返します。
'@graphprotocol/graph-ts'から { Address } をインポートします。

アドレス Address はイーサリアムのアドレス address 値を表現するために Bytes を継承しています。

Bytesの API の上に以下のメソッドを追加しています。

  • Address.fromString(s: string): Address - 16進数文字列から Address を作成します。
  • Address.fromBytes(b: Bytes): Address - b から Address を生成します。これは正確に20バイト長でなければなりません。それ以下のバイト数の値を渡すとエラーになります。
'@graphprotocol/graph-ts'から { store } をインポートします。

Store API は、グラフノードのストアにエンティティを読み込んだり、保存したり、削除したりすることができます。

Entities written to the store map one-to-one to the @entity types defined in the subgraph's GraphQL schema. To make working with these entities convenient, the graph codegen command provided by the Graph CLI generates entity classes, which are subclasses of the built-in Entity type, with property getters and setters for the fields in the schema as well as methods to load and save these entities.

エンティティの作成

このセクションへのリンク

Ethereum のイベントからエンティティを作成する際の一般的なパターンを以下に示します。

// Import the Transfer event class generated from the ERC20 ABI
import { Transfer as TransferEvent } from '../generated/ERC20/ERC20'
// Import the Transfer entity type generated from the GraphQL schema
import { Transfer } from '../generated/schema'
// Transfer event handler
export function handleTransfer(event: TransferEvent): void {
// Create a Transfer entity, using the transaction hash as the entity ID
let id = event.transaction.hash
let transfer = new Transfer(id)
// Set properties on the entity, using the event parameters
transfer.from = event.params.from
transfer.to = event.params.to
transfer.amount = event.params.amount
// Save the entity to the store
transfer.save()
}

チェーンの処理中に Transfer イベントが発生すると、生成された Transfer 型(エンティティ型との名前の衝突を避けるために、ここでは TransferEvent のエイリアス)を使用して handleTransfer イベントハンドラに渡されます。この型はイベントの親トランザクションやそのパラメータなどのデータにアクセスすることを可能にします。

各エンティティは、他のエンティティとの衝突を避けるために、ユニークな ID を持たなければなりません。 イベントのパラメータには、使用可能な一意の識別子が含まれているのが一般的です。 注:トランザクションのハッシュを ID として使用することは、同じトランザクション内の他のイベントがこのハッシュを ID としてエンティティを作成しないことを前提としています。

ストアからのエンティティの読み込み

このセクションへのリンク

エンティティがすでに存在する場合、以下の方法でストアからロードすることができます。

let id = event.transaction.hash // or however the ID is constructed
let transfer = Transfer.load(id)
if (transfer == null) {
transfer = new Transfer(id)
}
// Use the Transfer entity as before

エンティティはまだストアに存在していない可能性があるため、loadメソッドはTransfer | null型の値を返します。 そのため、値を使用する前に、nullのケースをチェックする必要があるかもしれません。

Note: エンティティのロードは、マッピングでの変更がエンティティの以前のデータに依存する場合にのみ必要です。 既存のエンティティを更新する 2 つの方法については、次のセクションを参照してください。

ブロック内で作成されたエンティティの検索

このセクションへのリンク

graph-node v0.31.0、@graphprotocol/graph-ts v0.30.0、および @graphprotocol/graph-cli v0.49.0 以降、 loadInBlock メソッドはすべてのエンティティ タイプで使用できます。

ストア API を使用すると、現在のブロックで作成または更新されたエンティティの取得が容易になります。この一般的な状況は、あるハンドラーがオンチェーン イベントからトランザクションを作成し、後のハンドラーがこのトランザクションが存在する場合にアクセスしようとすることです。トランザクションが存在しない場合、サブグラフはエンティティが存在しないことを確認するためだけにデータベースにアクセスする必要があります。エンティティが同じブロック内に作成されている必要があることをサブグラフの作成者がすでに知っている場合は、loadInBlock を使用すると、このデータベースのラウンドトリップが回避されます。一部のサブグラフでは、これらのルックアップの欠落がインデックス作成時間に大きく影響する可能性があります。

let id = event.transaction.hash // または ID が構築される方法
let transfer = Transfer.loadInBlock(id)
if (transfer == null) {
transfer = 新しい転送(id)
}
// 以前と同様に Transfer エンティティを使用します

注: 指定されたブロックにエンティティが作成されていない場合、ストア内に指定された ID を持つエンティティが存在する場合でも、loadInBlock は null を返します。

派生エンティティの検索

このセクションへのリンク

graph-node v0.31.0、@graphprotocol/graph-ts v0.31.0、および @graphprotocol/graph-cli v0.51.0 以降、loadMany メソッドが利用可能です。

これにより、イベント ハンドラー内から派生エンティティ フィールドをロードできるようになります。たとえば、次のスキーマがあるとします。

type Token @entity {
id: ID!
holder: Holder!
color: String
}
type Holder @entity {
id: ID!
tokens: [Token!]! @derivedFrom(field: "holder")
}

次のコードは、Holder エンティティの派生元である Token エンティティを読み込みます。

let holder = Holder.load('test-id')
// Load the Token entities associated with a given holder
let tokens = holder.tokens.load()

既存のエンティティの更新

このセクションへのリンク

既存のエンティティを更新するには 2 つの方法があります。

  1. Transfer.load(id)などでエンティティをロードし、エンティティにプロパティを設定した後、.save()でストアに戻す。
  2. 単純にnew Transfer(id)でエンティティを作成し、エンティティにプロパティを設定し、ストアに .save()します。 エンティティがすでに存在する場合は、変更内容がマージされます。

プロパティの変更は、生成されたプロパティセッターのおかげで、ほとんどの場合、簡単です。

let transfer = new Transfer(id)
transfer.from = ...
transfer.to = ...
transfer.amount = ...

また、次の 2 つの命令のいずれかで、プロパティの設定を解除することも可能です。

transfer.from.unset()
transfer.from = null

これは、オプションのプロパティ、つまり GraphQL で!を付けずに宣言されているプロパティでのみ機能します。 例としては、owner: Bytesやamount: BigIntです。

エンティティから配列を取得すると、その配列のコピーが作成されるため、配列のプロパティの更新には少し手間がかかります。 つまり、配列を変更した後は、明示的に配列のプロパティを設定し直す必要があります。 次の例では、entity が numbers: [BigInt!]! を持っていると仮定します。

// This won't work
entity.numbers.push(BigInt.fromI32(1))
entity.save()
// This will work
let numbers = entity.numbers
numbers.push(BigInt.fromI32(1))
entity.numbers = numbers
entity.save()

ストアからのエンティティの削除

このセクションへのリンク

現在、生成された型を使ってエンティティを削除する方法はありません。 代わりに、エンティティを削除するには、エンティティタイプの名前とエンティティ ID をstore.removeに渡す必要があります。

mport { store } from '@graphprotocol/graph-ts'
...
let id = event.transaction.hash
store.remove('Transfer', id)

Ethereum API は、スマートコントラクト、パブリックステート変数、コントラクト関数、イベント、トランザクション、ブロック、および Ethereum データのエンコード/デコードへのアクセスを提供します。

Ethereum タイプのサポート

このセクションへのリンク

エンティティと同様に、graph codegenは、サブグラフで使用されるすべてのスマートコントラクトとイベントのためのクラスを生成します。 このためには、コントラクト ABI がサブグラフマニフェストのデータソースの一部である必要があります。 通常、ABI ファイルはabis/フォルダに格納されています。

生成されたクラスでは、Ethereum Typeとbuilt-in types間の変換が舞台裏で行われるため、サブグラフ作成者はそれらを気にする必要がありません。

以下の例で説明します。 以下のようなサブグラフのスキーマが与えられます。

type Transfer @entity {
id: Bytes!
from: Bytes!
to: Bytes!
amount: BigInt!
}

イーサリアムの Transfer(address,address,uint256) イベントシグネチャを使用すると、from, to, uint256 型の値は AddressBigInt に変換され、Transfer エンティティの Bytes! プロパティと BigInt! プロパティに渡すことができます:

let id = event.transaction.hash
let transfer = new Transfer(id)
transfer.from = event.params.from
transfer.to = event.params.to
transfer.amount = event.params.amount
transfer.save()

イベントとブロック/トランザクションデータ

このセクションへのリンク

前述の例のTransferイベントのように、イベントハンドラに渡された Ethereum イベントは、イベントパラメータへのアクセスだけでなく、その親となるトランザクションや、それらが属するブロックへのアクセスも提供します。 event インスタンスからは、以下のデータを取得することができます(これらのクラスは、 graph-tsのethereumモジュールの一部です)。

class Event {
address: Address
logIndex: BigInt
transactionLogIndex: BigInt
logType: string | null
block: Block
transaction: Transaction
parameters: Array<EventParam>
receipt: TransactionReceipt | null
}
class Block {
hash: Bytes
parentHash: Bytes
unclesHash: Bytes
author: Address
stateRoot: Bytes
transactionsRoot: Bytes
receiptsRoot: Bytes
number: BigInt
gasUsed: BigInt
gasLimit: BigInt
timestamp: BigInt
difficulty: BigInt
totalDifficulty: BigInt
size: BigInt | null
baseFeePerGas: BigInt | null
}
class Transaction {
hash: Bytes
index: BigInt
from: Address
to: Address | null
value: BigInt
gasLimit: BigInt
gasPrice: BigInt
input: Bytes
nonce: BigInt
}
class TransactionReceipt {
transactionHash: Bytes
transactionIndex: BigInt
blockHash: Bytes
blockNumber: BigInt
cumulativeGasUsed: BigInt
gasUsed: BigInt
contractAddress: Address
logs: Array<Log>
status: BigInt
root: Bytes
logsBloom: Bytes
}
class Log {
address: Address
topics: Array<Bytes>
data: Bytes
blockHash: Bytes
blockNumber: Bytes
transactionHash: Bytes
transactionIndex: BigInt
logIndex: BigInt
transactionLogIndex: BigInt
logType: string
removed: bool | null
}

スマートコントラクトの状態へのアクセス

このセクションへのリンク

graph codegenが生成するコードには、サブグラフで使用されるスマートコントラクトのクラスも含まれています。 これらを使って、パブリックな状態変数にアクセスしたり、現在のブロックにあるコントラクトの関数を呼び出したりすることができます。

よくあるパターンは、イベントが発生したコントラクトにアクセスすることです。 これは以下のコードで実現できます。

// Import the generated contract class and generated Transfer event class
import { ERC20Contract, Transfer as TransferEvent } from '../generated/ERC20Contract/ERC20Contract'
// Import the generated entity class
import { Transfer } from '../generated/schema'
export function handleTransfer(event: TransferEvent) {
// Bind the contract to the address that emitted the event
let contract = ERC20Contract.bind(event.address)
// Access state variables and functions by calling them
let erc20Symbol = contract.symbol()
}

Transferは、エンティティタイプとの名前の衝突を避けるために、ここではTransferEventにエイリアスされています。

Ethereum の ERC20Contractにsymbolというパブリックな読み取り専用の関数があれば、.symbol()で呼び出すことができます。 パブリックな状態変数については、同じ名前のメソッドが自動的に作成されます。

サブグラフの一部である他のコントラクトは、生成されたコードからインポートすることができ、有効なアドレスにバインドすることができます。

リバートされた呼び出しの処理

このセクションへのリンク

コントラクトの読み取り専用メソッドが復帰する可能性がある場合は、try_を前置して生成されたコントラクトメソッドを呼び出すことで対処しなければなりません。 例えば、Gravity コントラクトではgravatarToOwnerメソッドを公開しています。 このコードでは、そのメソッドの復帰を処理することができます。

let gravity = Gravity.bind(event.address)
let callResult = gravity.try_gravatarToOwner(gravatar)
if (callResult.reverted) {
log.info('getGravatar reverted', [])
} else {
let owner = callResult.value
}

ただし、Geth や Infura のクライアントに接続された Graph ノードでは、すべてのリバートを検出できない場合があるので、これに依存する場合は Parity のクライアントに接続された Graph ノードを使用することをお勧めします。

符号化/復号化 ABI

このセクションへのリンク

ethereumモジュールのencode/ decode関数を使用して、Ethereum の ABI エンコーディングフォーマットに従ってデータをエンコード/デコードすることができます。

import { Address, BigInt, ethereum } from '@graphprotocol/graph-ts'
let tupleArray: Array<ethereum.Value> = [
ethereum.Value.fromAddress(Address.fromString('0x0000000000000000000000000000000000000420')),
ethereum.Value.fromUnsignedBigInt(BigInt.fromI32(62)),
]
let tuple = tupleArray as ethereum.Tuple
let encoded = ethereum.encode(ethereum.Value.fromTuple(tuple))!
let decoded = ethereum.decode('(address,uint256)', encoded)

その他の情報:

The native token balance of an address can be retrieved using the ethereum module. This feature is available from apiVersion: 0.0.9 which is defined subgraph.yaml. The getBalance() retrieves the balance of the specified address as of the end of the block in which the event is triggered.

import { ethereum } from '@graphprotocol/graph-ts'
let address = Address.fromString('0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045')
let balance = ethereum.getBalance(address) // returns balance in BigInt

Check if an Address is a Contract or EOA

このセクションへのリンク

To check whether an address is a smart contract address or an externally owned address (EOA), use the hasCode() function from the ethereum module which will return boolean. This feature is available from apiVersion: 0.0.9 which is defined subgraph.yaml.

import { ethereum } from '@graphprotocol/graph-ts'
let contractAddr = Address.fromString('0x2E645469f354BB4F5c8a05B3b30A929361cf77eC')
let isContract = ethereum.hasCode(contractAddr).inner // returns true
let eoa = Address.fromString('0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045')
let isContract = ethereum.hasCode(eoa).inner // returns false
'@graphprotocol/graph-ts'から{ log } をインポートします。

The log API allows subgraphs to log information to the Graph Node standard output as well as Graph Explorer. Messages can be logged using different log levels. A basic format string syntax is provided to compose log messages from argument.

log API には以下の機能があります:

  • log.debug(fmt: string, args: Array<string>): void - デバッグメッセージを記録します。
  • log.info(fmt: string, args: Array<string>): void - インフォメーションメッセージを記録します。
  • log.warning(fmt: string, args: Array<string>): void - 警告メッセージを記録します。
  • log.error(fmt: string, args: Array<string>): void - エラーメッセージを記録します。
  • log.critical(fmt: string, args: Array<string>): void - クリティカル・メッセージを記録して、サブグラフを終了します。

log API は、フォーマット文字列と文字列値の配列を受け取ります。 そして、プレースホルダーを配列の文字列値で置き換えます。 最初のプレースホルダーは配列の最初の値に置き換えられ、2 番目のプレースホルダーは 2 番目の値に置き換えられ、以下のようになります。

log.info('表示されるメッセージ。{}, {}, {}', [value.toString(), anotherValue.toString(), 'すでに文字列'])

1 つまたは複数の値を記録する

このセクションへのリンク
1 つの値を記録する
このセクションへのリンク

以下の例では、文字列値 "A" を配列に渡して['A'] にしてからログに記録しています。

let myValue = 'A'
export function handleSomeEvent(event: SomeEvent): void {
// Displays : "My value is: A"
log.info('My value is: {}', [myValue])
}
既存の配列から 1 つのエントリをロギングする
このセクションへのリンク

以下の例では、配列に 3 つの値が含まれているにもかかわらず、引数の配列の最初の値だけがログに記録されます。

let myArray = ['A', 'B', 'C']
export function handleSomeEvent(event: SomeEvent): void {
// Displays : "My value is: A" (Even though three values are passed to `log.info`)
log.info('My value is: {}', myArray)
}

既存の配列から複数のエントリを記録する

このセクションへのリンク

引数配列の各エントリは、ログメッセージ文字列に独自のプレースホルダーを必要とします。 以下の例では、ログメッセージに 3 つのプレースホルダーが含まれています。 このため、myArrayの 3 つの値すべてがログに記録されます。

let myArray = ['A', 'B', 'C']
export function handleSomeEvent(event: SomeEvent): void {
// Displays : "My first value is: A, second value is: B, third value is: C"
log.info('My first value is: {}, second value is: {}, third value is: {}', myArray)
}
既存の配列から特定のエントリをロギングする
このセクションへのリンク

配列内の特定の値を表示するには、インデックス化された値を指定する必要があります。

export function handleSomeEvent(event: SomeEvent): void {
// Displays : "My third value is C"
log.info('My third value is: {}', [myArray[2]])
}
イベント情報の記録
このセクションへのリンク

以下の例では、イベントからブロック番号、ブロックハッシュ、トランザクションハッシュをログに記録しています。

'@graphprotocol/graph-ts'から { log } をインポートします。
export function handleSomeEvent(event: SomeEvent): void {
log.debug('Block number: {}, block hash: {}, transaction hash: {}', [
event.block.number.toString(), // "47596000"
event.block.hash.toHexString(), // "0x..."
event.transaction.hash.toHexString(), // "0x..."
])
}
'@graphprotocol/graph-ts'から { ipfs } をインポートします。

スマートコントラクトは時折、チェーン上の IPFS ファイルをアンカリングします。 これにより、マッピングはコントラクトから IPFS ハッシュを取得し、IPFS から対応するファイルを読み取ることができます。 ファイルのデータはBytesとして返されますが、通常は、このページで後述する json API などを使ってさらに処理する必要があります。

IPFS のハッシュやパスが与えられた場合、IPFS からのファイルの読み込みは以下のように行われます。

// Put this inside an event handler in the mapping
let hash = 'QmTkzDwWqPbnAh5YiV5VwcTLnGdwSNsNTn2aDxdXBFca7D'
let data = ipfs.cat(hash)
// Paths like `QmTkzDwWqPbnAh5YiV5VwcTLnGdwSNsNTn2aDxdXBFca7D/Makefile`
// that include files in directories are also supported
let path = 'QmTkzDwWqPbnAh5YiV5VwcTLnGdwSNsNTn2aDxdXBFca7D/Makefile'
let data = ipfs.cat(path)

注: ipfs.cat は今のところ決定論的なものではありません。もし要求がタイムアウトする前にIPFSネットワーク上でファイルを取得できなければ、 nullを返します。このため、常に null の結果をチェックする価値があります。

また、ipfs.map.を使って、大きなファイルをストリーミングで処理することも可能です。 この関数は、IPFS ファイルのハッシュまたはパス、コールバックの名前、そして動作を変更するためのフラグを受け取ります。

import { JSONValue, Value } from '@graphprotocol/graph-ts'
export function processItem(value: JSONValue, userData: Value): void {
// See the JSONValue documentation for details on dealing
// with JSON values
let obj = value.toObject()
let id = obj.get('id')
let title = obj.get('title')
if (!id || !title) {
return
}
// Callbacks can also created entities
let newItem = new Item(id)
newItem.title = title.toString()
newitem.parent = userData.toString() // Set parent to "parentId"
newitem.save()
}
// Put this inside an event handler in the mapping
ipfs.map('Qm...', 'processItem', Value.fromString('parentId'), ['json'])
// Alternatively, use `ipfs.mapJSON`
ipfs.mapJSON('Qm...', 'processItem', Value.fromString('parentId'))

現在サポートされているフラグは json だけで、これは ipfs.map に渡さなければなりません。json フラグを指定すると、IPFS ファイルは一連の JSON 値で構成されます。ipfs.map を呼び出すと、ファイルの各行を読み込んで JSONValue にデシリアライズし、それぞれのコールバックを呼び出します。コールバックは JSONValue からデータを格納するためにエンティティ操作を使用することができます。エンティティの変更は、ipfs.map を呼び出したハンドラが正常に終了したときのみ保存されます。その間はメモリ上に保持されるので、ipfs.map が処理できるファイルのサイズは制限されます。

成功すると,ipfs.mapは voidを返します。 コールバックの呼び出しでエラーが発生した場合、ipfs.mapを呼び出したハンドラは中止され、サブグラフは失敗とマークされます。

'@graphprotocol/graph-ts'から { crypto } をインポートします。

crypto API は、マッピングで使用できる暗号化関数を提供します。 今のところ、1 つしかありません。

  • crypto.keccak256(input: ByteArray): ByteArray
'@graphprotocol/graph-ts'から{ json, JSONValueKind } をインポートします。

JSON データは、json API を使って解析することができます。

  • json.fromBytes(data: Bytes): JSONValue - 有効な UTF-8 シーケンスとして解釈され、 Bytes 配列から JSON データをパースします。
  • json.try_fromBytes(data: Bytes): Result<JSONValue, boolean> - json.fromBytes の安全バージョンで、パースに失敗した場合はエラーバリアントを返します。
  • json.fromString(data: string): JSONValue - 有効な UTF-8 String から JSON データをパースします。
  • json.try_fromString(data: string): Result<JSONValue, boolean> - json.fromString の安全バージョンで、パースに失敗した場合はエラーバリアントを返します。

JSONValue クラスは、任意の JSON ドキュメントから値を引き出す方法を提供します。 JSON の値には、ブーリアン、数値、配列などがあるため、JSONValueには、値の種類をチェックするためのkindプロパティが付属しています。

let value = json.fromBytes(...)
if (value.kind == JSONValueKind.BOOL) {
...
}

さらに、値がnullかどうかをチェックするメソッドもあります`:

  • value.isNull(): boolean

値の型が確実な場合は、以下のいずれかの方法で組み込み型に変換することができます:

  • value.toBool(): boolean
  • value.toI64(): i64
  • value.toF64(): f64
  • value.toBigInt(): BigInt
  • value.toString(): string
  • value.toArray(): Array<JSONValue> - (その後、上記の 5 つのメソッドのいずれかを使用して JSONValue を変換します)

タイプ 変換参照

このセクションへのリンク
Source(s)DestinationConversion function
AddressBytesnone
AddressStrings.toHexString()
BigDecimalStrings.toString()
BigIntBigDecimals.toBigDecimal()
BigIntString (hexadecimal)s.toHexString() or s.toHex()
BigIntString (unicode)s.toString()
BigInti32s.toI32()
BooleanBooleannone
Bytes (signed)BigIntBigInt.fromSignedBytes(s)
Bytes (unsigned)BigIntBigInt.fromUnsignedBytes(s)
BytesString (hexadecimal)s.toHexString() or s.toHex()
BytesString (unicode)s.toString()
BytesString (base58)s.toBase58()
Bytesi32s.toI32()
Bytesu32s.toU32()
BytesJSONjson.fromBytes(s)
int8i32none
int32i32none
int32BigIntBigint.fromI32(s)
uint24i32none
int64 - int256BigIntnone
uint32 - uint256BigIntnone
JSONbooleans.toBool()
JSONi64s.toI64()
JSONu64s.toU64()
JSONf64s.toF64()
JSONBigInts.toBigInt()
JSONstrings.toString()
JSONArrays.toArray()
JSONObjects.toObject()
StringAddressAddress.fromString(s)
BytesAddressAddress.fromString(s)
StringBigIntBigDecimal.fromString(s)
StringBigDecimalBigDecimal.fromString(s)
String (hexadecimal)BytesByteArray.fromHexString(s)
String (UTF-8)BytesByteArray.fromUTF8(s)

データソースのメタデータ

このセクションへのリンク

ハンドラを起動したデータソースのコントラクトアドレス、ネットワーク、コンテキストは、以下のようにして調べることができます。

  • dataSource.address(): Address
  • dataSource.network(): string
  • dataSource.context(): DataSourceContext

エンティティと DataSourceContext

このセクションへのリンク

ベースとなるエンティティクラスと子クラスのDataSourceContextクラスには、フィールドを動的に設定・取得するためのヘルパーが用意されています。

  • setString(key: string, value: string): void
  • setI32(key: string, value: i32): void
  • setBigInt(key: string, value: BigInt): void
  • setBytes(key: string, value: Bytes): void
  • setBoolean(key: string, value: bool): void
  • setBigDecimal(key, value: BigDecimal): void
  • getString(key: string): string
  • getI32(key: string): i32
  • getBigInt(key: string): BigInt
  • getBytes(key: string): Bytes
  • getBoolean(key: string): boolean
  • getBigDecimal(key: string): BigDecimal

マニフェスト内のDataSourceContext

このセクションへのリンク

DataSourcescontextセクションでは、サブグラフマッピング内でアクセス可能なキーと値のペアを定義することができます。使用可能な型はBoolStringIntInt8BigDecimalBytesListBigInt` です。

以下は context セクションのさまざまな型の使い方を示す YAML の例です:

dataSources:
- kind: ethereum/contract
name: ContractName
network: mainnet
context:
bool_example:
type: Bool
data: true
string_example:
type: String
data: 'hello'
int_example:
type: Int
data: 42
int8_example:
type: Int8
data: 127
big_decimal_example:
type: BigDecimal
data: '10.99'
bytes_example:
type: Bytes
data: '0x68656c6c6f'
list_example:
type: List
data:
- type: Int
data: 1
- type: Int
data: 2
- type: Int
data: 3
big_int_example:
type: BigInt
data: '1000000000000000000000000'
  • Bool: Specifies a Boolean value (true or false).
  • String: Specifies a String value.
  • Int: Specifies a 32-bit integer.
  • Int8: Specifies an 8-bit integer.
  • BigDecimal: Specifies a decimal number. Must be quoted.
  • Bytes: Specifies a hexadecimal string.
  • List: Specifies a list of items. Each item needs to specify its type and data.
  • BigInt: Specifies a large integer value. Must be quoted due to its large size.

このコンテキストは、サブグラフのマッピング・ファイルからアクセスでき、よりダイナミックで設定可能なサブグラフを実現します。

ページを編集

サブグラフの作成
AssemblyScriptのよくある問題
ページを編集