> For the complete documentation index, see [llms.txt](https://lunes-labs.gitbook.io/dao-lunes-labs-pt/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://lunes-labs.gitbook.io/dao-lunes-labs-pt/developers/para-desenvolvedores/smart-contract-ink-4.x/macros-e-atributos/ink-contract.md).

# #\[ink::contract]

A macro `#[ink::contract]` é o ponto de entrada para escrever contratos inteligentes ink!.&#x20;

Se você é um iniciante que está tentando aprender ink!, recomendamos que você dê uma olhada no nosso extenso [workshop de ink!](https://docs.substrate.io/tutorials/smart-contracts/).

### Descrição[​](https://use.ink/macros-attributes/contract#description) <a href="#description" id="description"></a>

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

### Usage[​](https://use.ink/macros-attributes/contract#usage) <a href="#usage" id="usage"></a>

#### Argumentos do cabeçalho[​](https://use.ink/macros-attributes/contract#header-arguments) <a href="#header-arguments" id="header-arguments"></a>

A macro `#[ink::contract]` pode receber argumentos de cabeçalho adicionais separados por vírgulas:

#### `compile_as_dependency: bool`[​](https://use.ink/macros-attributes/contract#compile_as_dependency-bool) <a href="#compile_as_dependency-bool" id="compile_as_dependency-bool"></a>

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:**

```rust
#[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`[​](https://use.ink/macros-attributes/contract#env-impl-environment) <a href="#env-impl-environment" id="env-impl-environment"></a>

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`:

```rust
pub struct MyEnvironment;

impl ink::env::Environment for MyEnvironment {
    const MAX_EVENT_TOPICS: usize = 3;

    type AccountId = u64;
    type Balance = u128;
    type Hash = [u8; 32];
    type Timestamp = u64;
    type BlockNumber = u32;
    type ChainExtension = ::ink::env::NoChainExtension;
}
```

Um usuário pode implementar seu contrato ink! usando a implementação personalizada do Ambiente conforme demonstrado abaixo:

```rust
#[ink::contract(env = MyEnvironment)]
mod my_contract {
    pub struct MyEnvironment;

    impl ink::env::Environment for MyEnvironment {
        const MAX_EVENT_TOPICS: usize = 3;
        type AccountId = u64;
        type Balance = u128;
        type Hash = [u8; 32];
        type Timestamp = u64;
        type BlockNumber = u32;
        type ChainExtension = ::ink::env::NoChainExtension;
    }

    #[ink(storage)]
    pub struct MyStorage;

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

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

**Valor padrão:** `DefaultEnvironment` definido no pacote `ink_env`.

### Análise[​](https://use.ink/macros-attributes/contract#analysis) <a href="#analysis" id="analysis"></a>

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:**

```rust
#[ink::contract]
mod flipper {
    #[ink(storage)]
    pub struct Flipper {
        value: bool,
    }

    impl Flipper {
        #[ink(constructor)]
        pub fn construct() -> Self { Flipper { value: false } }

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

* 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.&#x20;

**Exemplo:** Dada a definição do contrato `Flipper` acima, adicionamos um `#[ink(constructor)]` da seguinte maneira:

```rust
#[ink::contract]
mod flipper {
    #[ink(storage)]
    pub struct Flipper {
        value: bool,
    }

    impl Flipper {
        #[ink(constructor)]
        pub fn new(initial_value: bool) -> Self {
            Flipper { value: false }
        }

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

* 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.

<mark style="color:purple;">Nota: Uma mensagem ink! com um receptor</mark> <mark style="color:purple;"></mark><mark style="color:purple;">`&self`</mark> <mark style="color:purple;"></mark><mark style="color:purple;">só pode ler o estado, enquanto uma mensagem ink! com um receptor</mark> <mark style="color:purple;"></mark><mark style="color:purple;">`&mut self`</mark> <mark style="color:purple;"></mark><mark style="color:purple;">pode alterar o armazenamento do contrato.</mark>

**Exemplo**

Dado a definição do contrato `Flipper` acima, adicionamos algumas definições `#[ink(message)]` da seguinte forma:

```rust
#[ink::contract]
mod flipper {
    #[ink(storage)]
    pub struct Flipper {
        value: bool,
    }

    impl Flipper {
        #[ink(constructor)]
        pub fn new(initial_value: bool) -> Self {
            Flipper { value: false }
        }

        /// Flips the current value.
        #[ink(message)]
        pub fn flip(&mut self) {
            self.value = !self.value;
        }

        /// Returns the current value.
        #[ink(message)]
        pub fn get(&self) -> bool {
            self.value
        }
    }
}
```

**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:&#x20;

Observe que os construtores ink! são sempre implicitamente pagáveis e, portanto, não podem ser marcados como tal.

```rust
#[ink::contract]
mod flipper {
    #[ink(storage)]
    pub struct Flipper {
        value: bool,
    }

    impl Flipper {
        #[ink(constructor)]
        pub fn new(initial_value: bool) -> Self {
            Flipper { value: false }
        }

        /// Flips the current value.
        #[ink(message)]
        #[ink(payable)] // You can either specify payable out-of-line.
        pub fn flip(&mut self) {
            self.value = !self.value;
        }

        /// Returns the current value.
        #[ink(message, payable)] // ...or specify payable inline.
        pub fn get(&self) -> bool {
            self.value
        }
    }
}
```

**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.&#x20;

O autor de um smart contract ink! pode controlar o seletor de uma mensagem ou construtor usando a flag `selector`. Um exemplo é mostrado abaixo:

```rust
#[ink::contract]
mod flipper {
    #[ink(storage)]
    pub struct Flipper {
        value: bool,
    }

    impl Flipper {
        #[ink(constructor)]
        #[ink(selector = "0xDEADBEEF")] // Works on constructors as well.
        pub fn new(initial_value: bool) -> Self {
            Flipper { value: false }
        }

        /// Flips the current value.
        #[ink(message)]
        #[ink(selector = "0xCAFEBABE")] // You can either specify selector out-of-line.
        pub fn flip(&mut self) {
            self.value = !self.value;
        }

        /// Returns the current value.
        #[ink(message, selector = "0xFEEDBEEF")] // ...or specify selector inline.
        pub fn get(&self) -> bool {
            self.value
        }
    }
}
```

### Interacting with the Contract Executor[​](https://use.ink/macros-attributes/contract#interacting-with-the-contract-executor) <a href="#interacting-with-the-contract-executor" id="interacting-with-the-contract-executor"></a>

A crate `ink_env` fornece recursos para interagir com o executor do contrato que conecta os contratos inteligentes ink! com o mundo exterior.&#x20;

Por exemplo, é possível consultar o chamador da chamada atual através de:

```rust
use ink_env;
ink::env::test::run_test::<ink::env::DefaultEnvironment, _>(|_| {
    let caller = ink::env::caller::<ink::env::DefaultEnvironment>();
    let _caller = caller;
    Ok(())
}).unwrap();
```

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:

```rust
#[ink::contract]
mod greeter {
    #[ink(storage)]
    pub struct Greeter;

    impl Greeter {
        #[ink(constructor)]
        pub fn new() -> Self {
            let caller = Self::env().caller();
            let message = format!("thanks for instantiation {:?}", caller);
            ink::env::debug_println(&message);
            Greeter {}
        }

        #[ink(message, payable)]
        pub fn fund(&mut self) {
            let caller = self.env().caller();
            let value = self.env().transferred_balance();
            let message = format!("thanks for the funding of {:?} from {:?}", value, caller);
            ink::env::debug_println(&message);
        }
    }
}
```

### Eventos[​](https://use.ink/macros-attributes/contract#events) <a href="#events" id="events"></a>

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.&#x20;

O exemplo a seguir mostra um contrato ink! que define e emite um evento "`Transferred`" no `#[ink(constructor)]`.

```rust
 #[ink::contract]
 mod erc20 {
     /// Defines an event that is emitted every time value is transferred.
     #[ink(event)]
     pub struct Transferred {
         from: Option<AccountId>,
         to: Option<AccountId>,
         value: Balance,
     }

     #[ink(storage)]
     pub struct Erc20 {
         total_supply: Balance,
         // more fields ...
     }

     impl Erc20 {
         #[ink(constructor)]
         pub fn new(initial_supply: Balance) -> Self {
             let caller = Self::env().caller();
             Self::env().emit_event(Transferred {
                 from: None,
                 to: Some(caller),
                 value: initial_supply,
             });
             Self { total_supply: initial_supply }
         }

         #[ink(message)]
         pub fn total_supply(&self) -> Balance {
             self.total_supply
         }
     }
 }
```

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[​](https://use.ink/macros-attributes/contract#example-flipper) <a href="#example-flipper" id="example-flipper"></a>

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.&#x20;

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`.

```rust
#[ink::contract]
pub mod flipper {
    #[ink(storage)]
    pub struct Flipper {
        value: bool,
    }

    impl Flipper {
        /// Creates a new flipper smart contract initialized with the given value.
        #[ink(constructor)]
        pub fn new(init_value: bool) -> Self {
            Self { value: init_value }
        }

        /// Flips the current value of the Flipper's bool.
        #[ink(message)]
        pub fn flip(&mut self) {
            self.value = !self.value;
        }

        /// Returns the current value of the Flipper's bool.
        #[ink(message)]
        pub fn get(&self) -> bool {
            self.value
        }
    }
}
```

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`.
