Solidity

如何在solidity中訪問映射?

  • June 14, 2022

這是我之前的問題 如何在契約中訪問映射的解決方案? | 由@kerry99 解決

這次我在映射中添加了 strct 頂點,現在如何從庫中呼叫 x 和 y 的值到主合約中?

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

 library Test{

 struct Vertex {
   bytes x;
   bytes y;
 }

 struct Data {
   mapping(bytes => Vertex) a;
 }

 function inc(Data storage self) internal {
   self.a['0'].x = "ban"; self.a['0'].y = "sam";
   self.a['1'].x = "tom"; self.a['1'].y = "pan";
 }
}

contract Example{

 address recipient = 0x5B38Da6a701c568545dCfcB03FcB875f56beddC4;
 // NOTE: Declare a new instance about mapping inside Data struct in 'Test' library
 Test.Data Datastruct;

 // NOTE: Function that allow you to call 'inc' function inside 'Test' Library for 
 fill the mapping
 function setName() public {
   Test.inc(Datastruct);
 }

 function getNames() external view returns(bytes memory) {
   // NOTE: With instance about mapping, you can read data 
   Vertex memory v = DataStruct.a['0'];
   return v.x;
   // return Datastruct.a['0'];
 }
}

您的問題是您必須在結構名稱之前指定庫名稱,在這種情況下您必須更改此行:

Vertex memory v = DataStruct.a['0'];

有了這個:

Test.Vertex memory v = Datastruct.a['0'];

(如@sola24 所說)。您的庫結構名稱的另一個問題是:(Datastruct小寫的 s)並且在第 34 行中您已聲明DataStruct(大寫的 S)。

另一件事,從你的getNames()函式返回值以字節為單位,你不會看到“ban”,而是像這樣的 0x62616e。要檢索“ban”值,您必須將字節轉換為字元串,並使用以下語句將函式的返回值從更改bytes為:string

string(abi.encodePacked([bytesValue]))

我調整了你的智能合約,你可以在這條線下面看到它:

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

 library Test{

 struct Vertex {
   bytes x;
   bytes y;
 }

 struct Data {
   mapping(bytes => Vertex) a;
 }

 function inc(Data storage self) internal {
   self.a['0'].x = "ban"; self.a['0'].y = "sam";
   self.a['1'].x = "tom"; self.a['1'].y = "pan";
 }
}

contract Example{

   address recipient = 0x5B38Da6a701c568545dCfcB03FcB875f56beddC4;
   // NOTE: Declare a new instance about mapping inside Data struct in 'Test' library
   Test.Data Datastruct;

   // NOTE: Function that allow you to call 'inc' function inside 'Test' Library for fill the mapping
   function setName() public {
       Test.inc(Datastruct);
   }

   function getNames() external view returns(string memory) {
       // NOTE: With instance about mapping, you can read data
       Test.Vertex memory v = Datastruct.a['0'];
       return string(abi.encodePacked(v.x));
   }
}

如果你改變這個

Vertex memory v = DataStruct.a['0'];

對此

Test.Vertex memory v = Datastruct.a['0'];

getNames 返回

0x62616e

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