Hello all I'm learning the basics of react, and how to program in solidity. I recently completed this smart contract that functions as a lottery and have full functionality. I have gone back and now want to display the address of the winner who will receive the funds from the lottery but have encountered this error
./src/App.js Line 22: 'lastWinner' is not defined no-undef
Search for the keywords to learn more about each error.
Here is the main react component *note- have have starred/ bolded the area where the error is
import React, { Component } from 'react';
//import logo from './logo.svg';
import './App.css';
import web3 from './web3';
import lottery from './lottery';
class App extends Component {
state ={
manager: ' ',
players: [] , // players set to empty array
balance: ' ',
value: ' ',
message: ' ',
**lastWinner:' ',**
}; //inatilizing state
async componentDidMount() {
const manager = await lottery.methods.manager().call();// retrieve manager from ETH ntwrk
const winner = await lottery.methods.pickWinner().call(); // displays last winner address
const players = await lottery.methods.getPlayer().call(); // get number of players
const balance = await web3.eth.getBalance(lottery.options.address); // get contract's balance
this.setState({manager, players, balance, **lastWinner**});// set state object
}
onSubmit= async (event) => { // function that calls contract entry
event.preventDefault(); //makes sure form doesnt auto submit itself
const accounts = await web3.eth.getAccounts(); // get accounts enterd in lotto
this.setState({message: 'Waiting on transaction to be processed'}); //tells users whats going on with application
//asume 1st account in array is entering lotto
await lottery.methods.enter().send({
from: accounts [0],
value: web3.utils.toWei(this.state.value, 'ether')
});
this.setState({message: 'You have been entered'}); // update message
};
onClick = async () => {
const accounts = await web3.eth.getAccounts(); // get accounts enterd in lotto
this.setState({message: 'Waiting on transaction to be processed'});
await lottery.methods.pickWinner().send({ // calls picks winner function
from: accounts[0]
});
this.setState({message: 'Winner has been picked'});
};
render() {
return (
<div>
<h2>Lottery Contract</h2>
<p>
This contract is managed by {this.state.manager}.
Currently {this.state.players.length} people entered in the lottery.
The lottery is valued at {web3.utils.fromWei(this.state.balance, 'ether')} ether!
The last person to win was: {this.state.lastWinner}.
</p>
<hr/>
<form onSubmit ={this.onSubmit}>
<h4>Want to try your luck?</h4>
<div>
<label>Amount of ETH to enter. </label>
<input
value = {this.state.value}
onChange={event => this.setState({value: event.target.value })} // updates a prop. called value which hold amount of ether
/>
</div>
<button>Enter</button>
</form>
<hr/>
<h4>Ready to Pick a winner?</h4>
<button onClick={this.onClick}> Pick~Winner</button>
<hr/>
<h1>{this.state.message}</h1>
</div>
);
}
}
export default App;
also here is my code for the Ethereum Contract
pragma solidity ^0.4.17;
contract Lottery{
address public manager;
address[] public players;
address public lastWinner;
function Lottery() public{ // starting of lottery creation contract. assigns the person who calls this contract as manager.
manager = msg.sender;
}
function enter() public payable { // entry function to contract- requires that entrants must submit at lesat .01ETH
require(msg.value > 0.01 ether);
players.push(msg.sender);
}
function random() private view returns (uint){ // function that CALCULATES a winner based on current block diff. present time, and # of players
return uint(keccak256(block.difficulty, now, players));//note* ispsudo random, can be reverse engineered.
}
function pickWinner() public restricted{ //inclusion of function modifier named 'restricted'
//require (msg.sender == manager); --Including the function modifier 'restriced' reduces the need for this duplicate line
uint index = random() % players.length; //uses random calculation and modulods op to calculate a winner from index of players
players[index].transfer(this.balance); //sends lottery funds to the index positioned winner
players = new address[](0); // resets players in contract index back to 0
lastWinner = players[index]; // records address of person who last won lottery
lastWinner = msg.sender;
//return lastWinner;
}
modifier restricted(){ // function modifier- purpose to reduce the need for repetitive code. can be applied on any function
require (msg.sender == manager);
_;
}
function getPlayer()public view returns(address[]){ //function that returns the full list of players entered into the lottery
return players; // public- seen by everyone~ view- does not modify contract data~ should return a dynamic array of addys.
}
}
In the line:
this.setState({manager, players, balance, **lastWinner**});// set state object
You are trying to pass in a variable called lastWinner
but the variable you defined for the winner is called winner
:
const winner = await lottery.methods.pickWinner().call(); // displays last winner address
Either change the variable name to lastWinner:
const lastWinner = await lottery.methods.pickWinner().call(); // displays last winner address
Or pass in the winner
variable with the lastWinner key:
this.setState({manager, players, balance, lastWinner: winner});