Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

can not get value from complex struct #4419

Closed
Colonel86 opened this issue Jul 4, 2018 · 6 comments
Closed

can not get value from complex struct #4419

Colonel86 opened this issue Jul 4, 2018 · 6 comments

Comments

@Colonel86
Copy link

Colonel86 commented Jul 4, 2018

contract Complex {
    struct Data {
        uint a;
        bytes3 b;
        mapping (uint => uint) map;
    }
    Data public tempData = Data({a:123,b:"abc"});
    
    mapping (uint => mapping(bool => Data[])) public data;
    
    function setData() public{
        tempData.map[0] = 456;
    }
    
    function getValue() public returns(uint){
        return tempData.map[0];
    }
    
    function setComplex() public {
        data[0][false].push(tempData);
    }
    
    function getData(uint arg1, bool arg2, uint arg3) public returns (uint a, bytes3 b, uint value,uint tempInt) {
        // a = data[arg1][arg2][arg3].a;
        // b = data[arg1][arg2][arg3].b;
        Data mdata = data[arg1][arg2][arg3];
        a = mdata.a;
        b = mdata.b;
        mapping (uint => uint) tempMap = mdata.map;
        value = tempMap[0];
        tempInt = mdata.map[0];
    }
}

In remix ,Current version:0.4.24+commit.e67f0147.Emscripten.clang
setData()
getValue()
setComplex()

but call getData(0, false, 0).

 a = 123
b  = 0x616263
value  = 0
tempInt = 0

why "value" and "tempInt" = 0
Logically it should value = 456 and tempInt = 456
What's the reason?

@chriseth
Copy link
Contributor

chriseth commented Jul 4, 2018

I do not yet fully understand your code, but do you realize that data[0][false].push(tempData); pushes an independent copy of tempData?

@chriseth
Copy link
Contributor

chriseth commented Jul 4, 2018

Ah right and this independent copy does not include the mapping type (because mappings cannot be copied), I think that is the problem.

@chriseth
Copy link
Contributor

chriseth commented Jul 4, 2018

We are trying to improve the visibility of implicit copy operations: #2435

@Colonel86
Copy link
Author

Colonel86 commented Jul 5, 2018

@chriseth Sorry, I didn't describe it clearly. It's causing trouble for you. I'm from China and my English is not very good。
I reorganized the code

pragma solidity ^0.4.24;

contract ComplexStruct {
    struct Data {
        uint a;
        bytes3 b;
        mapping (uint => uint) map;
    }
    
    Data data;
    mapping (uint => mapping(bool => Data[])) public dataMap;
    
    //123,"0x424344",0,456,0,false
    function setDataMap(
        uint _a, 
        bytes3 _b, 
        uint _mapKey, 
        uint _mapValue, 
        uint dataMapUintKey, 
        bool dataMapBoolKey
        ) 
        public
    {
        data.a = _a;
        data.b = _b;
        data.map[_mapKey] = _mapValue;
        dataMap[dataMapUintKey][dataMapBoolKey].push(data);
    }
    
    //0,false,0
    function getData(uint arg1, bool arg2, uint arg3) public view returns (uint a, bytes3 b, uint value, uint tempUint) {
        a = dataMap[arg1][arg2][arg3].a;
        b = dataMap[arg1][arg2][arg3].b;
        value = dataMap[arg1][arg2][arg3].map[0];
        
        Data storage tempData = dataMap[arg1][arg2][arg3];
        tempUint = tempData.map[0];
    }
}

I use the browser remix,The operation is as follows:
setDataMap(123,"0x424344",0,456,0,false)
getData(0,false,0)
result:
0: uint256: a 23
1: bytes3: b 0x424344
2: uint256: value 0
3: uint256: tempUint 0

When I was in the getData() debugger,I can see that:
`
tempData: struct ComplexStruct.Data

a: 23 uint256

b: 0x424344 bytes3

map: mapping(uint256 => uint256)
0000000000000000000000000000000000000000000000000000000000000000: 456 uint256
`
But why can't I get map[0]?
you say:"mappings cannot be copied", But it's not from above。

I don't know how to get it from dataMap[0][false][0].map[0]

@chriseth
Copy link
Contributor

You cannot use tempData or data like that. Only use dataMap. Especially, the effect of data.map[_mapKey] = _mapValue; will not be taken over for the push. You have to set it after the push using dataMap[dataMapUintKey][dataMapBoolKey].length++; uint p = dataMap[dataMapUintKey][dataMapBoolKey].length - 1; dataMap[dataMapUintKey][dataMapBoolKey][p].map[_mapKey] = _mapValue;

@Colonel86
Copy link
Author

@chriseth I did as you said. Thank you very much

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants