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



我正在尝试让一个已部署的 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

我认为您的问题可能是由.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。您可以通过使用 solc 或在线 solidity 编译器或任何其他方式获得它。

然后,若要部署协定,请使用web3.eth.sendTransactiondata参数设置为字节码,并有一个空的to地址。sendTransaction会给你一个transactionHash,你需要等待被挖掘和确认。最简单的方法是通过轮询 - 一个好的起点可以是我写的这种方法 - https://gist.github.com/gaiazov/17c9fc7fdedf297e82386b74b34c61cd

如果您的合约采用构造函数参数,它们将附加到字节码中,例如data: bytecode + encodedConstructorArguments.

最新更新