首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在NodeJS上使用英弗拉和web3js@1.x.x部署智能合同?

如何在NodeJS上使用英弗拉和web3js@1.x.x部署智能合同?
EN

Ethereum用户
提问于 2019-02-21 07:40:53
回答 1查看 1.7K关注 0票数 1

我有一个用NodeJS编写的应用程序,每次启动它都必须部署一个智能契约。一旦部署了契约,这个应用程序将与它交互,进行一些事务处理并侦听其事件。

关于事务处理、调用智能契约函数和侦听事件的部分工作正常,我曾经无法做的一件事就是使用NodeJS部署智能契约。

要部署它,我必须通过命令行使用块菌,然后启动我的NodeJS应用程序,将智能契约地址传递给它。就这样一切都很好。

通过直接从NodeJS应用程序运行控制台命令(process,捕捉其输出,解析字符串并找到合同地址),我找到了一个非常糟糕的解决方法。还有..。是的,它有效!)。

很明显我试过通过恩弗拉做这件事,但没有成功。为什么?我不知道,但我可以解释我做了什么。由于部署智能契约不亚于进行正常事务,所以我准备好了它,签署了它,并以与前面提到的其他正常事务和合同函数调用相同的方式发送它。看上去很管用!但每次我都会犯两个类似的错误:

  • 天然气价格*天然气+价值是不够的
  • 如果我把汽油调高,就会超过汽油限额。

我几乎可以肯定,这不是关于气体的问题,而是在准备过程中的其他错误--准备>标志>发送。

请注意,我没有必要在每次运行时编译智能契约!ABI和字节码在每次运行时都是相同的,因此在没有重新编译的情况下迁移/部署它就足够了。

这是NodeJS中用于部署智能契约的函数的代码,它失败并返回气体错误:

代码语言:javascript
复制
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部署智能契约吗?即使不参考我在这个问题中暴露的代码和问题?

更新:

EN

回答 1

Ethereum用户

回答已采纳

发布于 2019-02-25 19:40:19

这就是我工作时的样子:

代码语言:javascript
复制
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.json

package.json的内容:

代码语言:javascript
复制
{
  "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含量

代码语言:javascript
复制
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网络

代码语言:javascript
复制
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看起来如下所示:

代码语言:javascript
复制
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'];

以及产出:

代码语言:javascript
复制
PS C:\Projects\Eth_Dev\simple> node .\deploy.js
Attempting to deploy from account 0x15ec...B
Contract deployed to  0x5...2DA9269a
票数 3
EN
页面原文内容由Ethereum提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://ethereum.stackexchange.com/questions/67407

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档