8

I want to sent a string as an argument to a function. But some user may enter maybe 100 size string or even larger.

[Q] Inside the function is it possible to check the size of the string and return false if it exceeds the length limit that I have specified.

For example, a user is only allowed to send string which has length of 64 characters, and the contract's function returns throw if the string exceeds the limit of 64 character.

Test.transaction().setVariable("very_large_size_string_entered_65_chars");

For example:

Contract Test{
   String data;
   function setVariable(string str) {
       //check somehow does the string exceeds the character limit.
       data = str;
   }
}

Thank you for your valuable time and help.

14

Just check if bytes(str).length is too big.

EDIT:

See the answer below if you need to know an exact length of a utf-8 encoded string. This will cost significantly more gas, however. Note that the utf-8 length will be at most the byte length.

  • 4
    This way you can check th byte-length of string. If string encoding, for example UTF8, number of characters can differ from bytes(str).length – Alexey Barsuk Apr 4 '17 at 1:39
  • This answer should be edited to include Alexey's comment. bytes(str).length does NOT give the intended behavior in some cases, so it must be used with caution. – Symeof Oct 2 '18 at 20:19
  • I would argue that byte-length is the more important metric in most cases, since length in encodings like utf-8 is still upper-bounded by byte length. It seems rather arbitrary to assume that OP is using utf8 or any other particular encoding. – Tjaden Hess Oct 3 '18 at 15:14
18

Code for calculating string length in characters

contract utf8StringLength
{
    //---------------------BEGIN Code to copy-paste--------------

    function utfStringLength(string str) constant
    returns (uint length)
    {
        uint i=0;
        bytes memory string_rep = bytes(str);

        while (i<string_rep.length)
        {
            if (string_rep[i]>>7==0)
                i+=1;
            else if (string_rep[i]>>5==0x6)
                i+=2;
            else if (string_rep[i]>>4==0xE)
                i+=3;
            else if (string_rep[i]>>3==0x1E)
                i+=4;
            else
                //For safety
                i+=1;

            length++;
        }
    }

    ////////////////////END Code to copy-paste///////////////////


    //-----------------BEGIN testing stuff code-----------------

    string constant hello1= "Привет";
    string constant hello2= "Hello";
    string constant hello3= "你好";
    string constant hello4= "هيلو";
    string constant hello5= "مرحبا";


    function test() constant
    returns
        (uint,
        uint,
        uint,
        uint,
        uint)
    {
        return(
            utfStringLength(hello1),
            utfStringLength(hello2),
            utfStringLength(hello3),
            utfStringLength(hello4),
            utfStringLength(hello5)
        );
    }
    //////////////////END testing stuff code//////////////////////
}
  • IMO this is the better answer. – TripleSpeeder Jul 15 '17 at 7:37
  • This seems like, it will consume much more gas. @Alexey Barsuk – alper Apr 14 '18 at 15:22
  • 1
    @Alper Yes it will. If I measured right, about 10 times more for this function in comparison with bytes(str).length for the same string. – Alexey Barsuk Apr 15 '18 at 16:59
  • Thats pretty expensive as cost of ether @AlexeyBarsuk – alper Apr 15 '18 at 17:48
-1

stirng is the special kind of array and compatible with bytes. Solidity does not provide much string operation and hence we can rely on bytes to carry out any string related operations like null check, length ...

pls find below the modified code to check for the string limit. If supplied styring lenght is more than required then this funcction would revert the function call.

In ther latest solidity release, 'throw' has deprecated, thats why I have used 'revert'.

pragma solidity ^0.4.4;

contract Test{
   string data;
   uint stringLimit;

   function setVariable(string str)  {
      bytes memory strBytes = bytes(str);
      if(strBytes.length >= stringLimit)
          revert;
      else 
         data = str;
    }
}

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.