Contract-Development

在 ethereumj 中使用建構子創建合約

  • July 8, 2016
contract Calculator{
   int result;
   function Calculator(int initialResult){
      result=initialResult;
   }
}

如果上面是我創建的合約原始碼,那麼如何使用 ethereumj API 呼叫 Calculator 函式。我已經用過

contract.callFunction("Calculator", 10)

但這沒有用。也被稱為

contract.callConstFunction("Calculator", 10)

但這也不起作用。

當看到 ABI 時,它的函式類型為 =“constructor”,但找不到任何表示呼叫建構子的方法。

請建議是否有任何方法可以呼叫建構子?

我終於找到了解決方案。正如另一個答案中所討論的,您需要在發送交易之前解析初始化參數並將其附加到合約程式碼中。我實際上並沒有找到一種優雅而通用的方式來直接在 Java 中解析參數(但應該不難做到)所以我將 ABI 語法解碼為字節

$$ $$. 首先複製 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 中,引用修改後的類,修改範例合約以在建構子中有 2 個參數(我沒有時間檢查所有類型,但它應該可以正常工作)並分配參數 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 值傳遞給建構子,所以如果你知道這一點,請更新答案。

你不需要呼叫建構子,你需要送出合約,你會自動擁有一個指向合約的指針,這樣:

StandaloneBlockchain bc = new StandaloneBlockchain().withAutoblock(true);
bc.createBlock();
SolidityContract contract = bc.submitNewContract(contractSrc);
System.out.println(contract.callConstFunction("result")[0]);

您可以在github上看到一個簡單但完整的工作範例

引用自:https://ethereum.stackexchange.com/questions/4395