0

My Lottery contract code:

   contract Lottery {
    address public manager;
    address[] public players;

    constructor () {
        manager = msg.sender;
    }

In the above code, I declared a public address variable manager. The frontend code :

   useEffect(() => {
    (async () => {
      const manager = await lottery.methods.manager().call();
      console.log(manager);
    })();
  }, []);

Whenever I access the manager(), I expect the address of the person who deployed the contract but I get the following in the console

__length__: 
 0[[Prototype]]: 
  Objectconstructor: ƒ Object()
  hasOwnProperty: ƒ hasOwnProperty()
  isPrototypeOf: ƒ isPrototypeOf()
  propertyIsEnumerable: ƒ propertyIsEnumerable()
  toLocaleString: ƒ toLocaleString()
  toString: ƒ toString()
  length: 0name: "toString" arguments: (...)caller: (...)[[Prototype]]: ƒ ()[[Scopes]]: 
   Scopes[0]
  valueOf: ƒ valueOf()
  __defineGetter__: ƒ __defineGetter__()
  __defineSetter__: ƒ __defineSetter__()
  __lookupGetter__: ƒ __lookupGetter__()
  __lookupSetter__: ƒ __lookupSetter__() 
  __proto__: (...)
  get __proto__: ƒ __proto__()
  set __proto__: ƒ __proto__()

When I call the manager in remix IDE, I get the address of the deployer. I am currently learning solidity. Any help is appreciated.

The entire contract code for ref:

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

contract Lottery {
    address public manager;
    address[] public players;

    constructor () {
        manager = msg.sender;
    }

    function enter() public payable {
        require(msg.value > 0.01 ether, "Enter atleast 0.01 Ether");
        players.push(msg.sender);
    } 

    function random() private view returns (uint) {
        return uint(keccak256(abi.encodePacked(msg.sender, block.timestamp, players)));
    }
    
    function pickWinner() public restricted {
        uint index = random() % players.length;
        payable(players[index]).transfer(address(this).balance);
        players = new address[](0);
    }

    modifier restricted() {
        require(msg.sender == manager, "The Function can only be called by the manager of the contract");
        _;
    }

    function getPlayers() public view returns (address[] memory){
        return players;
    }
}  

4 Answers 4

0

There is no problem with your solidity code. I think problem from your js code. Please try this abi, it's from remix when you compile your code

[
    {
        "inputs": [],
        "name": "enter",
        "outputs": [],
        "stateMutability": "payable",
        "type": "function"
    },
    {
        "inputs": [],
        "name": "pickWinner",
        "outputs": [],
        "stateMutability": "nonpayable",
        "type": "function"
    },
    {
        "inputs": [],
        "stateMutability": "nonpayable",
        "type": "constructor"
    },
    {
        "inputs": [],
        "name": "getPlayers",
        "outputs": [
            {
                "internalType": "address[]",
                "name": "",
                "type": "address[]"
            }
        ],
        "stateMutability": "view",
        "type": "function"
    },
    {
        "inputs": [],
        "name": "manager",
        "outputs": [
            {
                "internalType": "address",
                "name": "",
                "type": "address"
            }
        ],
        "stateMutability": "view",
        "type": "function"
    },
    {
        "inputs": [
            {
                "internalType": "uint256",
                "name": "",
                "type": "uint256"
            }
        ],
        "name": "players",
        "outputs": [
            {
                "internalType": "address",
                "name": "",
                "type": "address"
            }
        ],
        "stateMutability": "view",
        "type": "function"
    }
]
1
  • The ABI provided works fine. The ABI that was created by solidity compiler using solc v0.8.19 had ``` { inputs: [], name: 'manager', outputs: [ [Object] ], stateMutability: 'view', type: 'function' } ``` Why was the abi created in this way that the output is set to return object?
    – DarkL
    Apr 8 at 11:32
0

I changed the ABI from

  {
    inputs: [],
    name: 'manager',
    outputs: [ [Object] ],
    stateMutability: 'view',
    type: 'function'
  }

to

 {
    inputs: [],
    name: "manager",
    outputs: [{ name: "", type: "address" }],
    stateMutability: "view",
    type: "function",
  }

I don't know whether it is the right thing to mess with the ABI but it now returns the address instead of an object. If there is a 'real' fix please let me know

3
  • Where are you getting your ABI from? Apr 8 at 7:36
  • The ABI was received using solc v0.8.19 installed from node package manager. By using the following code const compiledContract = JSON.parse(solc.compile(JSON.stringify(input))) .contracts["Lottery.sol"].Lottery; const abi = compiledContract.abi; console.log(abi);
    – DarkL
    Apr 8 at 11:37
  • Please check my answer. Apr 8 at 12:34
0

In constructor, you did set the manager as the deployer. Hence will return the deployer address.


    constructor () {
        manager = msg.sender; //deployer
    }
1
  • Thumbs up if it helps :D Apr 8 at 9:16
0

While you're generating the ABI using solc in Javascript and then logging it, it's wrapping up all the Object types when using console.log().

In order to ensure unlimited recursion while logging the ABI, you might have to use console.dir:

console.dir(abi, { depth: null }); // `depth: null` ensures unlimited recursion

Here's the full code snippet for the same (provided your Lottery contract is inside Lottery.sol file):

const solc = require("solc");
const fs = require("fs");

const source = fs.readFileSync("Lottery.sol", "utf8");

var input = {
    language: "Solidity",
    sources: { "Lottery.sol": { content: source } },
    settings: {
        outputSelection: {
            "*": {
                "*": ["*"]
            }
        }
    }
};

const output = JSON.parse(solc.compile(JSON.stringify(input)));

const abi = output.contracts["Lottery.sol"]["Lottery"].abi;

console.dir(abi, { depth: null });  // `depth: null` ensures unlimited recursion
2
  • Sorry for replying so late. The problem here occurs when I call the contract's method using lottery.methods.func_name().call(); Where lottery is the name of the contract. Before changing the ABI, the output was an object. After changing the ABI I am getting a proper output which is whether a string or number. I don't know why but the ABI generated by RemixIDE was different from the one that was created through solc npm package. When the ABI was replaced with the one of Remix, it works normally. I don't know the exact reason for this behaviour.
    – DarkL
    Apr 17 at 1:49
  • I think that’s what I’ve addressed in my answer. While you’re logging the ABI using solc, you’re logging it directly using console.log(abi). But, if you log it using console.dir(abi, {depth: null}), then it’ll give you the exactly similar output as what you’re getting using Remix IDE. Apr 17 at 6:48

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.