1

this is probably a really really simple question but shamefully it's had me stumped for a while. I am building a simple application which would allow users to purchase Newspaper Articles. Simple enough but the relations is killing me.

I'll outline my goal and where I am so you get an idea of my thinking and perhaps can point me in a more logical direction if needed.

So the way I see it, I have 3 entities.

An Author, An Article and A Reader

An Author can have many Articles

An Article can have one Author

An Article can have many Readers

A Reader can have many Articles

An Author and a Reader have no relation

Mapping a new Article to an Author is not a problem and I have this working

My problem is with mapping many Articles with many Readers

I've thought about having a mapping table like ArticlesRead which would simply have the address of each Reader & the ID of each Article, but how do I go about retrieving the Articles the Reader has purchased.

I think I'm getting a little hung up on how traditional arrays work..

I'm sure this is simple so any advice would be appreciated,

struct Article {
    uint index;
    string content;
    uint price;
}

struct Reader {
    address _address;
}

My code is pretty rubbish for now so I don't think it will help posting it

Thanks

1

This is not that simple, do not worry :) indeed you need to map to a structure itself containing arrays.

here is an overview of the mapping I am proposing

corresponding to the following code

struct Article {
    uint index;
    string content;
    uint price;
    address[] readerId;
}

struct Reader {
    address[] articleId;
}

struct Author {
    address[] articleId;
}

// map id to id
mapping(address => address) mapArticleIdToAuthorId; //only valid if an article always has one and only one Author

// map id to Struct
mapping(address => Article) mapArticleIdToArticleStruct;
mapping(address => Author) mapAuthorIdToAuthorStruct;
mapping(address => Reader) mapReaderIdToReaderStruct

instead of address you can of course use other types (like uint256).

I am looking forward seing if anyone is coming with some alternative solution !

Hope this helps

extra: I have some code samples (with uint, I let you adapt them for address type) for adding / removing items

you can add entry in a array as such

// add articleId to author struct
Author storage author = mapAuthorIdToAuthorStruct[_authorId];
author.articleId.push(_articleId)

and removing an entry:

// remove articleId from author struct
Author storage author = mapArticleIdToAuthorStruct[_articleId];
uint[] memory temp = new uint[](author.articleId.length-1);
uint j = 0;
for (uint i = 0; i < author.articleId.length; i++) {
    if (author.articleId[i] != _articleId) {
        temp[j] = author.articleId[i];
        j++;
    }
}
author.articleId = temp;
// remove mapping between articleId and authorId
mapArticleIdToAuthorId[articleId] = 0;

keep in mind that storage is expensive in ethereum. Gas costs are defined in the yellow paper

1
  • What I read that using the loop is not a good idea as it consumes more gas. I am also struggling in retrieving the values in a nice way – Uahmed Jun 8 '18 at 11:27

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.