无法在已部署的合同中调用函数

时间:2017-07-16 11:29:15

标签: ethereum web3js

我试图让部署的HelloWorld合同在节点应用中运行。我想运行call()函数来检查它:

const deployed = helloWorldContract.new({
  from: acct1,
  data: compiled.contracts[':HelloWorld'].bytecode,
  gas: 151972,
  gasPrice: 5
}, (error, contract) => {
    if(!error){
      console.log(contract.displayMessage.call());
    } else {
      console.log(error);
    }
});

以下是供参考的合同:

contract HelloWorld {
  function displayMessage() public constant returns (string){
    return "hello from smart contract - {name}";
  }
}

当我在回调中尝试console.log(contract.displayMessage.call())时,会返回TypeError: Cannot read property 'call' of undefined,但是,当我记录console.log(contract.displayMessage)时,它会返回:

{ [Function: bound ]
   request: [Function: bound ],
   call: [Function: bound ],
   sendTransaction: [Function: bound ],
   estimateGas: [Function: bound ],
   getData: [Function: bound ],
   '': [Circular] }

我在这里做错了什么?如何在已部署的合同中运行函数call

1 个答案:

答案 0 :(得分:1)

我认为您的问题可能是由.new构造函数引起的。我个人不建议使用它,因为它很奇怪。相反,您应该将字节码部署为标准事务。

无论如何,如果您查看.new的{​​{3}},您会看到回调实际上是两次调用。这是完全非标准的,据我所知,没有证件。

第一次在发送事务后调用回调,contract对象将设置transactionHash

第二次调用回调时,contract对象应该设置address属性。这就是你想要的,因为没有address属性,你就无法调用契约方法。

简而言之,试试这个

const deployed = helloWorldContract.new({
  from: acct1,
  data: compiled.contracts[':HelloWorld'].bytecode,
  gas: 151972,
  gasPrice: 5
}, (error, contract) => {
    if (error){
      console.error(error);
    } else {
      console.log(contract);
      if (contract.address) {
        console.log(contract.displayMessage());
      }
    }
});

要在不使用.new方法的情况下部署合同,首先需要生成合同字节码和ABI。您可以使用source code或在线可靠性编译器或其他任何方式来获取它。

然后要部署合同,使用web3.eth.sendTransaction data参数设置为字节码,以及空to地址。 sendTransaction会返回transactionHash,您需要等待开采和确认。最简单的方法是通过民意调查 - 一个好的起点可以是我写的这个方法 - solc

如果您的契约采用构造函数参数,则它们会附加到字节码,例如data: bytecode + encodedConstructorArguments