我目前正在尝试从头开始编写一个 dapp,使用 Dapp 大学的 EthSwap ( https://github.com/dappuniversity/eth_swap ) 作为模型(基本上是在不查看他的代码的情况下尝试重新创建这个 dapp)。基本上,dapp 只允许你购买 erc20 代币。它似乎确实有效,但它确实很慢。我认为这可能是 react 的一个问题,因为我目前是该框架的新手,并且可能陷入了一些性能问题。我尝试了以下方法以确保消除其他原因:
- 更改浏览器(Chrome --> Brave)并在两者上安装和使用元掩码
- 从 ganache gui 切换到 ganache-cli
- 我将与 web3 的连接视为一个单独的组件并导入它,但最后只是将此代码放入 App.js
这是我的代码:
// App.js
import './App.css';
import PageNavbar from './components/PageNavbar';
import TokenExchangeForm from './components/TokenExchangeForm';
import Web3 from 'web3';
import { useContext, useState, useEffect } from 'react';
import GenericToken from './abis/GenericToken.json';
import TokenExchange from './abis/TokenExchange.json';
function App() {
const [account, setAccount] = useState('');
const [ethBalance, setEthBalance] = useState('');
const [tokenBalance, setTokenBalance] = useState('');
const [genericToken, setGenericToken] = useState(null);
const [tokenExchange, setTokenExchange] = useState(null);
useEffect(() => {
const init = async () => {
await getWeb3();
await getBlockchainData();
}
init();
});
const getBlockchainData = async () => {
const web3 = window.web3
let retrievedAccounts = await web3.eth.getAccounts();
setAccount(retrievedAccounts[0]);
let ethBalance = await web3.eth.getBalance(retrievedAccounts[0]);
setEthBalance(web3.utils.fromWei(ethBalance.toString(), 'Ether'));
let networkId = await web3.eth.net.getId()
let genericTokenData = GenericToken.networks[networkId];
let tokenExchangeData = TokenExchange.networks[networkId];
let genericToken = new web3.eth.Contract(GenericToken.abi, genericTokenData.address);
setGenericToken(genericToken);
let tokenExchange = new web3.eth.Contract(TokenExchange.abi, tokenExchangeData.address);
setTokenExchange(tokenExchange);
let tokenBalance = await genericToken.methods.balanceOf(retrievedAccounts[0]).call();
setTokenBalance(web3.utils.fromWei(tokenBalance.toString(), 'Ether'));
}
const getWeb3 = async () => {
if (window.ethereum) {
window.web3 = new Web3(window.ethereum);
try {
await window.ethereum.request({ method: 'eth_requestAccounts' });
} catch (err) {
console.log('Transaction rejected by user:', err)
}
}
else if (window.web3) {
window.web3 = new Web3(window.web3.currentProvider);
}
else {
console.log('Non-Ethereum browser detected. You should consider trying MetaMask!');
}
}
let buy = (etherAmount) => {
//const gasEstimate = await tokenExchange.methods.buy().estimateGas({ from: account, value: window.web3.utils.toWei(etherAmount, 'ether') });
//const gasPriceEstimate = await window.web3.eth.getGasPrice();
tokenExchange.methods.buy().send({ from: account, value: window.web3.utils.toWei(etherAmount, 'Ether')});
}
return (
<div className="App">
<PageNavbar title='Token Exchange' account={account}/>
<TokenExchangeForm ethBalance={ethBalance} tokenBalance={tokenBalance} buy={buy}></TokenExchangeForm>
</div>
);
}
export default App;
// TokenExchangeForm.js
import Card from 'react-bootstrap/Card';
import Container from 'react-bootstrap/esm/Container';
import Form from 'react-bootstrap/Form';
import Button from 'react-bootstrap/Button';
import { useState } from 'react';
import ExchangeField from './ExchangeField';
const TokenExchangeForm = (props) => {
const [etherValue, setEtherValue] = useState('');
const [tokenValue, setTokenValue] = useState('');
const changeHandlerEth = (event) => {
setEtherValue(event.target.value);
}
const changeHandlerToken = (event) => {
setTokenValue(window.web3.utils.fromWei(etherValue, 'Ether'));
}
const submitHandlerBuy = (event) => {
event.preventDefault();
props.buy(etherValue);
}
return(
<Container>
<Card id="centered-form">
<Form onSubmit={submitHandlerBuy}>
<Container>
<br />
<ExchangeField label ='Input' balance={props.ethBalance} value={props.etherValue} onChange={changeHandlerEth} placeholder='0' appendtext ="ETH"/>
<br/>
<ExchangeField label='Output' balance={props.tokenBalance} value={props.tokenValue} onChange={changeHandlerToken} placeholder='0' appendtext="GT"/>
<br />
<Form.Row>
<Form.Label>Exchange Rate</Form.Label>
<Form.Label className='add-space'>1 ETH = 100 GT</Form.Label>
</Form.Row>
<br />
<Button type='submit' variant="primary" size="lg" className ="w-100" block>
SWAP
</Button>
</Container>
</Form>
</Card>
</Container>
);
}
export default TokenExchangeForm;