LoginSignup
1
0

More than 3 years have passed since last update.

solidityのコントラクトをJavaのコントラクトクラスに変換する方法

Posted at

記事の内容

solidityで使ったコントラクトをweb3jで使用する場合、コントラクトを操作するためのJavaのクラスを使用する必要があります。

一からこのコントラクトを操作するクラスを作成することはもちろん可能ですが、簡単に作成する方法があったのでメモを残します。

環境

  • solidity:v0.4.24
  • solc:0.4.24+commit.6ae8fb59.Windows.msvc
  • jdk:1.8
  • web3j:4.5.0
  • OS:Windows10

Web3jのダウンロード

コマンドラインでsolファイルをjavaファイルに変換するツールが提供されているので、ダウンロードします。

web3j

  1. リンク先にzipファイルがあるのでダウンロードします。
  2. zipファイルを解凍し、任意のディレクトリに配置します。
  3. 配置したディレクトリのbinディレクトリへパスを通します。
  4. コマンドプロンプトで「web3j」と入力します。

以下の表示が出れば設定完了です。


              _      _____ _     _
             | |    |____ (_)   (_)
__      _____| |__      / /_     _   ___
\ \ /\ / / _ \ '_ \     \ \ |   | | / _ \
 \ V  V /  __/ |_) |.___/ / | _ | || (_) |
  \_/\_/ \___|_.__/ \____/| |(_)|_| \___/
                         _/ |
                        |__/
Usage: web3j version|wallet|solidity ...

binファイルとabiファイルを作成する

まずは、solファイルを用意します。

addition.sol
pragma solidity ^0.4.24;

contract Addition{
  int num = 0;
  function add(int a) public {
    num += a;
  }
  function get() public view returns(int)  {
    return num;
  }
}

このsolファイルをコンパイルし、binとabiを取り出します。

solc --bin addition.sol > addition.bin
solc --abi addition.sol > addition.abi

それぞれ出力されるファイルは以下のとおりとなります。

addition.bin
======= addition.sol:Addition =======
Binary: 
60806040526000805534801561001457600080fd5b5060e7806100236000396000f3006080604052600436106049576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff1680636d4ce63c14604e57806387db03b7146076575b600080fd5b348015605957600080fd5b50606060a0565b6040518082815260200191505060405180910390f35b348015608157600080fd5b50609e6004803603810190808035906020019092919050505060a9565b005b60008054905090565b806000808282540192505081905550505600a165627a7a723058200522274b97a5967f28327168f4654fbd3921238ed6de8e155c966f7dad168e020029
addition.abi
======= addition.sol:Addition =======
Contract JSON ABI 
[{"constant":true,"inputs":[],"name":"get","outputs":[{"name":"","type":"int256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"a","type":"int256"}],"name":"add","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"}]

この2ファイルですが、最初の数行(~Binary:まで/~JSON ABIまで)はこれからの処理に不要な内容になるので、削除しておきます。

コントラクトクラスを作成する

以下のコマンドで作成します

web3j solidity generate -a=addition.abi -b=addition.bin -o=src -p=jp.ethereum.contracts

実行結果


              _      _____ _     _
             | |    |____ (_)   (_)
__      _____| |__      / /_     _   ___
\ \ /\ / / _ \ '_ \     \ \ |   | | / _ \
 \ V  V /  __/ |_) |.___/ / | _ | || (_) |
  \_/\_/ \___|_.__/ \____/| |(_)|_| \___/
                         _/ |
                        |__/

Generating jp.ethereum.contracts.Addition ... File written to src

この結果が出れば出力が完了です。
「-O」オプションで指定したディレクトリに出力されます。
この場合だと、srcディレクトリ配下に「-p」で指定した「jp.ethereum.contracts」パッケージを作成し、その配下にAddtion.javaが作成されます。

addtion.java
package jp.ethereum.contracts;

import java.math.BigInteger;
import java.util.Arrays;
import java.util.Collections;
import org.web3j.abi.TypeReference;
import org.web3j.abi.datatypes.Function;
import org.web3j.abi.datatypes.Type;
import org.web3j.abi.datatypes.generated.Int256;
import org.web3j.crypto.Credentials;
import org.web3j.protocol.Web3j;
import org.web3j.protocol.core.RemoteCall;
import org.web3j.protocol.core.RemoteFunctionCall;
import org.web3j.protocol.core.methods.response.TransactionReceipt;
import org.web3j.tx.Contract;
import org.web3j.tx.TransactionManager;
import org.web3j.tx.gas.ContractGasProvider;

/**
 * <p>Auto generated code.
 * <p><strong>Do not modify!</strong>
 * <p>Please use the <a href="https://docs.web3j.io/command_line.html">web3j command line tools</a>,
 * or the org.web3j.codegen.SolidityFunctionWrapperGenerator in the 
 * <a href="https://github.com/web3j/web3j/tree/master/codegen">codegen module</a> to update.
 *
 * <p>Generated with web3j version 4.5.0.
 */
public class Addition extends Contract {
    private static final String BINARY = "60806040526000805534801561001457600080fd5b5060e7806100236000396000f3006080604052600436106049576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff1680636d4ce63c14604e57806387db03b7146076575b600080fd5b348015605957600080fd5b50606060a0565b6040518082815260200191505060405180910390f35b348015608157600080fd5b50609e6004803603810190808035906020019092919050505060a9565b005b60008054905090565b806000808282540192505081905550505600a165627a7a723058200522274b97a5967f28327168f4654fbd3921238ed6de8e155c966f7dad168e020029\r\n";

    public static final String FUNC_GET = "get";

    public static final String FUNC_ADD = "add";

    @Deprecated
    protected Addition(String contractAddress, Web3j web3j, Credentials credentials, BigInteger gasPrice, BigInteger gasLimit) {
        super(BINARY, contractAddress, web3j, credentials, gasPrice, gasLimit);
    }

    protected Addition(String contractAddress, Web3j web3j, Credentials credentials, ContractGasProvider contractGasProvider) {
        super(BINARY, contractAddress, web3j, credentials, contractGasProvider);
    }

    @Deprecated
    protected Addition(String contractAddress, Web3j web3j, TransactionManager transactionManager, BigInteger gasPrice, BigInteger gasLimit) {
        super(BINARY, contractAddress, web3j, transactionManager, gasPrice, gasLimit);
    }

    protected Addition(String contractAddress, Web3j web3j, TransactionManager transactionManager, ContractGasProvider contractGasProvider) {
        super(BINARY, contractAddress, web3j, transactionManager, contractGasProvider);
    }

    public RemoteFunctionCall<BigInteger> get() {
        final Function function = new Function(FUNC_GET, 
                Arrays.<Type>asList(), 
                Arrays.<TypeReference<?>>asList(new TypeReference<Int256>() {}));
        return executeRemoteCallSingleValueReturn(function, BigInteger.class);
    }

    public RemoteFunctionCall<TransactionReceipt> add(BigInteger a) {
        final Function function = new Function(
                FUNC_ADD, 
                Arrays.<Type>asList(new org.web3j.abi.datatypes.generated.Int256(a)), 
                Collections.<TypeReference<?>>emptyList());
        return executeRemoteCallTransaction(function);
    }

    @Deprecated
    public static Addition load(String contractAddress, Web3j web3j, Credentials credentials, BigInteger gasPrice, BigInteger gasLimit) {
        return new Addition(contractAddress, web3j, credentials, gasPrice, gasLimit);
    }

    @Deprecated
    public static Addition load(String contractAddress, Web3j web3j, TransactionManager transactionManager, BigInteger gasPrice, BigInteger gasLimit) {
        return new Addition(contractAddress, web3j, transactionManager, gasPrice, gasLimit);
    }

    public static Addition load(String contractAddress, Web3j web3j, Credentials credentials, ContractGasProvider contractGasProvider) {
        return new Addition(contractAddress, web3j, credentials, contractGasProvider);
    }

    public static Addition load(String contractAddress, Web3j web3j, TransactionManager transactionManager, ContractGasProvider contractGasProvider) {
        return new Addition(contractAddress, web3j, transactionManager, contractGasProvider);
    }

    public static RemoteCall<Addition> deploy(Web3j web3j, Credentials credentials, ContractGasProvider contractGasProvider) {
        return deployRemoteCall(Addition.class, web3j, credentials, contractGasProvider, BINARY, "");
    }

    @Deprecated
    public static RemoteCall<Addition> deploy(Web3j web3j, Credentials credentials, BigInteger gasPrice, BigInteger gasLimit) {
        return deployRemoteCall(Addition.class, web3j, credentials, gasPrice, gasLimit, BINARY, "");
    }

    public static RemoteCall<Addition> deploy(Web3j web3j, TransactionManager transactionManager, ContractGasProvider contractGasProvider) {
        return deployRemoteCall(Addition.class, web3j, transactionManager, contractGasProvider, BINARY, "");
    }

    @Deprecated
    public static RemoteCall<Addition> deploy(Web3j web3j, TransactionManager transactionManager, BigInteger gasPrice, BigInteger gasLimit) {
        return deployRemoteCall(Addition.class, web3j, transactionManager, gasPrice, gasLimit, BINARY, "");
    }
}

このクラスはWeb3jを使用しコントラクトを実行する際に必要となります。
非推奨となっているメソッドが多数存在しますので、使用する際は注意が必要です。

参考

web3j docs

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0