Solidity

嵌套映射未返回正確結果

  • July 19, 2017

我試圖在 SmartContract 中建構一個嵌套的結構映射。使用單個級別,在插入數據(insertData)之後,驗證方法將返回正確的結果,下面的程式碼包含很少的註釋行。但是當我取消註釋與 childMap 相關的東西時 - ParentStruct 中的 childMap、insertData 方法中的參數和初始化 childMap 然後它返回錯誤的結果。請在下面找到智能合約程式碼。

pragma solidity ^0.4.13;

contract SampleContract {
struct ChildStruct {
   bool isPresent;
   bytes32 name;
}

struct ParentStruct {
   bool isPresent;
   bytes32 name;
   //mapping (bytes32 => ChildStruct) childMap; 
}

mapping(bytes32 => ParentStruct) sampleStructs;

function insertData(bytes32 parentAddress, bytes32 parentName
                      //,bytes32 childAddress, bytes32 childName
                      )
public returns(bool success)
{
   ParentStruct storage c = sampleStructs[parentAddress];
   c.isPresent = true;
   c.name = parentName;
   //c.childMap[childAddress] = ChildStruct(true, childName);
   return true;
}

function validate(bytes32 parentAddress)
public returns(bool isPresent, string name) 
{
   return 
   (sampleStructs[parentAddress].isPresent,
   bytes32ToString(sampleStructs[parentAddress].name)
   );
}

function bytes32ToString(bytes32 x) constant returns (string) 
{
   bytes memory bytesString = new bytes(32);
   uint charCount = 0;
   for (uint j = 0; j < 32; j++) {
       byte char = byte(bytes32(uint(x) * 2 ** (8 * j)));
       if (char != 0) {
           bytesString[charCount] = char;
           charCount++;
       }
   }
   bytes memory bytesStringTrimmed = new bytes(charCount);
   for (j = 0; j < charCount; j++) {
       bytesStringTrimmed[j] = bytesString[j];
   }
   return string(bytesStringTrimmed);
}
}

如果我遺漏了什麼,你能幫我嗎?

我玩弄了你的程式碼並想出了這個:

pragma solidity ^0.4.11;

contract SampleContract {

 struct ChildStruct {
   bool isPresent;
   bytes32 name;
 }

 struct ParentStruct {
   bool isPresent;
   bytes32 name;
   mapping (bytes32 => ChildStruct) childStructs; 
 }

 mapping(bytes32 => ParentStruct) public parentStructs;

 function insertData(
   bytes32 parentKey, 
   bytes32 parentName, 
   bytes32 childKey, 
   bytes32 childName)
   public 
   returns(bool success)
 {

   parentStructs[parentKey].isPresent = true;
   parentStructs[parentKey].name = parentName;
   parentStructs[parentKey].childStructs[childKey].isPresent = true;
   parentStructs[parentKey].childStructs[childKey].name = childName;
   return true;
 }

 function getChild(bytes32 parentKey, bytes32 childKey) public constant returns(bool isPresent, bytes32 name) {
   return (parentStructs[parentKey].childStructs[childKey].isPresent, parentStructs[parentKey].childStructs[childKey].name);
 }

}

在這個簡單的解決方案中有一個隱藏的假設——呼叫者必須知道父母和孩子的密鑰,因為合約沒有提供列舉它們的方法。

我刪除了字元串轉換,因為客戶可以照顧它。還將“地址”重命名為“密鑰”,因為前者使它聽起來像錢包/合約地址。我認為它們是其他東西,因為它們沒有被強制轉換為address.

看起來你的目標是這樣的。這種模式讓您可以通過父子連接(一對多關係)做很多事情。https://medium.com/@robhitchens/enforcing-referential-integrity-in-ethereum-smart-contracts-a9ab1427ff42

希望能幫助到你。

編輯:

契約似乎有效,所以我會集中精力在客戶端。我不確定sampleContract從哪裡來。將交易發送到一個合約然後向另一個合約詢問結果似乎很奇怪。

這些函式需要十六進制,而不是字元串。此外,請務必使用 .then(這是 Truffle 嗎?)等待響應。順便說一句,txn 雜湊結果令人鼓舞但具有誤導性。這並不意味著它被開採或成功。

裡面的東西可能會有所幫助。

在我仔細檢查契約時,我刪除了getParent(). 它並沒有比我們從製作mapping public. 你可以parentStructs('key')以同樣的方式使用。

這是在 Remix 中展示它的工作。

在此處輸入圖像描述

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