代码之家  ›  专栏  ›  技术社区  ›  ameya.dubey

简单Solidity合约和脚本的操作码错误无效

  •  4
  • ameya.dubey  · 技术社区  · 6 年前

    我是Solidity和web3的新手。js。我在这里学习教程-

    https://medium.com/@mvmurthy/full-stack-hello-world-voting-ethereum-dapp-tutorial-part-1-40d2d0d807c2

    构建一个简单的投票Dapp。 我已经使用npm在本地node\u modules文件夹中安装了ganache cli、solc和web3版本0.20.2。投票。sol合同的实体为:

    pragma solidity ^0.4.18;
    
    contract Voting {
    
      mapping (bytes32 => uint8) public votesReceived;
      bytes32[] public candidateList;
    
      function Voting(bytes32[] candidateNames) public {
        candidateList = candidateNames;
      }
    
      function totalVotesFor(bytes32 candidate) view public returns (uint8) {
        return votesReceived[candidate];
      }
    }
    

    使用以下名为voting\u main的脚本。js公司:

    Web3 = require('web3')
    web3 = new Web3(new Web3.providers.HttpProvider("http://localhost:8545"))
    
    fs = require('fs')
    code = fs.readFileSync('Voting.sol').toString()
    
    solc = require('solc')
    compiledCode = solc.compile(code)
    
    abiDefinition = JSON.parse(compiledCode.contracts[':Voting'].interface)
    VotingContract = web3.eth.contract(abiDefinition)
    byteCode = compiledCode.contracts[':Voting'].bytecode
    deployedContract = VotingContract.new(['Rama','Nick','Jose'],{data: byteCode, from: web3.eth.accounts[0], gas: 4700000})
    contractInstance = VotingContract.at(deployedContract.address)
    
    contractInstance.totalVotesFor.call('Rama')
    

    当我在localhost:8545上运行ganache cli,然后在另一个终端上运行该脚本时,会出现以下错误。

    ameya@ameya-HP-ENVY-15-Notebook-PC:~/Fresh_install$ node voting_main.js 
    /home/ameya/Fresh_install/node_modules/solc/soljson.js:1
    (function (exports, require, module, __filename, __dirname) { var Module;if(!Module)Module=(typeof Module!=="undefined"?Module:null)||{};var moduleOverrides={};for(var key in Module){if(Module.hasOwnProperty(key)){moduleOverrides[key]=Module[key]}}var ENVIRONMENT_IS_WEB=typeof window==="object";var ENVIRONMENT_IS_WORKER=typeof importScripts==="function";var ENVIRONMENT_IS_NODE=typeof process==="object"&&typeof require==="function"&&!ENVIRONMENT_IS_WEB&&!ENVIRONMENT_IS_WORKER;var ENVIRONMENT_IS_SHELL=!ENVIRONMENT_IS_WEB&&!ENVIRONMENT_IS_NODE&&!ENVIRONMENT_IS_WORKER;if(ENVIRONMENT_IS_NODE){if(!Module["print"])Module["print"]=function print(x){process["stdout"].write(x+"\n")};if(!Module["printErr"])Module["printErr"]=function printErr(x){process["stderr"].write(x+"\n")};var nodeFS=require("fs");var nodePath=require("path");Module["read"]=function read(filename,binary){filename=nodePath["normalize"](filename);var ret=nodeFS["readFileSync"](filename);if(!r
    
    Error: VM Exception while processing transaction: invalid opcode
        at Object.InvalidResponse (/home/ameya/Fresh_install/node_modules/web3/lib/web3/errors.js:38:16)
        at RequestManager.send (/home/ameya/Fresh_install/node_modules/web3/lib/web3/requestmanager.js:61:22)
        at Eth.send [as call] (/home/ameya/Fresh_install/node_modules/web3/lib/web3/method.js:145:58)
        at SolidityFunction.call (/home/ameya/Fresh_install/node_modules/web3/lib/web3/function.js:135:32)
        at Object.<anonymous> (/home/ameya/Fresh_install/voting_main.js:16:32)
        at Module._compile (internal/modules/cjs/loader.js:654:30)
        at Object.Module._extensions..js (internal/modules/cjs/loader.js:665:10)
        at Module.load (internal/modules/cjs/loader.js:566:32)
        at tryModuleLoad (internal/modules/cjs/loader.js:506:12)
        at Function.Module._load (internal/modules/cjs/loader.js:498:3)
    

    这似乎是一个仍然抛出无效操作码错误的非常简单的示例。我哪里做错了?

    1 回复  |  直到 6 年前
        1
  •  3
  •   Adam Kipnis    6 年前

    你不需要打电话 .at() 如果您正在使用 .new() .您使用 at() 当您想要与已部署到区块链的合同进行交互时。

    如果选择部署新契约,则应使用异步版本的方法调用(web3j 1.0不再支持同步)。你的电话应该是这样的:

    VotingContract.new(['Rama','Nick','Jose'],{data: byteCode, from: web3.eth.accounts[0], gas: 4700000}, (error, deployedContract) => {
        if (!error) {
            if (deployedContract.address) {
                console.log(deployedContract.totalVotesFor.call('Rama'));
            }
        }
    });
    

    请注意,回调被触发两次。首次提交交易( deployedContract.transactionHash 将被设置),并在挖掘事务后的第二次。

    您还可以查看 web3js docs (为了方便粘贴在下面)。

    const fs = require("fs");
    const solc = require('solc')
    
    let source = fs.readFileSync('nameContract.sol', 'utf8');
    let compiledContract = solc.compile(source, 1);
    let abi = compiledContract.contracts['nameContract'].interface;
    let bytecode = compiledContract.contracts['nameContract'].bytecode;
    let gasEstimate = web3.eth.estimateGas({data: bytecode});
    let MyContract = web3.eth.contract(JSON.parse(abi));
    
    var myContractReturned = MyContract.new(param1, param2, {
       from:mySenderAddress,
       data:bytecode,
       gas:gasEstimate}, function(err, myContract){
        if(!err) {
           // NOTE: The callback will fire twice!
           // Once the contract has the transactionHash property set and once its deployed on an address.
    
           // e.g. check tx hash on the first call (transaction send)
           if(!myContract.address) {
               console.log(myContract.transactionHash) // The hash of the transaction, which deploys the contract
    
           // check address on the second call (contract deployed)
           } else {
               console.log(myContract.address) // the contract address
           }
    
           // Note that the returned "myContractReturned" === "myContract",
           // so the returned "myContractReturned" object will also get the address set.
        }
      });