So senden Sie eine signierte Transaktion mit der Java-Bibliothek "Web3j" von Ethereum
Es ist ziemlich rau, weil es ein Code ist, den ich für mein eigenes Lernen geschrieben habe. .. In dieser Beispielquelle wird die Sendemethode der Transaktion mit bzw. ohne Signatur erstellt, und beide werden in der Reihenfolge von der Hauptmethode aufgerufen.
SendTransaction.java
package jp.ethereum.transaction;
import java.io.IOException;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.Optional;
import org.web3j.crypto.CipherException;
import org.web3j.crypto.Credentials;
import org.web3j.crypto.RawTransaction;
import org.web3j.crypto.TransactionEncoder;
import org.web3j.crypto.WalletUtils;
import org.web3j.protocol.admin.Admin;
import org.web3j.protocol.admin.methods.response.PersonalUnlockAccount;
import org.web3j.protocol.core.methods.response.EthGetTransactionReceipt;
import org.web3j.protocol.core.methods.response.EthSendTransaction;
import org.web3j.protocol.core.methods.response.TransactionReceipt;
import org.web3j.protocol.exceptions.TransactionException;
import org.web3j.protocol.http.HttpService;
import org.web3j.tx.Transfer;
import org.web3j.utils.Convert.Unit;
import org.web3j.utils.Numeric;
public class SendTransaction {
// ①
public static final Admin web3j = Admin.build(new HttpService("http://127.0.0.1:8545"));
public static void main(String args[]) {
try {
// ②
//Anmeldeinformationen des Transaktionssenders abrufen
//Zu den Anmeldeinformationen gehören öffentliche und private Schlüssel
String password = "password";
Credentials credentials = WalletUtils.loadCredentials(password, "Vollständiger Pfad der privaten Schlüsseldatei");
String toAddress = "0x66b4e7be902300f9a15d900822bbd8803be87391";
SendTransaction tx= new SendTransaction();
//Senden einer Transaktion
tx.sendTransaction(credentials, password, toAddress, 10);
//Signierte Transaktion senden
TransactionReceipt receipt = tx.sendSignedTransaction(credentials, password, toAddress);
if (receipt != null) System.out.println(receipt.getTransactionHash()) ;
}catch(IOException | CipherException ex) {
ex.printStackTrace();
}
}
public TransactionReceipt sendTransaction(Credentials credentials, String password, String toAddress, long value) {
TransactionReceipt receipt = null;
try {
//Eine Transaktion generieren
// "personal_unlockAccount"Senden Sie eine Anfrage und erhalten Sie eine Antwort
PersonalUnlockAccount unlockAccountResponse = web3j.personalUnlockAccount(
credentials.getAddress(), //Adresse
password //Passwort
).send();
//Wenn das Entsperren erfolgreich ist, senden Sie Ether
if (unlockAccountResponse.getResult()) {
//Senden Sie eine Transaktion. Es wird keine Antwort zurückgegeben, bis sie in den Block geladen wird
receipt = Transfer.sendFunds(web3j, credentials, toAddress, BigDecimal.valueOf(value), Unit.ETHER).send();
}
}catch(IOException | TransactionException ex) {
ex.printStackTrace();
}catch(Exception ex) {
ex.printStackTrace();
}
return receipt;
}
public TransactionReceipt sendSignedTransaction(Credentials credentials, String password, String toAddress) {
TransactionReceipt receipt = null;
try {
//Eine Transaktion generieren
// "personal_unlockAccount"Senden Sie eine Anfrage und erhalten Sie eine Antwort
PersonalUnlockAccount unlockAccountResponse = web3j.personalUnlockAccount(
credentials.getAddress(), //Adresse
password //Passwort
).send();
//Wenn das Entsperren erfolgreich ist, senden Sie Ether
if (unlockAccountResponse.getResult()) {
// "eth_sendTransaction"Erstellen Sie ein Objekt, das an das Argument von übergeben werden soll
RawTransaction rawTransaction = RawTransaction.createEtherTransaction(
BigInteger.valueOf(10), // nonce
BigInteger.valueOf(700), // gasPrice
BigInteger.valueOf(4712388), // gasLimit
toAddress, // to
BigInteger.valueOf(101) // value
);
//Unterzeichnen Sie die Transaktion
byte[] signedMessage = TransactionEncoder.signMessage(rawTransaction, credentials);
String hexValue = Numeric.toHexString(signedMessage);
//Senden einer Transaktion
EthSendTransaction ethSendTransaction = web3j.ethSendRawTransaction(hexValue).send();
String response = ethSendTransaction.getRawResponse();
String transactionHash = ethSendTransaction.getTransactionHash();
Optional<TransactionReceipt> transactionReceipt = null;
int retry = 0;
//Transaktionsüberwachung
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;
}
}
Ich werde die Punkte ergänzen, die wahrscheinlich Punkte sind.
Stellen Sie eine Verbindung zu Ethereum her
SendTransaction.java
// ①
public static final Admin admin = Admin.build(new HttpService("http://127.0.0.1:8545"));
Hier erstellen wir eine Instanz der Admin-Klasse. Die Admin-Klasse ist eine Klasse, die von der Web3j-Klasse erbt. Sie können Methoden verwenden, die persönliche Informationen verwenden, die nicht in der Web3j-Klasse implementiert sind. Verwenden Sie die Admin-Klasse anstelle von Web3j, da zum Senden von Transaktionen das Konto entsperrt werden muss.
Die im Argument angegebene URL ist die Adresse, die in der Option "--rpcaddr" angegeben ist, wenn geth gestartet wird. Wenn Sie den Port nicht angeben, lautet er "8545".
SendTransaction.java
//Anmeldeinformationen des Transaktionssenders abrufen
//Zu den Anmeldeinformationen gehören öffentliche und private Schlüssel
String password = "password";
Credentials credentials = WalletUtils.loadCredentials(password, "Vollständiger Pfad der privaten Schlüsseldatei");
Rufen Sie die privaten Schlüsselinformationen mit der WalletUtils.loadCredentials-Methode ab. Benutzerkontokennwort als erstes Argument Geben Sie im zweiten Argument den Pfad (einschließlich des Dateinamens) der privaten Schlüsseldatei (Datei beginnend mit UTC) an.
Sie müssen lediglich Ihr Konto entsperren und Ihre Transaktion übermitteln.
SendTransaction.java
public TransactionReceipt sendTransaction(Credentials credentials, String password, String toAddress, long value) {
TransactionReceipt receipt = null;
try {
//Eine Transaktion generieren
// "personal_unlockAccount"Senden Sie eine Anfrage und erhalten Sie eine Antwort
PersonalUnlockAccount unlockAccountResponse = web3j.personalUnlockAccount(
credentials.getAddress(), //Adresse
password //Passwort
).send();
//Wenn das Entsperren erfolgreich ist, senden Sie Ether
if (unlockAccountResponse.getResult()) {
//Senden Sie eine Transaktion. Es wird keine Antwort zurückgegeben, bis sie in den Block geladen wird
receipt = Transfer.sendFunds(web3j, credentials, toAddress, BigDecimal.valueOf(value), Unit.ETHER).send();
}
}catch(IOException | TransactionException ex) {
ex.printStackTrace();
}catch(Exception ex) {
ex.printStackTrace();
}
return receipt;
}
Der Punkt ist, dass dieser Prozess keine Antwort zurückgab, bis die Transaktion in den Block aufgenommen wurde. Obwohl das Blockgenerierungsintervall kürzer als bei Bitcoin ist, scheint es notwendig zu sein, es zu berücksichtigen, wenn es eine Situation gibt, in der es in einer tatsächlichen Anwendung verwendet werden kann.
receipt = Transfer.sendFunds(web3j, credentials, toAddress, BigDecimal.valueOf(value), Unit.ETHER).send();
Überprüfen Sie zunächst mit "eth.getTransaction", wann die Transaktion generiert wird.
INFO [09-15|23:28:07.213] Submitted transaction fullhash=0xfa7ab0924c82b9e45a10acd5c6b72136a088b4dee0d4d4810a2d4f4408c3ee97 recipient=0x66B4e7bE902300F9a15D900822Bbd8803Be87391
> eth.getTransaction("0xfa7ab0924c82b9e45a10acd5c6b72136a088b4dee0d4d4810a2d4f4408c3ee97")
{
blockHash: "0x0000000000000000000000000000000000000000000000000000000000000000",
blockNumber: null,
from: "0x945cd603a6754cb13c3d61d8fe240990f86f9f8a",
gas: 21000,
gasPrice: 1000000000,
hash: "0xfa7ab0924c82b9e45a10acd5c6b72136a088b4dee0d4d4810a2d4f4408c3ee97",
input: "0x",
nonce: 7,
r: "0x3ca5a820995553d30656f2218dc10729d3e0f660c35817bbd69845ac96dc6279",
s: "0x2e915ae47699771108f65881273f464d70db0229ad12a94ac38746f498ea7ed3",
to: "0x66b4e7be902300f9a15d900822bbd8803be87391",
transactionIndex: 0,
v: "0x1c",
value: 10000000000000000000
}
Die Transaktion wurde erstellt. Bergbau und sehen, ob es in den Block gelangt.
> eth.getTransaction("0xfa7ab0924c82b9e45a10acd5c6b72136a088b4dee0d4d4810a2d4f4408c3ee97")
{
blockHash: "0xc9634aec9670d312759a0e12ea5fee54948688c88e4d45a5b9cdbeef3c44c681",
blockNumber: 2792,
from: "0x945cd603a6754cb13c3d61d8fe240990f86f9f8a",
gas: 21000,
gasPrice: 1000000000,
hash: "0xfa7ab0924c82b9e45a10acd5c6b72136a088b4dee0d4d4810a2d4f4408c3ee97",
input: "0x",
nonce: 7,
r: "0x3ca5a820995553d30656f2218dc10729d3e0f660c35817bbd69845ac96dc6279",
s: "0x2e915ae47699771108f65881273f464d70db0229ad12a94ac38746f498ea7ed3",
to: "0x66b4e7be902300f9a15d900822bbd8803be87391",
transactionIndex: 0,
v: "0x1c",
value: 10000000000000000000
}
Es wurde sicher aufgenommen.
SendTransaction.java
public TransactionReceipt sendSignedTransaction(Credentials credentials, String password, String toAddress) {
TransactionReceipt receipt = null;
try {
//Eine Transaktion generieren
// "personal_unlockAccount"Senden Sie eine Anfrage und erhalten Sie eine Antwort
PersonalUnlockAccount unlockAccountResponse = web3j.personalUnlockAccount(
credentials.getAddress(), //Adresse
password //Passwort
).send();
//Wenn das Entsperren erfolgreich ist, senden Sie Ether
if (unlockAccountResponse.getResult()) {
// "eth_sendTransaction"Erstellen Sie ein Objekt, das an das Argument von übergeben werden soll
RawTransaction rawTransaction = RawTransaction.createEtherTransaction(
BigInteger.valueOf(10), // nonce
BigInteger.valueOf(700), // gasPrice
BigInteger.valueOf(4712388), // gasLimit
toAddress, // to
BigInteger.valueOf(101) // value
);
//Unterzeichnen Sie die Transaktion
byte[] signedMessage = TransactionEncoder.signMessage(rawTransaction, credentials);
String hexValue = Numeric.toHexString(signedMessage);
//Senden einer Transaktion
EthSendTransaction ethSendTransaction = web3j.ethSendRawTransaction(hexValue).send();
String response = ethSendTransaction.getRawResponse();
String transactionHash = ethSendTransaction.getTransactionHash();
Optional<TransactionReceipt> transactionReceipt = null;
int retry = 0;
//Transaktionsüberwachung
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;
}
}
Was machst du
Es wird der Fluss sein. Die Transaktionsüberwachung prüft, ob der Hashwert der angegebenen Transaktion in den Block eingefügt wurde.
Die Transaktion wurde erstellt.
INFO [09-15|23:29:23.752] Submitted transaction fullhash=0x533ff5d2635284d01d8e85015da00d8962de8b98bf5efaa6d9ceca3200243a88 recipient=0x66B4e7bE902300F9a15D900822Bbd8803Be87391
> eth.getTransaction("0x533ff5d2635284d01d8e85015da00d8962de8b98bf5efaa6d9ceca3200243a88")
{
blockHash: "0x0000000000000000000000000000000000000000000000000000000000000000",
blockNumber: null,
from: "0x945cd603a6754cb13c3d61d8fe240990f86f9f8a",
gas: 4712388,
gasPrice: 800,
hash: "0x533ff5d2635284d01d8e85015da00d8962de8b98bf5efaa6d9ceca3200243a88",
input: "0x",
nonce: 10,
r: "0xc8022528f46078b3e9a8f2a3174d147b85c23af6794fc8b07d58651931b7556f",
s: "0x1ab35d15cf3afa6990bc6e96a593e6c2cba6432f769d0de919c770cec4a3f2c7",
to: "0x66b4e7be902300f9a15d900822bbd8803be87391",
transactionIndex: 0,
v: "0x1b",
value: 101
}
Diese Transaktion ist jedoch nicht im Block enthalten, egal wie viel Mining ich mache, da mein Verständnis nicht aufholt. Stimmt etwas mit dem für die Transaktion angegebenen Wert nicht? Oder ist es nicht im Block enthalten, ohne die signierte Transaktion zu validieren?
Ich werde diesen Bereich weiter studieren.
Ich habe nur gelernt, indem ich den Inhalt des Buches vage eingegeben habe, aber als ich untersuchte, wie man ihn in Java, meiner stärksten Sprache, verwendet, wurden die Punkte, auf die bisher hingewiesen wurde, immer mehr miteinander verbunden.
Da noch wenig Informationen verfügbar sind, möchte ich das Gelernte positiv ausgeben können.
Es heißt, dass signierte Transaktionen nicht im Block enthalten sind, aber ich habe die Lösung gefunden (ich habe meine Senioren gefragt und sie in 1 Minute gefunden), also habe ich sie im folgenden Artikel geschrieben.
Überprüfen Sie, ob Ethereum-Transaktionen nicht im Block enthalten sind