I want to test the following code in Remix. But what is the procedure?
What do I put in the input field for the function labeled set?
Mapping.sol
// https://solidity-by-example.org/mapping
// Mapping
// Maps are created with the syntax mapping(keyType => valueType).
// The keyType can be any built-in value type, bytes, string, or any contract.
// valueType can be any type including another mapping or an array.
// Mappings are not iterable.
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.13;
contract Mapping {
// Mapping from address to uint
mapping(address => uint) public myMap;
function get(address _addr) public view returns (uint) {
// Mapping always returns a value.
// If the value was never set, it will return the default value.
return myMap[_addr];
}
function set(address _addr, uint _i) public {
// Update the value at this address
myMap[_addr] = _i;
}
function remove(address _addr) public {
// Reset the value to the default value.
delete myMap[_addr];
}
}
contract NestedMapping {
// Nested mapping (mapping from address to another mapping)
mapping(address => mapping(uint => bool)) public nested;
function get(address _addr1, uint _i) public view returns (bool) {
// You can get values from a nested mapping
// even when it is not initialized
return nested[_addr1][_i];
}
function set(
address _addr1,
uint _i,
bool _boo
) public {
nested[_addr1][_i] = _boo;
}
function remove(address _addr1, uint _i) public {
delete nested[_addr1][_i];
}
}
This code came from Solidity by Example.
When I implement it on Remix, I get the following screen.
At this point, to test it, I think I need to map an address to a uint256, so I enter the following in the field next to the set button:
["0xcf646ed6e21fd0756ec45a6be5e1057fc24a1b8308175ff0b9f97f565b594eb3", 7439]
The value of the address was a randomly generated hash (I suspect the random hash might be a problem?)
I expect to see the set function render the value 7439. But, instead, it throws the following error:
transact to Mapping.set errored: Error encoding arguments: Error: invalid address (argument="address", value=["0xcf646ed6e21fd0756ec45a6be5e1057fc24a1b8308175ff0b9f97f565b594eb3",7439], code=INVALID_ARGUMENT, version=address/5.5.0) (argument=null, value=["0xcf646ed6e21fd0756ec45a6be5e1057fc24a1b8308175ff0b9f97f565b594eb3",7439], code=INVALID_ARGUMENT, version=abi/5.5.0)
What am I doing wrong?
You have generated a random SHA-256 that is of the format of a valid address, but it doesn't exist on the Remix's browser-based (Javascript VM) chain as any account. If it does, you might be just lucky.
If you want to use valid addresses that do exist on the browser-based VM chain, copy and use the addresses in the account section.
Related
I'm new to Solidity but I can't find much information about my problem.
For example, I want to make different contracts for different functionalities (I see them as classes)
For example
Main contract
// SPDX-License-Identifier: None
pragma solidity >=0.8.6;
import "./AuthContract.sol";
contract Contract {
string public message;
constructor() {
message = "test";
}
function getMessage() public view returns(string memory) {
return message;
}
}
and second contract
contract Auth {
struct UserDetail {
address addr;
string name;
string password;
string CNIC;
bool isUserLoggedIn;
}
mapping(address => UserDetail) user;
// user registration function
function register(
address _address,
string memory _name,
string memory _password,
string memory _cnic
) public returns (bool) {
require(user[_address].addr != msg.sender);
user[_address].addr = _address;
user[_address].name = _name;
user[_address].password = _password;
user[_address].CNIC = _cnic;
user[_address].isUserLoggedIn = false;
return true;
}
// user login function
function login(address _address, string memory _password)
public
returns (bool)
{
if (
keccak256(abi.encodePacked(user[_address].password)) ==
keccak256(abi.encodePacked(_password))
) {
user[_address].isUserLoggedIn = true;
return user[_address].isUserLoggedIn;
} else {
return false;
}
}
// check the user logged In or not
function checkIsUserLogged(address _address) public view returns (bool) {
return (user[_address].isUserLoggedIn);
}
// logout the user
function logout(address _address) public {
user[_address].isUserLoggedIn = false;
}
}
How could I use the functionalities from that contract in the main contract?
Is such a thing possible in the blockchain?
I am quite new here also but i can solve your problem, if not solve i can lead you to a good path .
so firstly you said you want to create multiple contract for different functionalities, this is good but keep in my you are going to exhaust a lot of gas.
so the answer to your problem is easy you can just read it and implement it.
if you want to use a contract in the Another contract (main in your case) you can do it in two ways(according to my knowledge there might be other).
using new keyword
using address of your previously deployed contract
we will be using the First case as i suppose you havenot deployed the second contract yet
In Order to do it you can use
Auth myObj=new Auth();
This will create a new instance of the contract Auth in your main contract and now you can use the Auth contract's function in your Main contract.you can create a function copy the above line and you can use the Functions using dot operator.
myObj.register(_address,_name,moreandmore);
I believe this will solve your problem if not you can ask it.
Thank You!
help, I'm getting errors on my code saying: TypeError: Type address is not implicitly convertible to expected type uint256. And I am in desperate need of help. I don't know what to do and if you need the full code pls say so
I think it has something to do with the address though I am not quite sure since I am still a beginner, so I am absolutely clueless so far. If you do know how to help me solve please say so.
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import './ERC721.sol';
contract ERC721Enumerable is ERC721 {
uint256[] private _allTokens;
// CHALLENGE! Write out mapping yourself!!
// mapping from tokenId to position in _allTokens array
mapping(uint256 => uint256) private _allTokensIndex;
// mapping of owner to list of all owner token ids
mapping(uint256 => uint256[]) private _ownedTokens;
// mapping from token ID index of the owner tokens list
mapping(uint256 => uint256) private _ownedTokensIndex;
// #notice count NFTs tracked by this contract
// #return A count of valid NFTs tracked by this contract, where each on of
// them has an assigned and queryable ower not equal to the zero address
// #notice Enumerate valid NFT's
// #dev Throws if '_index" >= 'totalSupply()'.
// #param _index A couter less than 'totalSupply()'
// #return The token identifier for the '_index'th NFt,
// (sort order not specified)
//function tokenByIndex(uint256 _index) external view returns (uint256);
// #notice Enumerate NFTs assigned to an owner
// #dev Throws if '_index' >= 'balanceOf(_owner)' or if
// '_owner' is the zero address, representing invalid NFTs.
// #param _owner An address where we are interested in NFTs owned by them
// #param _index A counter less than 'balanceOf(_owner)'
// #return The token identifier for the '_index'th NFT assigned to '_owner',
// (sort order not specfied)
//function tokenOfOwnerByIndex(address _owner, uint256 _index) external view returns (uint256);
function _mint(address to, uint256 tokenId) internal override(ERC721) {
super._mint(to, tokenId);
// 2 things!
// a. add tokens too the owner
// b. all tokens to out totalSupply - allToken
_addTokensToAllTokenEnumeration(tokenId);
_addTokensToOwnerEnumeration(to, tokenId);
}
// add tokens to the _allTokens array and set the position of the tokens indexes
function _addTokensToAllTokenEnumeration(uint256 tokenId) private {
_allTokensIndex[tokenId] = _allTokens.length;
_allTokens.push(tokenId);
}
// two function - one that returns token by the index
// another one thata retruns tokenByOwnerIndex
function tokenByIndex(uint256 index) public view returns(uint256) {
// make sure that the undex is not our of bounds of the
// total supply
require(index < totalSupply(), 'global index is out of bounds');
return _allTokens[index];
}
// return the total supply of the _allTokens array
function totalSupply() public view returns(uint256) {
return _allTokens.length;
}
function _addTokensToOwnerEnumeration(address to, uint256 tokenId) public {
_ownedTokensIndex[tokenId] = _ownedTokens[to].length;
_ownedTokens[to].push(tokenId);
}
}
In your code, your mapping is wrong. In your function _addTokensToOwnerEnumeration() you have taken address as mapping key. but in your declaration you have taken
//this is wrong as per you have used in your function
mapping(uint256=> uint256[]) private _ownedTokens;
// You have to declare like this.
mapping(address=>uint256[]) private _ownedTokens;
_ownedTokens have uint256 as key type it should be address type:
// mapping of owner to list of all owner token ids
mapping(address => uint256[]) private _ownedTokens;
solidity newbie here. when I try to read the value of the people array. I'm getting an error:
call to SimpleStorage.people errored: Error encoding arguments: Error:
invalid BigNumber string (argument="value" value=""
code=INVALID_ARGUMENT version=bignumber/5.4.2)
my compiler version is 0.6.6. not sure what's wrong? any suggestions?
// SPD-License_Identifier: MIT
pragma solidity ^0.6.0;
contract SimpleStorage {
uint256 favNum;
struct People {
uint256 favNum;
string name;
}
People[] public people;
function store(uint256 _favNum) public {
favNum = _favNum;
}
function retrieve() public view returns(uint256) {
return favNum;
}
function addPerson(string memory _name, uint256 _favNum) public {
people.push(People(_favNum, _name));
}
}
The error happens when you're trying to call the people() function (from Remix IDE) without passing any value.
Since the People[] public people is a public property, it autogenerates a getter function during compilation. But because it's an array, the getter function requires an uint256 param specifying the index of the array that you want to retrieve.
When you pass an empty string, Remix tries to encode it to the BigNumber instance, but this fails. Only when you pass an (existing) index of the array, it works correctly:
If you want to get the whole array in one call, you need to create a separate getter function:
function getAllPeople() public view returns (People[] memory) {
return people;
}
You must click on the small arrow to the right of the deploy button, then the fields will be displayed so that you can complete the data that the contract must receive.
Does anyone know how can I read meanings of variables in the array from another contract ? For example:
pragma solidity 0.8.7;
contract Contract1{
uint[] newData ;
constructor(uint _i){
newData.push(_i);
}
}
interface IContract1 {
function newData() external returns(uint[] memory);
}
contract Contract2 {
uint public newOne;
function foo(address _addr, uint _i) external{
newOne = IContract1(_addr).newData()[_i];
}
}
This code has compiled success in the Remix, but I have an error when I trying call foo()
Contract1.newData is an internal (default visibility when you don't specify it) property.
But the interface IContract1 defines an external function named newData() (without the index argument).
You can modify the newData property to have a public visibility, for which the compiler autogenerates a getter function (with the index argument).
Then you also need to update the function definition in the interface, so that it contains the index argument and returns just one item (and not the whole array).
pragma solidity ^0.8;
contract Contract1 {
// changed visibility to `public`
uint[] public newData;
constructor(uint _i){
newData.push(_i);
}
}
interface IContract1 {
// added `_index` argument
// changed the return value to one item of the array
function newData(uint256 _index) external returns(uint);
}
contract Contract2 {
uint public newOne;
function foo(address _addr, uint _i) external{
// changed the call to the getter function
// instead of trying to access the property directly
newOne = IContract1(_addr).newData(_i);
}
}
Note that the Contract1 constructor pushes the first item to the array, so you need to pass 0 (as for the first index) to the foo() function argument uint _i.
Repro steps:
Deploy Contract1 passing it 123 as constructor param. Deployed to address 0x456.
Deploy Contract2
Execute Contract2 function foo(0x456, 0), which will effectively set Contract2.newOne value to 123.
I am hitting hard to creating a lottery smart contract in solidity. I have tried a couple of ways, first I stored all the players address inside an array, but unfortunately that logic fail, just because of slow execution of array (when entries are more 1000+).
Now I am trying mapping mapping(address => Struct) entries;. Now what I have done here. I created a structure with user first ticket number and user last ticket number i.e uint userFstTcktNumber;
uint userLstTcktNumber;
Here is my structure
struct UserInfo {
uint userFstTcktNumber;
uint userLstTcktNumber;
} UserInfo userinfo;
Then I created a mapping
mapping(address => UserInfo ) public entry;
Then I have Created a function to enter the values inside the mapping and structure.
function letsdo(uint first, uint last) public{
entry[msg.sender];
userinfo.userLstTcktNumber = first;
userinfo.userLstTcktNumber = last;
}
Now what I want to do? I just want to get the values from the mapping and structure corresponding to the address, let's say I have 10 entries from 1 to 10 from address "0x617F2E2fD72FD9D5503197092aC168c91465E7f2" . And I have another 50 entries from 11 to 51 from another address "0x14723A09ACff6D2A60DcdF7aA4AFf308FDDC160C".
To return this I am using the function
function get(address) public view returns(uint, uint){
return (userinfo.userFstTcktNumber, userinfo.userLstTcktNumber);
}
But it's not returning me the expected result.
It's always returning the userFstTcktNumber is 0, no matter what address I have passed inside the get().
What's wrong with this code?
You are not really using your map, you need to set the values to be able to search inside it.
function letsdo(uint first, uint last) public {
entry[msg.sender] = UserInfo(first, last);
}
You don't need a get function as well, since entry is already public, you can search directly using entry[<address>]
UserInfo userinfo after your struct is also unnecessary, since you want to work with map, you will need more than just an instance, the letsdo function I mentioned above is already doing it
Hey thanks everyone for helping me out, Actually Last night I sorted it out my own. And here is the full logic for the problem.
pragma solidity ^0.4.18;
contract lottery{
uint public lastTicketNumber = 0;
uint youEntredWithAmount;
address [] public players;
uint public entryFee = 0.01 ether;
struct UserInfo {
uint userFstTcktNumber;
uint userLstTcktNumber;
}
mapping(address => UserInfo ) public entry;
function letsdo(uint first, uint last) public{
players.push(msg.sender);
entry[msg.sender].userFstTcktNumber = first;
entry[msg.sender].userLstTcktNumber = last;
}
function currentLevel(address userAddress) public constant returns (uint, uint) {
return (entry[userAddress].userFstTcktNumber, entry[userAddress].userLstTcktNumber);
}
function numberOfParticipents() public view returns(address [] memory){
return players;
}
}