Solidity

Solidity 將逗號分隔的字元串拆分為單個單詞

  • November 11, 2020

由於Solidity函式不能接受String Arrays作為參數,因此我嘗試傳入一個以逗號分隔的長字元串,然後即時將其轉換為字元串數組。

我很接近 - 但else聲明中的底部一行 - 我在評論中指出 - 不斷破壞契約。

這是我的程式碼:

function splitString(string calldata stringToSplit) external pure returns(string memory) {
   // 1. Declare a string array to hold all the individual words I'm able to tease 
   //    out of the passed-in string: 
   string[] memory finalWordsArray;
   
   // 2. Declare a word-counter var to keep track of how many words I've gotten:
   uint256 wordCounter = 0;

   // 3. Convert and store the passed-in String argument into a Bytes Array so 
   //    I can iterate through it one character at a time:
   bytes memory stringAsBytesArray = bytes(stringToSplit);

   // 4. Declare another bytes array to contain all the characters that will be
   //    in my next full individual Word:
   string memory tmp = new string(stringAsBytesArray.length);
   bytes memory tempWord = bytes(tmp);
   
   
   // 5. Iterate through the "stringAsBytesArray" one Char at a time:
   // ["Hello,here,we,are,today"]
   for(uint i = 0; i < stringAsBytesArray.length; i++) {
       // if current char is NOT a comma, append it to my "tempWord":
       if (stringAsBytesArray[i] != ",") {
           tempWord[i] = stringAsBytesArray[i];
       }
       else {
           // We found a Comma, which means we've reached the end of a word. So 
           // let's convert our "tempWord" from a bytes Array to a String:
           string memory newWord = string(tempWord);
           
           // And then add that word to our "finalWordsArray":  
           // -->this next line causes a crash!
           // finalWordsArray[wordCounter] = newWord;
           
           // Iterate our wordCounter:
            wordCounter++;
            
           // And reset/blank-out our "tempWord" for the next go-around:
           tempWord = bytes(tmp);
           

           // This next statement DOES work: it returns the first word it
           // found before hitting that first comma. I put this in just to
           // see that I am getting at least SOMETHING out of this:
           return newWord;
       }
   }

   return "no Commas found!!!";

   // return string(finalWordsArray[2]);
}

由於 Solidity 函式不能接受字元串數組作為參數

這在技術上並不能回答您的問題,但如果您啟用ABIEncoderV2,您可以簡單地將字元串數組傳遞給函式,而不是嘗試自己拆分它。就氣體使用而言,這可能更有效。

例如:

pragma solidity ^0.7.4;
pragma experimental ABIEncoderV2;

contract Foo {
 function bar (string[] calldata baz) public {
   // do something with `baz` here 
 }
}

問題是它finalWordsArray永遠不會被分配,所以它是空的,你不能將項目分配給任何索引。為了使分配起作用,您必須分配finalWordsArray足夠的條目。不幸的是,記憶體數組不是動態的,一旦初始化就不能改變它的長度。

可能最好的選擇是像@Morten 所說的那樣使用 A​​BIEncoverV2 或使用solidity -stringutils來避免手動解析。

引用自:https://ethereum.stackexchange.com/questions/90060