Hot answers tagged

51

You need to use an array in storage because it is not possible to resize memory arrays. contract D { uint[] myArray; function Test() constant returns (uint[]) { myArray.push(123); return myArray; } } Otherwise you need to define the size of the array during initialization: contract C { function f(uint len) { uint[] ...


28

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-...


24

The best way is simply not to clear them. In many (most?) situations, the array varies in size over time, and emptied slots will eventually be filled again. Instead of shortening the array, keep a separate count of live elements: uint numElements = 0; uint[] array; function insert(uint value) { if(numElements == array.length) { array.length += ...


17

The following will work: contract Test { struct Object { uint a; string b; string[] c; mapping(uint => uint) d; } Object field; function Test() { field = Object({ a: 1, b: "abc", c: new string[](0) }); } }


17

There is no need to initialize storage arrays in Solidity. Only memory arrays has to be initialized before usage. So in your case, no need to initialize x inside Bar as long as you are not assigning a value to one of the x indexes inside your foobar. Actually, making initialization in your code will consume gas for no reason. The following code works well ...


13

Some issues: The compiler does not yet support copying memory struct arrays to storage, so things[id] = thing; will fail. Thing thing; will initialize thing to a Thing with thing.items set to an empty array, so there's no need to use the constructor at all. Since all elements of mappings come pre-initialized to their "zero" values, there's no need to ...


11

You're doing something wrong. This works perfectly fine. Try it in the browser compiler. contract Test { address[] public arr = [0x36eaf79c12e96a3dc6f53426c, 0xf235aa56dd96bda02acfb361e]; }


11

No, I don't believe so. As I understand it, Solidity doesn't have a built-in way yet to deserialize string arrays. It can cheat when the contract is passing an array it created itself to itself, which is why it works with private functions. But if you want to take string arrays from the outside, you're going to have to handle the serialization and ...


11

You can't assign a value to an array of size 0, you need to have enough space to write your value. It is true, you declared a variable size array but you still need to tell the VM to increase the array size before assign it. You can increase array size and assign values in different ways: All-in-one (increase and set, my preferred) using push method, like ...


11

Dynamic arrays are only available in storage, not in memory. In your case, the size of the result array is known upfront (n). So, you can just declare an array with length of n. Then you can fill it up using i, which goes from 0 to n - 1 pragma solidity ^0.4.21; contract Foo { function getRange(uint n) public pure returns(uint[]) { uint[] ...


11

Oh boy I'm stupid. address payable[] users works. Nevermind people. This question never happened...


10

There is no any limitation, this is just syntactic feature. It is quite unusual but has some rationale behind it. E.g. in C language int8 x[5] reads as "x is an array of 5 int8 elements". And this one int8 y[5][4] is "y is an array of 5 arrays of 4 int8 elements each". Note that order of terms x, int8, 5, 4 in declaration and in English explanation is not ...


10

Is it possible to return an array of strings ( string[] ) from a Solidity function? Not yet, as this requires two levels of dynamic arrays (string is a dynamic array itself). Doc However you can return an Array of Bytes32 ( fixed size of 32 byte) So you can try to do something like this ( you can copy paste on Remix to test it ) pragma solidity ^0.4.11; ...


10

There are no limits in specification, so arrays may grow up to 2^256-1 elements.


10

To initialize an empty array instead of uint8[12] memory traits = new uint8[12]; use uint8[12] memory traits;. Then you can alter the array in the // alter values in traits ... section. function splitN(uint256 n) constant returns (uint8[12]) { uint8[12] memory traits; // alter values in traits ... return traits; }


9

Try the following: function getUsersCount() public constant returns(uint) { return users.length; } function getUser(uint index) public constant returns(uint, string, address) { return (users[index].idNum, users[index].name, users[index].userAddress); } You should then be able use the statements: > var numberOfUsers = contract.usersCount(); ...


9

Thanks to Piper and Chris I found a working solution for Solidity <= 0.2.1. The reason why the first two log statements return different results is, because uintN is right-aligned and bytesN is left-aligned. Conversion between uintN and bytesN first shortens and then changes alignment. That's why it has to be converted back to bytes32 before converted to ...


9

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-1]; ...


8

There are many ways to attack this problem. One approach would be to design the contract as one shop and deploy instances of it for each new shop. Then the contract address becomes the unique ID for each shop. Here's an example: // Basic contract for a shop. A shop is identified by it contract address contract Shop { address owner; string name; ...


8

Yes solidity support arrays of addresses to be passed as method arguments. Here is an working example pragma solidity ^0.4.11; contract AddressStore { address[] public bought; // set the addresses in store function setStore(address[] _addresses) public { bought = _addresses; } } https://ethfiddle.com/gfNfIFcT2C


8

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>...


8

Solidity 0.6.0 and Greater (Updated 2020) As of Solidity 0.6.0, there is array slice functionality built into Solidity. The syntax is similar to existing languages in that the array takes the following parameters x[start:end]. Here, start and end are ints that represent the starting and ending index to be sliced. If start is greater than end or if end is ...


7

Solidity <= 0.2.1 You can retrieve the nth byte of any bytesXX type with the following code. bytes32 v = ...; byte b = byte(bytes32(uint(v) * 2 ** (8 * n))); Solidity > 0.2.1 Starting in the next release of solidity you will be able to access them using indices. bytes32 v = ...; byte b = v[n];


7

The other answer which didnt work brought me on track to find it out myself: contract testStruct { struct stru{ string[] s; } stru myStru; function add(string s) { myStru.s.push(s); } function getAt(uint256 i) constant returns (string s) { s = myStru.s[i]; } }


7

One possible approach is to use a single dynamic-size byte array as you suggest, another is to group the parameters together by their type, so if you have three arguments of type address you instead pass a single array of addresses, of which you expect the user to send three. That avoids the need to construct then parse out a byte array. But often this will ...


7

In order to initialize an array from memory you have to do it like this: uint8[] memory theArray = new uint8[](12) Where the 12 inside the parenthesis is the array length. You can also initialize the array as follows: function getTraits() constant returns (uint8[3]){ uint8[3] memory traits = [1,2,3]; return traits; }


7

This is going to take a few hops to explain. The code looks innocent enough, but there is a compiler warning about uninitialized storage pointers. The warning shouldn't be ignored. Written explicitly, it would be bytes storage first; Storage pointers can start to look like slight of hand. Consider this: MyStruct s = structsMap[key]; s.someVal = false;...


6

Declaring an array inside a function is allocating a Memory Array which is different than storage array. Source new is used to declare variable sized array so I would do function getValue(uint8 x, uint8 y) constant returns (uint8) { var length = 5; uint8[5][5] memory myArr; for (uint i = 0; i < length; i++) for (uint j = 0; j < ...


6

Here's a way to do backerList.length--; on an address[] memory backerList by using inline assembly: assembly { mstore(backerList, sub(mload(backerList), 1)) } Some important points to remember: Make sure this assembly code never runs when backerList.length == 0 (don't allow the array length to underflow) Don't try to use this to increase the size of an ...


6

Operation push has changed behavior since since solidity 0.6. It no longer returns the length but a reference to the added element. You can solve this by splitting the assignment in two operations: sketchs.push(_sketch); uint _id = sketchs.length - 1;


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