When I was writing my code I got warning at 10th line of my code. Can anyone tell me what's this warning means?
My Code
// SPDX-License-Identifier: UNLICENSED
pragma solidity >=0.5.0 < 0.9.0;
contract PracticeTest // It's a class
{
string name ;
uint256 age;
constructor() public
{
name = "Ali";
age = 21 ;
}
}
This is the Warning
Warning: Visibility for constructor is ignored. If you want the contract to be non-deployable, making it "abstract" is sufficient.
--> contracts/PracticeTest.sol:10:5:
|
10 | constructor() public
| ^ (Relevant source part starts here and spans across multiple lines).
Visibility (public / internal) is not needed for constructors anymore: To prevent a contract from being created, it can be marked abstract. This makes the visibility concept for constructors obsolete.
Source: https://docs.soliditylang.org/en/v0.8.13/070-breaking-changes.html#functions-and-events
So, if you're compiling your contract with Solidity version 0.7 or newer, the constructor visibility (in your case public) is ignored, and you can safely remove it.
constructor()
{
name = "Ali";
age = 21 ;
}
I am just adding to the answer of Petr Hejda. Prior to solidity compiler versions 0.7.0 we were required to provide the visibility of constructors as either public or internal. With public visibility the contract can be directly deployed by itself on the blockchain whereas if the contract is not intended to be created directly but rather inherited, then we declared the constructor with internal visibility.
However, for solidity compiler versions 0.7.0 or greater we do the same thing but differently. If we want the contract not to be deployed directly but inherited we declare the contract itself as abstract. If we want that the contract can be deployed directly and can also be inherited, we don't declare it as abstract contract and we don't specify any visibility in the constructor of that class.
Related
As IVotes is a interface and cannot be deployed.
IVotes public immutable token;
constructor(IVotes tokenAddress) {
token = tokenAddress;
}
....
Error: *** Deployment Failed ***
"IVotes" is an abstract contract or an interface and cannot be deployed.
Import abstractions into the '.sol' file that uses them instead of deploying them separately.
Contracts that inherit an abstraction must implement all its method signatures exactly.
A contract that only implements part of an inherited abstraction is also considered abstract.
I want to use IVotes address passing in GovernorVotes constructor.
I tried bunch of methods but none works
The Solidity snippet, that you shared, expects a contract on the tokenAddress to implement the IVotes interface.
But it needs to be a "full" contract with all function bodies - not just the function declarations.
In Solidity we have four types of access. Two of them are private and internal.
What is the difference if both of them can be used inside smart contract and both of them are not visible after deploying?
Access types:
public - can be used when contract was deployed, can be used in inherited contract
external can be used when contract was deployed , can NOT be used in inherited contract
internal - can NOT be used when contract was deployed , can be used in inherited contract
private - can NOT be used when contract was deployed, can NOT be used in inherited contract
internal properties can be accessed from child contracts (but not from external contracts).
private properties can't be accessed even from child contracts.
pragma solidity ^0.8;
contract Parent {
bool internal internalProperty;
bool private privateProperty;
}
contract Child is Parent {
function foo() external {
// ok
internalProperty = true;
// error, not visible
privateProperty = true;
}
}
You can find more info in the docs section Visibility and Getters.
public: anyone can access the function
private: only this smart contract can call this function
internal: only this smart contract and smart contracts that inherit from it can call this function
external: anyone can access this function unless this smart contract
Note that external uses less gas than public so if the function is not used by your contract, prefer external over public.
More explanations in this article
I was digging into this OZ smart contract:
https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/utils/Context.sol
As you may see, it has only two functions to deal with metatxs. I can't figure out why this contract is defined as abstract, as both functions are implemented. Thanks in advance to all of you!
The Context contract was made abstract in the pull request #2229. One of the contributors links to the issue #8162 for explanation:
it seems like what the keyword does is mark the contract as non-deployable (i.e. it needs to be inherited from). Because contracts missing function implementations are always non-deployable, they require abstract.
From my understanding, their reason was just to explicitly say "This contract has no use on its own, and should not be deployable (on its own)."
class Person
{
private BankAccount account;
Person(BankAccount account)
{
this.account = account;
}
public Person someMethod(Person person)
{
//Why accessing private field is possible?
BankAccount a = person.account;
}
}
Please forget about the design. I know that OOP specifies that private objects are private to the class. My question is, why was OOP designed such that private fields have class-level access and not object-level access?
I am also a bit curious with the answer.
The most satisfying answer that I find is from Artemix in another post here (I'm renaming the AClass with Person class):
Why have class-level access modifiers instead of object-level?
The private modifier enforces Encapsulation principle.
The idea is that 'outer world' should not make changes to Person internal processes because Person implementation may change over time (and you would have to change the whole outer world to fix the differences in implementation - which is nearly to impossible).
When instance of Person accesses internals of other Person instance - you can be sure that both instances always know the details of implementation of Person. If the logic of internal to Person processes is changed - all you have to do is change the code of Person.
EDIT:
Please vote Artemix' answer. I'm just copy-pasting it.
Good question. It seems that object level access modifier would enforce the Encapsulation principle even further.
But actually it's the other way around. Let's take an example. Suppose you want to deep copy an object in a constructor, if you cannot access the private members of that object. Then the only possible way is to add some public accessors to all of the private members. This will make your objects naked to all other parts of the system.
So encapsulation doesn't mean being closed to all of the rest of the world. It means being selective about whom you want to be open to.
See the Java Language Specification, Section 6.6.1. Determining Accessibility
It states
Otherwise, if the member or constructor is declared private, then
access is permitted if and only if it occurs within the body of the
top level class (§7.6) that encloses the declaration of the member or
constructor.
Click the link above for more details. So the answer is: Because James Gosling and the other authors of Java decided it to be that way.
This works because you are in the class Person - a class is allowed to poke inside it's own type of class. This really helps when you want to write a copy constructor, for example:
class A
{
private:
int x;
int y;
public:
A(int a, int b) x(a), y(b) {}
A(A a) { x = a.x; y = y.x; }
};
Or if we want to write operator+ and operator- for our big number class.
Just my 2 cents on the question of why the semantics of the private visibility in Java is class level rather than object level.
I would say that convenience seems to be the key here. In fact, a private visibility at object level would have forced to expose methods to other classes (e.g. in the same package) in the scenario illustrated by the OP.
In truth I was not able neither to concoct nor to find an example showing that the visibility at class-private level (like offered by Java) creates any issues if compared to visibility at object-private level.
That said, programming languages with a more fine-grained system of visibility policies can afford both object visibility at object level and class level.
For example Eiffel, offers selective export: you can export any class feature to any class of your choice, from {NONE} (object-private) to {ANY} (the equivalent of public, and also the default), to {PERSON} (class-private, see the OP's example), to specific groups of classes {PERSON, BANK}.
It's also interesting to remark that in Eiffel you don't need to make an attribute private and write a getter to prevent other classes from assigning to it. Public attributes in Eiffel are by default accessible in read-only mode, so you don't need a getter just to return their value.
Of course you still need a setter to set an attribute, but you can hide it by defining it as "assigner" for that attribute. This allows you, if you wish, to use the more convenient assignment operator instead of the setter invocation.
Because the private access modifier renders it visible only within the class. This method is still IN the class.
the private field is accessible in the class/object in which the field is declared. It is private to other classes/objects outside of the one it is located in.
First thing here we have to understand is all we have to do is must follow oops principles so encapsulation is say that wrap data within package(i.e. class) and than represent all data as Object and easy to access. so if we make field as non-private than
it's accessed indivisually. and it result into bad paratice.
With reflection concept in Java is possible modify fields and methods privates
Modificando metodos y campos privados con Refleccion en Java
Currently reading solidity documentation:
https://solidity.readthedocs.io/en/develop/types.html#function-types
By default, function types are internal, so the internal keyword can
be omitted. In contrast, contract functions themselves are public by
default, only when used as the name of a type, the default is
internal.
This does not make sense to me. How can a function be internal and public at the same time?
I know internal means functions can only be called within the contract and external can be called outside of the contract. So to me, internal is private and external is public but the documentation makes it sound like it can be public and internal at the same time?
So what is the difference, if any, between internal/external and public/private in regards to functions?
Here is the difference between the four keywords:
private means it's only callable from other functions inside the contract
internal is like private but can also be called by contracts that inherit from the current one
external can only be called outside the contract
public can be called anywhere, both internally and externally.
In the terminology of Solidity internal/external also uses as description 'two kinds of function calls' and not only as access modifiers.
Take a look at the documentation section about 'Visibility and Getters' inside the contracts.
Since Solidity knows two kinds of function calls (internal ones that do not create an actual EVM call (also called a “message call”) and external ones that do), there are four types of visibilities for functions and state variables.