web3j ist eine Java-Bibliothek, die über JSON-RPC mit Ethereum-Clients (Knoten) kommunizieren kann. In diesem Artikel werde ich die grundlegende Verwendung von web3j vorstellen.
Thema
Starten Sie zunächst den Ethereum-Client und aktivieren Sie die JSON-RPC-Kommunikation. Starten Sie beispielsweise "Geth", um die JSON-RPC-Kommunikation über HTTP zu aktivieren.
Wenn Sie bereit sind, verwenden Sie web3j, um eine Verbindung zum Ethereum-Client herzustellen.
//HTTP-Verbindung
Web3j web3j = Web3j.build(new HttpService("http://<ip address>:<port>"));
//IPC-Verbindung(Unix)
Web3j web3 = Web3j.build(new UnixIpcService("/path/to/socketfile"));
//IPC-Verbindung(Windows)
Web3j web3 = Web3j.build(new WindowsIpcService("/path/to/namedpipefile"));
Nachdem Sie erfolgreich eine Verbindung zum Ethereum-Client hergestellt haben, können Sie mit JSON-RPC kommunizieren. Die JSON-RPC-Kommunikation mit web3j ist sehr einfach.
web3_clientVersion
Um beispielsweise die Methode "web3_clientVersion" von JSON-RPC aufzurufen, schreiben Sie wie folgt.
(Web3_clientVersion
ist eine Methode zum Überprüfen der Version des Ethereum-Clients)
//Stellen Sie eine Verbindung mit dem Ethereum-Client her
Web3j web3j = Web3j.build(new HttpService("http://localhost:8545"));
// JSON-RPC-Anfrage senden und Antwort empfangen
Web3ClientVersion response = web3j.web3ClientVersion().send();
//Ausgabeergebnis
System.out.println(response.getResult());
Ausgabe(Beispiel)
Geth/v1.8.17-stable-8bbe7207/windows-amd64/go1.11.1
Wie Sie sehen können, bietet web3j eine eigene Java-Methode zum Anfordern jeder JSON-RPC-Methode.
eth_getBlockByNumber Im Folgenden finden Sie ein Beispiel, in dem Sie ein Methodenargument angeben müssen. Hier erhalten Sie die neuesten ("neuesten") Blockinformationen mithilfe der JSON-RPC-Methode "eth_getBlockByNumber".
//Stellen Sie eine Verbindung mit dem Ethereum-Client her
Web3j web3j = Web3j.build(new HttpService("http://localhost:8545"));
// JSON-RPC-Anfrage senden und Antwort empfangen
EthBlock response = web3j.ethGetBlockByNumber(
DefaultBlockParameterName.LATEST, //Blocknummer. Hier ist ein Tag, das den neuesten Block darstellt"latest"Konkretisieren
false //Wenn dies der Fall ist, erhalten Sie die Transaktionsdetails. Wenn false, erhalten Sie nur den Transaktions-Hash
).send();
//Ausgabeergebnis
Block block = response.getResult();
System.out.println("hash:" + block.getHash());
System.out.println("number:" + block.getNumber());
Ausgabe(Beispiel)
hash:0x7abc74f4b77054a378cd8969b77ca207ed74ff925bd751314186180d37818d33
number:7311
Auf diese Weise können Methodenargumente auch gemäß den JSON-RPC-Spezifikationen angegeben werden, sodass ich denke, dass dies sehr einfach zu verstehen ist.
eth_sendTransaction
Das folgende Beispiel beinhaltet die Ausgabe einer Transaktion.
Hier senden wir Ether mit dem JSON-RPC eth_sendTransaction
.
Zuvor müssen Sie jedoch Ihr Konto entsperren. Wenn der Ethereum-Client "Geth" ist, bietet JSON-RPC eine "personal_unlockAccount" -Methode. Verwenden Sie diese Methode, um Ihr Konto zu entsperren und dann Ether zu senden.
//Stellen Sie eine Verbindung mit dem Ethereum-Client her
//Admin ist eine Unterklasse von Web3j"personal_unlockAccount"Die Anforderungsverarbeitung ist implementiert.
Admin web3j = Admin.build(new HttpService("http://localhost:8545"));
// "personal_unlockAccount"Senden Sie eine Anfrage und erhalten Sie eine Antwort
PersonalUnlockAccount unlockAccountResponse = web3j.personalUnlockAccount(
"0x766a1c4737970feddde6f2b8659fca05bd0339ab", //Adresse
"pass1" //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
Transaction transaction = Transaction.createEtherTransaction(
"0x766a1c4737970feddde6f2b8659fca05bd0339ab", // from
null, //nonce. Diesmal nicht angegeben, also null
null, //gasPreis. Diesmal nicht angegeben, also null
null, //Gaslimit. Diesmal nicht angegeben, also null
"0x0cbc0fe59d39e58d7369ca436fe5c6b4b71341d5", // to
BigInteger.valueOf(100) // value
);
// "eth_sendTransaction"Senden Sie eine Anfrage und erhalten Sie eine Antwort
EthSendTransaction sendTransactionResponse = web3j.ethSendTransaction(transaction).send();
//Ausgabeergebnis
System.out.println(sendTransactionResponse.getResult());
}
Ausgabe(Beispiel)
0x3557db13b5ac56f1e3e23ab9eeccd11b2c4daf73e416496d53c5bba377202a61
web3j bietet nützliche Funktionen, die über das einfache Aufrufen von JSON-RPC-Methoden hinausgehen. Hier werden die folgenden drei Funktionen vorgestellt.
Was ist eine Wallet-Datei? Das könnte man denken. Dies wird in "Geth" als "Schlüsseldatei" bezeichnet. Die Schlüsseldatei wird erstellt, wenn Sie "geth account new" ausführen. Normalerweise wird die Schlüsseldatei in "Geth" in "\ <datadir > / keystore" abgelegt. Diese "Schlüsseldatei" wird in web3j als "Brieftaschendatei" bezeichnet.
In web3j wird der Vorgang zum Entsperren des Kontos mithilfe der Brieftaschendatei vereinfacht. Hier senden wir Ether mithilfe der Wallet-Datei.
Platzieren (kopieren) Sie zunächst die Wallet-Datei an einem Ort, auf den von der Umgebung aus zugegriffen werden kann, in der das web3j-Programm ausgeführt wird. Wenn Sie bereit sind, verwenden Sie Ihre Wallet-Datei, um Ether zu senden.
//Stellen Sie eine Verbindung mit dem Ethereum-Client her
Web3j web3j = Web3j.build(new HttpService("http://localhost:8545"));
//Brieftaschendatei laden
Credentials credentials = WalletUtils.loadCredentials(
"pass1", //Konto Passwort
"/pass/to/walletfile"
);
//Sende Äther
TransactionReceipt receipt = Transfer.sendFunds(
web3j,
credentials,
"0xdc87fc3ac1ec09ed43623dd9da4c6f3d792a88f5", // to
new BigDecimal("1000"), // value
Unit.ETHER // unit
).send();
Sobald Sie die Brieftaschendatei geladen haben, können Sie sie beliebig oft verwenden. Wenn Sie mehrere Transaktionen ausführen möchten, müssen Sie "personal_unlockAccount" nicht mehrmals anfordern, was den Vorgang vereinfacht.
web3j bietet ein Tool (Befehlszeilentool) zum Generieren einer Wrapper-Klasse für einen Vertrag.
Wrapper-Klassen vereinfachen die Bereitstellung von Verträgen und Aufrufmethoden.
(Natürlich ist es auch möglich, die JSON-RPC eth_sendTransaction
und eth_call
anzufordern, den Vertrag bereitzustellen und die Methode aufzurufen, ohne die Wrapper-Klasse zu verwenden.)
Hier wird als Beispiel die Wrapper-Klasse der folgenden in Solidity geschriebenen Quelle generiert.
Token.sol
pragma solidity ^0.5.0;
contract Token {
uint256 public totalSupply;
mapping (address => uint256) public balanceOf;
constructor (uint256 _initialSupply) public {
totalSupply = _initialSupply;
balanceOf[msg.sender] = _initialSupply;
}
function transfer(address _to, uint256 _value) public {
require(balanceOf[msg.sender] >= _value);
require(balanceOf[_to] + _value >= balanceOf[_to]);
balanceOf[msg.sender] -= _value;
balanceOf[_to] += _value;
}
}
Kompilieren Sie zunächst die Quelle mit Online Compiler. Sie können den ABI und den Bytecode erhalten, indem Sie die Quelle kompilieren. Speichern Sie den erhaltenen ABI- und Bytecode in einer Datei.
Im Beispiel habe ich den ABI und den Bytecode wie unten gezeigt in einer Datei gespeichert.
Token.abi
[{"constant":true,"inputs":[],"name":"totalSupply","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"","type":"address"}],"name":"balanceOf","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_to","type":"address"},{"name":"_value","type":"uint256"}],"name":"transfer","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"inputs":[{"name":"_initialSupply","type":"uint256"}],"payable":false,"stateMutability":"nonpayable","type":"constructor"}]
Token.bin
0x608060405234801561001057600080fd5b506040516020806103a28339810180604052602081101561003057600080fd5b81019080805190602001909291905050508060008190555080600160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550506103068061009c6000396000f3fe608060405260043610610051576000357c01000000000000000000000000000000000000000000000000000000009004806318160ddd1461005657806370a0823114610081578063a9059cbb146100e6575b600080fd5b34801561006257600080fd5b5061006b610141565b6040518082815260200191505060405180910390f35b34801561008d57600080fd5b506100d0600480360360208110156100a457600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610147565b6040518082815260200191505060405180910390f35b3480156100f257600080fd5b5061013f6004803603604081101561010957600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291908035906020019092919050505061015f565b005b60005481565b60016020528060005260406000206000915090505481565b80600160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054101515156101ad57600080fd5b600160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205481600160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054011015151561023c57600080fd5b80600160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254039250508190555080600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282540192505081905550505056fea165627a7a72305820f97c3c938c56e1b594db9c9b681f3a08bb4ef81ef0fa5888d5982034167a44ba0029
Als nächstes erhalten Sie die Befehlszeilen-Tools. Sie können die Befehlszeilentools von der GitHub-Release-Seite (https://github.com/web3j/web3j/releases) herunterladen.
Entpacken Sie die heruntergeladene komprimierte Datei und führen Sie die ausführbare Datei im bin-Verzeichnis wie folgt aus.
web3j solidity generate -a=/path/to/Token.abi -b=/path/to/Token.bin -o=/path/to/src/main/java -p=package.name
Wenn der Befehl erfolgreich ist, wird eine Wrapper-Klasse mit dem Namen "Token.java" in dem durch -o und -p angegebenen Verzeichnis generiert.
Nachdem Sie fertig sind, verwenden wir die Wrapper-Klasse, um den Vertrag bereitzustellen und die Methode aufzurufen.
//Stellen Sie eine Verbindung mit dem Ethereum-Client her
Web3j web3j = Web3j.build(new HttpService("http://localhost:8545"));
//Brieftaschendatei laden
Credentials credentials = WalletUtils.loadCredentials(
"pass1", //Konto Passwort
"/pass/to/walletfile"
);
//Vertrag bereitstellen
Token token = Token.deploy(
web3j,
credentials,
BigInteger.valueOf(1000000000L), // gasPrice
BigInteger.valueOf(4700000L), // gasLimit
BigInteger.valueOf(100000000000L) //initialSupply (Konstruktorargument)
).send();
//Geben Sie die Adresse des Vertrags aus
System.out.println("contract address: " + token.getContractAddress());
//Methodenaufruf (keine Transaktion)
System.out.println("totalSupply: " + token.totalSupply().send());
System.out.println("balance of user1: " + token.balanceOf("0x766a1c4737970feddde6f2b8659fca05bd0339ab").send());
//Methodenaufruf (mit Transaktion)
System.out.println("Sending ether to user2...");
TransactionReceipt tran = token.transfer("0xdc87fc3ac1ec09ed43623dd9da4c6f3d792a88f5", BigInteger.valueOf(1000L)).send();
//Ergebnisausgabe
System.out.println("transaction hash: " + tran.getTransactionHash());
System.out.println("balance of user1: " + token.balanceOf("0x766a1c4737970feddde6f2b8659fca05bd0339ab").send());
System.out.println("balance of user2: " + token.balanceOf("0xdc87fc3ac1ec09ed43623dd9da4c6f3d792a88f5").send());
Ausgabe(Beispiel)
contract address: 0x7b1530efbcbc4e9588fea3e505a95a3aeb84f3ed
totalSupply: 100000000000
balance of user1: 100000000000
Sending ether to user2...
transaction hash: 0x47cea479cd5aa3b4fc2fda5a0fcf6f5edc83ad2692a10355338b43aad9de41ef
balance of user1: 99999999000
balance of user2: 1000
Sie sehen, dass die Vertragsbereitstellung und der Methodenaufruf sehr einfach beschrieben werden können.
Abschließend werde ich die Ereignisüberwachungsfunktion vorstellen. web3j bietet eine Funktion zum reaktiven Verarbeiten von Ethereum-Ereignissen.
Bei der Ereignisüberwachung mit JSON-RPC wird normalerweise zuerst ein Filter mit "eth_newBlockFilter", "eth_newFilter" usw. registriert und anschließend das Ereignis mit "eth_getFilterChanges" abgefragt. .. Das ist sehr mühsam, nicht wahr?
Mit der von web3j bereitgestellten Funktion kann die Ereignisüberwachung wie folgt beschrieben werden.
//Stellen Sie eine Verbindung mit dem Ethereum-Client her
Web3j web3j = Web3j.build(new HttpService("http://localhost:8545"));
//Filter registrieren (Ereignisüberwachung starten)
Disposable disposable = web3j.blockFlowable(false).subscribe(ethBlock -> {
//Wenn ein neuer Block auftritt, führen Sie die folgende Verarbeitung durch
Block block = ethBlock.getBlock();
System.out.println(block.getNumber());
});
//Filter entfernen (Endereignisüberwachung)
disposable.dispose();
Es ist sehr einfach zu schreiben.
Recommended Posts