Skip to content

Instantly share code, notes, and snippets.

@jdaly13
Created April 28, 2020 20:38
Show Gist options
  • Save jdaly13/cdeceb794099e4d44fc8e2ba4b56f95e to your computer and use it in GitHub Desktop.
Save jdaly13/cdeceb794099e4d44fc8e2ba4b56f95e to your computer and use it in GitHub Desktop.
react application for donating on ethereum blockchain part of ethereum-blockchain-developing-applications tutorial on pluralsight
import React, { Component } from 'react';
import { Button, Input, Table } from 'semantic-ui-react'
import { createContract } from './../ethereum/crowdfundingContract'
import { web3 } from './../ethereum/web3';
export class Campaign extends Component {
ONGOING_STATE = '0'
FAILED_STATE = '1'
SUCCEEDED_STATE = '2'
PAID_OUT_STATE = '3'
state = {
campaign: {
name: 'N/A',
targetAmount: 0,
totalCollected: 0,
campaignFinished: false,
deadline: new Date(0),
isBeneficiary: false,
state: ''
},
contributionAmount: '0',
}
contract = {};
constructor(props) {
super(props)
this.onContribute = this.onContribute.bind(this);
this.finishCampaign = this.finishCampaign.bind(this);
this.giveToBeneficiary = this.giveToBeneficiary.bind(this);
this.withdraw = this.withdraw.bind(this);
}
async componentDidMount() {
const currentCampaign = await this.getCampaign(this.getCampaignAddress());
this.setState({
campaign: currentCampaign
})
}
async finishCampaign(e) {
const accounts = await web3.eth.getAccounts()
try {
const receipt = await this.contract.methods.finishCrowdFunding().send({
from: accounts[0]
});
console.log('receipt', receipt);
const state = await this.contract.methods.state().call();
this.setState({
campaign: Object.assign({}, this.state.campaign, {state})
});
} catch(e) {
console.warn('error', e);
}
}
async giveToBeneficiary() {
const accounts = await web3.eth.getAccounts();
try {
const receipt = await this.contract.methods.collect().send({
from: accounts[0]
});
console.log(receipt);
const state = await this.contract.methods.state().call();
this.setState({
campaign: Object.assign({}, this.state.campaign, {state})
});
} catch (e) {
console.warn('error', e);
}
}
async withdraw() {
const accounts = await web3.eth.getAccounts()
try {
const receipt = await this.contract.methods.withdraw().send({
from: accounts[0]
})
console.log(receipt);
} catch (e) {
console.warn('error');
}
}
getCampaignAddress() {
return this.props.match.params.address
}
async getCampaign(address) {
this.contract = createContract(address)
const name = await this.contract.methods.name().call()
const targetAmount = await this.contract.methods.targetAmount().call()
const totalCollected = await this.contract.methods.totalCollected().call()
const beforeDeadline = await this.contract.methods.beforeDeadline().call()
const beneficiary = await this.contract.methods.beneficiary().call()
const deadlineSeconds = await this.contract.methods.fundingDeadline().call()
const state = await this.contract.methods.state().call()
console.log('before deadline', beforeDeadline); //FIX THIS IN SOLIDITY
var deadlineDate = new Date(0);
var accounts = [];
deadlineDate.setUTCSeconds(deadlineSeconds)
await window.ethereum.enable()
accounts = await web3.eth.getAccounts();
return {
name: name,
targetAmount: targetAmount,
totalCollected: totalCollected,
campaignFinished: new Date() > deadlineDate, //!beforeDeadline
deadline: deadlineDate,
isBeneficiary: beneficiary.toString().toLowerCase() === accounts[0].toLowerCase(),
state: state
}
}
campaignInteractionSection() {
if (this.state.campaign.campaignFinished) {
return this.postCampaignInterface()
} else {
return this.contributeInterface()
}
}
postCampaignInterface() {
if (this.state.campaign.state === this.ONGOING_STATE) {
return <div>
<Button type='submit' onClick={this.finishCampaign} positive>Finish campaign</Button>
</div>
}
if (this.state.campaign.state === this.SUCCEEDED_STATE
&& this.state.campaign.isBeneficiary === true) {
return <div>
<Button type='submit' onClick={this.giveToBeneficiary} negative>Collect funds</Button>
</div>
}
if (this.state.campaign.state === this.FAILED_STATE) {
return <div>
<Button type='submit' onClick={this.withdraw} negative>Refund</Button>
</div>
}
if (this.state.campaign.state === this.PAID_OUT_STATE) {
return (
<h1>Your Campiagn is complete</h1>
)
}
}
contributeInterface() {
return <div>
<Input
action={{
color: 'teal',
content: 'Contribute',
onClick: this.onContribute
}}
actionPosition='left'
label='ETH'
labelPosition='right'
placeholder='1'
onChange={(e) => this.setState({contributionAmount: e.target.value})}
/>
</div>
}
async onContribute(event) {
const accounts = await web3.eth.getAccounts()
const amount = web3.utils.toWei(
this.state.contributionAmount,
'ether'
)
const receipt = await this.contract.methods.contribute().send({
from: accounts[0],
value: amount
})
console.log(receipt);
const campaign = this.state.campaign
campaign.totalCollected = Number.parseInt(campaign.totalCollected) + Number.parseInt(amount)
this.setState({ campaign: campaign })
}
render() {
return (
<div>
<Table celled padded color="teal" striped>
<Table.Header>
<Table.Row>
<Table.HeaderCell>Name</Table.HeaderCell>
<Table.HeaderCell>Value</Table.HeaderCell>
</Table.Row>
</Table.Header>
<Table.Body>
<Table.Row>
<Table.Cell singleLine>
Name
</Table.Cell>
<Table.Cell singleLine>
{this.state.campaign.name}
</Table.Cell>
</Table.Row>
<Table.Row>
<Table.Cell singleLine>
Target amount
</Table.Cell>
<Table.Cell singleLine>
{this.state.campaign.targetAmount}
</Table.Cell>
</Table.Row>
<Table.Row>
<Table.Cell singleLine>
Total collected
</Table.Cell>
<Table.Cell singleLine>
{this.state.campaign.totalCollected}
</Table.Cell>
</Table.Row>
<Table.Row>
<Table.Cell singleLine>
Has finished
</Table.Cell>
<Table.Cell singleLine>
{this.state.campaign.campaignFinished.toString()}
</Table.Cell>
</Table.Row>
<Table.Row>
<Table.Cell singleLine>
Deadline
</Table.Cell>
<Table.Cell singleLine>
{this.state.campaign.deadline.toString()}
</Table.Cell>
</Table.Row>
<Table.Row>
<Table.Cell singleLine>
I am beneficiary
</Table.Cell>
<Table.Cell singleLine>
{this.state.campaign.isBeneficiary.toString()}
</Table.Cell>
</Table.Row>
<Table.Row>
<Table.Cell singleLine>
Contract state
</Table.Cell>
<Table.Cell singleLine>
{this.state.campaign.state}
</Table.Cell>
</Table.Row>
</Table.Body>
<Table.Footer fullWidth>
<Table.Row>
<Table.HeaderCell colSpan="2">
{this.campaignInteractionSection()}
</Table.HeaderCell>
</Table.Row>
</Table.Footer>
</Table>
</div>
);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment