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
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.
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.
I am learning solidity and got to know that interface and abstract are both classes that may contain unused functions.
My doubt is: What is the difference between interface and abstract contract in a solidity smart contract?
It's the same as in most other object-oriented programming languages:
Interface only declares functions. Cannot implement them.
Abstract class can declare functions (same as interface) as well as implement them.
Both cannot be instantiated and need to be implemented/inherited from.
Example:
interface IMyContract {
// can declare, cannot implement
function foo() external returns (bool);
}
abstract contract MyContract {
// can declare
function foo() virtual external returns (bool);
// can implement
function hello() external pure returns (uint8) {
return 1;
}
}
Extensibility is key when building larger, more complex distributed applications. Solidity offers two ways to facilitate this:
Abstract Contract
Contracts are identified as abstract contracts if at least one of their functions lacks an implementation. This is the only requirement for abstract class. As a result, they cannot be compiled. They can however be used as base contracts from which other contracts can inherit from.
Unlike other languages, Solidity contracts do not need an abstract keyword to be marked as abstract. Rather, any contract that has at least one unimplemented function is treated as abstract in Solidity. An abstract contract can be neither compiled nor deployed unless it has an implementing contract
contract MyAbstractContract {
function myAbstractFunction() public pure returns (string);
}
if a contract inherits an abstract contract and does not implement all the unimplemented functions, then that contract will be considered abstract as well
//MyContract is also abstract
contract MyContract is MyAbstractContract {
function myAbstractFunction() public pure returns (string)
}
But this is not abstract because we are implementing the function.
contract MyContract is MyAbstractContract {
function myAbstractFunction() public pure returns (string)
{ return "string value to return"; }
}
An abstract contract can have both implemented and unimplemented functions.
Interfaces
interfaces can have only unimplemented functions. Also, they are neither compiled nor deployed. They are also called pure abstract contracts.
Interfaces cannot implement any of their functions. All interface functions are implicitly virtual
Interfaces are defined with the keyword Interface.
Interfaces cannot inherit other contracts or interfaces (after solidity 6.0.0 interfaces can inherit from interfaces) but other contracts can inherit from interfaces.
Interfaces cannot define a constructor
Functions of an interface can be only of type external.
Interfaces cannot have state variables
As of now Interfaces cannot define structs and enums but might change soon.
I have a security problem in my Solidity contracts and I can't figure out how to fix it.
The flow goes like this:
First, we create an instance of contract A;
Create an instance of contract B, which receives the contract A instance in the constructor (its address);
At some point, contract B calls a function 'foo' from contract A which tells contract A to send money to an address (the address is received as a parameter);
Contract A sees the msg.sender as the address of contract B;
My problem is:
I want to restrict the access for the function 'foo' in contract B only to be called by contract A (no calls made by humans manually);
I cannot make a modifier to check the address. Since I create Contract A before Contract B, I cannot know the address of Contract B in Contract A;
I cannot make the function internal as the contracts are not derived;
Can you please offer me advice on how to fix this problem or explain another approach on this? I am new to Solidity.
Thank you!
I cannot make a modifier to check the address.
You can, but the address needs to be in a variable, set after the contract B has been deployed.
pragma solidity ^0.8;
contract ContractA {
address contractB;
modifier onlyContractB {
require(msg.sender == contractB);
_;
}
function foo() external onlyContractB {
}
function setContractBAddress(address _contractB) external {
contractB = _contractB;
}
}
pragma solidity ^0.8;
interface IContractA {
function foo() external;
}
contract ContractB {
IContractA contractA;
constructor(address _contractA) {
contractA = IContractA(_contractA);
}
function callFoo() external {
contractA.foo();
}
}
Deploy contract A
Deploy contract B, passing it the "A" address in the constructor
Set the contractB value in "Contract A".
I left out any auth mechanism while setting the contractB address in ContractA for simplicity. In this example, anyone can set the address, which you probably don't want, and you should add a mechanism allowing only authorized senders to set the contractB value in ContractA.
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.