Printing asset amount in eosio_assert()

Suppose you want your EOS contract to only accept payments of exact specific amounts. Then, of course, you would need to print the desired amount in eosio_assert(), so that the payer gets an idea what kind of amount is expected. But eosiolib, the library of all standard tools for building a contract, does not provide a function that simply generates a string out of an asset object.

You may try using sprintf() for this, but you will soon discover that its adds up about 20KB to your binary, and that results in 200KB extra RAM usage when you upload your contract to the network. In current prices, that’s about $200 surplus.

So, I wrote this piece of code to mitigate this issue:

if( payment != exactprice ) {
int64_t pres = (int64_t)exactprice.symbol.precision();
char buf[64];
char* start = buf + sizeof(buf) - 10;
char* end = start;
int digits = 0;

int64_t amount = exactprice.amount;
while( amount != 0 || digits < pres+1 ) {
--start;
*start = (amount % 10) + '0';
digits++;
if( digits == pres ) {
*--start = '.';
}
amount /= 10;
}

*end++ = ' ';
auto sym = exactprice.symbol.name();
for( int i = 0; i < 7; ++i ) {
char c = (char)(sym & 0xff);
*end++ = c;
if( c == 0 ) break;
sym >>= 8;
}
*end = 0;

char str[256] = "Incorrect payment amount. Expected ";
strcat(str, start);
eosio_assert(0, str);
}

Some of you may enjoy turning back to basic Computer Science class assignments :)

Telegram: cc32d9, EOS account: "cc32dninexxx"

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store