Solidity

使用 web3 1.0 和 testrpc 正確部署合約(無效操作碼錯誤)

  • December 12, 2021

我遵循以下教程: https ://medium.com/@mvmurthy/full-stack-hello-world-voting-ethereum-dapp-tutorial-part-1-40d2d0d807c2

現在本教程沒有使用最新版本的 web3,但我嘗試使用 web3 文件解決這個問題。

這是我走了多遠:

>byteCode = compiledCode.contracts[':Voting'].bytecode       
>deployedContract = VotingContract.new(['Rama','Nick','Jose'],{data:   byteCode, from: web3.eth.accounts[0], gas: 4700000})
>deployedContract.address
>contractInstance = VotingContract.at(deployedContract.address)

我成功編譯了字節碼並通過以下方式部署了合約:

> VotingContract.deploy({ data: byteCode, arguments: [[web3.utils.asciiToHex("name1"),web3.utils.asciiToHex("name2"),web3.utils.asciiToHex("name3")]] }).send({ from: acc1, gas: 4700000, gasPrice: '3000000' }).on('confirmation', function(confirmationNumber, receipt){console.log(confirmationNumber + ' ' + receipt) }).then(function(instance) {contractInstance = instance});

現在我應該有一個合約實例,不是嗎?或者這是別的什麼?作者繼續進行以下操作:

>contractInstance = VotingContract.at(deployedContract.address)

我這樣做了:

var contract3 = new web3.eth.Contract(byteCode, contractInstance.options.address, {from: acc1, gasPrice:‘3000000’});

現在,如果我嘗試呼叫此契約上的方法,例如:

contract3.methods.totalVotesFor(web3.utils.toHex(’name1’)).call(acc1).then(function(returned, err) {console.log(returned + ’ ’ + err)});

我收到以下回复:

Promise {
 _bitField: 0,
 _fulfillmentHandler0: undefined,
 _rejectionHandler0: undefined,
 _promise0: undefined,
 _receiver0: undefined }
> Unhandled rejection Error: Returned error: Error: VM Exception while executing eth_call: invalid opcode
   at C:\Path\node_modules\ethereumjs-testrpc\build\cli.node.js:59368:17
   at C:\Path\node_modules\ethereumjs-testrpc\build\cli.node.js:69306:5
   at C:\Path\node_modules\ethereumjs-testrpc\build\cli.node.js:11335:9
   at C:\Path\node_modules\ethereumjs-testrpc\build\cli.node.js:7895:16
   at replenish (C:\Path\node_modules\ethereumjs-testrpc\build\cli.node.js:8415:25)
   at iterateeCallback (C:\Path\node_modules\ethereumjs-testrpc\build\cli.node.js:8405:17)
   at C:\Path\node_modules\ethereumjs-testrpc\build\cli.node.js:8380:16
   at C:\Path\node_modules\ethereumjs-testrpc\build\cli.node.js:11332:13
   at C:\Path\node_modules\ethereumjs-testrpc\build\cli.node.js:69302:9
   at C:\Path\node_modules\ethereumjs-testrpc\build\cli.node.js:63982:7
   at Object.ErrorResponse (C:\Path\node_modules\web3-core-helpers\src\errors.js:29:16)
   at C:\Path\node_modules\web3-core-requestmanager\src\index.js:137:36
   at XMLHttpRequest.request.onreadystatechange (C:\Path\node_modules\web3-providers-http\src\index.js:64:13)
   at XMLHttpRequestEventTarget.dispatchEvent (C:\Path\node_modules\xhr2\lib\xhr2.js:64:18)
   at XMLHttpRequest._setReadyState (C:\Path\node_modules\xhr2\lib\xhr2.js:354:12)

我可能做錯了什麼?

謝謝你的幫助!

我已經使用這個腳本來部署使用 web3 v1.0-beta24 的合約

const Web3 = require('web3');
const web3 = new Web3('http://127.0.0.1:8545');

const ownerAddress = "0x....";
const contractAbi = [{"constant":false.... }];
const contractCode = "0x606060...";

const MyContract = new web3.eth.Contract(contractAbi);

MyContract.deploy({
 data: contractCode,
})
.send({
 from: ownerAddress,
 gas: 4000000,
 gasPrice: '30000000000000',
})
.then((instance) => {
 console.log(`Address: ${instance.options.address}`);
});

而這個其他腳本發送消息並進行查詢

const Web3 = require('web3');
const web3 = new Web3('http://127.0.0.1:8545');

const ownerAddress = "0x....";
const contractAbi = [{"constant":false.... }];
const contractCode = "0x606060...";
const contractAddress = "0x....";  // <----- previous script output

const myContract = new web3.eth.Contract(contractAbi, contractAddress);

const options = {
 from: ownerAddress,
 gas: 4000000,
 gasPrice: '30000000000000',
};

const message = web3.utils.asciiToHex('hola');

myContract.methods.sendMessage(message)
.send(options, (err, hash) => {
 if (err) {
   console.log(err);
 }
 console.log(`TxHash: ${hash}`);
})
.then((result) => {
 myContract.methods.getMessage().call()
 .then((result) => {
   console.log(web3.utils.hexToAscii(result));
 });
});

我使用的範例合約非常簡單

pragma solidity ^0.4.18;

contract Echo {
   bytes32 public message;

   function sendMessage(bytes32 _message) public {
       message = _message;
   }

   function getMessage() view public returns (bytes32) {
       return message;
   }
}

合約地址在receiptconfirmation事件上返回。這是投票並獲得結果的完整程式碼。

const fs = require('fs');
const solc = require('solc');
const Web3 = require('web3');
const web3 = new Web3(new Web3.providers.HttpProvider("http://localhost:7545"));

async function deploy() {
   let accounts = await web3.eth.getAccounts();

   let code = fs.readFileSync('Voting.sol').toString();
   let compiledCode = solc.compile(code);
   let abi = JSON.parse(compiledCode.contracts[':Voting'].interface);
   let bytecode = compiledCode.contracts[':Voting'].bytecode;
   let votingContract = new web3.eth.Contract(abi, {from: accounts[0], gas: 47000, data: bytecode});

   let rama = web3.utils.asciiToHex('Rama');
   let nick = web3.utils.asciiToHex('Nick');
   let jose = web3.utils.asciiToHex('Jose');

   let contractInstance = await votingContract.deploy({
       arguments: [[rama, nick, jose]]
   })
   .send({
       from: accounts[0],
       gas: 1500000
   }, (err, txHash) => {
       console.log('send:', err, txHash);
   })
   .on('error', (err) => {
       console.log('error:', err);
   })
   .on('transactionHash', (err) => {
       console.log('transactionHash:', err);
   })
   .on('receipt', (receipt) => {
       console.log('receipt:', receipt);
       votingContract.options.address = receipt.contractAddress;
   });

   console.log('contractInstance.options:', contractInstance.options);

   let result = await votingContract.methods.totalVotesFor(rama).call({from: accounts[0]});
   console.log('result:', result); // 0

   let receipt = await votingContract.methods.voteForCandidate(rama).send({from: accounts[0]});
   console.log('voteForCandidate receipt:', receipt);

   result = await votingContract.methods.totalVotesFor(rama).call({from: accounts[0]});
   console.log('new result:', result); // 1
}

deploy()
.then(() => console.log('Success'))
.catch(err => console.log('Script failed:', err));

引用自:https://ethereum.stackexchange.com/questions/29074