一直在关注https://github.com/dappuniversity/starter_kit中的示例,但是当我尝试购买代币时,MetaMask 错误出现了。
$ truffle version Truffle v5.1.14 (core: 5.1.14) Solidity v0.5.16 (solc-js) Node v12.18.3 Web3.js v1.2.1 Ganache
本地运行自定义 RPC
我试图增加 GAS,但没有奏效。该项目的所有测试都通过了,所有合同都编译了,但我似乎无法让它发挥作用。任何帮助将不胜感激。谢谢
主.js
import React, { Component } from 'react';
import BuyForm from './BuyForm'
import SellForm from './SellForm'
class Main extends Component {
constructor(props) {
super(props)
this.state = {
currentForm: 'buy'
}
}
render() {
let content
if(this.state.currentForm === 'buy'){
content = <BuyForm
ethBalance={this.props.ethBalance}
tokenBalance={this.props.tokenBalance}
buyTokens={this.props.buyTokens}
/>
}else{
content = <SellForm
ethBalance={this.props.ethBalance}
tokenBalance={this.props.tokenBalance}
sellTokens={this.props.sellTokens}
/>
}
return (
<div id="content" className="mt-3">
<div className="d-flex justify-content-between mb-3">
<button
className="btn btn-light"
onClick={(event) => {
this.setState({ currentForm: 'buy'})
}}
>
Buy
</button>
<span className="text-muted">< ></span>
<button className="btn btn-light"
onClick={(event) => {
this.setState({ currentForm: 'sell'})
}}
>
Sell
</button>
</div>
<div className="card mb-4">
<div className="card-body">
{content}
</div>
</div>
</div>
);
}
}
export default Main;
应用程序.js
import React, { Component } from 'react';
import Web3 from 'web3';
import Token from '../abis/Token.json'
import EthSwap from '../abis/EthSwap.json'
import Navbar from './Navbar'
import Main from './Main'
import './App.css';
class App extends Component {
async componentWillMount() {
await this.loadWeb3()
await this.loadBlockchainData()
}
async loadBlockchainData(){
const web3 = window.web3
const accounts = await web3.eth.getAccounts()
this.setState({ account: accounts[0] })
const ethBalance = await web3.eth.getBalance(this.state.account)
this.setState({ ethBalance })
//Load Token
const networkId = await web3.eth.net.getId()
const tokenData = Token.networks[networkId]
if(tokenData){
const token = new web3.eth.Contract(Token.abi, tokenData.address)
this.setState({token})
let tokenBalance = await token.methods.balanceOf(this.state.account).call()
this.setState({tokenBalance: tokenBalance.toString() })
}
else {
window.alert('Token contract not deployed to detected network')
}
//Load EthSwap
const ethSwapData = EthSwap.networks[networkId]
if(ethSwapData){
const ethSwap = new web3.eth.Contract(EthSwap.abi, tokenData.address)
this.setState({ethSwap})
}
else {
window.alert('EthSwap contract not deployed to detected network')
}
this.setState({loading: false})
}
async loadWeb3() {
if (window.ethereum) {
window.web3 = new Web3(window.ethereum)
await window.ethereum.enable()
}
else if (window.web3) {
window.web3 = new Web3(window.web3.currentProvider)
}
else {
window.alert('Non-Ethereum browser detected. You should consider trying MetaMask')
}
}
buyTokens = (etherAmount) => {
this.setState({ loading: true})
this.state.ethSwap.methods.buyTokens().send({value: etherAmount, from: this.state.account}).on('transactionHash', (hash) => {
this.setState({loading: false})
})
}
sellTokens = (tokenAmount) => {
this.setState({ loading: true})
this.state.token.methods.approve(this.state.ethSwap.address, tokenAmount)
.send({ from: this.state.account}).on('transactionHash', (hash) => {
this.state.ethSwap.methods.sellTokens(tokenAmount).send({ from:
this.state.account}).on('transactionHash',(hash) =>{
this.setState({loading: false})
})
})
}
constructor(props) {
super(props)
this.state = {
account:'',
token: {},
ethSwap: {},
ethBalance:'0',
tokenBalance:'0',
loading: false
}
}
render() {
let content
if(this.state.loading){
content = <p id="loader" className="text-center">Loading...</p>
}else {
content = <Main
ethBalance={this.state.ethBalance}
tokenBalance={this.state.tokenBalance}
buyTokens= {this.buyTokens}
sellTokens={this.sellTokens}
/>
}
return (
<div>
<Navbar account={this.state.account} />
<div className="container-fluid mt-5">
<div className="row">
<main role="main" className="col-lg-12 ml-auto mr-auto" style={{maxWidth: '600px'}}>
<div className="content mr-auto ml-auto">
<a
href="http://www.dappuniversity.com/bootcamp"
target="_blank"
rel="noopener noreferrer"
>
</a>
{content}
</div>
</main>
</div>
</div>
</div>
);
}
}
export default App;
合同:
EthSwap.sol
pragma solidity ^0.5.0;
import "./Token.sol";
contract EthSwap {
string public name = "EthSwap Instant Exchange";
Token public token;
uint public rate = 100;
event TokensPurchased(
address account,
address token,
uint amount,
uint rate
);
event TokensSold(
address account,
address token,
uint amount,
uint rate
);
constructor(Token _token) public {
token = _token;
}
function buyTokens() public payable {
//Calculate the number of tokens to buy
uint tokenAmount = msg.value * rate;
//Require that EthSwap has enough tokens
require(token.balanceOf(address(this)) >= tokenAmount);
//Transer tokens to the user
token.transfer(msg.sender, tokenAmount);
//Emit on event
emit TokensPurchased(msg.sender, address(token), tokenAmount, rate);
}
function sellTokens(uint _amount) public {
//Uswer can't sell more tokens than they have
require(token.balanceOf(msg.sender) >= _amount);
// Calculate the amount of Ether to redeem
uint etherAmount = _amount / rate;
//Require that EthSwap has enough ether
require(address(this).balance >= etherAmount);
//Perform sale
token.transferFrom(msg.sender, address(this), _amount);
msg.sender.transfer(etherAmount);
//Emit on event
emit TokensSold(msg.sender, address(token), _amount, rate);
}
}
令牌.sol
pragma solidity ^0.5.0;
contract Token {
string public name = "DApp Token";
string public symbol = "DAPP";
uint256 public totalSupply = 1000000000000000000000000; // 1 million tokens
uint8 public decimals = 18;
event Transfer(
address indexed _from,
address indexed _to,
uint256 _value
);
event Approval(
address indexed _owner,
address indexed _spender,
uint256 _value
);
mapping(address => uint256) public balanceOf;
mapping(address => mapping(address => uint256)) public allowance;
constructor() public {
balanceOf[msg.sender] = totalSupply;
}
function transfer(address _to, uint256 _value) public returns (bool success) {
require(balanceOf[msg.sender] >= _value);
balanceOf[msg.sender] -= _value;
balanceOf[_to] += _value;
emit Transfer(msg.sender, _to, _value);
return true;
}
function approve(address _spender, uint256 _value) public returns (bool success) {
allowance[msg.sender][_spender] = _value;
emit Approval(msg.sender, _spender, _value);
return true;
}
function transferFrom(address _from, address _to, uint256 _value) public returns (bool success) {
require(_value <= balanceOf[_from]);
require(_value <= allowance[_from][msg.sender]);
balanceOf[_from] -= _value;
balanceOf[_to] += _value;
allowance[_from][msg.sender] -= _value;
emit Transfer(_from, _to, _value);
return true;
}
}