LoginSignup
1
1

More than 3 years have passed since last update.

web3jを使ってコントラクトを実行する方法

Posted at

記事の内容

web3jを使ってsolidityで作成したコントラクトを実行する方法です。
solファイルをJavaのクラスに変換する方法についてはこちらをご確認ください。
本記事で使用するコントラクトは以下の記事に記載の内容を使用します。

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

コード

sample.java
try {
  SampleGasProvider gasProvider = new SampleGasProvider(BigInteger.valueOf(500), BigInteger.valueOf(200000));

  Addition contract = Addition.deploy(
      web3j,
      credentials,
      gasProvider
      ).send();
  // コントラクトのアドレスを出力
  System.out.println("contract address: " + contract.getContractAddress());
  // メソッド呼び出し(トランザクションなし)
  System.out.println("get: " + contract.get().send());
  System.out.println("add: " + contract.add(BigInteger.valueOf(10)).sendAsync());
  System.out.println("get: " + contract.get().send());

} catch (Exception e) {
  e.printStackTrace();
}
SampleGasProvider.java
package jp.ethereum;

import java.math.BigInteger;
import org.web3j.tx.gas.ContractGasProvider;

public class SampleGasProvider implements ContractGasProvider{

  private BigInteger gasPrice;
  private BigInteger gasLimit;

  public SampleGasProvider(BigInteger gasPrice, BigInteger gasLimit) {
    this.gasPrice = gasPrice;
    this.gasLimit = gasLimit;
  }
  @Override
  public BigInteger getGasPrice(String contractFunc) {
    return this.gasPrice;
  }
  @Override
  public BigInteger getGasPrice() {
    return this.gasPrice;
  }
  @Override
  public BigInteger getGasLimit(String contractFunc) {
    return this.gasLimit;
  }
  @Override
  public BigInteger getGasLimit() {
    return this.gasLimit;
  }
}

コードの内容は単純です。
まずは、コントラクトをデプロイします。
この処理が終わると、コントラクトをデプロイ用のトランザクションが作成され、ブロックに取り込まれた後に処理が完了します。

Sample.java
  Addition contract = Addition.deploy(
      web3j,
      credentials,
      gasProvider
      ).send();

実行結果(gethコンソール)

INFO [09-16|17:19:41.983] Submitted contract creation              fullhash=0xd169416410c2e6e7bdc02a2a27384ed2425e1433f39117a3810675fcfed85353 contract=0xf5ad7542173e8944D1aE16B4394eAA34cfdA4814

次にコントラクトを実行します。

Sample.java
  System.out.println("get: " + contract.get().send());
  System.out.println("add: " + contract.add(BigInteger.valueOf(10)).sendAsync());

この例ではコントラクトのget処理をまずは呼び出します。
getは値を参照するだけなのでトランザクションは作成されず、すぐに応答が返ってきます。

次のadd処理は値を更新する処理なのでトランザクションが作成されます。
「sendAsync」を使用しているため、ブロックに取り込まれる前に応答が返ってきます。
この例だと以下のような出力になります。

add: java.util.concurrent.CompletableFuture@18271936[Not completed]

ブロックに取り込まれるまで処理を待つ必要がある場合は、以下のとおり変更します。

Sample.java
  System.out.println("add: " + contract.add(BigInteger.valueOf(10)).send());

コントラクトのロード

上述したコードはコントラクトをデプロイして実行するという方法でしたが、既にデプロイ済みのコントラクトを実行する方法もあります。

Sample.java
Addition contract = Addition.load(
  address,
  web3j,
  credentials,
  gasProvider
);

デプロイと引数はほとんど変わりませんが、第一引数にコントラクトのアドレスが入ります。(0xを含む)
それ以降の操作は全く変わりません。

1
1
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
1