I have a simple lottery contract. When I call functions to it from Remix IDE I get the expected result. However, when I make calls to it from React, I get nothing back (such as from manager() or getPlayers()). I am, however, able to get the contract balance. I'm not sure what I'm doing wrong here but my code is below:
Lottery.sol:
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.7.0 <0.8.0;
contract Lottery {
address public manager;
address[] public players;
constructor() {
// The manager will be the person deploying the contract
manager = msg.sender;
}
modifier restrictedToManager() {
require(
msg.sender == manager,
"This function is restricted to the manager"
);
_;
}
function enter() public payable {
// Players must stake at least 0.01 ether to be entered into the lottery
require(
msg.value >= 0.01 ether,
"Players must stake at least 0.01 ether to be entered into the lottery"
);
players.push(msg.sender);
}
function random() private view returns (uint256) {
// Pseudo-random number generator
return
uint256(
keccak256(
abi.encodePacked(block.difficulty, block.timestamp, players)
)
);
}
function pickWinner() public payable restrictedToManager {
// Get a random player
uint256 index = random() % players.length;
// Pay the random player the balance on this contract
payable(players[index]).transfer(address(this).balance);
// Clear the array of players
players = new address[](0);
}
function getPlayers() public view returns (address[] memory) {
return players;
}
}
web.js
import Web3 from 'web3';
const web3 = new Web3(window.ethereum);
export default web3;
lottery.js
import web3 from './web3';
const address = '0x89a7a5d894797a6f26ACA2E5f2F3b39f29bB9f96';
const abi = [
{
inputs: [],
stateMutability: 'nonpayable',
type: 'constructor',
constant: undefined,
payable: undefined,
signature: 'constructor'
},
{
inputs: [],
name: 'enter',
outputs: [],
stateMutability: 'payable',
type: 'function',
constant: undefined,
payable: true,
signature: '0xe97dcb62'
},
{
inputs: [],
name: 'getPlayers',
outputs: [[Object]],
stateMutability: 'view',
type: 'function',
constant: true,
payable: undefined,
signature: '0x8b5b9ccc'
},
{
inputs: [],
name: 'manager',
outputs: [[Object]],
stateMutability: 'view',
type: 'function',
constant: true,
payable: undefined,
signature: '0x481c6a75'
},
{
inputs: [],
name: 'pickWinner',
outputs: [],
stateMutability: 'payable',
type: 'function',
constant: undefined,
payable: true,
signature: '0x5d495aea'
},
{
inputs: [[Object]],
name: 'players',
outputs: [[Object]],
stateMutability: 'view',
type: 'function',
constant: true,
payable: undefined,
signature: '0xf71d96cb'
}
];
export default new web3.eth.Contract(abi, address);
App.js
import './App.css';
import web3 from './web3';
import React, { useEffect, useState } from 'react';
import lottery from './lottery';
function App() {
const [manager, setManager] = useState('');
const [players, setPlayers] = useState([]);
const [balance, setBalance] = useState('');
const [value, setValue] = useState('');
const [loading, setLoading] = useState(false);
const [winMessage, setWinMessage] = useState('');
useEffect(() => {
async function loadWeb3() {
const manager = await lottery.methods.manager().call();
setManager(manager);
update();
}
loadWeb3();
}, []);
async function update() {
const players = await lottery.methods.getPlayers().call();
const balance = await web3.eth.getBalance(lottery.options.address);
setPlayers(players);
setBalance(balance);
}
async function onSubmit(event) {
event.preventDefault();
const accounts = await web3.eth.getAccounts();
setLoading(true);
await lottery.methods.enter().send({ from: accounts[0], value: web3.utils.toWei(value, 'ether') });
update();
setLoading(false);
}
async function onClick() {
const accounts = await web3.eth.getAccounts();
setLoading(true);
await lottery.methods.pickWinner().send({ from: accounts[0] });
update();
setWinMessage('A winner has been picked!');
setLoading(false);
}
return (
<div className="App">
<h2>Lottery Contract</h2>
<p>This contract is managed by {manager}.
There are currently {players.length} people entered,
competing to win {web3.utils.fromWei(balance, 'ether')} ether!
</p>
<hr />
{loading ? <p>Waiting for transaction to complete...</p> :
<div>
<form onSubmit={onSubmit}>
<h4>Want to try your luck?</h4>
<div>
<label>Amount of ether to enter</label>
<input
value={value}
onChange={event => setValue(event.target.value)}>
</input>
<button type="submit">Enter</button>
</div>
</form>
<hr />
<h4>Ready to pick a winner?</h4>
{winMessage && <h5>{winMessage}</h5>}
<button onClick={onClick}>Pick a winner!</button>
</div>
}
</div>
);
}
export default App;