I am using Solc version 0.7.0 installed by npm. When I try to create a Struct that contains mapping, I received an error: "Struct containing a (nested) mapping cannot be constructed."
Please check the code:
// SPDX-License-Identifier: MIT
pragma solidity 0.7.0;
contract Test {
struct Request {
uint256 value;
mapping(address => bool) approvals;
}
Request[] public requests;
...
function createRequest(
uint256 value
) public {
Request memory newRequest = Request({// here the compiler complains
value: value
});
requests.push(newRequest);
}
}
When I use older versions of solc, the code compiles without problems.
Thank you in advance!
This should work:
function createRequest(uint256 value) public {
Request storage newRequest = requests.push();
newRequest.value = value;
}
Cheers!
This worked in my case:
struct Request{
uint256 value;
mapping(address => bool) approvals;
}
uint256 numRequests;
mapping (uint256 => Request) requests;
function createRequest (uint256 value) public{
Request storage r = requests[numRequests++];
r.value= value;
}
Related
I am triying to deploy mi ERC721 contract in my private Blockchian. This is the Smart Contract:
// SPDX-License-Identifier: MIT
pragma solidity >=0.4.22 <0.9.0;
import "#openzeppelin/contracts/token/ERC721/ERC721.sol";
import "#openzeppelin/contracts/token/ERC721/extensions/ERC721Enumerable.sol";
import "#openzeppelin/contracts/token/ERC721/extensions/ERC721URIStorage.sol";
import "#openzeppelin/contracts/token/ERC721/extensions/ERC721Burnable.sol";
import "#openzeppelin/contracts/access/Ownable.sol";
import "#openzeppelin/contracts/utils/Counters.sol";
contract MyToken is ERC721, ERC721Enumerable, ERC721URIStorage, ERC721Burnable, Ownable {
using Counters for Counters.Counter;
Counters.Counter private _tokenIdCounter;
constructor() ERC721("MyToken", "MTK") {}
function safeMint(address to, string memory uri) public onlyOwner {
uint256 tokenId = _tokenIdCounter.current();
_tokenIdCounter.increment();
_safeMint(to, tokenId);
_setTokenURI(tokenId, uri);
}
// 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 _burn(uint256 tokenId) internal override(ERC721, ERC721URIStorage) {
super._burn(tokenId);
}
function tokenURI(uint256 tokenId)
public
view
override(ERC721, ERC721URIStorage)
returns (string memory)
{
return super.tokenURI(tokenId);
}
function supportsInterface(bytes4 interfaceId)
public
view
override(ERC721, ERC721Enumerable)
returns (bool)
{
return super.supportsInterface(interfaceId);
}
}
However, when running
truffle migrate --reset
I am getting the following error:
Error parsing #openzeppelin/contracts/token/ERC721/ERC721.sol: ParsedContract.sol:54:28: ParserError: Expected primary expression.
interfaceId == type(IERC721).interfaceId ||
^--^
Compilation failed. See above.
This is not the first time in running this migration. However, it is the first time it is not succesful. Does anyone know why I am getting this error? Thanks
I have two questions.
1) I am getting the following error:
TypeError: Contract "MyToken" should be marked as abstract.
--> contracts/MyToken.sol:8:1:
According to my understanding, contract should be abstract when there is a unimplemented function. Here I have the function foo. But still getting this error?
2) Also I want write a constructor which passes totalSupply_ to the contract. Is it possible to implement in the way I have done?
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.0;
//import '#openzeppelin/contracts/token/ERC20/IERC20.sol';
import '#openzeppelin/contracts/token/ERC20/ERC20.sol';
contract MyToken is ERC20 {
uint256 private _totalSupply;
string private _name;
string private _symbol;
constructor(string memory name_,string memory symbol_, uint totalSupply_ ) {
_name = name_;
_symbol = symbol_;
_totalSupply = totalSupply_;
}
function foo() external returns (uint) {
uint temp;
temp = 1+1;
return temp;
}
}
You are inheriting from ERC20 but you are not calling its constructor
constructor(string memory name_,string memory symbol_,uint totalSupply_)ERC20("name","SYM") {
_name = name_;
_symbol = symbol_;
_totalSupply = totalSupply_;
}
In your case you have to call ERC20("name","SYM") because ERC20 is inheriting from an abstract Context class.
contract ERC20 is Context, IERC20, IERC20Metadata {
if you did not inherit from Context you would not have to call ERC20("name","SYM")
contract ERC20 is IERC20, IERC20Metadata {
Since you are calling ERC20("name","SYM") you are actually setting name and symbol so you dont have to set them in MyToken constructor:
uint256 private _totalSupply;
constructor(uint totalSupply_ )ERC20("name","SYM") {
_totalSupply = totalSupply_;
}
Try this:
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.0;
//import '#openzeppelin/contracts/token/ERC20/IERC20.sol';
import '#openzeppelin/contracts/token/ERC20/ERC20.sol';
contract MyToken is ERC20 {
uint256 private _totalSupply;
constructor(string memory name_,string memory symbol_, uint totalSupply_ ) ERC20(name_, symbol_) {
_totalSupply = totalSupply_;
}
function foo() external returns (uint) {
uint temp;
temp = 1+1;
return temp;
}
}
I have a struct like so :
struct test {
string a;
string b;
}
and a mapping like this:
mapping (address => test) public tests;
I want to have a function to update the struct like this:
function updateStruct (string _paramName, string _newValue) {
tests[msg.sender].(_paramName) = _newValue; // this is the line that shows the logic but doesn't work in compilation
}
How can I do this?
Solidity currently (v0.8) does not support accessing properties via magic variables.
You'll need to access the properties directly.
function updateStructA(string memory _newValue) public {
tests[msg.sender].a = _newValue;
}
function updateStructB(string memory _newValue) public {
tests[msg.sender].b = _newValue;
}
When i get compile i get this error =ParserError: Expected '(' but got identifier
I am facing such an error, I tried many things but I could not do it. I want to make a small wallet and I want to run a withdraw function. I am waiting for your help.
strong text
// SPDX-License-Identifier: UNLICENSED
pragma solidity >= 0.7.0 <0.9.0;
contract Challenge0 {
address public owner;
uint256 userBalance;
uint256 withdrawAmount;
bool public canWithdraw= false;
constructor (address payable _withdrawAmount){
function withdrawAmount(uint256 amount) onlyOwner payable public {
require(msg.value == amount);
require(amount <= getBalance());
msg.sender.transfer(amount);
}
}
function setUserBalance()external view {
}
function getUserBalance()public returns (uint256){
return address(this).balance;
}
}
There are some errors in your smart contract:
In smart contract's constructor() you cannot declare a function. In your case you're declaring withdrawAmount() function into it. For resolve this, you must to move this function outside constructor;
You're using the same name for a withdrawAmount() function and uint256 variabile called withdrawAmount. The compiler give you error because you cannot use the same name for declaring a variabile and a function, thus you must to change one of these name with a different name;
withdrawAmount() has onlyOwner() modifier that you didn't declare into your smart contract. To solve this problem you must to declare it. More information about modifiers here;
You didn't declare and implement the getBalance() function in your contract;
When use transfer() function you must use it with payable address. In your case you must to cast the msg.sender address using payable() in this way:
payable(msg.sender).transfer(amount);
I tried to correct your smart contract, you can continue with this model:
// SPDX-License-Identifier: MIT
pragma solidity >= 0.7.0 <0.9.0;
contract Challenge0 {
address public owner;
uint256 userBalance;
uint256 withdrawAmountVariable;
bool public canWithdraw = false;
constructor() {
owner = msg.sender;
}
modifier onlyOwner() {
require(owner == msg.sender, "You aren't the smart contact's owner");
_;
}
function getBalance() public returns(uint) {
// TODO: implement your logic
}
function withdrawAmount(uint256 amount) onlyOwner payable public {
require(msg.value == amount);
require(amount <= getBalance());
payable(msg.sender).transfer(amount);
}
function setUserBalance()external view {
// TODO: implement your logic
}
function getUserBalance()public view returns (uint256){
return address(this).balance;
}
}
I am trying to return values from a struct, different approaches weren`successful
struct Briefing {
string description;
uint max_influencer;
uint jobvalue;
bool achievement;
}
function getSummary() public view returns (Briefing) {
return Briefing (
string,
uint,
uint,
bool
);
When you're working with reference types (such as struct), you always need to specify the data location. In this case, it's memory, because you need to load the values to memory first, and then return them from the memory.
Your question doesn't specify if you need to return a new instance of the struct or load it from storage, so here's example of both:
pragma solidity ^0.8;
contract MyContract {
struct Briefing {
string description;
uint max_influencer;
uint jobvalue;
bool achievement;
}
Briefing summary;
function getSummaryHardcoded() public view returns (Briefing memory) {
return Briefing("desc", 1, 1, true);
}
function getSummaryStored() public view returns (Briefing memory) {
return summary;
}
}