The difference can be in the way you access the variable and in the permission scheme.
ACCESSING
1 - If you have a public state variable of array type, then you can only retrieve single elements of the array via the generated getter function. This mechanism exists to avoid high gas costs when returning an entire array. You can use arguments to specify which individual element to return, for example data(0). If you want to return an entire array in one call, then you need to write a function, for example:
pragma solidity >=0.4.0 <0.6.0;
contract arrayExample {
// public state variable
uint[] public myArray;
// Getter function generated by the compiler
/*
function myArray(uint i) returns (uint) {
return myArray[i];
}
*/
// function that returns entire array
function getArray() returns (uint[] memory) {
return myArray;
}
}
Now you can use getArray() to retrieve the entire array, instead of myArray(i), which returns a single element per call.
2 - Moreover may be you need some particular elaboration before accessing: for instance to return int being the variable uint or so.
3 - Another important use case that I know very well is when many “copies” of the public variable exist in different contracts talking each other (multicontracts applications). In that a case you can ask your getter to sync and update the variable value before to return it.
4 - etc.
PERMISSIONS
A public variable generates a public getter, without any permission scheme possible: it is accessible by anyone.
On the contrary, you can reserve the getter written by you to classes of users, for instance inserted in some white list and/or being EOA and/or being not EOA and so on: it is up to you.
-> About comments about “pointless permissions”: yes you can still (ever) access a variable even if private, no doubts about it, but if you prevent the custom getter to do it by some require, you cannot do it easily if you cannot satisfy that require, in any case it is not just a matter of one call. And, in particular, it can be not accessible by other contracts! This does not mean that it is “secret”, it means that it remains “under the hood” for your users. You need a blockchain investigation and proper tools to access it. And for the majority of applications, this is definitively enough!
In short: It is a matter of use cases.
B
to know contractA
only by its interface, then the only way for contractB
to read a variable in contractA
, is by calling a getter function inA
, which returns this variable. The auto-generated getter of the variable is not going to help you because it is auto-generated in the contract only, not in the interface. And of course, you cannot declare it in the interface, because it is auto-generated in the contract aspublic
, and interface functions can only beexetrnal
.