Ethereum 无法在部署的协定中调用函数

Ethereum 无法在部署的协定中调用函数,ethereum,web3js,Ethereum,Web3js,我正在尝试在节点应用程序中运行已部署的HelloWorld契约。我想运行call()函数来检查它,如下所示: const deployed = helloWorldContract.new({ from: acct1, data: compiled.contracts[':HelloWorld'].bytecode, gas: 151972, gasPrice: 5 }, (error, contract) => { if(!error){ consol

我正在尝试在节点应用程序中运行已部署的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:无法读取未定义的属性'call',但是,当我记录
console.log(contract.displayMessage)
时,它返回以下内容:

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

我做错了什么?如何在部署的合约中运行函数
调用

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

无论如何,如果您查看
.new
的函数,您将看到回调实际上被调用了两次。这是完全不标准的,据我所知,没有文件记录

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

第二次调用回调时,
contract
对象应设置
地址
属性。这就是您想要的,因为如果没有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。您可以通过使用或在线solidity编译器或其他任何方式获得它

然后使用
web3.eth.sendTransaction
数据
参数设置为字节码,并将空的
设置为
地址来部署合约
sendTransaction
将返回一个
transactionHash
,您需要等待挖掘和确认。做到这一点最简单的方法是通过轮询-一个好的起点可以是我写的这个方法-


如果您的合约采用构造函数参数,则它们会附加到字节码中,例如,
数据:字节码+编码构造函数参数

它不是一个函数而不是一个属性吗?正确。如果它是一个属性,我不使用
contract.displayMessage.call访问它吗?如果它是一个函数,我是否不使用
contract.displayMessage.call()
访问它?在Clarity问题中添加了合同代码我是说displayMessage?是的,这是一个在我的合同中定义的函数,尽管
console.log(contract.displayMessage)
将返回上面发布的对象。如果我运行
console.log(contract.displayMessage())我自己得到:
contract.displayMessage不是一个函数,如果我运行
console.log(contract.displayMessage().call())
I get:
contract.displayMessage不是一个函数
你有什么建议吗?非常感谢!你是对的,它被呼叫了两次,我一点也不知道(因为我甚至没有走那么远)。您能否提供一个建议,说明如何将字节码部署为标准事务?我添加了一个简短的说明,说明如何在没有“新”方法的情况下部署契约。这是一个有点高的水平,但我希望它有帮助!