記事の内容
web3jを使って署名付きトランザクションを発行する記事を書きましたが、そのやり方ではトランザクションがブロックに取り込まれませんでした。
確認方法も含め、修正方法を残します。
トランザクションプールの確認
gethのJavaScriptコンソールで「txpool」を確認します。
> txpool
{
content: {
pending: {
0x945Cd603A6754cB13C3D61d8fe240990f86f9f8A: {
19: {...}
}
},
queued: {
0x66B4e7bE902300F9a15D900822Bbd8803Be87391: {
1: {...},
100: {...},
5: {...}
},
0x945Cd603A6754cB13C3D61d8fe240990f86f9f8A: {
100: {...}
}
}
},
inspect: {
pending: {
0x945Cd603A6754cB13C3D61d8fe240990f86f9f8A: {
19: "0xf5ad7542173e8944D1aE16B4394eAA34cfdA4814: 0 wei + 200000 gas × 500 wei"
}
},
queued: {
0x66B4e7bE902300F9a15D900822Bbd8803Be87391: {
1: "0x945Cd603A6754cB13C3D61d8fe240990f86f9f8A: 0 wei + 4712388 gas × 100 wei",
100: "0x945Cd603A6754cB13C3D61d8fe240990f86f9f8A: 0 wei + 4712388 gas × 100 wei",
5: "0x945Cd603A6754cB13C3D61d8fe240990f86f9f8A: 0 wei + 4712388 gas × 100 wei"
},
0x945Cd603A6754cB13C3D61d8fe240990f86f9f8A: {
100: "0x66B4e7bE902300F9a15D900822Bbd8803Be87391: 1000000000000000 wei + 200000 gas × 100 wei"
}
}
},
status: {
pending: 1,
queued: 4
},
getContent: function(callback),
getInspect: function(callback),
getStatus: function(callback)
}
ここでポイントとなるのが、「queued」です。
トランザクションが作成されると、queuedに入り、署名のチェックなど色々なチェックが行われ、チェックが問題なければ「pending」に移り、ブロックに格納されるのを待つみたいです。
こちらのサイトで詳しく説明されていました。
EthereumのPending TransactionとTransaction Poolについて
Web3jを使った署名付きトランザクションの送信方法
Web3jを使って署名付きトランザクションを送信する
この記事に書いたsendSignedTransactionを修正しました。
public TransactionReceipt sendSignedTransaction(Credentials credentials, String password, String toAddress) {
TransactionReceipt receipt = null;
try {
// nonce値を取得する
EthGetTransactionCount ethTransactionCount =
web3j.ethGetTransactionCount(credentials.getAddress(), DefaultBlockParameterName.PENDING).send();
BigInteger nonce = ethTransactionCount.getTransactionCount();
// "eth_sendTransaction"の引数に渡すオブジェクトを作成
RawTransaction rawTransaction = RawTransaction.createEtherTransaction(
nonce, // nonce
BigInteger.valueOf(100), // gasPrice
BigInteger.valueOf(4712388), // gasLimit
toAddress, // to
BigInteger.valueOf(1010000) // value
);
// トランザクションに署名
byte[] signedMessage = TransactionEncoder.signMessage(rawTransaction, credentials);
String hexValue = Numeric.toHexString(signedMessage);
EthSendTransaction ethSendTransaction = web3j.ethSendRawTransaction(hexValue).send();
String transactionHash = ethSendTransaction.getTransactionHash();
// トランザクションの送信
Optional<TransactionReceipt> transactionReceipt = null;
int retry = 0;
if(transactionHash != null) {
do {
System.out.printf("%3d checking if transaction " + transactionHash + " is mined....\n" ,retry);
EthGetTransactionReceipt ethGetTransactionReceiptResp = web3j.ethGetTransactionReceipt(transactionHash).send();
transactionReceipt = ethGetTransactionReceiptResp.getTransactionReceipt();
Thread.sleep(3000);
retry++;
}while(!transactionReceipt.isPresent() && retry < 100);
} else {
System.out.println("Transaction Send failed...");
System.out.println("Message:" + ethSendTransaction.getError().getMessage());
System.out.println("Data :" + ethSendTransaction.getError().getData());
}
}catch(IOException | InterruptedException ex) {
ex.printStackTrace();
}catch(Exception ex) {
ex.printStackTrace();
}
return receipt;
}
間違っていた点としては、RawTransactionに設定しているnonce値が固定値になっていたため、トランザクションのチェック処理に引っ掛かりqueuedに溜まったままとなっていました。
RawTransactionを送信した直後にトランザクションの情報を確認してみました。
INFO [09-17|20:52:21.455] Submitted transaction fullhash=0x84b89a096fcb1a5381319cf08348f633ebe2dc2ef93ba48b0c05d5b460110970 recipient=0x66B4e7bE902300F9a15D900822Bbd8803Be87391
> eth.getTransaction("0x84b89a096fcb1a5381319cf08348f633ebe2dc2ef93ba48b0c05d5b460110970")
{
blockHash: "0x0000000000000000000000000000000000000000000000000000000000000000",
blockNumber: null,
from: "0x945cd603a6754cb13c3d61d8fe240990f86f9f8a",
gas: 4712388,
gasPrice: 100,
hash: "0x84b89a096fcb1a5381319cf08348f633ebe2dc2ef93ba48b0c05d5b460110970",
input: "0x",
nonce: 24,
r: "0xd6bb90deea18af081795bc335c3323389c830721d5d7db54f6ef6c19f3425358",
s: "0x4e99740c21f5ef2f3debafcff0256340dfff07e00a86801eb90d72804439d602",
to: "0x66b4e7be902300f9a15d900822bbd8803be87391",
transactionIndex: 0,
v: "0x1c",
value: 1010000
}
> txpool.status
{
pending: 1,
queued: 0
}
pendingにトランザクションが溜まりました。
マイニングした後にも確認しました。
> eth.getTransaction("0x84b89a096fcb1a5381319cf08348f633ebe2dc2ef93ba48b0c05d5b460110970")
{
blockHash: "0x3a150aebfffbe81804f4d5b193e3a22aea79654c3bd5c53d2a3df8d7d8417c34",
blockNumber: 3066,
from: "0x945cd603a6754cb13c3d61d8fe240990f86f9f8a",
gas: 4712388,
gasPrice: 100,
hash: "0x84b89a096fcb1a5381319cf08348f633ebe2dc2ef93ba48b0c05d5b460110970",
input: "0x",
nonce: 24,
r: "0xd6bb90deea18af081795bc335c3323389c830721d5d7db54f6ef6c19f3425358",
s: "0x4e99740c21f5ef2f3debafcff0256340dfff07e00a86801eb90d72804439d602",
to: "0x66b4e7be902300f9a15d900822bbd8803be87391",
transactionIndex: 0,
v: "0x1c",
value: 1010000
}
> txpool.status
{
pending: 0,
queued: 0
}
ブロックに格納され、pendingが0に変わりました。
#所感
トランザクションに設定する内容やトランザクションが作られてからブロックに取り込まれるまでの流れを正確に理解する必要があると実感しました。