I have coded a smart contract which allows one to store a certain type of structure of datas which can be described as something like that :

├── Client1(Contract)
│   ├── Year2018 (Struct containing string,uint and struct)
│   │   ├── Case 1 (Struct containing string)
│   │   └── Case 2 (Struct containing string)
│   └── Year2017
│       └── Case 1 (Struct containing string)
├── Client 2
│   └── Year2018
│          ├──Case1 (Struct containing string)
│          └──Case2 (You got it)

I managed to fill it correctly and parse it too ( But only one case INDIVIDUALLY). I would like to be able to have a function which returns all the datas in a organized way (such as a multi-dimensionnal array or a JSON for example). What should I use ? Is it possible to store all these value in a bytes array ?

Thanks for your ideas and have a good day !


Should i try something like this ?

function massImport(bytes[] _datas)  view external onlyOwner(){
        for(uint i = 0;i<_datas.length;i++){
            for(uint j = 0; j<_datas[i].length;j++){

I typed the function bytes() because I assume that bytes are the only possible array in this case?

EDIT 2 : Here is the struct 'YEAR'

struct Year{ 
    string entryName; 
    string entryYear; 
    uint permissionType; 
    Elem elem; 
    uint[] elemList; 
    mapping(uint => Elem) allElem; 
    uint elemId; 

Do you think that it's too heavy to be stored fully on the blockchain ?

  • Setting aside what the user/server/application/client needs, what need of Year data does the contract logic have? Oct 10 '18 at 2:14

You may run out of gas by having those nested for-loops. What about having a mapping from uint to string, and use it to store a hash of the information for each year? Then you could store your structs in a centralized database and use the blockchain for validation purposes.

The idea behind this is that in order to take advantage of the immutability of the blockchain, there's no need to store the whole content but only a hash of the content. You can then use that hash as a proof that the information you have off-chain didn't change (because if it did, it's hash would be different than the one on-chain). Many projects do this, for example, https://www.po.et: it is not feasible to store a whole book in the blockchain, but if you hash it and store the hash, then that is enough to prove that at that moment of time you had a book with that exact text.

If you do want to store everything in the contract, I would not try to return a complex structure like that directly from the contract. Instead, I would write that logic in Javascript and call the contract several times to return the information for each pair of year & case number (or maybe just year).

  • Thank you for your answer, I don't really get how I can store these structs in a centralized DB and then use the blockchain on it to be honest Oct 15 '18 at 14:26
  • 1
    @LucasLareginie Just edited my answer and added an explanation. Let me know if it's not clear :)
    – Patricio
    Oct 17 '18 at 10:45
  • Thank you very much, you're right, I won't be able to store all these info ... I got the idea about "Hashing" the data, but I really don' t get how I would hash the struct ... And where would I store it .. Like in a classical db ? Oct 17 '18 at 12:24
  • @LucasLareginie You can use the crypto package for node and do something like this: crypto.createHash('sha256').update(data, 'utf8').digest('base64'). Exactly, you can use any classical database.
    – Patricio
    Oct 18 '18 at 13:29

A good rule of thumb when putting stuff in storage in Solidity is "do I need to operate on this data on-chain?" If you don't need to, then you probably don't need to put it in storage. If you're just posting this stuff to the blockchain to later read it, then you can just have an event log the data and fetch it later that way, which is much cheaper than putting it all in storage.

You can also use pragma experimental ABIEncoderV2; so that you supply structs to a function so the massImport function is much easier to look at. Be aware though that ABIEncoderv2 support is still in progress for some libraries (the newest Web3.js has pretty good support though.)

  • Thank you very much , I'll check out ABIEncoderv2 :) ! But I don't really get the concept of "log the data en fetch it later that way" , do you have any exemple in mind or a link to the associated part in the doc ? Thanks ! Oct 17 '18 at 13:44
  • 1
    No problem! You can read about how to log/fetch events here solidity.readthedocs.io/en/v0.4.21/contracts.html#events. It's much more efficient to use events if you don't need to read the data from within the contract later.
    – natewelch_
    Oct 17 '18 at 14:01

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.