Dado que Solidity tiene dos llamadas a funciones (las llamadas internas no generan llamadas EVM reales o "llamadas de mensajes", mientras que las llamadas externas generan una llamada EVM), hay cuatro tipos de visibilidad para funciones y variables de estado. Se puede especificar como una función de external
, public
, internal
o private
, en función del tipo de defecto public
. Para las variables de estado, no se puede establecer en external
, el valor predeterminado es internal
.
external
:
Las funciones externas son parte de la interfaz del contrato, lo que significa que podemos llamarlas desde otros contratos y transacciones. Una función externa f
no se puede llamar desde adentro (es decir f
, no funciona, pero this.f()
puede). Al recibir grandes cantidades de datos, las funciones externas a veces son más eficientes.
public
:
La función pública es parte de la interfaz del contrato y se puede llamar internamente o mediante mensajes. Para las variables de estado públicas, se genera automáticamente una función getter (ver más abajo).
internal
:
A estas funciones y variables de estado solo se puede acceder de forma interna (es decir, desde dentro del contrato actual o desde contratos derivados del mismo), sin this
llamarlas.
private
:
Las funciones privadas y las variables de estado solo se usan en el contrato actual que las define y no pueden ser usadas por contratos derivados.
anotación
Todo el contenido del contrato es visible para observadores externos. Establecer algunos private
tipos solo puede evitar que otros contratos accedan y modifiquen esta información, pero aún es visible para todo el mundo fuera de la cadena de bloques.
La posición de definición del identificador de visibilidad es después del tipo para las variables de estado y entre la lista de parámetros y la palabra clave de retorno para las funciones.
pragma solidity ^0.4.16;
contract C {
function f(uint a) private pure returns (uint b) { return a + 1; }
function setData(uint a) internal { data = a; }
uint public data;
}
En el siguiente ejemplo, se D
puede llamar c.getData()
para obtener data
el valor en el almacén de estado , pero no se puede llamar f
. El contrato se E
hereda C
, por lo que se puede llamar compute
.
// El siguiente error de compilación del código
pragma solidity ^0.4.0;
contract C {
uint private data;
function f(uint a) private returns(uint b) { return a + 1; }
function setData(uint a) public { data = a; }
function getData() public returns(uint) { return data; }
function compute(uint a, uint b) internal returns (uint) { return a+b; }
}
contract D {
function readData() public {
C c = new C();
uint local = c.f(7); // 错误:成员 `f` 不可见
c.setData(3);
local = c.getData();
local = c.compute(3, 5); // 错误:成员 `compute` 不可见
}
}
contract E is C {
function g() public {
C c = new C();
uint val = compute(3, 5); // 访问内部成员(从继承合约访问父合约成员)
}
}
Ge
función de tter
El compilador crea automáticamente funciones getter para todas las variables de estado públicas . Para el contrato que figura a continuación, el compilador genera una data
función denominada , que no recibe ningún parámetro y devuelve uno uint
, data
el valor de la variable de estado . La inicialización de las variables de estado se puede completar en el momento de la declaración.
pragma solidity ^0.4.0;
contract C {
uint public data = 42;
}
contract Caller {
C c = new C();
function f() public {
uint local = c.data();
}
}
La función getter tiene visibilidad externa. Si se accede al getter internamente (es decir, no hay this.
), se considera una variable de estado. Si se accede de forma externa (es decir, para su uso this.
), se considera una función.
pragma solidity ^0.4.0;
contract C {
uint public data;
function x() public {
data = 3; // 内部访问
uint val = this.data(); // 外部访问
}
}
El siguiente ejemplo es un poco más complicado:
pragma solidity ^0.4.0;
contract Complex {
struct Data {
uint a;
bytes3 b;
mapping (uint => uint) map;
}
mapping (uint => mapping(bool => Data[])) public data;
}
Esto generará una función de la forma
function data(uint arg1, bool arg2, uint arg3) public returns (uint a, bytes3 b) {
a = data[arg1][arg2][arg3].a;
b = data[arg1][arg2][arg3].b;
}
Tenga en cuenta que debido a que no existe una buena forma de proporcionar la clave asignada, se omite la asignación en la estructura.
Obtenga una mejor dirección de referencia: https://solidity-cn.readthedocs.io/zh/develop/contracts.html#visibility-and-getters