Does anyone know the correct way to get table rows using checksum256
(fixed_bytes<32>
) secondary index through the get_table_rows
RPC API?
I found a way using key256
, but key256
is deprecated in eosio.cdt 1.5.0.
warning: 'key256' is deprecated: Replaced by fixed_bytes [-Wdeprecated-declarations]
So I implemented a contract with checksum256
secondary index referring to this document, but I can't get proper rows using checksum256
secondary index. My contract is as follows, and I compile it with eosio.cdt 1.5.0.
#include <eosiolib/eosio.hpp>
using namespace eosio;
class [[eosio::contract]] test : public contract
{
using contract::contract;
public:
test(name receiver, name code, datastream<const char*> ds) :
contract(receiver, code, ds),
items(_self, _self.value)
{};
[[eosio::action]]
void additem(std::string identifier)
{
items.emplace(_self, [&](auto& row) {
row.key = items.available_primary_key();
row.identifier = identifier;
row.identifier_hash = hash(identifier);
});
}
private:
struct [[eosio::table]] item {
uint64_t key;
std::string identifier;
checksum256 identifier_hash;
uint64_t primary_key() const { return key; }
checksum256 by_identifier_hash() const { return identifier_hash; }
};
typedef multi_index<name("items"), item,
indexed_by<name("idhash"), const_mem_fun<item, checksum256, &item::by_identifier_hash>>
> item_index;
checksum256 hash(std::string str)
{
return sha256(const_cast<char*>(str.c_str()), str.size());
}
item_index items;
};
EOSIO_DISPATCH(test, (additem));
$ cleos -u https://api-kylin.eosasia.one push action checksumtest additem '["m0t0k1ch1"]' -p checksumtest@active
$ curl -s https://api-kylin.eosasia.one/v1/chain/get_table_rows -d '{"json":true,"code":"checksumtest","scope":"checksumtest","table":"items","table_key":"idhash","index_position":2,"key_type":"sha256","limit":1}'
{
"rows": [
{
"key": 0,
"identifier": "m0t0k1ch1",
"identifier_hash": "c5bae5b3f19a69d45594902726ce983c0948fcda5bbf408f893fff91298688b4"
}
],
"more": false
}
$ curl -s https://api-kylin.eosasia.one/v1/chain/get_table_rows -d '{"json":true,"code":"checksumtest","scope":"checksumtest","table":"items","table_key":"idhash","index_position":2,"key_type":"sha256","lower_bound":"c5bae5b3f19a69d45594902726ce983c0948fcda5bbf408f893fff91298688b4","upper_bound":"c5bae5b3f19a69d45594902726ce983c0948fcda5bbf408f893fff91298688b4","limit":1}'
{
"rows": [],
"more": false
}
Updated on Mar 18, 2019
It seems that the checksum256
data is divided into two parts per 16 bytes, and each part is stored in little endian. So I was able to get the proper row in the following way.
$ curl -s https://api-kylin.eosasia.one/v1/chain/get_table_rows -d '{"json":true,"code":"checksumtest","scope":"checksumtest","table":"items","table_key":"idhash","index_position":2,"key_type":"sha256","lower_bound":"3c98ce2627909455d4699af1b3e5bac5b488862991ff3f898f40bf5bdafc4809","upper_bound":"3c98ce2627909455d4699af1b3e5bac5b488862991ff3f898f40bf5bdafc4809","limit":1}'
{
"rows": [
{
"key": 0,
"identifier": "m0t0k1ch1",
"identifier_hash": "c5bae5b3f19a69d45594902726ce983c0948fcda5bbf408f893fff91298688b4"
}
],
"more": false
}
Thank you for the advice, @CoRe1o3 🙏
See also this issue.