无法在已部署的合约中调用函数
Posted
技术标签:
【中文标题】无法在已部署的合约中调用函数【英文标题】:Cannot call function within deployed contract 【发布时间】:2017-12-21 00:49:06 【问题描述】:我正在尝试让已部署的 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
函数?
【问题讨论】:
它不是一个函数而不是一个属性吗? 正确。如果它是一个属性,我不会使用contract.displayMessage.call
访问吗?如果它是一个函数,我不能用 contract.displayMessage.call()
访问它吗?为了清楚起见,将合同代码添加到问题中
我的意思是 displayMessage?
是的,它是一个函数,在我的合同中定义,尽管console.log(contract.displayMessage)
将返回上面发布的对象。如果我自己运行console.log(contract.displayMessage());
,我会得到:contract.displayMessage is not a function
如果我运行console.log(contract.displayMessage().call());
,我会得到:contract.displayMessage is not a function
你有什么建议?
【参考方案1】:
我认为您的问题可能是由.new
构造函数引起的。我个人不推荐使用它,因为它很奇怪。相反,您应该将字节码部署为标准事务。
无论如何,如果您查看.new
的source code,您会发现回调实际上被调用了两次。这是完全非标准的,据我所知,没有记录。
事务发送后第一次调用回调,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.sendTransaction
并将data
参数设置为字节码和一个空的to
地址的合约。 sendTransaction
会给你一个transactionHash
,你需要等待被挖掘和确认。最简单的方法是通过轮询——我写的这个方法是一个很好的起点——https://gist.github.com/gaiazov/17c9fc7fdedf297e82386b74b34c61cd
如果您的合约采用构造函数参数,它们会附加到字节码中,例如data: bytecode + encodedConstructorArguments
.
【讨论】:
非常感谢!你是对的,它被调用了两次,我没有任何线索(因为我什至没有走那么远)。您能否提供一个关于如何将字节码部署为标准事务的建议? 我添加了关于如何在没有“新”方法的情况下部署合约的简短描述。它有点高级,但我希望它有所帮助!以上是关于无法在已部署的合约中调用函数的主要内容,如果未能解决你的问题,请参考以下文章