18 dakika
AssemblyScript API'si
Note: If you created a Subgraph prior to graph-cli
/graph-ts
version 0.22.0
, then you’re using an older version of AssemblyScript. It is recommended to review the Migration Guide
.
Learn what built-in APIs can be used when writing Subgraph mappings. There are two kinds of APIs available out of the box:
- Graph TypeScript kütüphanesi (
graph-ts
) - Code generated from Subgraph files by
graph codegen
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ı
@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.
Sürümler
The apiVersion
in the Subgraph manifest specifies the mapping API version which is run by Graph Node for a given Subgraph.
Sürüm | Sürüm Notları |
---|---|
0.0.9 | Yeni host fonksiyonları ekler: eth_get_balance ve hasCode |
0.0.8 | Bir varlığı kaydederken şemadaki alanların varlığını doğrulama mekanizması ekler. |
0.0.7 | Ethereum türlerine TransactionReceipt ve Log sınıfları eklendiEthereum Event nesnesine receipt alanı eklendi |
0.0.6 | Ethereum Transaction nesnesine nonce alanı eklendiEthereum Block nesnesine baseFeePerGas eklendi |
0.0.5 | AssemblyScript upgraded to version 0.19.10 (this includes breaking changes, please see the Migration Guide )ethereum.transaction.gasUsed renamed to ethereum.transaction.gasLimit |
0.0.4 | Ethereum SmartContractCall nesnesine functionSignature alanı eklendi |
0.0.3 | Ethereum Call nesnesine from alanı eklendiethereum.call.address , ethereum.call.to olarak yeniden adlandırıldı |
0.0.2 | Ethereum Transaction nesnesine input alanı eklendi |
Dahili Türler
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.
ByteArray
1import { 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 ve0x
öneki ekler.toString(): string
- Baytları UTF-8 dizesi olarak yorumlar.toBase58(): string
- Baytları base58 dizesine kodlar.toU32(): u32
- Baytları little-endian biru32
olarak yorumlar. Aşım durumunda hata verir.toI32(): i32
- Bayt dizisini little-endian biri32
olarak yorumlar. Aşım durumunda hata verir.
Operatörler
equals(y: ByteArray): bool
–x == y
olarak yazılabilir.concat(other: ByteArray): ByteArray
-this
dizisinin sonunaother
dizisini ekleyerek yeni birByteArray
döner.concatI32(other: i32): ByteArray
-this
dizisinin sonunaother
’ın bayt temsili ekleyerek yeni birByteArray
döner.
BigDecimal
1import { 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)
– BirBigInt
’ten birBigDecimal
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): BigDecimal
–x + y
şeklinde yazılabilir.minus(y: BigDecimal): BigDecimal
–x - y
şeklinde yazılabilir.times(y: BigDecimal): BigDecimal
–x * y
şeklinde yazılabilir.div(y: BigDecimal): BigDecimal
–x / y
şeklinde yazılabilir.equals(y: BigDecimal): bool
–x == y
şeklinde yazılabilir.notEqual(y: BigDecimal): bool
–x != y
şeklinde yazılabilir.lt(y: BigDecimal): bool
–x < y
şeklinde yazılabilir.le(y: BigDecimal): bool
–x <= y
şeklinde yazılabilir.gt(y: BigDecimal): bool
–x > y
şeklinde yazılabilir.ge(y: BigDecimal): bool
–x >= y
şeklinde yazılabilir.neg(): BigDecimal
--x
şeklinde yazılabilir.
BigInt
1import { 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
– Biri32
’den birBigInt
oluşturur. -
BigInt.fromString(s: string): BigInt
– Bir dizeden birBigInt
oluşturur. -
BigInt.fromUnsignedBytes(x: Bytes): BigInt
–bytes
’i işaretsiz, little-endian bir tamsayı olarak yorumlar. Girdiniz big-endian ise önce.reverse()
metodunu kullanın. -
BigInt.fromSignedBytes(x: Bytes): BigInt
–bytes
’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(): dize
–BigInt
’i on altılık tabanda bir karakter dizesine dönüştürür. -
x.toString(): dize
–BigInt
’i ondalık tabanda bir dizeye dönüştürür. -
x.toI32(): i32
–BigInt
’i biri32
olarak döndürür, değeri32
’ye sığmazsa hata verir. İlk olarakx.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): BigInt
–x + y
şeklinde yazılabilir.x.minus(y: BigInt): BigInt
–x - y
şeklinde yazılabilir.x.times(y: BigInt): BigInt
–x * y
şeklinde yazılabilir.x.div(y: BigInt): BigInt
–x / y
şeklinde yazılabilir.x.mod(y: BigInt): BigInt
–x % y
şeklinde yazılabilir.x.equals(y: BigInt): bool
–x == y
şeklinde yazılabilir.x.notEqual(y: BigInt): bool
–x != y
şeklinde yazılabilir.x.lt(y: BigInt): bool
–x < y
şeklinde yazılabilir.x.le(y: BigInt): bool
–x <= y
şeklinde yazılabilir.x.gt(y: BigInt): bool
–x > y
şeklinde yazılabilir.x.ge(y: BigInt): bool
–x >= 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 biri32
’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): BigInt
–x | y
olarak yazılabilir.bitAnd(x: BigInt, y: BigInt): BigInt
–x & y
şeklinde yazılabilir.leftShift(x: BigInt, bits: u8): BigInt
–x << y
şeklinde yazılabilir.rightShift(x: BigInt, bits: u8): BigInt
–x >> y
şeklinde yazılabilir.
TypedMap
1import { 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 veV
türünde değerler içeren boş bir eşlem oluştururmap.set(key: K, value: V): void
–key
anahtarının değerinivalue
olarak ayarlarmap.getEntry(key: K): TypedMapEntry<K, V> | null
–key
için anahtar-değer çiftini döndürür, eğerkey
eşlemde mevcut değilsenull
dönermap.get(key: K): V | null
–key
için değeri döndürür, eğerkey
eşlemde mevcut değilsenull
dönermap.isSet(key: K): bool
– Eğerkey
eşlemde mevcutsatrue
, değilsefalse
döner
Baytlar
1import { 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): Bytes
–hex
dizesini, on altı tabanında çift sayıda basamaktan oluşması koşuluyla birByteArray
’e dönüştürür.hex
dizesi isteğe bağlı olarak0x
ile başlayabilirfromI32(i: i32): Bytes
–i
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ürb.toString()
– dizideki baytları Unicode karakterlerinden oluşan bir dizeye dönüştürürb.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): Bytes
–this
dizisinin sonunaother
dizisini ekleyerek yeni birBytes
döndürürb.concatI32(other: i32): ByteArray
–this
dizisinin sonrasınaother
’ın bayt temsilini eklenerek yeni birBytes
döndürür
Adres(Address)
1import { 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 birAddress
oluştururAddress.fromBytes(b: Bytes): Address
– Tam olarak 20 bayt uzunluğunda olması gerekenb
dizisinden birAddress
oluşturur. Daha az veya daha fazla bayt içeren bir değer geçildiğinde hata verir
Store API
1import { 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.
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.
Unsurların Oluşturulması
Aşağıdaki, Ethereum olaylarından varlıklar oluşturmak için yaygın bir modeldir.
1// ERC20 ABI'dan oluşturulan Transfer olay sınıfını içe aktarın2import { Transfer as TransferEvent } from '../generated/ERC20/ERC20'34// GraphQL şemasından oluşturulan Transfer varlık türünü içe aktarın5import { Transfer } from '../generated/schema'67// Transfer olayı işleyicisi8export function handleTransfer(event: TransferEvent): void {9 // İşlem hash'ını olay kimliği olarak kullanarak bir Transfer varlığı oluşturun10 let id = event.transaction.hash11 let transfer = new Transfer(id)1213 // Olay parametrelerini kullanarak varlığın özelliklerini ayarlayın14 transfer.from = event.params.from15 transfer.to = event.params.to16 transfer.amount = event.params.amount1718 // Varlığı depoya kaydedin19 transfer.save()20}
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
Bir varlık mevcutsa aiağıdaki kod kullanılarak depodan yüklenebilir:
1let id = event.transaction.hash // veya kimlik(ID) nasıl oluşturulmuşsa2let transfer = Transfer.load(id)3if (transfer == null) {4 transfer = new Transfer(id)5}67// 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
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.
The store API facilitates the retrieval of entities that were created or updated in the current block. A typical situation for this is that one handler creates a transaction from some onchain event, and a later handler wants to access this transaction if it exists.
- In the case where the transaction does not exist, the Subgraph will have to go to the database simply to find out that the entity does not exist. If the Subgraph author already knows that the entity must have been created in the same block, using
loadInBlock
avoids this database roundtrip. - For some Subgraphs, these missed lookups can contribute significantly to the indexing time.
1let id = event.transaction.hash // veya ID nasıl oluşturulurmuşsa2let transfer = Transfer.loadInBlock(id)3if (transfer == null) {4 transfer = new Transfer(id)5}67// 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
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:
1type Token @entity {2 id: ID!3 holder: Holder!4 color: String5}67type Holder @entity {8 id: ID!9 tokens: [Token!]! @derivedFrom(field: "holder")10}
Aşağıdaki kod, Holder
varlığının türetildiği Token
varlığını yükleyecektir:
1let holder = Holder.load('test-id')2// Belirli bir sahiple ilişkili Token unsurlarını yükleyin3let tokens = holder.tokens.load()
Mevcut varlıkları güncelleme
Mevcut bir varlığı güncellemenin iki yolu vardır:
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.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:
1let transfer = new Transfer(id)2transfer.from = ...3transfer.to = ...4transfer.amount = ...
Ayrıca aşağıdaki iki talimattan biriyle özellikleri kaldırmakta mümkündür:
1transfer.from.unset()2transfer.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, entity
nin bir numbers: [BigInt!]!
alanına sahip olduğunu varsayar.
1// Bu işe yaramaz2entity.numbers.push(BigInt.fromI32(1))3entity.save()45// Bu çalışır6let numbers = entity.numbers7numbers.push(BigInt.fromI32(1))8entity.numbers = numbers9entity.save()
Depodan varlık kaldırma
Ş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:
1import { store } from '@graphprotocol/graph-ts'2...3let id = event.transaction.hash4store.remove('Transfer', id)
Ethereum API
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
As with entities, graph codegen
generates classes for all smart contracts and events used in a Subgraph. For this, the contract ABIs need to be part of the data source in the Subgraph manifest. Typically, the ABI files are stored in an abis/
folder.
With the generated classes, conversions between Ethereum types and the built-in types take place behind the scenes so that Subgraph authors do not have to worry about them.
The following example illustrates this. Given a Subgraph schema like
1type Transfer @entity {2 id: Bytes!3 from: Bytes!4 to: Bytes!5 amount: BigInt!6}
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:
1let id = event.transaction.hash2let transfer = new Transfer(id)3transfer.from = event.params.from4transfer.to = event.params.to5transfer.amount = event.params.amount6transfer.save()
Olaylar ve Blok/İşlem Verileri
Ö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):
1class Event {2 address: Address3 logIndex: BigInt4 transactionLogIndex: BigInt5 logType: string | null6 block: Block7 transaction: Transaction8 parameters: Array<EventParam>9 receipt: TransactionReceipt | null10}1112class Block {13 hash: Bytes14 parentHash: Bytes15 unclesHash: Bytes16 author: Address17 stateRoot: Bytes18 transactionsRoot: Bytes19 receiptsRoot: Bytes20 number: BigInt21 gasUsed: BigInt22 gasLimit: BigInt23 timestamp: BigInt24 difficulty: BigInt25 totalDifficulty: BigInt26 size: BigInt | null27 baseFeePerGas: BigInt | null28}2930class Transaction {31 hash: Bytes32 index: BigInt33 from: Address34 to: Address | null35 value: BigInt36 gasLimit: BigInt37 gasPrice: BigInt38 input: Bytes39 nonce: BigInt40}4142class TransactionReceipt {43 transactionHash: Bytes44 transactionIndex: BigInt45 blockHash: Bytes46 blockNumber: BigInt47 cumulativeGasUsed: BigInt48 gasUsed: BigInt49 contractAddress: Address50 logs: Array<Log>51 status: BigInt52 root: Bytes53 logsBloom: Bytes54}5556class Log {57 address: Address58 topics: Array<Bytes>59 data: Bytes60 blockHash: Bytes61 blockNumber: Bytes62 transactionHash: Bytes63 transactionIndex: BigInt64 logIndex: BigInt65 transactionLogIndex: BigInt66 logType: string67 removed: bool | null68}
Akıllı Sözleşme Durumuna Erişim
The code generated by graph codegen
also includes classes for the smart contracts used in the Subgraph. These can be used to access public state variables and call functions of the contract at the current block.
Yaygın bir model, bir olayın kaynaklandığı sözleşmeye erişmektir. Bu, aşağıdaki kodla elde edilir:
1// Oluşturulan sözleşme sınıfı ve Transfer olayı sınıfını içe aktarın2import { ERC20Contract, Transfer as TransferEvent } from '../generated/ERC20Contract/ERC20Contract'3// Oluşturulan varlık sınıfını içe aktarın4import { Transfer } from '../generated/schema'56export function handleTransfer(event: TransferEvent) {7 // Sözleşmeyi olayı yayınlayan adresle bağlayın8 let contract = ERC20Contract.bind(event.address)910 // Durum değişkenlerine ve işlevlere erişmek için çağrı yapın11 let erc20Symbol = contract.symbol()12}
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.
Any other contract that is part of the Subgraph can be imported from the generated code and can be bound to a valid address.
Geri Dönen Çağrıları Yönetme
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:
1let gravity = Gravity.bind(event.address)2let callResult = gravity.try_gravatarToOwner(gravatar)3if (callResult.reverted) {4 log.info('getGravatar reverted', [])5} else {6 let owner = callResult.value7}
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
Veriler, ethereum
modülündeki encode
ve decode
fonksiyonları kullanılarak Ethereum’un ABI kodlama formatına göre kodlanabilir ve kodu çözülebilir.
1import { Address, BigInt, ethereum } from '@graphprotocol/graph-ts'23let tupleArray: Array<ethereum.Value> = [4 ethereum.Value.fromAddress(Address.fromString('0x0000000000000000000000000000000000000420')),5 ethereum.Value.fromUnsignedBigInt(BigInt.fromI32(62)),6]78let tuple = tupleArray as ethereum.Tuple910let encoded = ethereum.encode(ethereum.Value.fromTuple(tuple))!1112let decoded = ethereum.decode('(address,uint256)', encoded)
Daha fazla bilgi için:
- ABI Spec
- Kodlama/kod çözme Rust kütüphanesi/CLI
- Daha karmaşık bir örnek.
Bir Adresin Bakiyesi
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.
1import { ethereum } from '@graphprotocol/graph-ts'23let address = Address.fromString('0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045')4let 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
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.
1import { ethereum } from '@graphprotocol/graph-ts'23let contractAddr = Address.fromString('0x2E645469f354BB4F5c8a05B3b30A929361cf77eC')4let isContract = ethereum.hasCode(contractAddr).inner // true döndürür56let eoa = Address.fromString('0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045')7let isContract = ethereum.hasCode(eoa).inner // false döndürür
Logging API
1import { log } from '@graphprotocol/graph-ts'
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’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
– logs a critical message and terminates the Subgraph.
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.
1log.info('Message to be displayed: {}, {}, {}', [value.toString(), anotherValue.toString(), 'already a string'])
Bir veya daha fazla değerin loglanması
Tek bir değerin loglanması
Aşağıdaki örnekte, “A” dize değeri, kaydedilmeden önce bir diziye dönüştürülerek ['A']
haline getirilir:
1let myValue = 'A'23export function handleSomeEvent(event: SomeEvent): void {4 // Görüntüler : "My value is: A"5 log.info('My value is: {}', [myValue])6}
Mevcut bir diziden tek bir girişi loglama
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.
1let myArray = ['A', 'B', 'C']23export function handleSomeEvent(event: SomeEvent): void {4 // Görüntüler: "My value is: A" ('log.info'ya üç değer iletilmiş olsa da)5 log.info('My value is: {}', myArray)6}
Mevcut bir diziden birden çok girişi kaydetme
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.
1let myArray = ['A', 'B', 'C']23export function handleSomeEvent(event: SomeEvent): void {4 // Görüntüler: "My first value is: A, second value is: B, third value is: C"5 log.info('My first value is: {}, second value is: {}, third value is: {}', myArray)6}
Mevcut bir diziden belirli bir girişi loglama
Dizide belirli bir değeri görüntülemek için dizinlenmiş değer bulunmalıdır.
1export function handleSomeEvent(event: SomeEvent): void {2 // Görüntüler : "My third value is C"3 log.info('My third value is: {}', [myArray[2]])4}
Olay bilgilerinin loglanması
Aşağıdaki örnek, bir olaydan blok numarasını, blok hash’ını ve işlem hash’ını loglar:
1import { log } from '@graphprotocol/graph-ts'23export function handleSomeEvent(event: SomeEvent): void {4 log.debug('Block number: {}, block hash: {}, transaction hash: {}', [5 event.block.number.toString(), // "47596000"6 event.block.hash.toHexString(), // "0x..."7 event.transaction.hash.toHexString(), // "0x..."8 ])9}
IPFS API
1import { ipfs } from '@graphprotocol/graph-ts'
Smart contracts occasionally anchor IPFS files onchain. This allows mappings to obtain the IPFS hashes from the contract and read the corresponding files from IPFS. The file data will be returned as Bytes
, which usually requires further processing, e.g. with the json
API documented later on this page.
IPFS hash’ı veya yolu verildiğinde, bir dosyayı IPFS’den okuma şu şekilde yapılır:
1// Bunu eşleştirmedeki bir olay işleyicinin içine koyun2let hash = 'QmTkzDwWqPbnAh5YiV5VwcTLnGdwSNsNTn2aDxdXBFca7D'3let data = ipfs.cat(hash)45// `QmTkzDwWqPbnAh5YiV5VwcTLnGdwSNsNTn2aDxdXBFca7D/Makefile`6gibi yollar7// bu dizinlerdeki dosyaları içerenler de desteklenir8let path = 'QmTkzDwWqPbnAh5YiV5VwcTLnGdwSNsNTn2aDxdXBFca7D/Makefile'9let 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:
1import { JSONValue, Value } from '@graphprotocol/graph-ts'23export function processItem(value: JSONValue, userData: Value): void {4 // İşlem yapmayla ilgili ayrıntılar için JSONValue belgelerine bakın5 // JSON değerleri ile6 let obj = value.toObject()7 let id = obj.get('id')8 let title = obj.get('title')910 if (!id || !title) {11 return12 }1314 // Geri çağırmalar da varlık oluşturabilir15 let newItem = new Item(id)16 newItem.title = title.toString()17 newitem.parent = userData.toString() // Set parent to "parentId"18 newitem.save()19}2021// Bunu eşleştirmedeki bir olay işleyicisinin içine koyun22ipfs.map('Qm...', 'processItem', Value.fromString('parentId'), ['json'])2324// Alternatif olarak `ipfs.mapJSON` kullanın25ipfs.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 JSONValue
dan 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.
On success, ipfs.map
returns void
. If any invocation of the callback causes an error, the handler that invoked ipfs.map
is aborted, and the Subgraph is marked as failed.
Kripto(Crypto) API’si
1import { 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
JSON API
1import { 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 birBytes
dizisinden JSON verisini ayrıştırırjson.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ürjson.fromString(data: string): JSONValue
– Geçerli bir UTF-8String
den JSON verilerini ayrıştırırjson.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:
1let value = json.fromBytes(...)2if (value.kind == JSONValueKind.BOOL) {3 ...4}
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ındanJSONValue
değerini yukarıdaki 5 metottan biriyle dönüştürün)
Tip Dönüşümleri Referansı
Kaynak(lar) | Hedef | Dönüşüm fonksiyonu |
---|---|---|
Address | Bytes | yok |
Address | String | s.toHexString() |
BigDecimal | String | s.toString() |
BigInt | BigDecimal | s.toBigDecimal() |
BigInt | Dizgi (onaltılık) | s.toHexString() or s.toHex() |
BigInt | String (unicode) | s.toString() |
BigInt | i32 | s.toI32() |
Boolean | Boolean | yok |
Bytes (işaretli) | BigInt | BigInt.fromSignedBytes(s) |
Bytes (işaretsiz) | BigInt | BigInt.fromUnsignedBytes(s) |
Bytes | Dizgi (onaltılık) | s.toHexString() or s.toHex() |
Bytes | String (unicode) | s.toString() |
Bytes | String (base58) | s.toBase58() |
Bytes | i32 | s.toI32() |
Bytes | u32 | s.toU32() |
Bytes | JSON | json.fromBytes(s) |
int8 | i32 | yok |
int32 | i32 | yok |
int32 | BigInt | BigInt.fromI32(s) |
uint24 | i32 | yok |
int64 - int256 | BigInt | yok |
uint32 - uint256 | BigInt | yok |
JSON | boolean | s.toBool() |
JSON | i64 | s.toI64() |
JSON | u64 | s.toU64() |
JSON | f64 | s.toF64() |
JSON | BigInt | s.toBigInt() |
JSON | string | s.toString() |
JSON | Array | s.toArray() |
JSON | Object | s.toObject() |
String | Address | Address.fromString(s) |
Bytes | Address | Address.fromBytes(s) |
String | BigInt | BigInt.fromString(s) |
String | BigDecimal | BigDecimal.fromString(s) |
Dizgi (onaltılık) | Bytes | ByteArray.fromHexString(s) |
String (UTF-8) | Bytes | ByteArray.fromUTF8(s) |
Veri Kaynağı Meta Verileri
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ı
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
The context
section within dataSources
allows you to define key-value pairs that are accessible within your Subgraph mappings. The available types are Bool
, String
, Int
, Int8
, BigDecimal
, Bytes
, List
, and BigInt
.
İşte context
bölümünde çeşitli türlerin kullanımını gösteren bir YAML örneği:
1dataSources:2 - kind: ethereum/contract3 name: ContractName4 network: mainnet5 context:6 bool_example:7 type: Bool8 data: true9 string_example:10 type: String11 data: 'hello'12 int_example:13 type: Int14 data: 4215 int8_example:16 type: Int817 data: 12718 big_decimal_example:19 type: BigDecimal20 data: '10.99'21 bytes_example:22 type: Bytes23 data: '0x68656c6c6f'24 list_example:25 type: List26 data:27 - type: Int28 data: 129 - type: Int30 data: 231 - type: Int32 data: 333 big_int_example:34 type: BigInt35 data: '1000000000000000000000000'
Bool
: Boolean bir değer (true
veyafalse
) 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.
This context is then accessible in your Subgraph mapping files, enabling more dynamic and configurable Subgraphs.