我有一个用NodeJS编写的应用程序,每次启动它都必须部署一个智能契约。一旦部署了契约,这个应用程序将与它交互,进行一些事务处理并侦听其事件。
关于事务处理、调用智能契约函数和侦听事件的部分工作正常,我曾经无法做的一件事就是使用NodeJS部署智能契约。
要部署它,我必须通过命令行使用块菌,然后启动我的NodeJS应用程序,将智能契约地址传递给它。就这样一切都很好。
通过直接从NodeJS应用程序运行控制台命令(process,捕捉其输出,解析字符串并找到合同地址),我找到了一个非常糟糕的解决方法。还有..。是的,它有效!)。
很明显我试过通过恩弗拉做这件事,但没有成功。为什么?我不知道,但我可以解释我做了什么。由于部署智能契约不亚于进行正常事务,所以我准备好了它,签署了它,并以与前面提到的其他正常事务和合同函数调用相同的方式发送它。看上去很管用!但每次我都会犯两个类似的错误:
我几乎可以肯定,这不是关于气体的问题,而是在准备过程中的其他错误--准备>标志>发送。
请注意,我没有必要在每次运行时编译智能契约!ABI和字节码在每次运行时都是相同的,因此在没有重新编译的情况下迁移/部署它就足够了。
这是NodeJS中用于部署智能契约的函数的代码,它失败并返回气体错误:
const amountToSend = 0.010000;
const contract_PrintProofOfWork = new web3.eth.Contract(contractAbi, process.env.SMART_CONTRACT_ADDRESS, {
from: web3.eth.defaultAccount,
gasPrice: '10000000'
});
async function getBalance(address) {
let destinationBalanceWei = await web3.eth.getBalance(address);
let destinationBalance = web3.utils.fromWei(destinationBalanceWei, 'ether');
return destinationBalance;
}
const getCurrentGasPrices = async () => {
let response = await axios.get('https://ethgasstation.info/json/ethgasAPI.json');
let prices = {
low: response.data.safeLow / 10,
medium: response.data.average / 10,
high: response.data.fast / 10
};
log("\r\n");
log('Current ETH Gas Prices (in GWEI):');
log(`Low: ${prices.low} (transaction completes in < 30 minutes)`);
log(`Standard: ${prices.medium} (transaction completes in < 5 minutes)`);
log(`Fast: ${prices.high} (transaction completes in < 2 minutes)`);
log("\r\n");
return prices
};
// This function is used to deploy contract
const deploy = async () => {
log(process.env.WALLET_ADDRESS);
log(`Local PC wallet balance is currently ${await getBalance(web3.eth.defaultAccount)} ETH`.cyan);
let deploy = contract_PrintProofOfWork.deploy({
data: contractByteCode
//arguments: []
}).encodeABI();
let nonce = await web3.eth.getTransactionCount(web3.eth.defaultAccount);
log(`The outgoing transaction count for your wallet address is: ${nonce}`.yellow);
// Fetch the current transaction gas prices from https://ethgasstation.info/
let gasPrices = await getCurrentGasPrices();
// Build a new transaction object and sign it locally
let transactionObject = {
"to": process.env.DESTINATION_WALLET_ADDRESS,
"value": web3.utils.toHex(web3.utils.toWei(amountToSend.toString(), 'ether')),
"gas": 8000000,
"gasPrice": gasPrices.high * 1000000000, // converts the gwei price to wei
"nonce": nonce,
"chainId": 3 // EIP 155 chainId - mainnet: 1, ropsten: 3, rinkeby: 4 (https://ethereum.stackexchange.com/questions/17051/how-to-select-a-network-id-or-is-there-a-list-of-network-ids/17101#17101)
};
web3.eth.accounts.signTransaction(transactionObject, process.env.WALLET_PRIVATE_KEY, function (error, signedTx) {
if (error) {
log(`${error}`.red);
} else {
web3.eth.sendSignedTransaction(signedTx.rawTransaction)
.on('confirmation', function (number) {//dostuff
log(`Success: ${number}`.green);
});
// Note this address. It will be used to create contract instance from Angular 5 application.
//console.log("contract deployed to", result.options.address);
}
}).catch(function(err){
log(`${err}`.red);
});
};
// Call deploy function.
deploy();错误:
(节点:23315) UnhandledPromiseRejectionWarning:错误:节点错误:{“代码”:-32000,“消息”:“资金不足用于天然气*价格+价值”} (/Users/sahelanthropus/IdeaProjects/ThesisPrototype/prototype-local-simple/node_modules/web3-providers/dist/web3-providers.cjs.js:349:18) at /Users/sahelanthropus/IdeaProjects/ThesisPrototype/prototype-local-simple/node_modules/web3-providers/dist/web3-providers.cjs.js:692:57 at processTicksAndRejections ( Function.validate /process/next_tick.js:81:5)
或者如果我举起要用的气体:
(节点:23329) UnhandledPromiseRejectionWarning:错误:节点错误:{“代码”:-32000,在(/Users/sahelanthropus/IdeaProjects/ThesisPrototype/prototype-local-simple/node_modules/web3-providers/dist/web3-providers.cjs.js:349:18) at /Users/sahelanthropus/IdeaProjects/ThesisPrototype/prototype-local-simple/node_modules/web3-providers/dist/web3-providers.cjs.js:692:57 at processTicksAndRejections ( Function.validate /process/next_tick.js:81:5),“message”:“超过区块气体限值”}
有人能简单地告诉我如何使用web3js e Infura部署智能契约吗?即使不参考我在这个问题中暴露的代码和问题?
更新:

发布于 2019-02-25 19:40:19
这就是我工作时的样子:
PS C:\Projects\Eth_Dev\simple> ls
Directory: C:\Projects\Eth_Dev\simple
Mode LastWriteTime Length Name
---- ------------- ------ ----
d----- 27/02/2019 21:25 contracts
d----- 27/02/2019 21:22 node_modules
d----- 27/02/2019 21:25 test
-a---- 27/02/2019 21:25 691 compile.js
-a---- 27/02/2019 21:29 907 deploy.js
-a---- 27/02/2019 21:22 152654 package-lock.json
-a---- 27/02/2019 21:28 339 package.jsonpackage.json的内容:
{
"name": "myContract",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "mocha"
},
"author": "",
"license": "ISC",
"dependencies": {
"ganache-cli": "^6.2.5",
"mocha": "^5.2.0",
"solc": "^0.4.25",
"truffle-hdwallet-provider": "0.0.3",
"web3": "^1.0.0-beta.35"
}
}除了npm install之外,我唯一需要运行的其他命令是npm install --global --production windows-build-tools。
contracts\myContract.sol含量
pragma solidity ^0.4.17;
contract MyContract {
string public message;
function MyContract(string initialMessage) public {
message = initialMessage;
}
function setMessage(string newMessage) public {
message = newMessage;
}
}这是一个似乎有效的deploy.js脚本。运行“节点deploy.js”将部署到Rinkeby网络
const HDWalletProvider = require('truffle-hdwallet-provider');
const Web3 = require('web3');
const {interface, bytecode} = require('./compile');
const provider = new HDWalletProvider(
'your twelve word mnemonic',
'https://rinkeby.infura.io/v3/YOUR_API_KEY'
);
const web3 = new Web3(provider);
const deploy = async () => {
const accounts = await web3.eth.getAccounts();
console.log('Attempting to deploy from account', accounts[0]);
const result = await new web3.eth.Contract(JSON.parse(interface))
.deploy({data:bytecode, arguments:['This is deployed!']})
.send({gas:'1000000', from: accounts[0]});
console.log('Contract deployed to ', result.options.address);
};
deploy();有一个对编译文件的引用。compile.js看起来如下所示:
const path = require('path'); //builds a path from the current file.
const fs = require('fs');
//Need the solidity compiler
const solc = require('solc');
//__dirname will get the inbox dir path.
//look in the contracts folder and get a path to the Inbox.sol file.
const myContractPath = path.resolve(__dirname,'contracts','myContract.sol');
//Read in the contents of the file. The raw source code.
const source = fs.readFileSync(myContractPath,'utf8');
//console.log(solc.compile(source,1));
//This will export the compiled file. Make it available
//At the moment only interested in the Inbox contract.
module.exports = solc.compile(source,1).contracts[':MyContract'];以及产出:
PS C:\Projects\Eth_Dev\simple> node .\deploy.js
Attempting to deploy from account 0x15ec...B
Contract deployed to 0x5...2DA9269ahttps://ethereum.stackexchange.com/questions/67407
复制相似问题