subgraphs > Developing > Creating > AssemblyScript API > AssemblyScript API'si

AssemblyScript API'si

Reading time: 17 min

Not: Eğer graph-cli/graph-ts sürüm 0.22.0'den önce bir subgraph oluşturduysanız, eski bir AssemblyScript sürümünü kullanıyorsunuz demektir. Geçiş Kılavuzu gözden geçirmeniz önerilir.

Subgraph eşlemeleri yazarken kullanılabilecek yerleşik API'leri öğrenin. Hazır olarak sunulan iki tür API mevcuttur:

  • Graph TypeScript kütüphanesi (graph-ts)
  • Subgraph dosyalarından graph codegen tarafından üretilen kod

AssemblyScript ile uyumlu olduğu sürece diğer kütüphaneleri de bağımlılık olarak ekleyebilirsiniz.

Dil eşlemeleri AssemblyScript ile yazıldığından, AssemblyScript wiki'sindeki dil ve standart kütüphane özelliklerini gözden geçirmek faydalı olacaktır.

API Referansı

Bu bölüme bağlantı

@graphprotocol/graph-ts kütüphanesi aşağıdaki API'leri sağlar:

  • Ethereum akıllı sözleşmeleri, olaylar, bloklar, işlemler ve Ethereum değerleriyle çalışmak için bir ethereum API'si.
  • Varlıkları Graph Düğümü deposundan yüklemek ve depoya kaydetmek için bir store API'si.
  • Graph Düğümü çıktısına ve Graph Gezgini'ne mesaj kaydetmek için bir log API'si.
  • IPFS'ten dosyaları yüklemek için bir ipfs API'si.
  • JSON verilerini ayrıştırmak için bir json API'si.
  • Kriptografik fonksiyonları kullanmak için bir crypto API'si.
  • Ethereum, JSON, GraphQL ve AssemblyScript gibi farklı tip sistemler arası çeviri yapmak için düşük seviyeli yazılımlar.

Subgraph manifestosundaki apiVersion, bir subgraph için Graph Düğümü tarafından çalıştırılan eşleme (mapping) API'sinin sürümünü belirtir.

SürümSürüm Notları
0.0.9Yeni host fonksiyonları ekler: eth_get_balance ve hasCode
0.0.8Bir varlığı kaydederken şemadaki alanların varlığını doğrulama mekanizması ekler.
0.0.7Ethereum türlerine TransactionReceipt ve Log sınıfları eklendi
Ethereum Event nesnesine receipt alanı eklendi
0.0.6Ethereum Transaction nesnesine nonce alanı eklendi
Ethereum Block nesnesine baseFeePerGas eklendi
0.0.5AssemblyScript sürümü 0.19.10'a yükseltildi (bu sürümle birlikte uyumluluğu bozabilecek değişiklikler yapılmıştır, lütfen Geçiş Kılavuzu bölümüne bakın)
ethereum.transaction.gasUsed, ethereum.transaction.gasLimit olarak yeniden adlandırıldı
0.0.4Ethereum SmartContractCall nesnesine functionSignature alanı eklendi
0.0.3Ethereum Call nesnesine from alanı eklendi
etherem.call.address, ethereum.call.to olarak yeniden adlandırıldı
0.0.2Ethereum Transaction nesnesine input alanı eklendi

Dahili Türler

Bu bölüme bağlantı

AssemblyScript'e yerleşik olan temel türler hakkında dökümantasyona AssemblyScript wiki'sinden ulaşabilirsiniz.

Aşağıdaki ek türler @graphprotocol/graph-ts tarafından sağlanmaktadır.

import { ByteArray } from '@graphprotocol/graph-ts'

ByteArray, bir u8 dizisini temsil eder.

Oluşturma

  • fromI32(x: i32): ByteArray - x değerini baytlara ayrıştırır.
  • fromHexString(hex: string): ByteArray - Girdi uzunluğu çift sayı olmalıdır. 0x ile başlatmak isteğe bağlıdır.

Tür Dönüşümleri

  • toHexString(): string - On altılık tabanda bir dizeye (hex string) dönüştürür ve 0x öneki ekler.
  • toString(): string - Baytları UTF-8 dizesi olarak yorumlar.
  • toBase58(): string - Baytları base58 dizesine kodlar.
  • toU32(): u32 - Baytları little-endian bir u32 olarak yorumlar. Aşım durumunda hata verir.
  • toI32(): i32 - Bayt dizisini little-endian bir i32 olarak yorumlar. Aşım durumunda hata verir.

Operatörler

  • equals(y: ByteArray): boolx == y olarak yazılabilir.
  • concat(other: ByteArray): ByteArray - this dizisinin sonuna other dizisini ekleyerek yeni bir ByteArray döner.
  • concatI32(other: i32): ByteArray - this dizisinin sonuna other'ın bayt temsili ekleyerek yeni bir ByteArray döner.
import { BigDecimal } from '@graphprotocol/graph-ts'

BigDecimal, ondalık sayıları istenildiği kadar doğrulukta temsil etmek için kullanılır.

Not: Dahili olarak BigDecimal, IEEE-754 decimal128 floating-point formatında saklanır ve bu format 34 ondalık basamağa kadar destek sunar. Bu durum, BigDecimal'i, 34 basamağı aşabilen sabit noktalı türleri temsil etmek için (örneğin Solidity'deki ufixed256x18 gibi) uygun olmaktan çıkarır.

Oluşturma

  • constructor(bigInt: BigInt) – Bir BigInt'ten bir BigDecimal oluşturur.
  • static fromString(s: string): BigDecimal – Ondalık bir dizeyi ayrıştırır.

Tür Dönüşümleri

  • toString(): string – Ondalık bir dize olarak yazdırır.

Math

  • plus(y: BigDecimal): BigDecimalx + y şeklinde yazılabilir.
  • minus(y: BigDecimal): BigDecimalx - y şeklinde yazılabilir.
  • times(y: BigDecimal): BigDecimalx * y şeklinde yazılabilir.
  • div(y: BigDecimal): BigDecimalx / y şeklinde yazılabilir.
  • equals(y: BigDecimal): boolx == y şeklinde yazılabilir.
  • notEqual(y: BigDecimal): boolx != y şeklinde yazılabilir.
  • lt(y: BigDecimal): boolx < y şeklinde yazılabilir.
  • le(y: BigDecimal): boolx <= y şeklinde yazılabilir.
  • gt(y: BigDecimal): boolx > y şeklinde yazılabilir.
  • ge(y: BigDecimal): boolx >= y şeklinde yazılabilir.
  • neg(): BigDecimal - -x şeklinde yazılabilir.
import { BigInt } from '@graphprotocol/graph-ts'

BigInt, büyük tam sayıları temsil etmek için kullanılır. Buna, Ethereum'daki uint32 ile uint256 ve int64 ile int256 türlerindeki değerler dahildir. uint32'nin altındaki her şey, örneğin int32, uint24 veya int8, i32 olarak temsil edilir.

BigInt sınıfı aşağıdaki API'ye sahiptir:

Oluşturma

  • BigInt.fromI32(x: i32): BigInt – Bir i32'den bir BigInt oluşturur.

  • BigInt.fromString(s: string): BigInt – Bir dizeden bir BigInt oluşturur.

  • BigInt.fromUnsignedBytes(x: Bytes): BigIntbytes'i işaretsiz, little-endian bir tamsayı olarak yorumlar. Girdiniz big-endian ise önce .reverse() metodunu kullanın.

  • BigInt.fromSignedBytes(x: Bytes): BigIntbytes'i işaretli, little-endian bir tamsayı olarak yorumlar. Girdiniz big-endian ise önce .reverse() metodunu kullanın.

    Tür Dönüşümleri

  • x.toHex(): dizeBigInt'i on altılık tabanda bir karakter dizesine dönüştürür.

  • x.toString(): dizeBigInt'i ondalık tabanda bir dizeye dönüştürür.

  • x.toI32(): i32BigInt'i bir i32 olarak döndürür, değer i32'ye sığmazsa hata verir. İlk olarak x.isI32() kontrolünü yapmanız önerilir.

  • x.toBigDecimal(): BigDecimal – Kesirli kısmı olmayan bir ondalık sayıya dönüştürür.

Math

  • x.plus(y: BigInt): BigIntx + y şeklinde yazılabilir.
  • x.minus(y: BigInt): BigIntx - y şeklinde yazılabilir.
  • x.times(y: BigInt): BigIntx * y şeklinde yazılabilir.
  • x.div(y: BigInt): BigIntx / y şeklinde yazılabilir.
  • x.mod(y: BigInt): BigIntx % y şeklinde yazılabilir.
  • x.equals(y: BigInt): boolx == y şeklinde yazılabilir.
  • x.notEqual(y: BigInt): boolx != y şeklinde yazılabilir.
  • x.lt(y: BigInt): boolx < y şeklinde yazılabilir.
  • x.le(y: BigInt): boolx <= y şeklinde yazılabilir.
  • x.gt(y: BigInt): boolx > y şeklinde yazılabilir.
  • x.ge(y: BigInt): boolx >= y şeklinde yazılabilir.
  • x.neg(): BigInt-x şeklinde yazılabilir.
  • x.divDecimal(y: BigDecimal): BigDecimal – Ondalık bir sayı ile böler ve ondalık bir sonuç döndürür.
  • x.isZero(): bool – Sayının sıfır olup olmadığını kontrol etmek için kullanışlı bir metot.
  • x.isI32(): bool – Sayının bir i32'ye sığıp sığmadığını kontrol eder.
  • x.abs(): BigInt – Mutlak değer.
  • x.pow(exp: u8): BigInt – Üs alma işlemi.
  • bitOr(x: BigInt, y: BigInt): BigIntx | y olarak yazılabilir.
  • bitAnd(x: BigInt, y: BigInt): BigIntx & y şeklinde yazılabilir.
  • leftShift(x: BigInt, bits: u8): BigIntx << y şeklinde yazılabilir.
  • rightShift(x: BigInt, bits: u8): BigIntx >> y şeklinde yazılabilir.
import { TypedMap } from '@graphprotocol/graph-ts'

TypedMap, anahtar-değer çiftlerini saklamak için kullanılabilir. Bu örneği inceleyebilirsiniz.

TypedMap sınıfının API'si aşağıdaki gibidir:

  • new TypedMap<K, V>()K türünde anahtarlar ve V türünde değerler içeren boş bir eşlem oluşturur
  • map.set(key: K, value: V): voidkey anahtarının değerini value olarak ayarlar
  • map.getEntry(key: K): TypedMapEntry<K, V> | nullkey için anahtar-değer çiftini döndürür, eğer key eşlemde mevcut değilse null döner
  • map.get(key: K): V | nullkey için değeri döndürür, eğer key eşlemde mevcut değilse null döner
  • map.isSet(key: K): bool – Eğer key eşlemde mevcutsa true, değilse false döner
import { Bytes } from '@graphprotocol/graph-ts'

Bytes, keyfi uzunluktaki bayt dizilerini temsil etmek için kullanılır. Buna Ethereum'daki bytes, bytes32 gibi türler dahildir.

Bytes sınıfı, AssemblyScript'in Uint8Array sınıfını genişletir ve Uint8Array'in tüm işlevselliğini destekler. Buna ek olarak, aşağıdaki yeni metotlara sahiptir:

Oluşturma

  • fromHexString(hex: string): Byteshex dizesini, on altı tabanında çift sayıda basamaktan oluşması koşuluyla bir ByteArray'e dönüştürür. hex dizesi isteğe bağlı olarak 0x ile başlayabilir
  • fromI32(i: i32): Bytesi değerini bir bayt dizisine dönüştürür

Tür Dönüşümleri

  • b.toHex() – dizideki baytları temsil eden on altı tabanında bir dize döndürür
  • b.toString() – dizideki baytları Unicode karakterlerinden oluşan bir dizeye dönüştürür
  • b.toBase58() – bir Ethereum Bytes değerini base58 kodlamasına (IPFS hash'leri için kullanılır) dönüştürür

Operatörler

  • b.concat(other: Bytes): Bytesthis dizisinin sonuna other dizisini ekleyerek yeni bir Bytes döndürür
  • b.concatI32(other: i32): ByteArraythis dizisinin sonrasına other'ın bayt temsilini eklenerek yeni bir Bytes döndürür

Adres(Address)

Bu bölüme bağlantı
import { Address } from '@graphprotocol/graph-ts'

Address, Ethereum address değerlerini temsil etmek için Bytes sınıfını genişletir.

Bytes API'sine ek olarak aşağıdaki metotları sağlar:

  • Address.fromString(s: dize): Address – On altılık tabanda bir dizeden bir Address oluşturur
  • Address.fromBytes(b: Bytes): Address – Tam olarak 20 bayt uzunluğunda olması gereken b dizisinden bir Address oluşturur. Daha az veya daha fazla bayt içeren bir değer geçildiğinde hata verir
import { store } from '@graphprotocol/graph-ts'

store API'si, varlıkları Graph Düğümü deposundan yüklemeye, depoya kaydetmeye ve depodan kaldırmaya olanak tanır.

Depoya yazılan varlıklar, subgraph'in GraphQL şemasında tanımlanan @entity türleriyle bire bir eşleşir. Bu varlıklarla çalışmayı kolaylaştırmak için Graph CLI tarafından sağlanan graph codegen komutu varlık sınıfları oluşturur. Varlık sınıfları, şemadaki alanlar için özellik alıcıları ve ayarlayıcılarının yanı sıra bu varlıkları yüklemek ve kaydetmek için metotlar içeren, yerleşik Entity türünün alt sınıflarıdır.

Unsurların Oluşturulması

Bu bölüme bağlantı

Aşağıdaki, Ethereum olaylarından varlıklar oluşturmak için yaygın bir modeldir.

// ERC20 ABI'dan oluşturulan Transfer olay sınıfını içe aktarın
import { Transfer as TransferEvent } from '../generated/ERC20/ERC20'
// GraphQL şemasından oluşturulan Transfer varlık türünü içe aktarın
import { Transfer } from '../generated/schema'
// Transfer olayı işleyicisi
export function handleTransfer(event: TransferEvent): void {
// İşlem hash'ını olay kimliği olarak kullanarak bir Transfer varlığı oluşturun
let id = event.transaction.hash
let transfer = new Transfer(id)
// Olay parametrelerini kullanarak varlığın özelliklerini ayarlayın
transfer.from = event.params.from
transfer.to = event.params.to
transfer.amount = event.params.amount
// Varlığı depoya kaydedin
transfer.save()
}

Zincir işlenirken bir Transfer olayıyla karşılaşıldığında, oluşturulan Transfer türü (burada varlık türüyle adlandırma çakışmasını önlemek için TransferEvent olarak adlandırılmıştır) kullanılarak handleTransfer olay işleyicisine aktarılır. Bu tür, olayın ana işlemi ve parametreleri gibi verilere erişim sağlar.

Her varlık, diğer varlıklarla çakışmayı önlemek için benzersiz bir ID'ye sahip olmalıdır. Genellikle olay parametrelerinin içinde bu iş için kullanılabilecek benzersiz bir tanımlayıcı bulunur.

Not: ID olarak işlem hash'ini kullanmak, aynı işlemdeki diğer olayların bu hash'i ID olarak kullanarak varlık oluşturmadığını varsayar.

Depodan varlık yükleme

Bu bölüme bağlantı

Bir varlık mevcutsa aiağıdaki kod kullanılarak depodan yüklenebilir:

let id = event.transaction.hash // veya kimlik(ID) nasıl oluşturulmuşsa
let transfer = Transfer.load(id)
if (transfer == null) {
transfer = new Transfer(id)
}
// Transfer varlığı önceki gibi kullanılır

Varlık henüz depoda mevcut olmayabileceğinden, load yöntemi Transfer | null türünde bir değer döndürür. Değeri kullanmadan önce null olup olmadığını kontrol etmek gerekebilir.

Not: Varlıkları yüklemek, yalnızca, eşlemede yapılan değişikliklerin bir varlığın önceki verilerine bağlı olması durumunda gereklidir. Mevcut varlıkları güncellemenin iki yolunu görmek için bir sonraki bölüme bakın.

Bir blok içinde oluşturulan varlıkları arama

Bu bölüme bağlantı

graph-node v0.31.0, @graphprotocol/graph-ts v0.30.0 ve @graphprotocol/graph-cli v0.49.0 itibarıyla loadInBlock metodu tüm varlık türlerinde kullanılabilir hale gelmiştir.

Store API'si mevcut blokta oluşturulan veya güncellenen varlıkların alınmasına olanak tanır. Bunun tipik bir örneği, bir işleyicinin zincir-üzeri bir olaydan bir işlem oluşturması ve sonraki bir işleyicinin, bu işlem mevcutsa ona erişmek istemesidir.

  • Eğer işlem mevcut değilse subgraph sırf varlığın mevcut olmadığını öğrenmek için veritabanına başvurmak zorunda kalacaktır. Ancak, subgraph yazarı varlığın aynı blokta oluşturulmuş olması gerektiğini zaten biliyorsa, loadInBlock kullanmak bu veritabanı sorgusunu ortadan kaldırır.
  • Bazı subgraph'lerde bu başarısız aramalar endeksleme süresine önemli ölçüde etki edebilir.
let id = event.transaction.hash // veya ID nasıl oluşturulurmuşsa
let transfer = Transfer.loadInBlock(id)
if (transfer == null) {
transfer = new Transfer(id)
}
// Transfer varlığını daha önce olduğu gibi kullanın

Not: Belirtilen blokta bir varlık oluşturulmadıysa, depoda verilen ID'ye sahip bir varlık olsa bile loadInBlock yöntemi null döndürecektir.

Türetilmiş varlıkları arama

Bu bölüme bağlantı

graph-node v0.31.0, @graphprotocol/graph-ts v0.31.0 ve @graphprotocol/graph-cli v0.51.0 itibarıyla, loadRelated metodu kullanılabilir hale gelmiştir.

Bu, türetilmiş varlık alanlarının bir olay işleyicisi içinden yüklenmesini sağlar. Örneğin, aşağıdaki şema göz önüne alındığında:

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

Aşağıdaki kod, Holder varlığının türetildiği Token varlığını yükleyecektir:

let holder = Holder.load('test-id')
// Belirli bir sahiple ilişkili Token unsurlarını yükleyin
let tokens = holder.tokens.load()

Mevcut varlıkları güncelleme

Bu bölüme bağlantı

Mevcut bir varlığı güncellemenin iki yolu vardır:

  1. Transfer.load(id) ya da benzeri bir metotla varlığı yükleyin, varlık üzerindeki özellikleri ayarlayın ve ardından .save() ile tekrar depoya kaydedin.
  2. new Transfer(id) ya da benzeri bir metotla varlığı oluşturun, varlık üzerindeki özellikleri ayarlayın ve ardından .save() ile depoya kaydedin. Eğer varlık zaten mevcutsa, yapılan değişiklikler mevcut varlıkla birleştirilir.

Oluşturulan özellik ayarlayıcılar sayesinde çoğu durumda özellikerin değiştirilmesi kolaydır:

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

Ayrıca aşağıdaki iki talimattan biriyle özellikleri kaldırmakta mümkündür:

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

Bu yalnızca isteğe bağlı özelliklerle çalışır, yani GraphQL'de ! olmadan tanımlanan özelliklerle. Örnek olarak, owner: Bytes veya amount: BigInt verilebilir.

Dizi özelliklerini güncellemek biraz daha karmaşıktır, çünkü bir varlıktan bir dizi almak, o dizinin bir kopyasını oluşturur. Bu sebeple diziyi değiştirdikten sonra dizi özelliklerinin tekrar doğrudan ayarlanması gerekmektedir. Aşağıdaki örnek, entitynin bir numbers: [BigInt!]! alanına sahip olduğunu varsayar.

// Bu işe yaramaz
entity.numbers.push(BigInt.fromI32(1))
entity.save()
// Bu çalışır
let numbers = entity.numbers
numbers.push(BigInt.fromI32(1))
entity.numbers = numbers
entity.save()

Depodan varlık kaldırma

Bu bölüme bağlantı

Şu andabir varlığı oluşturulan türler aracılığıyla kaldırmanın bir yolu yoktur. Bunun yerine, bir varlığı kaldırmak için varlık türünün adını ve varlık ID'sini store.remove yöntemine iletmek gerekir:

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

Ethereum API'si, akıllı sözleşmelere, genel durum değişkenlerine, sözleşme fonksiyonlarına, olaylara, işlemlere, bloklara ve Ethereum verilerinin kodlama/çözme işlemlerine erişim sağlar.

Ethereum Türleri İçin Destek

Bu bölüme bağlantı

Varlıklarda olduğu gibi graph codegen, bir subgraph'te kullanılan tüm akıllı sözleşmeler ve olaylar için sınıflar oluşturur. Bunun için, sözleşme ABI'lerinin subgraph manifestosundaki veri kaynağının bir parçası olması gerekir. ABI dosyaları genelde abis/ klasöründe saklanır.

Oluşturulan sınıflarla sayesinde Ethereum türleri ile yerleşik türler arasındaki dönüşümler arka planda gerçekleşir, böylece subgraph yazarlarının bu dönüşümlerle ilgilenmesine gerek kalmaz.

Aşağıdaki örnek bunu açıklar. Aşağıdaki gibi bir subgraph şeması verildiğinde

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

ve Ethereum üzerindeki Transfer(address,address,uint256) olay imzası için, sırasıyla address, address ve uint256 türlerine sahipfrom, to ve amount değerleri, Address ve BigInt türlerine dönüştürülür. Bu sayede, bu değerler Transfer varlığındaki Bytes! ve BigInt! özelliklerine aktarılabilir:

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()

Olaylar ve Blok/İşlem Verileri

Bu bölüme bağlantı

Önceki örneklerdeki Transfer olayı gibi olay işleyicilere iletilen Ethereum olayları, sadece olay parametrelerine değil, aynı zamanda bu olayların ait olduğu işlem ve blok bilgilerine de erişim sağlar. event örneklerinden aşağıdaki veriler elde edilebilir (bu sınıflar graph-ts içindeki ethereum modülünün bir parçasıdır):

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
}

Akıllı Sözleşme Durumuna Erişim

Bu bölüme bağlantı

graph codegen tarafından oluşturulan kod, subgraph'te kullanılan akıllı sözleşmeler için sınıflar da içerir. Bu sınıflar, mevcut blokta sözleşmenin genel durum değişkenlerine erişmek ve sözleşme fonksiyonlarını çağırmak için kullanılabilir.

Yaygın bir model, bir olayın kaynaklandığı sözleşmeye erişmektir. Bu, aşağıdaki kodla elde edilir:

// Oluşturulan sözleşme sınıfı ve Transfer olayı sınıfını içe aktarın
import { ERC20Contract, Transfer as TransferEvent } from '../generated/ERC20Contract/ERC20Contract'
// Oluşturulan varlık sınıfını içe aktarın
import { Transfer } from '../generated/schema'
export function handleTransfer(event: TransferEvent) {
// Sözleşmeyi olayı yayınlayan adresle bağlayın
let contract = ERC20Contract.bind(event.address)
// Durum değişkenlerine ve işlevlere erişmek için çağrı yapın
let erc20Symbol = contract.symbol()
}

Burada Transfer, varlık türüyle adlandırma çakışmasını önlemek için TransferEvent olarak yeniden adlandırılmıştır

Ethereum üzerindeki ERC20Contract sözleşmesi symbol adında herkese açık ve salt okunur bir fonksiyona sahip olduğu sürece, .symbol() ile çağrılabilir. Genel durum değişkenleri için otomatik olarak aynı ada sahip bir metot oluşturulur.

Subgraph parçası olan diğer tüm sözleşmelerde oluşturulan koddan içe aktarılabilir ve geçerli bir adrese bağlanabilir.

Geri Dönen Çağrıları Yönetme

Bu bölüme bağlantı

Eğer sözleşmenizin salt okunur metotlarıının başarısız olması (revert) mümkünse, kodunuzu try_ öneki ile oluşturulmuş sözleşme metodunu çağırarak çözümleyebilirsiniz (handle).

  • Örneğin, Gravity sözleşmesi gravatarToOwner metodunu dışa açar. Bu kod, metodun başarısızlıkla sonuçlanmasını (revert) çözümleyebilir:
let gravity = Gravity.bind(event.address)
let callResult = gravity.try_gravatarToOwner(gravatar)
if (callResult.reverted) {
log.info('getGravatar reverted', [])
} else {
let owner = callResult.value
}

Not: Geth veya Infura istemcisine bağlı bir Graph Düğümü tüm başarısızlıkları (revert) algılamayabilir. Buna bel bağlıyorsanız Parity istemcisine bağlı bir Graph Düğümü kullanmanızı öneririz.

ABI Kodlama/Çözme

Bu bölüme bağlantı

Veriler, ethereum modülündeki encode ve decode fonksiyonları kullanılarak Ethereum'un ABI kodlama formatına göre kodlanabilir ve kodu çözülebilir.

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)

Daha fazla bilgi için:

Bir Adresin Bakiyesi

Bu bölüme bağlantı

Bir adresin yerel token bakiyesi ethereum modülü kullanılarak elde edilebilir. Bu özellik, subgraph.yaml dosyasında tanımlanan apiVersion: 0.0.9 itibarıyla kullanılabilir. getBalance() fonksiyonu, belirtilen adresin olayın tetiklendiği blok sonundaki bakiyesini alır.

import { ethereum } from '@graphprotocol/graph-ts'
let address = Address.fromString('0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045')
let balance = ethereum.getBalance(address) // bakiyeyi BigInt olarak döndürür

Bir Adresin Akıllı Sözleşme veya EOA (Harici Sahipli Hesap) Olup Olmadığını Kontrol Etme

Bu bölüme bağlantı

Bir adresin akıllı sözleşme adresi mi yoksa harici sahipli bir adres (EOA) mi olduğunu kontrol etmek için, ethereum modülündeki hasCode() fonksiyonu kullanılabilir. Bu fonksiyon boolean döner. Bu özellik subgraph.yaml dosyasında tanımlanan apiVersion: 0.0.9 itibarıyla kullanılabilir.

import { ethereum } from '@graphprotocol/graph-ts'
let contractAddr = Address.fromString('0x2E645469f354BB4F5c8a05B3b30A929361cf77eC')
let isContract = ethereum.hasCode(contractAddr).inner // true döndürür
let eoa = Address.fromString('0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045')
let isContract = ethereum.hasCode(eoa).inner // false döndürür
import { log } from '@graphprotocol/graph-ts'

log API'si, subgraph'lerin bilgileri Graph Düğümü standart çıktısına ve Graph Gezgini'ne kaydetmesine olanak tanır. Mesajlar farklı günlük seviyeleri kullanılarak kaydedilebilir. Verilen argümanlardan günlük mesajlarını oluşturmak için temel bir biçimlendirme dizesi sentaksı sunulmaktadır.

log API'si aşağıdaki fonksiyonları içerir:

  • log.debug(fmt: string, args: Array<string>): void – bir hata ayıklama mesajı kaydeder.
  • log.info(fmt: string, args: Array<string>): void – bir bilgilendirme mesajı kaydeder.
  • log.warning(fmt: string, args: Array<string>): void – bir uyarı mesajı kaydeder.
  • log.error(fmt: string, args: Array<string>): void – bir hata mesajı kaydeder.
  • log.critical(fmt: string, args: Array<string>): void – kritik bir mesaj kaydeder ve subgraph'i sonlandırır.

log API'si bir format dizesi ve bir dize değerleri dizisini alır. Daha sonra, dizideki dize değerlerini format dizesindeki yer tutucuların yerine koyar. İlk {} yer tutucusu dizideki ilk değerle, ikinci {} yer tutucusu ikinci değerle ve bu şekilde devam ederek değiştirilir.

log.info('Message to be displayed: {}, {}, {}', [value.toString(), anotherValue.toString(), 'already a string'])

Bir veya daha fazla değerin loglanması

Bu bölüme bağlantı
Tek bir değerin loglanması
Bu bölüme bağlantı

Aşağıdaki örnekte, "A" dize değeri, kaydedilmeden önce bir diziye dönüştürülerek ['A'] haline getirilir:

let myValue = 'A'
export function handleSomeEvent(event: SomeEvent): void {
// Görüntüler : "My value is: A"
log.info('My value is: {}', [myValue])
}
Mevcut bir diziden tek bir girişi loglama
Bu bölüme bağlantı

Aşağıdaki örnekte, bağımsız değişken dizisi üç değer içermesine rağmen dizinin yalnızca ilk değeri loglanır.

let myArray = ['A', 'B', 'C']
export function handleSomeEvent(event: SomeEvent): void {
// Görüntüler: "My value is: A" ('log.info'ya üç değer iletilmiş olsa da)
log.info('My value is: {}', myArray)
}

Mevcut bir diziden birden çok girişi kaydetme

Bu bölüme bağlantı

Argüman dizisindeki her girişin günlük mesajındaki bir yer tutucu {} ile eşleşmesi gerekir. Aşağıdaki örnek, günlük mesajında üç yer tutucu {} içerir. Bu nedenle, myArray'deki üç değerin üçü de loglanır.

let myArray = ['A', 'B', 'C']
export function handleSomeEvent(event: SomeEvent): void {
// Görüntüler: "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)
}
Mevcut bir diziden belirli bir girişi loglama
Bu bölüme bağlantı

Dizide belirli bir değeri görüntülemek için dizinlenmiş değer bulunmalıdır.

export function handleSomeEvent(event: SomeEvent): void {
// Görüntüler : "My third value is C"
log.info('My third value is: {}', [myArray[2]])
}
Olay bilgilerinin loglanması
Bu bölüme bağlantı

Aşağıdaki örnek, bir olaydan blok numarasını, blok hash'ını ve işlem hash'ını loglar:

import { log } from '@graphprotocol/graph-ts'
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..."
])
}
import { ipfs } from '@graphprotocol/graph-ts'

Akıllı sözleşmeler bazen IPFS dosyalarını zincire sabitler. Bu, eşlemelerin sözleşmeden IPFS hash'lerini almasını ve ilgili dosyaları IPFS'ten okumasını sağlar. Dosya verileri Bytes olarak döndürülür ve genellikle daha fazla işleme tabi tutulması gerekir; örneğin, bu sayfada daha sonra belgelenen json API'si ile.

IPFS hash'ı veya yolu verildiğinde, bir dosyayı IPFS'den okuma şu şekilde yapılır:

// Bunu eşleştirmedeki bir olay işleyicinin içine koyun
let hash = 'QmTkzDwWqPbnAh5YiV5VwcTLnGdwSNsNTn2aDxdXBFca7D'
let data = ipfs.cat(hash)
// `QmTkzDwWqPbnAh5YiV5VwcTLnGdwSNsNTn2aDxdXBFca7D/Makefile`
gibi yollar
// bu dizinlerdeki dosyaları içerenler de desteklenir
let path = 'QmTkzDwWqPbnAh5YiV5VwcTLnGdwSNsNTn2aDxdXBFca7D/Makefile'
let data = ipfs.cat(path)

Not: Şu anda ipfs.cat deterministik değildir. Eğer dosya, IPFS ağı üzerinden, talebin zaman aşımından önce getirilemezse, fonksiyon null döndürür. Bu nedenle, sonucunnull olup olmadığını kontrol etmek her zaman önemlidir.

Ayrıca, daha büyük dosyaları akış halinde işlemek için ipfs.map kullanmak da mümkündür. Bu fonksiyon, bir IPFS dosyasının hash'ini veya yolunu, bir geri çağırma işlevinin adını ve davranışını değiştirmek için bayraklar alır:

import { JSONValue, Value } from '@graphprotocol/graph-ts'
export function processItem(value: JSONValue, userData: Value): void {
// İşlem yapmayla ilgili ayrıntılar için JSONValue belgelerine bakın
// JSON değerleri ile
let obj = value.toObject()
let id = obj.get('id')
let title = obj.get('title')
if (!id || !title) {
return
}
// Geri çağırmalar da varlık oluşturabilir
let newItem = new Item(id)
newItem.title = title.toString()
newitem.parent = userData.toString() // Set parent to "parentId"
newitem.save()
}
// Bunu eşleştirmedeki bir olay işleyicisinin içine koyun
ipfs.map('Qm...', 'processItem', Value.fromString('parentId'), ['json'])
// Alternatif olarak `ipfs.mapJSON` kullanın
ipfs.mapJSON('Qm...', 'processItem', Value.fromString('parentId'))

Şu anda desteklenen tek bayrak ipfs.map'e iletilmesi gereken json bayrağıdır. json bayrağı ile IPFS dosyası, her satırda bir JSON değeri olacak şekilde bir dizi JSON değerinden oluşmalıdır. ipfs.map çağrısı, dosyadaki her satırı okur, bir JSONValue olarak ayrıştırır (deserialize eder) ve her biri için geri çağırma (callback) fonksiyonunu çağırır. Geri çağırma fonksiyonu daha sonra JSONValuedan gelen verileri depolamak için varlık operasyonlarını kullanabilir. Varlık değişiklikleri yalnızca ipfs.map'i çağıran işleyici başarıyla tamamlandığında depolanır; bu sırada değişiklikler bellekte tutulur ve bu nedenle ipfs.map'in işleyebileceği dosya boyutu sınırlıdır.

Başarılı olduğunda ipfs.map, void döndürür. Geri çağırma fonksiyonunun herhangi bir çağrısı bir hataya neden olursa, ipfs.map'i çağıran işleyici durdurulur ve subgraph başarısız olarak işaretlenir.

Kripto(Crypto) API'si

Bu bölüme bağlantı
import { crypto } from '@graphprotocol/graph-ts'

crypto API'si, eşlemelerde kullanılan kriptografik fonksiyonları sağlar. Şu anda yalnızca bir fonksiyon mevcuttur:

  • crypto.keccak256(input: ByteArray): ByteArray
import { json, JSONValueKind } from '@graphprotocol/graph-ts'

JSON verileri, json API'si kullanılarak ayrıştırılabilir:

  • json.fromBytes(data: Bytes): JSONValue – Geçerli bir UTF-8 sekansı olarak yorumlanan bir Bytes dizisinden JSON verisini ayrıştırır
  • json.try_fromBytes(data: Bytes): Result<JSONValue, boolean>json.fromBytes'in güvenli versiyonu. Ayrıştırma başarısız olursa bir hata döndürür
  • json.fromString(data: string): JSONValue – Geçerli bir UTF-8 Stringden JSON verilerini ayrıştırır
  • json.try_fromString(data: string): Result<JSONValue, boolean>json.fromString'in güvenli versiyonu. Ayrıştırma başarısız olursa bir hata döndürür

JSONValue sınıfı, rastgele bir JSON belgesinden değerleri çekmek için bir yol sağlar. JSON değerleri boolean, sayı, dizi gibi türlerde olabileceği için, JSONValue sınıfı bir değerin türünü kontrol etmek için kind özelliği ile birlikte gelir:

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

Ayrıca, değerin null olup olmadığını kontrol etmek için bir metot da vardır:

  • value.isNull(): boolean

Bir değerin türü kesin olduğunda, aşağıdaki yöntemlerden biri kullanılarak yerleşik türlerden birine dönüştürülebilir:

  • value.toBool(): boolean
  • value.toI64(): i64
  • value.toF64(): f64
  • value.toBigInt(): BigInt
  • value.toString(): string
  • value.toArray(): Array<JSONValue> – (ve ardından JSONValue değerini yukarıdaki 5 metottan biriyle dönüştürün)

Tip Dönüşümleri Referansı

Bu bölüme bağlantı
Kaynak(lar)HedefDönüşüm fonksiyonu
AddressBytesyok
AddressStrings.toHexString()
BigDecimalStrings.toString()
BigIntBigDecimals.toBigDecimal()
BigIntDizgi (onaltılık)s.toHexString() or s.toHex()
BigIntString (unicode)s.toString()
BigInti32s.toI32()
BooleanBooleanyok
Bytes (işaretli)BigIntBigInt.fromSignedBytes(s)
Bytes (işaretsiz)BigIntBigInt.fromUnsignedBytes(s)
BytesDizgi (onaltılık)s.toHexString() or s.toHex()
BytesString (unicode)s.toString()
BytesString (base58)s.toBase58()
Bytesi32s.toI32()
Bytesu32s.toU32()
BytesJSONjson.fromBytes(s)
int8i32yok
int32i32yok
int32BigIntBigInt.fromI32(s)
uint24i32yok
int64 - int256BigIntyok
uint32 - uint256BigIntyok
JSONbooleans.toBool()
JSONi64s.toI64()
JSONu64s.toU64()
JSONf64s.toF64()
JSONBigInts.toBigInt()
JSONstrings.toString()
JSONArrays.toArray()
JSONObjects.toObject()
StringAddressAddress.fromString(s)
BytesAddressAddress.fromBytes(s)
StringBigIntBigInt.fromString(s)
StringBigDecimalBigDecimal.fromString(s)
Dizgi (onaltılık)BytesByteArray.fromHexString(s)
String (UTF-8)BytesByteArray.fromUTF8(s)

Veri Kaynağı Meta Verileri

Bu bölüme bağlantı

dataSource ad alanı üzerinden işleyiciyi çağıran veri kaynağının sözleşme adresini, ağını ve bağlamını inceleyebilirsiniz:

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

Varlık ve VeriKaynağıBağlamı

Bu bölüme bağlantı

Temel Entity sınıfı ve alt sınıf olan DataSourceContext sınıfı, alanları dinamik olarak ayarlamak ve almak için yardımcı programlara sahiptir:

  • 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

Manifest'teki DataSourceContext

Bu bölüme bağlantı

dataSources içindeki context bölümü, subgraph eşlemeleriniz içinde erişilebilen anahtar-değer çiftlerini tanımlamanıza olanak tanır. Kullanılabilir türler şunlardır: Bool, String, Int, Int8, BigDecimal, Bytes, List ve BigInt.

İşte context bölümünde çeşitli türlerin kullanımını gösteren bir YAML örneği:

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: Boolean bir değer (true veya false) belirtir.
  • String: Bir String (dize) değeri belirtir.
  • Int: 32-bit bir tamsayı belirtir.
  • Int8: 8-bit bir tamsayı belirtir.
  • BigDecimal: Ondalık bir sayı belirtir. Tırnak içinde yazılması gerekir.
  • Bytes: On altılık tabanda (hexadecimal) bir dizeyi belirtir.
  • List: Elemanlardan oluşan bir liste belirtir. Her elemanın türü ve verisi belirtilmelidir.
  • BigInt: Büyük bir tamsayı değeri belirtir. Büyük boyutu nedeniyle tırnak içinde yazılması gerekir.

Bu bağlama daha sonra subgraph eşleştirme dosyalarınızdan erişilebilir ve böylece daha dinamik ve yapılandırılabilir subgraphlar elde edebilirsiniz.

Sayfayı Düzenle

Önceki
Advance Subgraph Features
Sonraki
Genel AssemblyScript Sorunları
Sayfayı Düzenle