我正在使用truffle-webpack-demo,但自从我升级到 truffle 3.2.1 后开始出现错误。我找到了同一个 repo 的新分支并从那里复制了配置。哪个应该可以工作,但现在npm start
给了我以下错误。
Starting the development server...
Failed to compile.
Error in ./contracts/MetaCoin.sol
Module build failed: Error: You must specify the network name to deploy to. (network)
@ ./src/components/AccountList/AccountListContainer.js 37:16-49
我已经升级到以下版本的 truffle、webpack-dev-server、webpack 和 truffle-solidity-loader
truffle-solidity-loader: "git+https://github.com/sogoiii/truffle-solidity-loader.git#1f1e213d52f033b6863218307b8968ae68220fe1"
truffle: 3.2.1
webpack-dev-server: 2.4.1
webpack: 2.2.1
下面是我的配置/webpack.config.dev.js
var path = require('path')
var autoprefixer = require('autoprefixer')
var webpack = require('webpack')
var HtmlWebpackPlugin = require('html-webpack-plugin')
var precss = require('precss')
// TODO: hide this behind a flag and eliminate dead code on eject.
// This shouldn't be exposed to the user.
var isInNodeModules = path.basename(path.resolve(path.join(__dirname, '..', '..'))) === 'node_modules'
var relativePath = isInNodeModules ? '../../..' : '..'
var isInDebugMode = process.argv.some(arg =>
arg.indexOf('--debug-template') > -1
)
if (isInDebugMode) {
relativePath = '../template'
}
var srcPath = path.resolve(__dirname, relativePath, 'src')
var nodeModulesPath = path.join(__dirname, '..', 'node_modules')
var indexHtmlPath = path.resolve(__dirname, relativePath, 'index.html')
var faviconPath = path.resolve(__dirname, relativePath, 'favicon.ico')
var buildPath = path.join(__dirname, isInNodeModules ? '../../..' : '..', 'build')
var provided = {
'Web3': 'web3'
}
module.exports = {
devtool: 'eval',
entry: [
require.resolve('webpack-dev-server/client') + '?http://localhost:3000',
require.resolve('webpack/hot/dev-server'),
path.join(srcPath, 'index')
],
output: {
// Next line is not used in dev but WebpackDevServer crashes without it:
path: buildPath,
pathinfo: true,
filename: 'bundle.js',
publicPath: '/'
},
resolve: {
root: srcPath,
extensions: ['', '.js'],
alias: {
contracts: path.resolve('contracts'),
// config: require('../truffle').networks.development,
config: path.resolve('truffle.js')
}
},
module: {
preLoaders: [
{
test: /\.js$/,
loader: 'eslint',
include: srcPath
}
],
loaders: [
{
test: /\.js$/,
include: srcPath,
loader: 'babel',
query: require('./babel.dev')
},
{
test: /\.css$/,
include: srcPath,
loader: 'style!css!postcss'
},
{
test: /\.json$/,
loader: 'json'
},
{
test: /\.(jpg|png|gif|eot|svg|ttf|woff|woff2)$/,
loader: 'file'
},
{
test: /\.(mp4|webm)$/,
loader: 'url?limit=10000'
},
{
test: /\.sol/,
loader: 'truffle-solidity',
loaders: ['json-loader', 'truffle-solidity-loader?migrations_directory=' + path.resolve(__dirname, '../migrations') + '&network=development&contracts_build_directory=' + path.resolve(__dirname, '../dist/contracts')]
}
]
},
eslint: {
configFile: path.join(__dirname, 'eslint.js'),
useEslintrc: false
},
postcss: function () {
return [precss, autoprefixer]
},
plugins: [
new HtmlWebpackPlugin({
inject: true,
template: indexHtmlPath,
favicon: faviconPath
}),
new webpack.ProvidePlugin(provided),
new webpack.DefinePlugin({
'myEnv': JSON.stringify(require('../truffle').networks.development),
'process.env.NODE_ENV': '"development"'
}),
new webpack.EnvironmentPlugin(['NODE_ENV']),
new webpack.HotModuleReplacementPlugin()
]
}
这是我的 MetaCoin.sol
pragma solidity ^0.4.4;
import "./ConvertLib.sol";
// This is just a simple example of a coin-like contract.
// It is not standards compatible and cannot be expected to talk to other
// coin/token contracts. If you want to create a standards-compliant
// token, see: https://github.com/ConsenSys/Tokens. Cheers!
contract MetaCoin {
mapping (address => uint) balances;
event Transfer(address indexed _from, address indexed _to, uint256 _value);
function MetaCoin() {
balances[tx.origin] = 6000000000;
}
function sendCoin(address receiver, uint amount) returns(bool sufficient) {
if (balances[msg.sender] < amount) return false;
balances[msg.sender] -= amount;
balances[receiver] += amount;
Transfer(msg.sender, receiver, amount);
return true;
}
function getBalanceInEth(address addr) returns(uint){
return convert(getBalance(addr),2);
}
function getBalance(address addr) returns(uint) {
return balances[addr];
}
function convert(uint amount,uint conversionRate) returns (uint convertedAmount)
{
return amount * conversionRate;
}
}
这是我的 AccountListContainer.js
import React, { Component } from 'react'
import AccountList from 'components/AccountList/AccountList'
import SendCoin from 'components/SendCoin/SendCoin'
import Contract from 'truffle-contract'
import MetaCoinArtifact from 'contracts/MetaCoin.sol';
const MetaCoin = Contract(MetaCoinArtifact)
import Web3 from 'web3';
const provider = new Web3.providers.HttpProvider('http://localhost:8545')
MetaCoin.setProvider(provider);
class AccountListContainer extends Component {
constructor(props) {
super(props)
this.state = {
accounts: [],
coinbase: ''
}
this._getAccountBalance = this._getAccountBalance.bind(this)
this._getAccountBalances = this._getAccountBalances.bind(this)
}
_getAccountBalance (account) {
return MetaCoin.deployed()
.then(meta => {
return meta.getBalance.call(account, {from: account})
})
.then(function (value) {
return { account: value.valueOf() }
})
.catch(function (e) {
console.log(e)
throw e
})
}
_getAccountBalances () {
this.props.web3.eth.getAccounts(function (err, accs) {
if (err != null) {
window.alert('There was an error fetching your accounts.')
console.error(err)
return
}
if (accs.length === 0) {
window.alert("Couldn't get any accounts! Make sure your Ethereum client is configured correctly.")
return
}
this.setState({coinbase: accs[0]})
var accountsAndBalances = accs.map((account) => {
return this._getAccountBalance(account).then((balance) => { return { account, balance } })
})
Promise.all(accountsAndBalances).then((accountsAndBalances) => {
this.setState({accounts: accountsAndBalances, coinbaseAccount: accountsAndBalances[0]})
})
}.bind(this))
}
componentDidMount() {
const refreshBalances = () => {
this._getAccountBalances()
}
refreshBalances()
setInterval(()=>{
refreshBalances();
return refreshBalances
}, 5000)
}
render() {
return (
<div>
<AccountList accounts={this.state.accounts} />
<SendCoin sender={this.state.coinbase} />
</div>
)
}
}
export default AccountListContainer
这是truffle.js
module.exports = {
networks: {
development: {
host: "localhost",
port: 8545,
network_id: "*"
},
staging: {
host: "localhost",
port: 8546,
network_id: 1337
}
}
};