๐Ÿ“‡#[ink::contract]

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 workshop de ink!.

Descriรงรฃoโ€‹

The macro does analysis on the provided smart contract code and generates proper code.

Usageโ€‹

Argumentos do cabeรงalhoโ€‹

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:

#[ink::contract(compile_as_dependency = true)]
mod my_contract {
    #[ink(storage)]
    pub struct MyStorage;

    impl MyStorage {
        #[ink(constructor)]
        pub fn construct() -> Self { MyStorage {} }

        #[ink(message)]
        pub fn message(&self) {}
    }
    // ...
}

Valor padrรฃo: Dependente da propagaรงรฃo do recurso do arquivo Cargo.toml.

env: impl Environmentโ€‹

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.

Anรกliseโ€‹

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:

Interacting with the Contract Executorโ€‹

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:

Eventosโ€‹

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.

Exemplo: Flipperโ€‹

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.

Last updated

Was this helpful?