Read contract variable with only interface definition - smartcontracts

I'm playing ethernaut Level 3, the original contract is here: https://ethernaut.openzeppelin.com/level/0x4dF32584890A0026e56f7535d0f2C6486753624f
When consecutiveWins is bigger or equal to 10, the player wins:
// SPDX-License-Identifier: MIT
pragma solidity ^0.6.0;
import '#openzeppelin/contracts/math/SafeMath.sol';
contract CoinFlip {
using SafeMath for uint256;
uint256 public consecutiveWins;
...
}
Now I want to read the consecutiveWins value in my contract, so I defined an interface:
interface CoinFlip {
uint256 public consecutiveWins;
function flip(bool _guess) external returns (bool);
}
But it is not allowed to have a variable in an interface, what should I do?

Solidity compiler will automatically generate getter functions for public variables, so what you need is replacing consecutiveWins variable in your interface with a getter function like this:
function consecutiveWins() public view returns (uint256);
You can read more about it in Solidity docs here.

Related

i am unable to use _totalSupply and _balances any private data type in OpenZeppelin and shows Undeclared identifier in solidity

Hey i am unable to implement _totalSupply and _balances in Remix but able to use remaining functions like name() and decimal() and symbol()
this is my code
pragma solidity ^0.8.0;
import "#openzeppelin/contracts/token/ERC20/ERC20.sol";
contract METoken is ERC20 {
constructor(uint256 initialSupply) ERC20 ("MAstering ther","MET")
{
_totalSupply=initialSupply;
_balances[msg.sender] = initialSupply;
emit Transfer(address(0), msg.sender, initialSupply);
}
}
i am using ERC20 and i have seen from ERC20.sol file from Github that there are _totalSupply and other variables to use the totalSupply() method but i am not able to use them plz help!
In the OpenZeppelin ERC20 implementation, that you're importing to your contract, properties _totalSupply and _balances have the private visibility.
From the Solidity docs page:
Private state variables are like internal ones but they are not visible in derived contracts.
So these specific properties (with private visibility) are not visible in your contract that derives from the contract that declares them.
Solution: The parent contract defines the _mint() function that effectively increases the balance of a selected address, the total supply, as well as emits the Transfer event.
constructor(uint256 initialSupply) ERC20 ("MAstering ther","MET")
{
// increases `msg.sender`'s balance, total supply, and emits the `Transfer` event
_mint(msg.sender, initialSupply);
}

Importing provable in remix ide

I am trying to learn solidity on the online ide. I am trying to use Provable within the ide and I have activated the plugin. I thought maybe that could just inherit 'usingProvable' off the bat to my contract but the ide could not find the identifier. I tried importing the plugin from github but still is not able to find it. If anything it creates a bigger problem because the ide does not find any of the openzepplin files when I try to import the package. How would I accomplish this on the online ide?
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.4;
import "#openzeppelin/contracts#4.5.0/token/ERC721/ERC721.sol";
import "#openzeppelin/contracts#4.5.0/token/ERC721/extensions/ERC721Enumerable.sol";
import "#openzeppelin/contracts#4.5.0/access/Ownable.sol";
import "#openzeppelin/contracts#4.5.0/utils/Counters.sol";
import "github.com/provable-things/ethereum-api/provableAPI.sol";
contract Neuron is ERC721, ERC721Enumerable, Ownable {
using Counters for Counters.Counter;
Counters.Counter private _tokenIdCounter;
constructor() ERC721("Neuron", "Neuron") {}
// function make_call() public {
// provable_query("URL","https://api.kraken.com/0/public/Ticker?pair=ETHXBT");
// }
function _baseURI() internal pure override returns (string memory) {
return "http://api.Neuron.com/tokens/";
}
function safeMint(address to) public onlyOwner {
uint256 tokenId = _tokenIdCounter.current();
_tokenIdCounter.increment();
_safeMint(to, tokenId);
}
// The following functions are overrides required by Solidity.
function _beforeTokenTransfer(address from, address to, uint256 tokenId)
internal
override(ERC721, ERC721Enumerable)
{
super._beforeTokenTransfer(from, to, tokenId);
}
function supportsInterface(bytes4 interfaceId)
public
view
override(ERC721, ERC721Enumerable)
returns (bool)
{
return super.supportsInterface(interfaceId);
}
}
this is a simple premade contract on remix and had not changed anything yet. I had commented out the function for testing a query call.
provable_api is a bit outdated. The file you import is a symlink to provableAPI_0.4.25.sol which allows compiler versions >= 0.4.22 < 0.5, while your imported OpenZeppelin contracts require ^0.8.0.
You can find a matching version
You can copy the provable_api contract locally in Remix IDE and use a relative path and try using a higher compiler version
PS. I think Remix IDE is having trouble with symbolic links. You can see the problem easier if you import the library like this:
import "github.com/provable-things/ethereum-api/provableAPI_0.5.sol";

Can't use array of contracts inside a function in solidity

Can someone please explain me why this works fine
import "./SimpleStorage.sol";
pragma solidity ^0.6.0;
contract storageFactoryContract {
SimpleStorage[] public asd;
function createSimpleStorageContract() public{
SimpleStorage simpleStorage = new SimpleStorage();
}
}
but this doesn't
import "./SimpleStorage.sol";
pragma solidity ^0.6.0;
contract storageFactoryContract {
function createSimpleStorageContract() public{
SimpleStorage[] public asd;
SimpleStorage simpleStorage = new SimpleStorage();
}
}
The error is:
freecodecamptutorial/FactoryContract.sol:14:26: ParserError: Expected ';' but got 'public'
SimpleStorage[] public asd;
^----^
In the second snippet, you're trying to set a visibility modifier for a regular variable. Only state variables (i.e. contract properties) and functions can have visibility modifiers.
Reference type variables (such as a contract) need to also have a data location. Since you're not working with the variable further, you can safely use the memory location. If you were to store it in storage, you might want to use the storage data location.
function createSimpleStorageContract() public {
// removed the `public` modifier
// added the `memory` data location
SimpleStorage[] memory asd;
SimpleStorage simpleStorage = new SimpleStorage();
}
This will generate two warnings about the unused variables asd and simpleStorage. It's simply because you're assigning the variables but never using them later. In this context, you can safely ignore them.
Note: I'm assuming that the SimpleStorage is a contract without a constructor or with a 0-argument constructor. Otherwise, you might get some different errors, for example wrong argument count.

What is the point of inheriting from ERC271 contract?

I have just started Solidity. For this question, I think it's useful if I first state my understanding of inheritance: If Contract B inherits from Contract A (ie. in contractB.sol we have
contract B is A {...
}
then Contract B will have access to functions from contract A.
Also, from my understanding, if I want to use some functions from another contract by someone else, I would have the following in my code:
contract someoneElsesInterface {
function someFunction() returns(something) }
contract myContract {
someoneElsesInterface someoneElsesContract = someonElsesInterface(address);
value = someoneElsesContract.someFunction();
}
My confusion arises when trying to implement the ERC721 standard. First, I must save the erc721.sol file in my directory; the file contains
contract ERC721 {
event Transfer(address indexed _from, address indexed _to, uint256 indexed _tokenId);
event Approval(address indexed _owner, address indexed _approved, uint256 indexed _tokenId);
function balanceOf(address _owner) external view returns (uint256);
function ownerOf(uint256 _tokenId) external view returns (address);
function transferFrom(address _from, address _to, uint256 _tokenId) external payable;
function approve(address _approved, uint256 _tokenId) external payable;
}
And then in a separate file, I must inherit from the ERC721 contract and then define the content of the four functions balanceOf, ownerOf, transferFrom, approve; as well as emitting the Transfer and Approve events. So the following:
contract myContract is ERC721 {
function balanceOf...
function ownerOf...
function transferrFrom...
...
}
This is what I don't understand: Why is ERC721 not inheriting from myContract, since we are defining functions in myContract and just stating the function name and returns in ERC721 like my example above? What even is the point of the ERC721 contract and having myContract inherit from ERC721, when we already defined all the function content in myContract? When working from on the front end, do I call the functions from myContract or from ERC721?
I hope my question is clear, if not I can clarify in comments. Thank you in advance for the replies.
First of all, you don't inherit an interface, but you implement it. In an interface contract, you don't define, you declare. You declare functionality, inputs, and outputs.
An interface can't inherit from a concrete (actual) contract. Only interfaces can inherit each other. If you think about it, concrete contracts contain more information than interfaces, how can an interface inherit from a concrete contract?
Generally speaking interfaces are contracts between user and program, and this is also true for Solidity. They guarantee a certain functionality to users. By implementing ERC721, you are declaring that your contract is ERC721 compatible. Because of this, the user does not need to know about your contract's implementation details, instead, they can call your contract using the ERC721 interface.
Consider following:
ContractA { ... }
vs
ContractB is ERC721 { ... }
Let's say both contracts are implementing ERC721 functionality.
To be able to call ContractA for ERC721 interaction, I have to import its ABI and verify that it is compatible. For example, I would call it like:
ContractA(ADDRESS_OF_CONTRACT_A).safeTransferFrom(...)
On the other hand to call ContractB, only thing I need is ERC721 ABI, I don't need to know about ContractB. So I can do:
ERC721(ADDRESS_OF_CONTRACT_B).safeTransferFrom(...)
Before I end, I would like to emphasize that your question is not actually about Solidity or smart contracts, but it is about object-oriented programming, inheritance, and interfaces. I recommend you to read about it more to have a better understanding of the concept.

Erorr after truffle compile in Erc721 openzeppelin contract

im doing step by step of this article and i had a problem on truffle compile part.
I've got this error in cmd:
Error parsing #openzeppelin/contracts/token/ERC721/ERC721.sol: ParsedContract.sol:51:72: ParserError: Expected '{' but got reserved keyword 'override'
function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) {
^------^
my contract :
pragma solidity ^0.6.0;
import "#openzeppelin/contracts/token/ERC721/ERC721.sol";
import "#openzeppelin/contracts/utils/Counters.sol";
contract Uniken is ERC721{
using Counters for Counters.Counter;
Counters.Counter private _tokenIds;
mapping(string => uint8) hashes;
constructor() public ERC721("Uniken", "Ukn") {
}
function awardItem(address recipient, string memory hash, string memory metadata)
public
returns (uint256)
{
require(hashes[hash] != 1);
hashes[hash] = 1;
_tokenIds.increment();
uint256 newItemId = _tokenIds.current();
_mint(recipient, newItemId);
_setTokenURI(newItemId, metadata);
return newItemId;
}
}
I'd be thankfull if anyone tell me whatis the problem?
It seems like it isn't seeing the ERC165 contract that ERC721 extends from. That function that it is getting stuck on should be overriding a function of the same name in ERC165, but the truffle compiler doesn't see a function named supportsInterface() in a class that ERC721 inherits from. So I would check to make sure everything imported in the ERC721 smart contract is in the right place in your folder structures, and that ERC721 is correctly inheriting ERC165.
After made some research , I was in truffle version 5.0 and update to the latest version of truffle -> v5.4.6, I am now able to compile