I got an example of a solidity Interface.
1/ Any clue if this method is accurate as it's implementing the Interface within the inherited from Contract and not within the extension Contract.
2/ I tried implementing it, contractA functions run correctly, however contractB getCount function is not running correctly.
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
interface InterfaceA {
function count() external view returns (uint256);
function increment() external;
}
contract contractA {
uint256 number = 0;
function count() external view returns (uint256) {
return number;
}
function increment() external {
number++ ;
}
}
// SPDX-License-Identifier: MIT
import './contractA.sol' ;
pragma solidity ^0.8.0;
contract contractB {
address addressA;
function setPointer(address _addressA) external {
addressA = _addressA;
}
function getCount() external view returns (uint256) {
InterfaceA b = InterfaceA(addressA);
b.count();
}
function addToIncrement() external {
InterfaceA b = InterfaceA(addressA);
b.increment();
}
}
I think the only issue is you are not returning anything from getCount. You added the return signature, you should had a warning when you compiled it.
function getCount() external view returns (uint256) {
InterfaceA b = InterfaceA(addressA);
return b.count();
}
Related
Is it possible to use a modifier on a function that was overriden ?
I have a virtual function and overrided it in another class, but I get error when I call it due to using a modifier on it.
abstract contract A {
function stake(
address _userAddress,
uint256 _amount
) internal virtual {}
function investByToken(
address _userAddress,
IERC20Upgradeable _token,
uint256 _amount,
) external payable {
// ... calling some functions like deduct fee
stake(_userAddress, _liquidity);
}
}
contract B is A {
function stake(
address _userAddress,
uint256 _amount
) internal override updateRewards {}
}
Error: cannot estimate gas; transaction may fail or may require manual gas limit [ See: https://links.ethers.org/v5-errors-UNPREDICTABLE_GAS_LIMIT ] (reason="Transaction reverted:
function selector was not recognized and there's no fallback function", method="estimateGas"
I'm getting this error while testing with hardhat, but it's working fine on Mainnet.
Yes, you can add modifiers to the overriding function.
pragma solidity ^0.8;
abstract contract A {
function stake(address _userAddress, uint256 _amount) internal virtual {}
}
contract B is A {
modifier updateRewards {
_;
}
function callStake() external {
stake(address(0x123), 1);
}
function stake(address _userAddress, uint256 _amount) internal override updateRewards {}
}
The "function selector was not recognized" error message is thrown when you're trying to invoke an unreachable or non-existing function. Mind that in your example, the stake() function has internal visibility which makes it unreachable for external callers (such as your JS app or IDE). See the docs page for more info on function visibility.
Either change its visibility to external or public (in both contracts) or wrap it with another external / public function (see the code of this answer).
Here, I'm trying to get tempMap data from MainContract in Temp contract but I'm not able to get value form tempMap, as well as I'm using external visibility in MainContract but still didn’t get any response.
// SPDX-License-Identifier: MIT
pragma solidity >=0.4.22 <0.9.0;
contract MainContract {
mapping(uint => string) public tempMap;
function addData(uint number,string memory name ) public {
tempMap[number] = name;
}
function get(uint number) external view returns(string memory){
return tempMap[number];
}
}
contract Temp{
MainContract main = new MainContract();
function getData(uint number) public view returns(string memory){
return main.get(number);
}
}
You have to pass the address of the deployed contract, so it knows where to make the call.
Your temp contract will look something like this.
contract Temp{
MainContract main;
constructor(MainContract _main) {
main = _main;
}
function getData(uint number) public view returns(string memory){
return main.get(number);
}
}
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.4;
interface IBank {
function addTax(uint256 moneyToAdd) external payable;
}
contract Counter {
uint public count;
address bankAddress;
function setbankAddress(address _bankAddress) public payable {
bankAddress = _bankAddress;
}
function addMon(uint moneyToAdd) public payable {
require(moneyToAdd <= msg.value, "Ether value sent is not
correct");
}
function pay(uint _Amount) public payable {
IBank(bankAddress).addTax{value:_Amount}(_Amount);
}
}
when I deploy it I first add the contract address that I want to interact with, it's working with all functions that do not require value
I'm using Truffle and upgradable Openzeppelin contracts. I have two contracts.
Token.sol:
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.2;
import "#openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol";
import "#openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";
contract MyToken is Initializable, ERC20Upgradeable {
/// #custom:oz-upgrades-unsafe-allow constructor
constructor() initializer {}
function initialize() initializer public {
__ERC20_init("MyToken", "MTK");
_mint(msg.sender, 10000000 * 10 ** decimals());
}
}
AnotherContract.sol:
pragma solidity ^0.8.2;
import "./IAnotherContract.sol";
contract AnotherContract is IAnotherContract {
function doSomethingIfBalanceIsEnough()
external
returns (string memory)
{
// ...
}
}
How do I check how many MTK tokens a user has? I need to check it in doSomethingIfBalanceIsEnough function.
The token contract implements a balanceOf() function that returns token balance of an address.
You can make an external call from AnotherContract to MyToken address, invoking its balanceOf() function, passing it the user's address.
pragma solidity ^0.8.2;
import "./IAnotherContract.sol";
interface IERC20 {
function balanceOf(address) external view returns (uint256);
}
contract AnotherContract is IAnotherContract {
function doSomethingIfBalanceIsEnough()
external
returns (string memory)
{
uint256 userBalance = IERC20(myTokenAddress).balanceOf(msg.sender);
if (userBalance > 0) {
// ...
}
}
}
I'm using solidity version 0.5.2
pragma solidity ^0.5.2;
contract CampaignFactory{
address[] public deployedCampaigns;
function createCampaign(uint minimum) public{
address newCampaign = new Campaign(minimum,msg.sender); //Error
//here!!!
deployedCampaigns.push(newCampaign);
}
function getDeployedCampaigns() public view returns(address[] memory){
return deployedCampaigns;
}
}
I'm getting the error while assigning calling the Campaign contract inside CampaignFactory contract
TypeError: Type contract Campaign is not implicitly convertible to expected
type address.
address newCampaign = new Campaign(minimum,msg.sender);
I have another contract called Campaign which i want to access inside CampaignFactory.
contract Campaign{
//some variable declarations and some codes here......
and I have the constructor as below
constructor (uint minimum,address creator) public{
manager=creator;
minimumContribution=minimum;
}
You can just cast it:
address newCampaign = address(new Campaign(minimum,msg.sender));
Or better yet, stop using address and use the more specific type Campaign:
pragma solidity ^0.5.2;
contract CampaignFactory{
Campaign[] public deployedCampaigns;
function createCampaign(uint minimum) public {
Campaign newCampaign = new Campaign(minimum, msg.sender);
deployedCampaigns.push(newCampaign);
}
function getDeployedCampaigns() public view returns(Campaign[] memory) {
return deployedCampaigns;
}
}
To call an existing contract from another contract ,pass the contract address inside cast
pragma solidity ^0.5.1;
contract D {
uint x;
constructor (uint a) public {
x = a;
}
function getX() public view returns(uint a)
{
return x;
}
}
contract C {
//DAddress : is the exsiting contract instance address after deployment
function getValue(address DAddress) public view returns(uint a){
D d =D(DAddress);
a=d.getX();
}
}