0

The solidity contract has defined the following mapping

struct recordStruct {
    uint256 price;
    uint64 time;
}

mapping(address => recordStruct[]) public records;

Question: How can we use Web3.js to retrieve the entire mapping?

If this is not possible, how can we pass in the address and receive the object stored in the recordStruct array?

Attempt When using the following web3 code:

var record = await MyContractInstance.records.call('0xDbB7d1Ed07F8D1D0C5D5bB9b9e427E997f240F7d')

I get the following error

(node:2452) UnhandledPromiseRejectionWarning: Error: Invalid number of arguments to Solidity function

I am using Web3.js 1.0.0-beta.34

2

You need to specify both the address and the index of the array, since the ABI gonna have this structure:

[
    {
        "constant": true,
        "inputs": [
            {
                "name": "",
                "type": "address"
            },
            {
                "name": "",
                "type": "uint256"
            }
        ],
        "name": "records",
        "outputs": [
            {
                "name": "price",
                "type": "uint256"
            },
            {
                "name": "time",
                "type": "uint64"
            }
        ],
        "payable": false,
        "stateMutability": "view",
        "type": "function"
    }
]

And consider that the javascript code is also not completely correct:

var record = await MyContractInstance.records('0xDbB7d1Ed07F8D1D0C5D5bB9b9e427E997f240F7d', 0).call({ from: ... })

or

var record = await MyContractInstance.methods.records('0xDbB7d1Ed07F8D1D0C5D5bB9b9e427E997f240F7d', 0).call({ from: ... })

should work.

  • Thanks! What is the difference between Contract.method(params).call(options) and Contract.methods.method(params).call(options)? – Nyxynyx Jul 4 '18 at 4:04
  • Also, is it necessary to pass {from: ... }? The web3js docs say this sets The address the call “transaction” should be made from. Does this set the value of msg.sender, in the contract function and if so, isn't this spoofing a msg.sender if you can set any address that you like? – Nyxynyx Jul 4 '18 at 4:06
  • contract.methods.name.call() and contract.name.call() are exactly the same. 'from: ...' is not required since in case you will not provide it the default account would be used. You can't spoof it, in case of transaction your wallet must be unlocked and the transaction has to be confirmed from metamask (in case you use it). In your case is just a read, the status wouldn't be changed – mirg Jul 4 '18 at 4:09

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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