Hot answers tagged

39

Mappings do not store their keys, only the value which is stored at the state memory address calculated by a sha3 hash of the the key itself. Any lookup into a mapping has to provide that original key or be able to calculate it. This means that a contract has no way of discovering mapped data without assistance which can lead to orphaned data bloating the ...


29

You can't directly find out if any key exists in a mapping, ever, because they all exist. mapping(key => value) name; creates a namespace in which all possible keys exist, and values are initialized to 0/false. If you want to check that a value was explicitly set, and not merely the default (0), then you have to program something. In some cases, ...


26

You can store structs as the values of your mapping, not as the key. Here is some more info: http://solidity.readthedocs.org/en/latest/types.html#structs struct Funder { address addr; uint amount; } struct Campaign { address beneficiary; uint fundingGoal; uint numFunders; uint amount; mapping (uint => Funder) funders; } uint numCampaigns; ...


25

mapping is generally recommended. For this use case of a contract, which could have an unlimited number of documents, which could be updated, the recommendation holds. The main advantage of an array is for iteration. But the iteration needs to be limited, not only for speed, but potentially for security. As an extreme example, a permanent Denial-of-...


22

One way is to check for the length of a String: if (bytes(m1[msg.sender]).length != 0 && bytes(m2[msg.sender].someString).length != 0) // do your thing See the answer I posted here


22

Yes, delete user[someAddress]; will work with structs that do not contain a mapping. For this question, because name and nickname are not mappings, they will be deleted (set to zero) automatically: there is no need to do something like "delete user[someAddress].name". http://solidity.readthedocs.io/en/develop/types.html#delete if you delete a struct, it ...


21

Mappings can only use elementary types (address, uint, bytes, string) as keys, and more specifically any type for which sha3() is defined. This means structs and arrays currently can't be used as keys. mapping(uint => Foo[]) foo; should work, and does for me. Your code has some syntax errors, which might be the problem (struct shouldn't be capitalized, ...


20

The thing was that my mapping was public, and there are no public accessors implemented for it yet. The solution is just to not declare the mapping as public.


17

The cost of an addition to or a read from a mapping does not change with the number of keys mapped. The location of a value key is computed by sha3(key, p) where p is the storage slot that acts as the pointer of the mapping. As you can see the location of an individual value is random, and you may theoretically overwrite data from another key. The total ...


14

The address needs be surrounded with quotes. "0xca35b7d915458ef540ade6068dfe2f44e8fa733c" should work.


12

You can't iterate over the key of balanceOf as the data stored in the mapping to represent the key is the sha3 of the specified key. From Solidity In Depth - Mappings, The key data is not actually stored in a mapping, only its sha3 hash used to look up the value. You could instead use the following script to find all transaction made to the account. ...


11

You can't loop through the keys or count the keys in a mapping (but patterns exist for accomplishing such functionality using a few more variables). You're on the right path, tracking it yourself. For example: pragma solidity ^0.4.8; contract Vote { uint public totalVotes; mapping (address => uint) public voterCount; function vote(uint votes) ...


11

Unfortunately you can't delete a mapping. From the solidity docs at: http://solidity.readthedocs.io/en/develop/types.html delete has no effect on whole mappings (as the keys of mappings may be arbitrary and are generally unknown). So if you delete a struct, it will reset all members that are not mappings and also recurse into the members unless they ...


10

You could just store the index of the mapping in an array. uint[] indexes; mapping (uint => uint) example; function add(uint x){ example[indexes.length] = x; indexes.push(indexes.length); } Then just iterate over the array index as key. if you want custom unordered keys, it's the same. You would just need to pass the key in the add function ...


10

All problems in computer science can be solved by another level of indirection. pragma solidity ^0.4.20; contract DeletableMapping { // Input is keccak256(uint32 mappingVersion, string carVIN) mapping (bytes32 => string) carfaxReports; uint32 currentMappingVersion; function getCarfaxReport(string _carVIN) external view returns(string) { ...


9

I suppose customStruct is a struct with timestamp property. Then your code should work. However here my test scenario: import "dapple/test.sol"; contract MyTest is Test { struct Struct { uint timestamp; } // Mapping test mapping(uint => mapping(uint => uint)) mymap; mapping(address => mapping(uint => Struct[])) someName; ...


9

Rather than using the hash of the enum as the key, you could just explicitly cast the enum to uint. Because the actual uint size the compiler uses is just big enough to hold all enum values, it will be uint8 for TestEnum but you do not have to specify that. I mention that just to highlight that the key will be only 1 byte instead of 32 bytes. (Ref: http://...


9

Solidity doesn't provide a contains method, you'd have to manually iterate and check. Using an array for what you're trying to achieve would be a highly inefficient pattern. The best and most cost efficient method is use a mapping data structure. Set the key to be the address and the value to be a boolean. Lists that are too long have the possibility of ...


8

The second error you get tells you that external functions cannot have internal types as arguments (i.e. structs and mappings). You can solve that one by specifying internal or private for your function. For the first error, im not sure if it is a bug or not, but you cannot pass mappings as arguments. What you could do is wrap them in a struct and pass the ...


8

Source: https://github.com/su-squares/ethereum-contract/blob/master/contracts/SuNFT.sol Here you go: Algorithm: uint[] assets; mapping(uint=>uint) indexOfAsset; function removeAssetFromArray(uint _assetToDelete) { uint index = indexOfAsset[_assetToDelete]; if (!index) return; if (assets.length > 1) { assets[index] = assets[assets.length-...


7

Yes, you can. For example, in the solidity code below. There is a struct User that has a mapping of friends, from address to another struct Friend. Then there's a mapping of users, from address to User [note that User is a struct]. struct Friend { string name; string email; string phoneNumber; } struct User { string name; string email;...


7

You need to specify constant so that you get the return value of a call: function get_from_map(uint _key) constant returns (address). Without constant, test.get_from_map(1) is a sendTransaction which always returns a transaction hash. See What is the difference between a transaction and a call?


7

I would go with: if (reg[sender].first != "" || reg[sender].last != "") { throw; }


7

You need to break the interface down into smaller chunks. In practice, you'll want to extend the internal storage pattern a little, I think. Iterable mapping comes to mind. You keep lists of keys to mappings in arrays. Something like this: struct VoterStruct { address voterAddress; uint256 tokensBought; mapping (bytes32 => uint256) ...


7

You have to track an index of the elements you stored in the mapping. Some solution patterns here: Are there well-solved and simple storage patterns for Solidity? Hope it helps.


6

There is no way to have a default value for a state variable, especially for a mapping as there is no way for the EVM to know prior to assignment where it will be stored. The next best thing for setting up storage values is the constructor. So there is no way to assign default struct values in Solidity, however in analysing compiled traces of the following ...


6

simple: get all the blocks from each block get all the transactions filter all the transactions with a value > 0 record the list of all the to addresses filter out duplicates filter out addresses with balance 0 const Web3 = require('web3') const web3 = new Web3(new Web3.providers.HttpProvider('https://mainnet.infura.io/<InfuraToken>')) let ...


6

Array does cost more than mapping, but that's because it's not doing the same thing. An Array in Solidity is basically a struct with this structure struct Array{ mapping(uint => someType) items; uint length; } On top of this, Arrays have bounds checking around length such that attempts to access an item in the items mapping with a 0>index>...


6

If you use a struct, eg struct Participant { bool value1; uint value2; } mapping (address => Participant) participants; I don't think there's any way of using an actual Tuple eg var (a, b) in a mapping since the types of a and b cannot be declared with the syntax available. With a struct the types can be declared, which is necessary to declare ...


6

You can safely ignore this warning. The problem is your string variable in the parameters string memberName. Because a string has no fixed size, it is theoretically possible to require an infinite amount of gas to fill it with an infinite amount of characters. Your code will still compile and work if no other errors are being shown.


Only top voted, non community-wiki answers of a minimum length are eligible