Get error "Derived contract must override function _beforeTokenTransfer" - ethereum

I want to implement a burn feature in my ERC721 contract in Solidity. To do so, I have imported the function burn from ERC721Burnable.sol.
Since I have imported it I get the following error:
"Derived contract must override function _beforeTokenTransfer".
The same goes with supportsInterface function.
I did override both of them as you can see below. It works but I would like to understand why do I have to do that?
function _beforeTokenTransfer(
address from,
address to,
uint256 tokenId
) internal virtual override(ERC721, ERC721Enumerable) {
super._beforeTokenTransfer(from, to, tokenId);
}
function supportsInterface(bytes4 interfaceId)
public
view
virtual
override(ERC721, ERC721Enumerable)
returns (bool)
{
return super.supportsInterface(interfaceId);
}
I checked Openzeppelin repo, _beforeTokenTransfer is called inside _burn function. At first, I thought it was the main reason but the fact is that _beforeTokenTransfer is also called inside mint and I did not have that error before.
I have no idea why I have to override supportsInterface.
Thanks

ERC721Burnable inherits from two contracts:
abstract contract ERC721Burnable is Context, ERC721 {}
ERC721.sol contract has _beforeTokenTransfer and _afterTokenTransfer unimplemeted functions. you have to implement those in your contract.
from this github issue
ERC721Enumerable and ERC721Burnable both override the
_beforeTokenTransfer and supportsInterface functions. Solidity requires you to "fix" that overriding conflict. If we were able to
address that in our contract we would, but its a solidity requirement
that the child contract explicitly resolves this.
Looks like you 2 of contracts are conflicting inhering supportsInterface

Related

Solidity, Can Attacker bypass a internal functions?

I'm thinking about my smart contract and want to have a secure contract. But I really don't know that internal functions are safe or not.
This is a very BASIC contract that uses OpenZeppelin contracts:
contract MyContract is ERC20 {
constructor () ERC20("test", "test") {
_mint(msg.sender, 1000);
}
}
_mint is an internal function from Openzeppelin ERC20 contract.
Can someone deploy another contract and call the MyContract _mint() function?
If yes, How can we secure it?
The function _mint() from ERC20 is internal.
Internal functions can only be called within the contract or by the contracts inherited from the current one.
That means that no other contract can call MyContract._mint(), you can only call _mint() from inside MyContract.

Are Interfaces used for the sole purpose of generating ABI's in Solidity?

I have been following Solidity, Blockchain, and Smart Contract Course – Beginner to Expert Python Tutorial (https://www.youtube.com/watch?v=M576WGiDBdQ&t=28658s).
At a certain point in the tutorial (around hour 9), the following line of code exists:
weth=interface.IWeth(SomeAddress)
tx=weth.deposit({"from":account, "value": 0.01*10**18})
My understanding is that interfaces get compiled into ABI for use by some external entity.
the IWeth interface is as follows:
pragma solidity ^0.4.19;
/*this is the interface for the WETH contract */
interface IWeth {
function allowance(address owner, address spender)
external
view
returns (uint256 remaining);
function approve(address spender, uint256 value)
external
returns (bool success);
function balanceOf(address owner) external view returns (uint256 balance);
function decimals() external view returns (uint8 decimalPlaces);
function name() external view returns (string memory tokenName);
function symbol() external view returns (string memory tokenSymbol);
function totalSupply() external view returns (uint256 totalTokensIssued);
function transfer(address to, uint256 value)
external
returns (bool success);
function transferFrom(
address from,
address to,
uint256 value
) external returns (bool success);
function deposit() external;
function withdraw(uint256 wad) external;
}
The above interface is not implemented anywhere in the project but the project compiles and runs just fine. In my limited understanding of OOP, shouldn't an interface be implemented somewhere? if so, where is it implemented? If not, does the interface ( in this case IWeth) exist for the sole purpose of generating an ABI?
Also, I'm confused about how the interface is used as in weth=interface.IWeth(SomeAddress). In general, how can we write ...InterfaceName(someArg) when it is not even declared in the interface file?
Thanks in advance!
You can use an interface in your contract to call functions in another contract. Interfaces are most useful when you need to add functionality but instead of adding complexity to your application you use it from another contract. They reduce code duplication.
brownie is already loading interfaces. This is from docs
The InterfaceContainer object (available as interface) provides access
to the interfaces within your project’s interfaces/ folder.
interface.IWeth(SomeAddress) this tells Ethereum virtual machine to create a contract instance of given contract address with the functionalities of the interface. And then your app is calling deposit of that contract instance

Can't inherit contract from other one correctly

I have a ERC-721 smart contract defined like this
contract MintNFT is ERC721Enumerable, Ownable {
constructor(string _name, string _symbol) ERC721(_name, _symbol){}
}
in which I mint the NFTs and few more functions. Then I have created a new contract to purchase the NFTs and manage some stuff, but it forces me to mark it as abstract no matter what I write in the contract. I defined it like this:
contract ManagerNFT is MintNFT, IERC721 {
constructor(string memory _name, string memory _symbol) MintNFT(_name, _symbol){}
}
It throws an error saying linearization of inheritance graph impossible it goes away when I mark this ManagerNFT contract to abstract.
I don't know why this happens, I'm setting the constructors correctly I think, any thoughts on how to do this? Thanks.
As the IERC721 name suggests, it's an interface.
So the ManagerNFT needs to implement all functions of the interface.

Why is my smart contract constructor not called automatically when it is deployed?

When I deploy the below smart contract, the variable manager has the address 0x0000000000000000000000000000000000000000. It is only after I call the constructor (Lottery()) that the variable manager has an address that matches the account it is deployed by.
Why is my constructor not called automatically?
pragma solidity ^0.4.17;
contract Lottery {
address public manager;
function Lottery() public {
manager = msg.sender;
}
}
Your constructor should be called automatically.
I used Remix (https://remix.ethereum.org) with compiler version 0.4.17 and then deployed and manager was set to the deployment address as expected.
The issue you are experiencing would happen if the contract name and the constructor had different names, so the function was no longer a constructor.
Solidity 0.4.22 changed to use constructor instead of the contract name to avoid these type of bugs:
https://github.com/ethereum/solidity/releases/tag/v0.4.22
Constructors should now be defined using constructor(uint arg1, uint arg2) { ... } to make them stand out and avoid bugs when contracts are renamed but not their constructors.
I would suggest you look at using a later version of Solidity 0.5.x.

Fail to Deploy Simple Solidity Contract via Remix

Why does Remix fail to deploy the simple contract (simplified from the Mastering Ethereum book https://github.com/ethereumbook/ethereumbook/blob/develop/code/Solidity/Faucet2.sol )? --
pragma solidity ^0.4.19;
contract Faucet {
function withdraw(uint withdraw_amount) public {
require(withdraw_amount <= 100000000000000000);
msg.sender.transfer(withdraw_amount);
}
function () external payable {}
}
No matter how I raise gasLimit and/or gasPrice
Your code is fine (I have also tried it myself). From what I see above you are also sending a value along with the deploy. Since you have not defined a constructor yourself the default one is being called which is not payable. If you want to send ether when you deploy the contract you should also define a payable constructor.