contract Calculator{
int result;
function Calculator(int initialResult){
result=initialResult;
}
}
Если выше приведен исходный код контракта, который я создал, то как вызвать функцию калькулятора с помощью API ethereumj. я уже использовал
contract.callFunction("Calculator", 10)
Но это не сработало. Также называемый
contract.callConstFunction("Calculator", 10)
Но это тоже не сработало.
И когда я увидел ABI, у него был тип функции = "конструктор", но он не смог найти ни одного метода, представляющего вызывающий конструктор.
Пожалуйста, предложите, есть ли способ вызвать функции конструктора?
Я наконец нашел решение. Как обсуждалось в другом ответе, вам необходимо проанализировать и добавить параметры инициализации к коду контракта перед отправкой транзакции. На самом деле я не нашел элегантного и универсального способа анализа аргументов непосредственно в 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 сослаться на модифицированный класс, изменить типовой контракт, чтобы в конструкторе было 2 параметра (у меня не было времени проверить все типы, но должно работать без проблем) и присвоить параметрам начальные значения:
// 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: возможно, в следующих выпусках будет лучший способ передачи значений инициализации в конструктор, поэтому обновите ответ, если вы знаете об этом.
Вам не нужно вызывать конструктор, вам нужно отправить контракт, и у вас автоматически будет указатель на контракт, таким образом:
StandaloneBlockchain bc = new StandaloneBlockchain().withAutoblock(true);
bc.createBlock();
SolidityContract contract = bc.submitNewContract(contractSrc);
System.out.println(contract.callConstFunction("result")[0]);
Вы можете увидеть простой, но полностью рабочий пример на github .
Добавлено в 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);
Аджай Бходжак
Джузеппе Бертоне
Аджай Бходжак
Джузеппе Бертоне
Аджай Бходжак