0

This is the solution to my previous question How to access mapping in contract? | Solved by @kerry99

This time I have added the strct Vertex inside the mapping, now how call the value of x and y into the main contract from library?

// 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'];
  }
 }

2 Answers 2

1

Your issue is that you must to specify the library name before struct name, in this case you must change this line:

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

with this:

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

(as said @sola24). Another issue that your library struct name is: Datastruct (with s in lowercase) and in line 34 you have declared DataStruct (with S in uppercase).

Another thing, from your getNames() function return values in bytes consequentially you won't see "ban" but something like this 0x62616e. For retrieve the "ban" value you must cast bytes to string and change return about function from bytes to string with this statement:

string(abi.encodePacked([bytesValue]))

I adjusted your smart contract, you can see it below this line:

// 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));
    }
}
1
  • Thakyou ser, it worked :) Jun 14, 2022 at 13:30
0

if you change this

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

to this

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

getNames returns

0x62616e
4
  • I already tried this, but It's did not worked, here is the error - DeclarationError: Undeclared identifier. Did you mean "Datastruct"? --> libraray.sol:35:32: | 35 | Test.Vertex memory v = DataStruct.a['0']; Jun 14, 2022 at 10:25
  • How it's running at your end, can you copy past the about code in the remix, let me know if you are still able to get an answer!! Jun 14, 2022 at 10:28
  • there are two changes. Test in front of Vertex and big S to a little s in Datastruct, then the code ran
    – sola24
    Jun 14, 2022 at 12:37
  • My bad I haven't read the issue properly. Jun 14, 2022 at 13:30

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.