contract Calculator{
int result;
function Calculator(int initialResult){
result=initialResult;
}
}如果上面是我创建的契约源代码,那么如何使用ethereumj调用Calculator函数。我已经用过了
contract.callFunction("Calculator", 10)但这不起作用。又称
contract.callConstFunction("Calculator", 10)但这也没用。
当看到ABI时,它有函数类型=“构造函数”,但是找不到表示调用构造函数的任何方法。
请建议是否有任何方法来调用构造函数?
发布于 2016-05-31 06:17:21
我终于找到了解决办法。正如在另一个答案中所讨论的,在发送事务之前,您需要解析init参数并将其附加到契约代码中。实际上,我并没有找到一种优雅而通用的方法来直接解析Java中的参数(但这并不难做到),所以我将ABI语法解码为byte[]。
首先,复制StandaloneBlockchain.java并添加一个方法(对不起,我无法通过扩展找到一种简单的方法):
public SolidityContract submitNewContract(String soliditySrc, String contractName, byte[] initParameters) {
SolidityContractImpl contract = createContract(soliditySrc, contractName);
submitNewTx(new PendingTx(new byte[0], BigInteger.ZERO, ByteUtil.merge(Hex.decode(contract.getBinary()), initParameters), contract, null));
return contract;
}然后在StandaloneBlockchainSample.java中,引用修改后的类,修改示例合同,使其在构造函数中有两个参数(我没有时间检查所有类型,但它应该没有问题)并分配参数init值:
// Pretty simple (and probably the most expensive) Calculator
private static final String contractSrc =
"contract Calculator {" +
" int public result;" + // public field can be accessed by calling 'result' function
" string testString;" +
" bool testBool;"+
" function add(int num) {" +
" result = result + num;" +
" }" +
" function sub(int num) {" +
" result = result - num;" +
" }" +
" function mul(int num) {" +
" result = result * num;" +
" }" +
" function div(int num) {" +
" result = result / num;" +
" }" +
" function clear() {" +
" result = 0;" +
" }" +
" function getString() constant returns (string) { return testString; }" +
" function getBool() constant returns (bool) { return testBool; }" +
" function Calculator(string _testString, bool _testBool){" +
" testString = _testString;" +
" testBool = _testBool;" +
" }" +
"}";
[...]
String parameters = "{ 'inputs': [ { 'name': '_test', 'type': 'string' }, { 'name': '_test2', 'type': 'bool' } ] }".replaceAll("'", "\"");
byte[] initParameters = CallTransaction.Function.fromJsonInterface(parameters).encodeArguments("Test", true);
SolidityContract calc = bc.submitNewContract(contractSrc, null, initParameters);
System.out.println("Calculating...");之后,使用以下方法检查参数的正确值:
assertEqual("Test", (String) calc.callConstFunction("getString")[0]);
assertEqual(true, (boolean) calc.callConstFunction("getBool")[0]);注意,除了已经定义的assertEqual之外,您还需要修改类中的私有BigInteger方法来断言其他类型。我用EthereumJ 1.2.0测试了这个解决方案:也许下一个版本将包括一种将init值传递给构造函数的更好方法,所以如果您知道的话,就更新答案。
发布于 2016-05-28 22:28:37
您不需要调用构造函数,您需要提交契约,并且您将自动拥有一个指向契约的指针,这样:
StandaloneBlockchain bc = new StandaloneBlockchain().withAutoblock(true);
bc.createBlock();
SolidityContract contract = bc.submitNewContract(contractSrc);
System.out.println(contract.callConstFunction("result")[0]);您可以在github上看到一个简单而完整的示例。
发布于 2016-07-07 15:30:47
加入1.3.0-RC4:
SolidityContract a = sb.submitNewContract(
"contract A {" +
" uint public a;" +
" uint public b;" +
" function A(uint a_, uint b_) {a = a_; b = b_; }" +
"}", 555, 777);https://ethereum.stackexchange.com/questions/4395
复制相似问题