0

I deploy a Smart Contract first time and the action becomes usable as it's supposed to be, but when Action's parameters is updated with a new one between existing p1 and p2 old parameters (result: p1, new_parameter, p2), this action becomes unusable throwing out some errors like:

Error 1: Error 515193181: Unexpected exception Read past end of buffer Error Details: Read past end of buffer

Error 2: Unable to sign transaction

Steps to test:

  1. Compile Smart Contract

./somegoodtest/

eosio-cpp -abigen -I ./include -contract somegoodtest -o somegoodtest.wasm src/somegoodtest.cpp
  1. Deploy Smart Contract

    cleos -u <endpoint_url> set contract somegoodtest CONTRACT_DIR/somegoodtest -p somegoodtest@active

  2. Execute Action: Test from some testnet dashboard network

  3. Modify Smart Contract (Add new parameter between existing ones)

  4. Compile Smart Contract

./somegoodtest/

eosio-cpp -abigen -I ./include -contract somegoodtest -o somegoodtest.wasm src/somegoodtest.cpp
  1. Deploy Smart Contract

    cleos -u <endpoint_url> set contract somegoodtest CONTRACT_DIR/somegoodtest -p somegoodtest@active

  2. Execute Action adding new parameter

  3. Check error

Code:

./somegoodtest/include/somegoodtest.hpp
#include <eosio/eosio.hpp>

using namespace std;
using namespace eosio;

CONTRACT somegoodtest : public contract {
  public:
    using contract::contract;

    ACTION hi(name from, string message);
    ACTION clear();

  private:
    TABLE messages {
      name    user;
      string  text;
      auto primary_key() const { return user.value; }
    };
    typedef multi_index<name("messages"), messages> messages_table;
};



./somegoodtest/src/somegoodtest.cpp
#include <somegoodtest.hpp>

ACTION somegoodtest::hi(name from, string message) {
  require_auth(from);

  // Init the _message table
  messages_table _messages(get_self(), get_self().value);

  // Find the record from _messages table
  auto msg_itr = _messages.find(from.value);
  if (msg_itr == _messages.end()) {
    // Create a message record if it does not exist
    _messages.emplace(from, [&](auto& msg) {
      msg.user = from;
      msg.text = message;
    });
  } else {
    // Modify a message record if it exists
    _messages.modify(msg_itr, from, [&](auto& msg) {
      msg.text = message;
    });
  }
}

ACTION somegoodtest::clear() {
  require_auth(get_self());

  messages_table _messages(get_self(), get_self().value);

  // Delete all records in _messages table
  auto msg_itr = _messages.begin();
  while (msg_itr != _messages.end()) {
    msg_itr = _messages.erase(msg_itr);
  }
}

EOSIO_DISPATCH(somegoodtest, (hi)(clear))

Updated code:

./somegoodtest/include/somegoodtest.cpp
#include <eosio/eosio.hpp>

using namespace std;
using namespace eosio;

CONTRACT somegoodtest : public contract {
  public:
    using contract::contract;

    ACTION hi(name from, string detail, string message);
    ACTION clear();

  private:
    TABLE messages {
      name    user;
      string  text;
      auto primary_key() const { return user.value; }
    };
    typedef multi_index<name("messages"), messages> messages_table;
};



./somegoodtest/src/somegoodtest.cpp
#include <somegoodtest.hpp>

ACTION somegoodtest::hi(name from, string detail, string message) {
  require_auth(from);

  // Init the _message table
  messages_table _messages(get_self(), get_self().value);

  // Find the record from _messages table
  auto msg_itr = _messages.find(from.value);
  if (msg_itr == _messages.end()) {
    // Create a message record if it does not exist
    _messages.emplace(from, [&](auto& msg) {
      msg.user = from;
      msg.text = message;
    });
  } else {
    // Modify a message record if it exists
    _messages.modify(msg_itr, from, [&](auto& msg) {
      msg.text = message;
    });
  }
}

ACTION somegoodtest::clear() {
  require_auth(get_self());

  messages_table _messages(get_self(), get_self().value);

  // Delete all records in _messages table
  auto msg_itr = _messages.begin();
  while (msg_itr != _messages.end()) {
    msg_itr = _messages.erase(msg_itr);
  }
}

EOSIO_DISPATCH(somegoodtest, (hi)(clear))

Note: I know that after of a Smart Contract update, we must wait until that block transaction becomes immutable to make use of it but error still persist. Also is very important to add the new parameter between existing ones. Moreover looking for some of the error above described, none of the solutions helped me.

0

can you try to execute set contract with explicit --abi param?

cleos -u <endpoint_url> set contract somegoodtest CONTRACT_DIR --abi somegoodtest.abi somegoodtest.wasm -p somegoodtest@active

also can you paste the two commands that send the hi action, the one that works and the one which doesn't work?

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.