Visão geral
Este artigo apresenta uma solução de como usar o pagamento ASA para um serviço de contrato inteligente usando Algorand. Vamos implementar isto usando o Algo Builder.
O que é necessário
Bom conhecimento sobre Blockchain e Algorand.
Introdução detalhada ao algob.
Conhecimento detalhado sobre ativos, contas, transações.
Conhecimento detalhado sobre assinaturas inteligentes, contratos inteligentes algorand e contratos inteligentes.
Estrutura do projeto
contracts:(algob-project)
├── assets
│ ├── asa.yaml
│ ├── clear.py
│ ├── escrow.py
│ ├── stateful.py
├── scripts
│ ├── deploy.js
├── package.json
dapp
contém app react.
Sumário
1 . Visão geral 2
2 . Contratos
3 . Conta de garantia (contrato sem estado)
5 . DApp Web
Visão geral 2
Nesta solução temos um contrato inteligente (um app) que oferece um serviço e só registramos um novo usuário se ele pagar uma certa quantidade específica de tokens ASA.
Você pode encontrar o código para a solução aqui.
Nota: Um usuário só pode se registrar uma vez e pagar o dapp warcraft várias vezes.
A solução consiste em duas partes:
-
contracts
: Esta pasta consiste na implementação de ASA, assinaturas inteligentes e contratos inteligentes. -
dapp
: Esta pasta consiste na interface de usuário para interagir com contratos implantados e ASA.
Contratos
A pasta contracts
contém a lógica para esta solução. Nesta pasta vamos realizar as seguintes operações:
- Criar um token: WarcraftCoin (token ASA)
- Criar um aplicativo: Warcraft - tem apenas uma função: registrar (user_addr)
Estamos usando modelos PyTEAL, você pode ler mais sobre isso aqui.
Conta de garantia
A conta de garantia será usada para depositar o token ASA (token warcraft).
Neste contrato temos as ramificações optin
e register
.
Somente o manager
pode optar por enviar ASA para o endereço de garantia, isso é feito para que um usuário mal-intencionado não possa enviar spam de ASA para o endereço de garantia.
# transação de opção de participação
# Nota: estamos verificando que a primeira transação é o pagamento com o valor 0
# e enviado pelo manager da loja, porque não queremos outro
# usuário participando com muitos asa/app e bloqueando este endereço
opt_in = And(
Gtxn[0].amount() == Int(0),
Gtxn[0].sender() == Tmpl.Addr("TMPL_MANAGER"),
Gtxn[1].type_enum() == TxnType.AssetTransfer,
Gtxn[1].asset_amount() == Int(0)
)
O ramo de registro garante que o contrato de estado seja chamado.
register = And(
commons_checks,
Gtxn[1].type_enum() == TxnType.ApplicationCall,
Gtxn[1].application_id() == Tmpl.Int("TMPL_APPLICATION_ID"),
Gtxn[1].sender() == Gtxn[0].asset_sender()
)
Contrato de estado
No estado deste contrato é mencionado o endereço da conta de garantia da loja e o total registrado.
Além disso, codificamos rigidamente TMPL_MANAGER
(gerenciador de aplicativo) usando a variável de modelo (definida durante o carregamento do contrato inteligente).
Este contrato tem duas ramificações: on_update_escrow
, on_register
.
A ramificação on_update_escrow
só pode ser chamada pelo gerenciador de aplicativos para atualizar o endereço lsig de garantia.
Nota: primeiro precisamos criar o aplicativo sem definir o endereço da conta de garantia, porque o ID do aplicativo é necessário para inicializar corretamente o lsig de garantia.
on_update_escrow = Seq([
Assert(
And(
basic_checks,
Txn.sender() == Tmpl.Addr("TMPL_MANAGER")
)
),
App.globalPut(escrow, Txn.application_args[1]),
Return(Int(1))
])
A ramificação on_register
é usada para registrar um novo usuário no contrato em troca de tokens ASA (WarcraftCoin). Nesta ramificação verificamos que o usuário pagou exatamente 1 WarcraftCoin para o depósito. Finalmente, em seu estado local, definimos warcraft = 1
(para dar a ele acesso ao jogo) e incrementamos o contador global registrado em 1
.
on_register = Seq([
Assert(
And(
basic_checks,
Gtxn[0].type_enum() == TxnType.AssetTransfer,
Gtxn[0].asset_amount() == Int(1),
Gtxn[0].xfer_asset() == Tmpl.Int("TMPL_WARCRAFT_TOKEN"),
Gtxn[0].asset_receiver() == App.globalGet(escrow)
)
),
App.localPut(Int(0), Bytes("warcraft"), Int(1)),
App.globalPut(total_registered, Add(App.globalGet(total_registered), Int(1))),
Return(Int(1))
])
Preparamos uma amostra de scripts de implantação (para ASA
e Application
) em scripts/deploy.js
.
DApp Web
Criamos um dapp web para demonstrar e interagir com os contratos implantados. Ele usa @algo-builder/web
e Algosigner
.
Ele é criado usando create-react-app
.
Você pode encontrar o código completo em nosso repositório de modelos dapp.
O usuário pode usar este dapp para pagar a moeda do warcraft e se registrar no aplicativo. Este dapp possui um widget de pagamento que lida com essa transação de grupo.
Primeiro você precisa definir o ID ASA
(WarcraftCoin) e o ID App no código widget. Você pode encontrar esses valores após implantar os contratos (nos artefatos do Algo Builder).
Depois de definir os valores, você pode iniciar o aplicativo usando yarn run start
.
Para executar a transação, criamos um novo contexto AlgoSigner e usamos @algo-builer/web
para criar uma transação.
const web = new WebMode(AlgoSigner, CHAIN_NAME);
const groupTx = [
{
type: types.TransactionType.TransferAsset,
sign: types.SignType.SecretKey,
fromAccountAddr: fromAddress,
toAccountAddr: toAddress,
assetID: assetIndex,
amount: 1,
payFlags: {},
},
{
type: types.TransactionType.OptInToApp,
sign: types.SignType.SecretKey,
fromAccountAddr: fromAddress,
toAccountAddr: toAddress,
appID: appIndex,
payFlags: {},
}
];
// mostrar o estado de carregamento no botão enquanto enviamos & esperamos pela resposta da transação
setLoading (true);
let response = await web.executeTransaction(groupTx);
console.log(response);
Este artigo foi escrito por Amit Yadav e publicado no Portal do desenvolvedor Algorand. Traduzido por Marcelo Panegali.
Latest comments (0)