最近Ethereum又學了一點點,學會了主網衝浪和錢包的地址和私鑰的生成。分享一點點學習成果,分爲3部分:
- 申請infura主網的apikey
- 使用Web3j API網上衝浪
- 錢包生成和概念釋疑
因爲是初學小白,所以這中間又進行了一些基礎知識的補習,才慢慢使用Web3j。如果你也想了解區塊鏈,建議先了解足夠概念性的知識,這裏我踩坑比較多,幸好有個小夥伴隨時答疑,這裏表示感謝。
infura apikey
在Ethereum官方的教程中,是給出瞭如何使用不同語言的Ethereum客戶端連接主網同步區塊鏈信息的。本人操作了兩波,均已失敗告終。後來去論壇看其他小白的帖子,發現這並不是說可以一鍵安裝啓動的過程,還需要進行不少的配置。索性我就放棄了。
爲了進行主網的衝浪,特意查了一下,很多網上很多免費的Ethereum查詢節點,這裏我選擇infura
,無他,它排第一。
首先去官網註冊,申請apikey,然後查看使用規則,主要限速和次數限制。這一點非常贊,免費版每24小時10w次請求,足夠我的使用,申請還能測試併發。
然後通過apikey管理端獲取到主網的訪問地址和驗證信息。infura
還提供了請求次數,請求接口分佈等功能,的確非常良心。
如果你想使用測試網,請注意:
Goerli 測試網已棄用(opens in a new tab)↗,它將在 2023 年被 Holesovice(opens in a new tab)↗ 取代。 請考慮把你的應用程序遷移至 Sepolia。
Web3j API
這裏先介紹Web3j
的HTTP API
其他協議的還在看,搞明白了在跟大家分享。
Web3j
使用的是okhttp
,具體的封裝實現這裏就不說了,重點是Web3j
的語法習慣。
創建客戶端
首先我們需要創建一個Web3j
的對象,語法如下:
static Web3j web3 = Web3j.build(new HttpService("https://mainnet.infura.io/v3/{your apikey}"));
其實就是替換一下訪問地址。
創建請求
Web3j
的語法有點類似建造者模式(Builder Pattern),先構建request
,然後再send()
獲取response
。創建語法:
Request<?, NetVersion> netVersionRequest = web3.netVersion();
這樣我們就獲取了一個request
,Web3j
所有的請求方法都在org.web3j.protocol.core.Ethereum
中定義了,有4中不同的實現,有興趣的可以多翻一翻。
獲取響應
書接上文,語法如下:
NetVersion send = netVersionRequest.send();
Web3j
對每個請求類型都封裝了一個對象接收響應信息。響應中包含信息較多,如果不熟練的可以翻翻響應對象的源碼。
PS:這裏解析org.web3j.protocol.core.methods.response.EthBlock.TransactionResult
有個坑,需要強轉一下,分享:
List<EthBlock.TransactionResult> transactions = web3.ethGetBlockByNumber(new DefaultBlockParameterNumber(blockNumber),true).send().getBlock().getTransactions();
transactions.forEach(f->{
EthBlock.TransactionObject f1 = (EthBlock.TransactionObject) f;
output(parse(f1));
});
關於異步
這裏不提倡,因爲之前文章Web3j異步導致JVM無法退出BUG分享提到,已經提了issue
,但是開發者並沒有理我。看最新的代碼依舊沒打算修復這個問題。
如果你是開發服務,或者使用文章提到2種修復方案,異步還是很香的。
錢包
我之前一直有個困惑,錢包的信息是如何上傳到區塊鏈上的。區塊鏈並沒有認證機制來識別到底是不是有效的錢包,而且感覺好像誰都可以創建錢包。
學完這塊我才明白,錢包實際就是地址,區塊鏈只是記賬,把賬號(錢包)地址記住了。這個地址上面有多少餘額。
而私鑰就是取款密碼,而且不可更改。這是密碼學上的,加入私鑰丟了,就是失去了一切了。
這裏放一個生成本地錢包的方法,也是Web3j
提供的,並沒有助記詞的內容。據我查到資料,助記詞是另外的工具包纔有功能,實現也有很多,如需請自取。
import org.web3j.crypto.CipherException;
import org.web3j.crypto.Credentials;
import org.web3j.crypto.WalletUtils;
import java.io.File;
import java.io.IOException;
import java.security.InvalidAlgorithmParameterException;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
public class Wallet {
public static void main(String[] args) throws CipherException, IOException, InvalidAlgorithmParameterException, NoSuchAlgorithmException, NoSuchProviderException{
// 錢包存放路徑
String walletFilePath = "/Users/vallet/test";
// 錢包密碼
String password = "";
//生成錢包,對應目錄下會創建對應的私鑰文件。
String walletFileName = WalletUtils.generateNewWalletFile(password, new File(walletFilePath), false);
// 加載指定位置的錢包
Credentials credentials = WalletUtils.loadCredentials(password, walletFilePath + "/" + walletFileName);
String address = credentials.getAddress();
System.out.println("address:" + address);
System.out.println("PrivateKey:" + credentials.getEcKeyPair().getPrivateKey());
System.out.println("PublicKey:" + credentials.getEcKeyPair().getPublicKey());
}
}
如果你打開本地的錢包路徑,內容是一個JSON
格式的字符串,還可以進行二次加密,讓明文始終只存在於內存中。
PS:其實地址隨便寫都沒問題。如下: