4

I have known how to convert a string to bytes32. But if the string length is longer than 32, the rest of the string will be truncated. So how to convert a string to bytes32[] array?

Jesbus
  • 10,478
  • 6
  • 35
  • 62
黃智祥
  • 465
  • 6
  • 16
  • Why would you want to convert string to bytes array? What is the use case? Maybe there is a better alternative instead of doing it like this. – Mikko Ohtamaa Mar 18 '17 at 08:54
  • 1
    This sounds like an XY problem. Can you explain to us what you're trying to achieve, rather than how you're trying to achieve it? – Nick Johnson Mar 18 '17 at 10:43
  • @MikkoOhtamaa,@Nick
    For example,I have contract A and contract B. Contract A will call contract B and get the Contract B's return value. My question is "How can Contract B return data which length is longer than 32 to Contract A?"
    If I use string data type,Contract A will get some error like:"dynamic type is not implicitly convertible to expected type".
    So I must change the return data type to non-dynamic type. I find I can use bytes32 data type to transfer between Contract A and Contract B,but the length of bytes32 data type is only 32. It is not enough. Thanks
    – 黃智祥 Mar 19 '17 at 03:35

1 Answers1

1

I have coded this contract successfully.Below is the contract:

pragma solidity ^0.4.10;
contract StrToBytes32Array
{
    function StrToBytes32Array(string p_str) returns(bytes32[]){
        bytes  memory lbts_para;  //the result of convert p_str to bytes
        uint li_paralength;   //lbts_para's length
        string memory ls_new; //the result of convert ont bytes32 to string
        bytes32 lbt_row;      // the new bytes32 data  
        bytes32[] lbt_result32;    //the return bytes32 array     
        uint li_rowcount; // bytes32 array's length
        uint li_temp;  
        uint li_sum; //the total byte32 array's bytes amount
        uint li_colidx;  //the new column's index
        uint li_resultlength ; // the result bytes32 array's length

        lbts_para = bytes(p_str); //ex:'1234' = 0x31323334
        li_paralength = lbts_para.length;  //ex: 4 
        bytes memory lbts_new = new bytes(32); //for store to arrays32 array
        lbt_result32.length=0; //ininial the array32 array
        if (li_paralength <= 32 ){  //if actul data length is less equal than 32,use assemble method
            assembly {
               lbt_row := mload(add(p_str, 32))
            }
            lbt_result32.length = 1;
            lbt_result32[0] = lbt_row;
        } else {
            //li_rowcount :calculate the bytes32 array's length
            li_rowcount = li_paralength/32;
            li_temp = li_paralength%32;
            if (li_temp > 0 )
                li_rowcount = li_rowcount +1;
            //li_sum :the total bytes amount of bytes32 array
            li_sum = li_rowcount *32;
            li_colidx = 0;
            for (uint p = 1;p<= li_sum;p++){
                //decide whether to add a new row
                li_temp = p%32;  //if equal 0,add a new row
                if (li_temp == 0 ){
                    if (p > li_paralength) 
                        lbts_new[li_colidx] = 0x0;
                    else
                        lbts_new[li_colidx] = lbts_para[p - 1];
                    li_colidx = 0;
                    ls_new = string(lbts_new);
                    assembly {
                        lbt_row := mload(add(ls_new, 32))
                    }
                    li_resultlength = lbt_result32.length ;
                    li_resultlength = li_resultlength +1;
                    lbt_result32.length = li_resultlength;
                    lbt_result32[li_resultlength - 1] = lbt_row;
                }else {
                    if (p > li_paralength) 
                        lbts_new[li_colidx] = 0x0;
                    else
                        lbts_new[li_colidx] = lbts_para[p - 1];
                    li_colidx = li_colidx +1;
                }

            }

        }

        return lbt_result32;

    }
}
黃智祥
  • 465
  • 6
  • 16
  • 1
    I tried your code but I think it went into an infinite loop as it wouldn't finish executing in remix.ethereum.org (using "JavaScript VM"). Also, I got 'Warning: Variable is declared as a storage pointer. Use an explicit "storage" keyword to silence this warning' for 'bytes32[] lbt_result32'. When I added "storage", I got 'Warning: Uninitialized storage pointer.' How do I get your code to work? – Curt Aug 16 '17 at 21:11