Guia rápido para contratos de solidez

Neste artigo, exploraremos os contratos do Solidity , incluindo sua estrutura , tipos de dados, funções e modificadores.

Também discutiremos as melhores práticas para escrever código Solidity seguro e eficiente e apresentaremos algumas ferramentas e estruturas populares para o desenvolvimento Solidity.



Contratos de Solidez

Os contratos de solidez encapsulam dados e funções e representam objetos ou entidades na rede blockchain.

Existem várias propriedades dos contratos Solidity que os tornam únicos em relação aos programas de software tradicionais:

 

Propriedades Visão geral
Endereço Cada contrato Solidity tem seu próprio endereço blockchain. Um endereço é usado para identificar um contrato na rede e interagir com ele.
Variáveis ​​de Estado Usando variáveis ​​de estado no Solidity, os contratos podem armazenar dados no blockchain. Existem vários tipos de variáveis ​​de estado em um contrato, incluindo inteiros, booleanos, strings, arrays e muito mais. As variáveis ​​de estado são declaradas no nível superior do contrato.
Funções Uma conta externa ou outro contrato pode chamar as funções definidas nos contratos Solidity. Uma função modifica as variáveis ​​de estado de um contrato, realiza cálculos e interage com outros contratos na rede.
Eventos Em contratos, os eventos podem ser gerados para notificar contas ou aplicativos externos sobre alterações importantes de estado. Normalmente, os eventos são usados ​​para fins de registro ou para iniciar processos off-chain.
modificador Um modificador restringe o acesso a certas funções ou operações dentro de um contrato Solidity. O objetivo dessas funções é impor permissões, validar entradas e garantir que certas condições sejam atendidas antes de executá-las.
Herança A herança é um recurso importante dos contratos do Solidity, que permite aos desenvolvedores reutilizar o código e a funcionalidade em vários contratos, herdando um do outro.

 


Quantificadores de Visibilidade

Um quantificador de visibilidade controla a acessibilidade de funções e variáveis ​​de estado dentro de um contrato Solidity.

O Solidity fornece quatro quantificadores de visibilidade:

 

Quantificadores Visão geral
Público Variáveis ​​e funções públicas podem ser invocadas de qualquer lugar, dentro ou fora do contrato.
Privado Funções privadas e variáveis ​​de estado só podem ser acessadas dentro de um contrato no qual são declaradas.
interno As funções ou variáveis ​​acessíveis internamente são acessíveis apenas de dentro do contrato ou de seus descendentes.
Externo As funções externas não podem ser chamadas de dentro de um contrato, apenas de fora. Além de criar interfaces para interagir com outros contratos, as funções externas também permitem o acesso público a determinadas funcionalidades.

 

Nota : O padrão do Solidity é a visibilidade interna para funções e variáveis ​​de estado.

Quantificadores Públicos

As variáveis ​​e funções de estado público podem ser invocadas do contato pai (onde são criadas) ou de qualquer outro contrato.

O exemplo a seguir mostra o funcionamento de quantificadores públicos :

Example: 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
pragma solidity ^0.8.0;
// This is the Parent Method which contains all the arithmetic operations of solidity programming
contract SolidityTest {
uint public value=32;
function add(uint mrx,uint ample) public pure returns(uint){
return mrx+ample;
}
function subtract(uint mrx,uint ample) public pure returns(uint){
return mrx-ample;
}
function multiply(uint mrx,uint ample) public pure returns(uint){
return mrx*ample;
}
function modulus(uint mrx,uint ample) public pure returns(uint){
return mrx%ample;
}
}
// Here we have created another contract named as SolidityTest1 which is inherited from the parent contract SolidityTest //
// It have the direct access to the public variables and functions in the parent contract //
contract SolidityTest1 is SolidityTest{
function obtain_Sum() public pure returns(uint){
return add(2,5);
}
function obtain_Difference() public pure returns(uint){
return subtract(5,1);
}
function obtain_Product() public pure returns(uint){
return multiply(3,4);
}
function obtain_Modulus() public pure returns(uint){
return modulus(6,5);
}
function obtain_Value() public view returns(uint){
return value;
}
}
// This is an external contract but it has access to the public function and variables by creating an object of the parent contact or the inherited contract inside it
contract SolidityTest2{
SolidityTest obj=new SolidityTest();
function get_Add() public view returns(uint){
return obj.multiply(2,4);
}
function get_Sub() public view returns(uint){
return obj.subtract(4,1);
}
function get_Multiply() public view returns(uint){
return obj.multiply(5,2);
}
function get_Modulus() public view returns(uint){
return obj.modulus(8,4);
}
function get_Value() public view returns(uint){
return obj.value();
}
}
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
<div class="spinner-border" role="status"><span class="sr-only">Loading...</span></div>

Quantificadores Privados

O usuário tem acesso a variáveis ​​de estado privadas e funções restritas ao contrato em que são inicializadas.

O exemplo dado ilustra o funcionamento de variáveis ​​e funções de estado privado:

Example: 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
pragma solidity ^0.8.0;
// This is the Parent Method which contains all the private arithmetic operations of solidity programming
contract SolidityTest {
uint private value=13;
function add(uint mrx,uint ample) private pure returns(uint){
return mrx+ample;
}
function subtract(uint mrx,uint ample) private pure returns(uint){
return mrx-ample;
}
function multiply(uint mrx,uint ample) private pure returns(uint){
return mrx*ample;
}
function modulus(uint mrx,uint ample) private pure returns(uint){
return mrx%ample;
}
}
// Here we have created another contract named as SolidityTest1 which is inherited from the parent contract SolidityTest //
// It doesnot have an access to the private variables and functions we constructed in the parent contract (SolidityTest) //
contract SolidityTest1 is SolidityTest{
function obtain_Sum() public pure returns(uint){
return add(2,5);
}
function obtain_Difference() public pure returns(uint){
return subtract(5,1);
}
function obtain_Product() public pure returns(uint){
return multiply(3,4);
}
function obtain_Modulus() public pure returns(uint){
return modulus(6,5);
}
function obtain_Value() public view returns(uint){
return value;
}
}
// This is an external contract having the object of the parent class (SolidityTest) inside it but still can not access the private functions and variables of the contract SolidityTest
contract SolidityTest2{
SolidityTest obj=new SolidityTest();
function get_Add() public view returns(uint){
return obj.multiply(2,4);
}
function get_Sub() public view returns(uint){
return obj.subtract(4,1);
}
function get_Multiply() public view returns(uint){
return obj.multiply(5,2);
}
function get_Modulus() public view returns(uint){
return obj.modulus(8,4);
}
function get_Value() public view returns(uint){
return obj.value();
}
}
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
<div class="spinner-border" role="status"><span class="sr-only">Loading...</span></div>
Nota : A execução deste código resultará em erro, porque as variáveis ​​e funções privadas são inacessíveis fora do contrato em que foram criadas.

Quantificadores Internos

As funções internas e as variáveis ​​de estado são acessíveis a partir da classe pai, bem como do contrato herdado, mas não dos contratos externos.

O código a seguir ilustra o funcionamento do quantificador interno:

Example: 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
pragma solidity ^0.8.0;
// This is the Parent Method which contains all the internal functions to performs several arithmetic operations of solidity programming
contract SolidityTest {
uint internal value=13;
function add(uint mrx,uint ample) internal pure returns(uint){
return mrx+ample;
}
function subtract(uint mrx,uint ample) internal pure returns(uint){
return mrx-ample;
}
function multiply(uint mrx,uint ample) internal pure returns(uint){
return mrx*ample;
}
function modulus(uint mrx,uint ample) internal pure returns(uint){
return mrx%ample;
}
}
// Here we have created another contract named as SolidityTest1 which is inherited from the parent contract SolidityTest //
// It have an access to the internal variables and functions we constructed in the parent contract (SolidityTest) //
contract SolidityTest1 is SolidityTest{
function obtain_Sum() public pure returns(uint){
return add(2,5);
}
function obtain_Difference() public pure returns(uint){
return subtract(5,1);
}
function obtain_Product() public pure returns(uint){
return multiply(3,4);
}
function obtain_Modulus() public pure returns(uint){
return modulus(6,5);
}
function obtain_Value() public view returns(uint){
return value;
}
}
// This is an external contract having the object of the parent class (SolidityTest) inside it but still can not access the internal functions and variables of the contract SolidityTest as the internal variables and functions are restricted to the parent contract or its inherited child contracts only
contract SolidityTest2{
SolidityTest obj=new SolidityTest();
function get_Add() public view returns(uint){
return obj.multiply(2,4);
}
function get_Sub() public view returns(uint){
return obj.subtract(4,1);
}
function get_Multiply() public view returns(uint){
return obj.multiply(5,2);
}
function get_Modulus() public view returns(uint){
return obj.modulus(8,4);
}
function get_Value() public view returns(uint){
return obj.value();
}
}
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
<div class="spinner-border" role="status"><span class="sr-only">Loading...</span></div>

Quantificadores Externos

A palavra-chave externa impede que a função seja acessada no contrato pai (onde foi inicializada).

Não há como tornar as variáveis ​​de estado externas.

Se quisermos acessar as funções externas dentro do contrato pai, podemos usar a palavra-chave this para atender ao nosso requisito.

O exemplo abaixo mostra a chamada de funções externas e suas exceções:

Example: 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
pragma solidity ^0.8.0;
// This is the Parent Method which contains all the external functions to performs several arithmetic operations of solidity programming
contract SolidityTest {
// uint external value=4; // its is not possible to assign the external quantifier to a variable, hence it generates an error
function add(uint mrx,uint ample) external pure returns (uint){
return mrx+ample;
}
function subtract(uint mrx,uint ample) external pure returns (uint) {
return mrx-ample;
}
function multiply(uint mrx,uint ample) external pure returns (uint) {
return mrx*ample;
}
function modulus(uint mrx,uint ample) external pure returns (uint){
return mrx%ample;
}
}
// Here we have created another contract named as SolidityTest1 which is inherited from the parent contract SolidityTest //
// It lacks an access to the external variables and functions we constructed in the parent contract (SolidityTest) only the external contracts can access it//
contract SolidityTest1 is SolidityTest{
function obtain_Sum() public pure returns(uint){
return add(2,5);
}
function obtain_Difference() public pure returns(uint){
return subtract(5,1);
}
function obtain_Product() public pure returns(uint){
return multiply(3,4);
}
function obtain_Modulus() public pure returns(uint){
return modulus(6,5);
}
function obtain_Value() public view returns(uint){
return value;
}
}
// This is an external contract having the object of the parent class (SolidityTest) only it can access the external functions and variables from the parent contract SolidityTest
contract SolidityTest2{
SolidityTest obj=new SolidityTest();
function get_Add() public view returns(uint){
return obj.multiply(2,4);
}
function get_Sub() public view returns(uint){
return obj.subtract(4,1);
}
function get_Multiply() public view returns(uint){
return obj.multiply(5,2);
}
function get_Modulus() public view returns(uint){
return obj.modulus(8,4);
}
}
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
<div class="spinner-border" role="status"><span class="sr-only">Loading...</span></div>
Se você deseja que as classes herdadas usem as funções externas da classe pai, isso pode ser feito usando a palavra-chave this como:

Example: 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
pragma solidity ^0.8.0;
// This is the Parent Method which contains all the external functions to performs several arithmetic operations of solidity programming
contract SolidityTest {
// uint external value=4; // its is not possible to assign the external quantifier to a variable, hence it generates an error
function add(uint mrx,uint ample) external pure returns (uint){
return mrx+ample;
}
function subtract(uint mrx,uint ample) external pure returns (uint) {
return mrx-ample;
}
function multiply(uint mrx,uint ample) external pure returns (uint) {
return mrx*ample;
}
function modulus(uint mrx,uint ample) external pure returns (uint){
return mrx%ample;
}
}
// Here we have created another contract named as SolidityTest1 which is inherited from the parent contract SolidityTest //
// After using the (this) keyword the inherited class from the parent contract can now have an access to the external variables and functions we constructed in the parent contract (SolidityTest) only the external contracts can access it//
contract SolidityTest1 is SolidityTest{
function obtain_Sum() public view returns(uint){
return this.add(2,5);
}
function obtain_Difference() public view returns(uint){
return this.subtract(5,1);
}
function obtain_Product() public view returns(uint){
return this.multiply(3,4);
}
function obtain_Modulus() public view returns(uint){
return this.modulus(6,5);
}
}
// This is an external contract having the object of the parent class (SolidityTest) only it can access the external functions and variables from the parent contract SolidityTest
contract SolidityTest2{
SolidityTest obj=new SolidityTest();
function get_Add() public view returns(uint){
return obj.multiply(2,4);
}
function get_Sub() public view returns(uint){
return obj.subtract(4,1);
}
function get_Multiply() public view returns(uint){
return obj.multiply(5,2);
}
function get_Modulus() public view returns(uint){
return obj.modulus(8,4);
}
}
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
<div class="spinner-border" role="status"><span class="sr-only">Loading...</span></div>

Importância dos quantificadores de visibilidade de solidez

A importância de um quantificador de visibilidade de solidez reside em sua capacidade de ajudá-lo a criar contratos inteligentes que sejam seguros, modulares e sustentáveis.

Quando você escolhe o quantificador certo para cada função e variável, seus contratos podem ser acessados ​​apenas pelas partes necessárias.

Ao fazer isso, você minimizará o risco de vulnerabilidades e ataques, além de melhorar a legibilidade e a estrutura do seu código.

É crucial, por exemplo, declarar uma função privada para impedir que quaisquer outros contratos ou entidades externas tenham acesso à lógica armazenada nessa função, reduzindo assim o potencial de manipulação ou exploração não autorizada.

Além disso, declarar uma função externa pode ser benéfico para otimizar o uso do gás porque somente chamadas externas poderão invocar a função. Desta forma, a necessidade de mudanças de estado desnecessárias é eliminada.

Os quantificadores de visibilidade do Solidity podem ajudá-lo a escrever um código mais modular e sustentável. Os quantificadores permitem que você e outros desenvolvedores entendam melhor a finalidade e a funcionalidade de um determinado contrato, indicando o uso pretendido e a acessibilidade de uma função.

Isso facilitará o desenvolvimento de contratos inteligentes mais complexos e interoperáveis.

Nós valorizamos o seu feedback.
+1
0
+1
0
+1
0
+1
0
+1
0
+1
0
+1
0

Assine a nossa newsletter
Digite seu e-mail para receber um resumo semanal de nossos melhores posts. Saber mais!
ícone