public

公开的,表示可以在合约内部和外部调用。都支持外部访问。

private

私有的,表示只能在合约内部调用。

internal

内部的,表示只能在合约内部调用。在0.5版本以后,已经废弃,建议使用private替代。

external

外部的,表示只能该在外部调用。状态变量不支持external类型。只支持外部函数访问,如果内部函数访问会报错。

对于,public、internal、private的状态变量都支持合约内部函数的访问。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
pragma solidity ^0.8.0;

contract MyContract {
// 只能在外部调用
function externalFunction() external {
//...
}

// 可以在合约内部和外部调用
function publicFunction() public {
//...
}

// 只能在合约内部调用
function privateFunction() private {
//...
}
}

状态变量继承

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
pragma solidity ^0.8.0;

contract Car{
string private _name;
string public _color;
uint _kw;

constructor(){
_name="car";
_color="black";
_kw=0;
}

function getKW() view external returns(uint){
return _kw;
}

function getColor() view public returns (string memory){
return _color;
}

function getName() view private returns(string memory){
return _name;
}
}

contract Tesla is Car {
constructor() {
// _name="tesla";
_color="red";
_kw=100;
}

function go() public {
// uint kw=getKW();
string memory color = getColor();
// string memory name=getName();
}
}

getKW()是external可见性,只能从外部调用,所以注释掉报错。
getName()是private可见性,不支持继承,所以注释掉报错。

public、internal类型的状态变量都支持继承,private不支持。
external、public、internal可见性都支持继承,private不支持。

重写-override

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
pragma solidity ^0.8.0;

contract Car{
string private _name;
string public _color;
uint _kw;

constructor(){
_name="car";
_color="black";
_kw=0;
}

function getKW() view external returns(uint){
return _kw;
}

function getColor() view public virtual returns (string memory){
return _color;
}

function getName() view private returns(string memory){
return _name;
}
}

contract Tesla is Car {
constructor() {
// _name="tesla";
_color="red";
_kw=100;
}

function getColor() view public override returns (string memory){
return _color;
}
}

如果父合约支持子合约继承自己的行为,也就是函数,那么给函数前面添加virtual关键字。
子合约继承或重写行为的时候,要加上override关键字。