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?
-
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 OhtamaaMar 18, 2017 at 8:54
-
1This 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 JohnsonMar 18, 2017 at 10:43
-
@MikkoOhtamaa,@Nick <br>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, 2017 at 3:35
1 Answer
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;
}
}
-
1I 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?– CurtAug 16, 2017 at 21:11