0

I am currently writing a blog PoC on EOS. I would like the ability to delete a post. Now deleting by the ID alone is simple, I have it implemented as follows:

whisper::post_index posts(_code, _code.value);
//Find the post with the key
auto itr = posts.find(key);
if (itr != posts.end())
{
    .....    
}

Now obviously anyone can then just pass on an ID and delete a post, so I would like to ensure that only the owner of the post can delete their post.

My posts table does store the owner of the post, it is as follows:

 struct [[ eosio::table, eosio::contract("whisper") ]] posts
  {
    uint64_t key; //Primary key (ID)
    name account; //Account that made the post
    std::string headerImage; //Header image of the post
    std::string title; //Title of the post
    std::string excerpt; //Excerpt of the post
    std::string content; //Content of the post

    uint64_t primary_key() const { return key; }
  };

Is there a way to use .find on the table to search for both the primary key and the owner of the post? If not - how would you suggest on ensuring that only the owner can delete the post?+

bumped to the homepage by Community yesterday

This question has answers that may be good or bad; the system has marked it active so that they can be reviewed.

0

Is there a way to use .find on the table to search for both the primary key and the owner of the post? If not - how would you suggest on ensuring that only the owner can delete the post?+

Yes, you can use a composite key.

 struct [[ eosio::table, eosio::contract("whisper") ]] posts
  {
    uint64_t key; //Primary key (ID)
    name account; //Account that made the post
    std::string headerImage; //Header image of the post
    std::string title; //Title of the post
    std::string excerpt; //Excerpt of the post
    std::string content; //Content of the post

    uint64_t primary_key() const { return key; }
    uint64_t by_key_owner() const { return key + account.value; }
  };

Then make sure to properly define the index:

  typedef eosio::multi_index<"posts"_n, posts,
      indexed_by<"keyowner"_n, const_mem_fun<posts, uint64_t, &stats::by_key_owner>>> poststable;

And to use it...

whisper::poststable posts(_self, _self.value);
auto idx = posts.get_index<"keyowner"_n>();
auto iterator = idx.find(key + account.value);
  • To mention that key + account.value is not unique. But composite keys seem like the right way. – cmadh yesterday
  • Seems the key is the blog id which is always unique so adding username value to it would keep it unique. – netuoso - EOS Titan 23 hours ago
  • No. Key + account.value is a sum of two variables. Just as an example, if user with account.value 100 creates blogpost 80, sum is 180. If user with account.value 80 creates blogpost 100 sum is 180, too. – cmadh 9 hours ago
  • If you want it to be unique you have to shift bits. uint128_t my_unique = (uint128_t)key << 64 & account.value. This would also allow to use a single index instead of primary + secondary . – cmadh 9 hours ago
-1

Okay so all I did was to check that the account of the iterator after the find was equal to the user making the call. So it ended up looking like this:

//Get the posts
whisper::post_index posts(_code, _code.value);
//Find the post with the key
auto iterator = posts.find(key);
//Check that the post could be found
eosio_assert(iterator != posts.end(), "Post could not be found");
//Check that the user owns the post
eosio_assert(iterator->account == user, "User does not own the post.");
if (iterator != posts.end())
{
    iterator = posts.erase(iterator);
}
  • This method is less than efficient. I have provided an answer below that uses composite keys for an index. – netuoso - EOS Titan Aug 22 at 3: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.