getLedgerEntries
For reading the current value of ledger entries directly.
This method enables the retrieval of various ledger states, such as accounts, trustlines, offers, data, claimable balances, and liquidity pools. It also provides direct access to inspect a contract's current state, its code, or any other ledger entry. This serves as a primary method to access your contract data which may not be available via events or simulateTransaction
.
To fetch contract wasm byte-code, use the ContractCode ledger entry key.
Params
(1)Please note that parameter structure within the request must contain named parameters as a by-name object, and not as positional arguments in a by-position array
1. keys (required)
Array containing the keys of the ledger entries you wish to retrieve. (an array of serialized base64 strings)
Array containing ledger keys. The maximum number of ledger keys accepted is 200.
Result
(getLedgerEntriesResult)The sequence number of the latest ledger known to Stellar RPC at the time it handled the request.
Array of objects containing all found ledger entries
The key of the ledger entry (serialized in a base64 string).
The current value of the given ledger entry (serialized in a base64 string).
The ledger sequence number of the last time this entry was updated.
Sequence number of the ledger.
Examples
Example request to the getNetwork
method for a Counter(Address)
ledger entry.
Request
- cURL
- JavaScript
- Python
- JSON
curl -X POST \
-H 'Content-Type: application/json' \
-d '{
"jsonrpc": "2.0",
"id": 8675309,
"method": "getLedgerEntries",
"params": {
"keys": [
"AAAABgAAAAHMA/50/Q+w3Ni8UXWm/trxFBfAfl6De5kFttaMT0/ACwAAABAAAAABAAAAAgAAAA8AAAAHQ291bnRlcgAAAAASAAAAAAAAAAAg4dbAxsGAGICfBG3iT2cKGYQ6hK4sJWzZ6or1C5v6GAAAAAE="
]
}
}' \
https://soroban-testnet.stellar.org | jq
let requestBody = {
"jsonrpc": "2.0",
"id": 8675309,
"method": "getLedgerEntries",
"params": {
"keys": [
"AAAABgAAAAHMA/50/Q+w3Ni8UXWm/trxFBfAfl6De5kFttaMT0/ACwAAABAAAAABAAAAAgAAAA8AAAAHQ291bnRlcgAAAAASAAAAAAAAAAAg4dbAxsGAGICfBG3iT2cKGYQ6hK4sJWzZ6or1C5v6GAAAAAE="
]
}
}
let res = await fetch('https://soroban-testnet.stellar.org', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(requestBody),
})
let json = await res.json()
console.log(json)
import json, requests
res = requests.post('https://soroban-testnet.stellar.org', json={
"jsonrpc": "2.0",
"id": 8675309,
"method": "getLedgerEntries",
"params": {
"keys": [
"AAAABgAAAAHMA/50/Q+w3Ni8UXWm/trxFBfAfl6De5kFttaMT0/ACwAAABAAAAABAAAAAgAAAA8AAAAHQ291bnRlcgAAAAASAAAAAAAAAAAg4dbAxsGAGICfBG3iT2cKGYQ6hK4sJWzZ6or1C5v6GAAAAAE="
]
}
})
print(json.dumps(res.json(), indent=4))
{
"jsonrpc": "2.0",
"id": 8675309,
"method": "getLedgerEntries",
"params": {
"keys": [
"AAAABgAAAAHMA/50/Q+w3Ni8UXWm/trxFBfAfl6De5kFttaMT0/ACwAAABAAAAABAAAAAgAAAA8AAAAHQ291bnRlcgAAAAASAAAAAAAAAAAg4dbAxsGAGICfBG3iT2cKGYQ6hK4sJWzZ6or1C5v6GAAAAAE="
]
}
}
Result
{
"jsonrpc": "2.0",
"id": 8675309,
"result": {
"entries": [
{
"key": "AAAAB+qfy4GuVKKfazvyk4R9P9fpo2n9HICsr+xqvVcTF+DC",
"xdr": "AAAABgAAAAAAAAABzAP+dP0PsNzYvFF1pv7a8RQXwH5eg3uZBbbWjE9PwAsAAAAQAAAAAQAAAAIAAAAPAAAAB0NvdW50ZXIAAAAAEgAAAAAAAAAAIOHWwMbBgBiAnwRt4k9nChmEOoSuLCVs2eqK9Qub+hgAAAABAAAAAwAAAAw=",
"lastModifiedLedgerSeq": 2552504
}
],
"latestLedger": 2552990
}
}
Generar parámetros de keys
El ejemplo anterior está consultando un despliegue del [ejemplo de contrato increment
] para averiguar qué valor se almacena en la entrada del ledger COUNTER
. Este valor se puede derivar usando los siguientes fragmentos de código. Deberías ser capaz de extrapolar de los ejemplos proporcionados cómo obtener parámetros de keys
para otros tipos y valores.
Python
Si estás usando el Python stellar_sdk
para generar estas claves, necesitarás instalar la última versión del SDK. Esto se puede hacer así:
pip install --upgrade stellar-sdk
from stellar_sdk import xdr, scval, Address
def get_ledger_key_symbol(contract_id: str, symbol_text: str) -> str:
ledger_key = xdr.LedgerKey(
type=xdr.LedgerEntryType.CONTRACT_DATA,
contract_data=xdr.LedgerKeyContractData(
contract=Address(contract_id).to_xdr_sc_address(),
key=scval.to_symbol(symbol_text),
durability=xdr.ContractDataDurability.PERSISTENT
),
)
return ledger_key.to_xdr()
print(
get_ledger_key_symbol(
"CCPYZFKEAXHHS5VVW5J45TOU7S2EODJ7TZNJIA5LKDVL3PESCES6FNCI",
"COUNTER"
)
)
JavaScript
Si estás usando el JavaScript stellar-sdk
para generar estas claves, necesitarás instalar la última versión pre-lanzamiento del SDK. Esto se puede hacer así:
yarn add @stellar/stellar-sdk
import { xdr, Address } from "@stellar/stellar-sdk";
const getLedgerKeySymbol = (contractId, symbolText) => {
const ledgerKey = xdr.LedgerKey.contractData(
new xdr.LedgerKeyContractData({
contract: new Address(contractId).toScAddress(),
key: xdr.ScVal.scvSymbol(symbolText),
durability: xdr.ContractDataDurability.persistent(),
}),
);
return ledgerKey.toXDR("base64");
};
console.log(
getLedgerKeySymbol(
"CCPYZFKEAXHHS5VVW5J45TOU7S2EODJ7TZNJIA5LKDVL3PESCES6FNCI",
"COUNTER",
),
);
Solicitar una cuenta
Esta funcionalidad está incluida en el paquete de JavaScript stellar-sdk
como SorobanRpc.Server.getAccount(address)
.
Las cuentas se almacenan como entradas del ledger, por lo que podemos usar este método para buscar una cuenta junto con su número de secuencia actual.
import { xdr, Keypair } from '@stellar/stellar-sdk'
const getLedgerKeyAccount = (address) => {
const ledgerKey = xdr.LedgerKey.account(
new xdr.LedgerKeyAccount({
accountId: Keypair.fromPublicKey(address).xdrPublicKey(),
})
)
return ledgerKey.toXDR('base64')
}
console.log(getLedgerKeyAccount(
'GCU5YE6IVBOEZ5LUU5N2NB55VPB5YZNFERT65SSTVXTNMS7IEQWXKBM2'
))
# OUTPUT: AAAAAAAAAACp3BPIqFxM9XSnW6aHvavD3GWlJGfuylOt5tZL6CQtdQ==
Luego tomamos nuestra salida de esta función y la usamos como el elemento en el parámetro de array keys
en nuestra llamada al método getLedgerEntries
.
{
"jsonrpc": "2.0",
"id": 8675309,
"method": "getLedgerEntries",
"params": {
"keys": ["AAAAAAAAAACp3BPIqFxM9XSnW6aHvavD3GWlJGfuylOt5tZL6CQtdQ=="]
}
}
Y la respuesta que obtenemos contiene el LedgerEntryData
con la información actual sobre esta cuenta.
{
"jsonrpc": "2.0",
"id": 8675309,
"result": {
"entries": [
{
"key": "AAAAAAAAAACp3BPIqFxM9XSnW6aHvavD3GWlJGfuylOt5tZL6CQtdQ==",
"xdr": "AAAAAAAAAACp3BPIqFxM9XSnW6aHvavD3GWlJGfuylOt5tZL6CQtdQAAABdIdugAAAWpygAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAA",
"lastModifiedLedgerSeq": "164303"
}
],
"latestLedger": 246819
}
}
Luego podemos analizar este resultado como un tipo xdr.LedgerEntryData
.
const parsed = xdr.LedgerEntryData.fromXDR(
"AAAAAAAAAACp3BPIqFxM9XSnW6aHvavD3GWlJGfuylOt5tZL6CQtdQAAABdIdugAAAWpygAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAA",
"base64",
);
console.log(parsed);
Solicitar el código Wasm de un contrato
Esto puede ser un poco complicado de entender, pero las convenciones tienen sentido una vez que lo asimilas.
En los ejemplos anteriores, la clave COUNTER
se usó como un LedgerKey
mientras que el valor incrementado se almacenó en una LedgerEntry
. "Entrada del Ledger" es el término relevante a tener en cuenta durante esta discusión. Esa LedgerEntry
se almacenó en el ledger Stellar y se asoció con un LedgerKey
correspondiente. LedgerKey: LedgerEntry
funciona de la misma manera que pensarías en cualquier sistema de almacenamiento clave: valor
.
Cómo funciona el despliegue de contratos Soroban
Cuando despliegas un contrato, primero se "instala" el código (es decir, se sube a la blockchain). Esto crea un LedgerEntry
que contiene el código byte de Wasm, que se identifica de forma única por su hash (es decir, el hash del código subido). Luego, cuando el contrato es "desplegado", creamos un LedgerEntry
con una referencia al hash de ese código. Por lo tanto, obtener el código del contrato es un proceso de dos pasos:
- Primero, buscamos el propio contrato para ver qué hash de código está referenciando.
- Luego, podemos buscar el código byte de Wasm utilizando ese hash.
Solicitar el LedgerKey
para el código del contrato
Python
from stellar_sdk import xdr, Address
def get_ledger_key_contract_code(contract_id: str) -> str:
ledger_key = xdr.LedgerKey(
type=xdr.LedgerEntryType.CONTRACT_DATA,
contract_data=xdr.LedgerKeyContractData(
contract=Address(contract_id).to_xdr_sc_address(),
key=xdr.SCVal(xdr.SCValType.SCV_LEDGER_KEY_CONTRACT_INSTANCE),
durability=xdr.ContractDataDurability.PERSISTENT
)
)
return ledger_key.to_xdr()
print(
get_ledger_key_contract_code(
"CCPYZFKEAXHHS5VVW5J45TOU7S2EODJ7TZNJIA5LKDVL3PESCES6FNCI"
)
)
# OUTPUT: AAAABgAAAAGfjJVEBc55drW3U87N1Py0Rw0/nlqUA6tQ6r28khEl4gAAABQAAAAB
JavaScript
import { Contract } from "@stellar/stellar-sdk";
function getLedgerKeyContractCode(contractId) {
const instance = new Contract(contractId).getFootprint();
return instance.toXDR("base64");
}
console.log(
getLedgerKeyContractCode(
"CCPYZFKEAXHHS5VVW5J45TOU7S2EODJ7TZNJIA5LKDVL3PESCES6FNCI",
),
);
// OUTPUT: AAAABgAAAAGfjJVEBc55drW3U87N1Py0Rw0/nlqUA6tQ6r28khEl4gAAABQAAAAB
Luego tomamos nuestra salida de esta función y la usamos como el elemento en el parámetro de array keys
en nuestra llamada al método getLedgerEntries
.
{
"jsonrpc": "2.0",
"id": 8675309,
"method": "getLedgerEntries",
"params": {
"keys": ["AAAABgAAAAGfjJVEBc55drW3U87N1Py0Rw0/nlqUA6tQ6r28khEl4gAAABQAAAAB"]
}
}
Y la respuesta que obtenemos contiene el LedgerEntryData
que se puede usar para encontrar el hash
que debemos usar para solicitar el código byte de Wasm. Este hash es el LedgerKey
que se ha asociado con el código del contrato desplegado.
{
"jsonrpc": "2.0",
"id": 8675309,
"result": {
"entries": [
{
"key": "AAAABgAAAAGfjJVEBc55drW3U87N1Py0Rw0/nlqUA6tQ6r28khEl4gAAABQAAAAB",
"xdr": "AAAABgAAAAAAAAABn4yVRAXOeXa1t1POzdT8tEcNP55alAOrUOq9vJIRJeIAAAAUAAAAAQAAABMAAAAA5DNtbckOGVRsNVb8L7X/lIhAOy2o5G6GkLKXvc7W8foAAAAA",
"lastModifiedLedgerSeq": "261603"
}
],
"latestLedger": 262322
}
}
Solicitar el ContractCode
utilizando el LedgerKey
recuperado
Ahora toma el campo xdr
del objeto result
de la respuesta anterior y crea un LedgerKey
a partir del hash que contiene.
Python
from stellar_sdk import xdr
def get_ledger_key_wasm_id(contract_code_ledger_entry_data: str) -> str:
# First, we dig the wasm_id hash out of the xdr we received from RPC
contract_code_wasm_hash = xdr.LedgerEntryData.from_xdr(
contract_code_ledger_entry_data
).contract_data.val.instance.executable.wasm_hash
# Now, we can create the `LedgerKey` as we've done in previous examples
ledger_key = xdr.LedgerKey(
type=xdr.LedgerEntryType.CONTRACT_CODE,
contract_code=xdr.LedgerKeyContractCode(
hash=contract_code_wasm_hash
),
)
return ledger_key.to_xdr()
print(
get_ledger_key_wasm_id(
"AAAABgAAAAAAAAABn4yVRAXOeXa1t1POzdT8tEcNP55alAOrUOq9vJIRJeIAAAAUAAAAAQAAABMAAAAA5DNtbckOGVRsNVb8L7X/lIhAOy2o5G6GkLKXvc7W8foAAAAA"
)
)
# OUTPUT: AAAAB+QzbW3JDhlUbDVW/C+1/5SIQDstqORuhpCyl73O1vH6
JavaScript
import { xdr } from "@stellar/stellar-sdk";
function getLedgerKeyWasmId(contractCodeLedgerEntryData) {
const entry = xdr.LedgerEntryData.fromXDR(
contractCodeLedgerEntryData,
"base64",
);
const wasmHash = entry
.contractData()
.val()
.instance()
.executable()
.wasmHash();
let ledgerKey = xdr.LedgerKey.contractCode(
new xdr.LedgerKeyContractCode({
hash: wasmHash,
}),
);
return ledgerKey.toXDR("base64");
}
console.log(
getLedgerKeyWasmId(
"AAAABgAAAAAAAAABn4yVRAXOeXa1t1POzdT8tEcNP55alAOrUOq9vJIRJeIAAAAUAAAAAQAAABMAAAAA5DNtbckOGVRsNVb8L7X/lIhAOy2o5G6GkLKXvc7W8foAAAAA",
),
);
// OUTPUT: AAAAB+QzbW3JDhlUbDVW/C+1/5SIQDstqORuhpCyl73O1vH6
Ahora, finalmente tenemos un LedgerKey
que corresponde al código byte de Wasm que ha sido desplegado bajo el ContractId
con el que comenzamos hace mucho tiempo. Este LedgerKey
se puede usar en una solicitud final al endpoint Stellar-RPC.
{
"jsonrpc": "2.0",
"id": 8675309,
"method": "getLedgerEntries",
"params": {
"keys": ["AAAAB+QzbW3JDhlUbDVW/C+1/5SIQDstqORuhpCyl73O1vH6"]
}
}