首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在ethereumj中创建带有构造函数的契约

在ethereumj中创建带有构造函数的契约
EN

Ethereum用户
提问于 2016-05-28 20:21:19
回答 3查看 1.6K关注 0票数 3
代码语言:javascript
复制
contract Calculator{
    int result;
    function Calculator(int initialResult){
       result=initialResult;
    }
}

如果上面是我创建的契约源代码,那么如何使用ethereumj调用Calculator函数。我已经用过了

代码语言:javascript
复制
contract.callFunction("Calculator", 10)

但这不起作用。又称

代码语言:javascript
复制
contract.callConstFunction("Calculator", 10)

但这也没用。

当看到ABI时,它有函数类型=“构造函数”,但是找不到表示调用构造函数的任何方法。

请建议是否有任何方法来调用构造函数?

EN

回答 3

Ethereum用户

发布于 2016-05-31 06:17:21

我终于找到了解决办法。正如在另一个答案中所讨论的,在发送事务之前,您需要解析init参数并将其附加到契约代码中。实际上,我并没有找到一种优雅而通用的方法来直接解析Java中的参数(但这并不难做到),所以我将ABI语法解码为byte[]。

首先,复制StandaloneBlockchain.java并添加一个方法(对不起,我无法通过扩展找到一种简单的方法):

代码语言:javascript
复制
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值:

代码语言:javascript
复制
// 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...");

之后,使用以下方法检查参数的正确值:

代码语言:javascript
复制
assertEqual("Test", (String) calc.callConstFunction("getString")[0]);
assertEqual(true, (boolean) calc.callConstFunction("getBool")[0]);

注意,除了已经定义的assertEqual之外,您还需要修改类中的私有BigInteger方法来断言其他类型。我用EthereumJ 1.2.0测试了这个解决方案:也许下一个版本将包括一种将init值传递给构造函数的更好方法,所以如果您知道的话,就更新答案。

票数 3
EN

Ethereum用户

发布于 2016-05-28 22:28:37

您不需要调用构造函数,您需要提交契约,并且您将自动拥有一个指向契约的指针,这样:

代码语言:javascript
复制
StandaloneBlockchain bc = new StandaloneBlockchain().withAutoblock(true);
bc.createBlock();
SolidityContract contract = bc.submitNewContract(contractSrc);
System.out.println(contract.callConstFunction("result")[0]);

您可以在github上看到一个简单而完整的示例。

票数 2
EN

Ethereum用户

发布于 2016-07-07 15:30:47

加入1.3.0-RC4:

代码语言:javascript
复制
SolidityContract a = sb.submitNewContract(
  "contract A {" +
  "  uint public a;" +
  "  uint public b;" +
  "  function A(uint a_, uint b_) {a = a_; b = b_; }" +
  "}", 555, 777);
票数 0
EN
页面原文内容由Ethereum提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://ethereum.stackexchange.com/questions/4395

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档