Esse artigo foi escrito por Jason Weathersby e traduzido por Dimitris Calixto, artigo original disponível aqui
Muitas vezes é necessário que um contrato inteligente leia o estado global de outro contrato inteligente. Isto pode ser porque você precisa de um contrato para agir como um oracle para multiplicar contratos ou você quer que um valor global no contrato atual seja calculado parcialmente sobre um valor de outro contrato. Este artigo explica como isto pode ser feito e que codificação é necessária para atingir esta capacidade. Observe que você também pode ler o estado local utilizado por outros contratos. Este artigo aborda apenas o acesso ao estado global. Para mais informações sobre o estado de leitura e escrita em Algorand, consulte a documentação do desenvolvedor.
Leitura do Estado Global a partir de Contratos Adicionais
Dentro do framework de contratos inteligentes do estado, os contratos podem de fato ler o estado global a partir de contratos adicionais. Isto é feito usando o opcode 'app_global_get_ex' em TEAL ou o método 'App.globalGetEx' em PyTeal. Ambos tomam dois parâmetros. Este primeiro parâmetro é um número inteiro que representa o índice no array de aplicações externas. O segundo parâmetro é a chave específica que você está tentando ler do estado global para o contrato inteligente com estado referenciado. O array de aplicações externas é apenas uma lista de contratos inteligentes disponíveis dos quais o contrato atual pode ler o estado global e pode ser definida em cada chamada para um contrato inteligente com o estado. Atualmente, a lista de aplicações externas só pode conter dois contratos inteligentes estaduais adicionais. Embora isto possa parecer muito limitante, é importante perceber que estes dois podem ser alterados para cada chamada subsequente para o contrato inteligente. Por exemplo, a transação um pode fazer referência aos contratos inteligentes um e dois, e a transação dois pode fazer referência aos contratos inteligentes três e quatro.
Para definir os contratos inteligentes específicos do estado no array de aplicações externas para uma determinada transação, você pode fazer o seguinte.
Com a ferramenta de linha de comando 'goal'
:
Goal
goal app call --app-id <current-contract-id> --from <address-of-caller> --foreign-app <foreign-contract-1> —foreign-app <foreign-contract-2> -d data
Javascript
// appID1 e appID2 são inteiros
let foreignApps = [appID1, appID2];
// Chamar contrato com estado
let transaction1 = algosdk.makeApplicationNoOpTxn(sender, params, appID, appArgs, appAccts, foreginApps);
Python
# appID1 e appID2 são inteiros
foreign_apps = [appid1,appid2]
txn = transaction.ApplicationNoOpTxn(sender, params, index, app_args, foreign_apps)
Uma vez que os contratos inteligentes são colocados no array de aplicações externas, você pode então lê-los com o código TEAL ou PyTeal. Por exemplo, suponha que tenhamos um contrato inteligente master stateful com o seguinte código.
Atenção
Observe que os exemplos a seguir devem ser usados somente para fins de aprendizagem e nunca em produção, pois não contêm nenhuma verificação de erros.
#pragma version 2
// read global state
byte "mastervalue"
int 5000
app_global_put
int 1
return
Assuma que o contrato acima é implantado e seu ID de aplicação é '12345'. Este contrato apenas armazena um valor global denominado "mastervalue" com um valor de 5000. Este valor pode ser lido a partir de outro contrato, adicionando-o ao conjunto de aplicações externas antes de fazer a chamada para o contrato inteligente que deseja fazer referência a este valor do contrato principal.
goal app call --app-id <current-contract-id> --from <address-of-caller> --foreign-app 12345 -d data
Este valor pode então ser lido usando o opcode app_global_get_ex
. Este opcode toma dois parâmetros. O primeiro é um valor inteiro que representa um índice no array de aplicações externas. Note que a posição 0 no array, na verdade contém o contrato inteligente atual, portanto, quando adicionamos o array de aplicações externas, a primeira entrada padrão é a posição um. É por isso que precisamos fornecer o int 1
para o primeiro parâmetro para a chamada. O segundo parâmetro contém a chave que você deseja ler. O app_gloabl_get_ex
retorna um 0
ou 1
, dependendo se a chave é encontrada. Se a chave for encontrada, esta chamada também retorna o valor da chave.
#pragma version 2
// primeira aplicação no array de aplicações
// note que o int 0 refere o atual
// executando um contrato inteligente
int 1
byte "mastervalue"
app_global_get_ex
bz failed
int 5000
==
bz failed
int 1
return
.
.
failed:
int 0
return
No exemplo acima, após fazer a chamada para o opcode app_global_get_ex
, utilizamos o opcode da branch bz
. Este opcode desempilha o valor superior da pilha e se este valor for 0
, ele saltará para a label da branch. Neste caso, falhou:
. Isto acontecerá se a chave "mastervalue" não for encontrada no contrato inteligente referenciado. Se o valor for 1
, a chamada também retornará o valor. Após o código bz
opcode, encontrar o valor estará agora no topo da pilha. Neste exemplo, comparamos com o valor 5000 e se esse for o valor lido, devolvemos o sucesso, caso contrário, devolvemos um fracasso.
O exemplo de contrato inteligente também pode ser escrito em python usando a biblioteca PyTeal.
from pyteal import *
failed = Return(Int(0))
mastervalue = App.globalGetEx(Int(1), Bytes("mastervalue"))
program = Seq([
mastervalue,
If(Not(mastervalue.hasValue()), failed),
If(mastervalue.value() != Int(5000), failed),
Return(Int(1)),
])
print(compileTeal(program, Mode.Application))
Conclusão
Este post cobriu apenas a leitura do estado global a partir de contratos inteligentes adicionais. Usando contratos inteligentes da Algorand , os desenvolvedores podem criar muitas aplicações únicas. Para mais informações sobre como construir com contratos inteligentes Algorand , veja a documentação do desenvolvedor. Para uma visão geral da arquitetura e linguagem de programação do contrato inteligente Algorand , veja nossa recente apresentação do horário de expediente do desenvolvedor. Além disso, não deixe de se inscrever no próximo horário de expediente dos desenvolvedores e junte-se a nós no discord.
Latest comments (0)