#[ink::contract]
Last updated
Was this helpful?
Last updated
Was this helpful?
A macro #[ink::contract]
é o ponto de entrada para escrever contratos inteligentes ink!.
Se você é um iniciante que está tentando aprender ink!, recomendamos que você dê uma olhada no nosso extenso .
The macro does analysis on the provided smart contract code and generates proper code.
A macro #[ink::contract]
pode receber argumentos de cabeçalho adicionais separados por vírgulas:
compile_as_dependency: bool
Indica ao gerador de código ink! para sempre compilar ou nunca compilar o smart contract como se fosse usado como uma dependência de outro smart contract ink!.
Normalmente, essa sinalização só é realmente útil para desenvolvedores ink! que desejam inspecionar a geração de código de smart contracts ink!. O autor não tem conhecimento de nenhum caso de uso prático específico para usuários que faça uso desse sinalizador, mas os escritores de contratos são encorajados a refutar essa afirmação.
Observe que é recomendado usar o recurso embutido da crate ink-as-dependency
para marcar as dependências de smart contracts listadas no Cargo.toml
de um contrato como dependências reais para ink!.
Exemplo de Uso:
Valor padrão: Dependente da propagação do recurso do arquivo Cargo.toml
.
Indica ao gerador de código ink! qual ambiente utilizar para o smart contract ink!. O ambiente deve implementar o traço Environment (definido em ink_env
) e fornecer todas as definições de tipos fundamentais necessárias, como Balance
, AccountId
, etc.
Ao usar uma implementação personalizada de Environment
para um smart contract, todos os tipos que ele expõe para o smart contract ink! e os tipos espelhados usados no tempo de execução devem estar alinhados em relação à codificação SCALE e semântica.
Usage Example:
Dada uma implementação personalizada do ambiente Environment
:
Um usuário pode implementar seu contrato ink! usando a implementação personalizada do Ambiente conforme demonstrado abaixo:
Valor padrão: DefaultEnvironment
definido no pacote ink_env
.
A macro #[ink::contract]
realiza uma análise completa do contrato inteligente de entrada em relação a argumentos inválidos e estrutura.
Algumas regras de exemplo incluem, mas não se limitam a:
Deve haver exatamente uma estrutura #[ink(storage)]
. Essa estrutura define o layout do armazenamento em que o contrato inteligente ink! opera. O usuário pode utilizar uma variedade de recursos integrados, combiná-los de várias maneiras ou até mesmo fornecer suas próprias implementações de estruturas de dados de armazenamento. Para mais informações, visite a documentação do crate ink_storage
.
Exemplo:
Deve haver pelo menos um método #[ink(constructor)]
definido. Os métodos marcados com #[ink(constructor)]
são especiais, pois são despacháveis ao instanciar o contrato. Um contrato pode definir vários construtores desse tipo, o que permite que os usuários do contrato instanciem o contrato de várias maneiras diferentes.
Exemplo: Dada a definição do contrato Flipper
acima, adicionamos um #[ink(constructor)]
da seguinte maneira:
Deve haver pelo menos um método #[ink(message)]
definido. Os métodos marcados com #[ink(message)]
são especiais, pois são despacháveis ao invocar o contrato. O conjunto de mensagens ink! definidas para um contrato ink! define a sua interface de programação de aplicação (API), com a qual os usuários podem interagir. Um contrato ink! pode ter vários métodos ink! definidos.
Nota: Uma mensagem ink! com um receptor &self
só pode ler o estado, enquanto uma mensagem ink! com um receptor &mut self
pode alterar o armazenamento do contrato.
Exemplo
Dado a definição do contrato Flipper
acima, adicionamos algumas definições #[ink(message)]
da seguinte forma:
Mensagens Pagáveis:
Uma mensagem ink! por padrão rejeitará chamadas que adicionem fundos ao contrato inteligente. Os autores de contratos ink! podem tornar uma mensagem ink! pagável adicionando o sinalizador "payable
" a ela. Um exemplo abaixo:
Observe que os construtores ink! são sempre implicitamente pagáveis e, portanto, não podem ser marcados como tal.
Controlando o seletor das mensagens:
Cada mensagem e construtor do ink! possui um seletor único que identifica de forma exclusiva a mensagem ou o construtor dentro do smart contract ink!. Esses seletores são usados principalmente para direcionar a chamada do contrato ao executá-lo.
O autor de um smart contract ink! pode controlar o seletor de uma mensagem ou construtor usando a flag selector
. Um exemplo é mostrado abaixo:
A crate ink_env
fornece recursos para interagir com o executor do contrato que conecta os contratos inteligentes ink! com o mundo exterior.
Por exemplo, é possível consultar o chamador da chamada atual através de:
No entanto, ink! fornece uma maneira muito mais simples de interagir com o executor do contrato por meio do seu acessor de ambiente. Um exemplo abaixo:
Um contrato inteligente ink! pode definir eventos que podem ser emitidos durante a execução do contrato. A emissão de eventos pode ser usada por ferramentas de terceiros para consultar informações sobre a execução e estado de um contrato.
O exemplo a seguir mostra um contrato ink! que define e emite um evento "Transferred
" no #[ink(constructor)]
.
Neste exemplo, o módulo erc20
define um contrato inteligente ink! para uma token ERC20 básica. O evento "Transferred" é definido como uma estrutura que contém informações sobre o remetente, destinatário e valor transferido. No construtor, o evento é emitido quando o contrato é instanciado, informando que uma transferência ocorreu do endereço do contrato para o endereço do chamador. O contrato também possui um método total_supply
que retorna o valor total de fornecimento do token.
O código abaixo mostra a implementação completa do contrato inteligente Flipper ink!. Para nós, ele funciona como o "Olá, mundo!" dos contratos inteligentes ink!, pois é mínimo, mas ainda fornece alguma funcionalidade mais ou menos útil.
Ele controla um único valor bool
que pode ser false
ou true
e permite que o usuário inverta esse valor usando a mensagem Flipper::flip
ou recupere o valor atual usando Flipper::get
.
O código abaixo mostra a implementação completa do contrato inteligente ink! chamado Flipper. Para nós, ele atua como o "Olá, mundo!" dos contratos inteligentes ink!, pois é mínimo, mas ainda fornece alguma funcionalidade mais ou menos útil. Ele controla um único valor booleano que pode ser falso ou verdadeiro e permite que o usuário inverta esse valor usando a mensagem Flipper::flip
ou obtenha o valor atual usando a mensagem Flipper::get
.