Ethereum Web3j网上冲浪

2023-09-10 09:44:22 浏览数 (2)

最近Ethereum又学了一点点,学会了主网冲浪和钱包的地址和私钥的生成。分享一点点学习成果,分为3部分

因为是初学小白,所以这中间又进行了一些基础知识的补习,才慢慢使用Web3j。如果你也想了解区块链,建议先了解足够概念性的知识,这里我踩坑比较多,幸好有个小伙伴随时答疑,这里表示感谢。

infura apikey

在Ethereum官方的教程中,是给出了如何使用不同语言的Ethereum客户端连接主网同步区块链信息的。本人操作了两波,均已失败告终。后来去论坛看其他小白的帖子,发现这并不是说可以一键安装启动的过程,还需要进行不少的配置。索性我就放弃了。

为了进行主网的冲浪,特意查了一下,很多网上很多免费的Ethereum查询节点,这里我选择infura,无他,它排第一。

首先去官网注册,申请apikey,然后查看使用规则,主要限速和次数限制。这一点非常赞,免费版每24小时10w次请求,足够我的使用,申请还能测试并发。

然后通过apikey管理端获取到主网的访问地址和验证信息。infura还提供了请求次数,请求接口分布等功能,的确非常良心。

如果你想使用测试网,请注意:

FunTester原创专题推荐~Goerli 测试网已弃用(opens in a new tab)↗,它将在 2023 年被 Holesovice(opens in a new tab)↗ 取代。请考虑把你的应用程序迁移至 Sepolia。 -- By FunTester

Web3j API

这里先介绍Web3jHTTP 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();

这样我们就获取了一个requestWeb3j所有的请求方法都在org.web3j.protocol.core.Ethereum中定义了,有4中不同的实现,有兴趣的可以多翻一翻。

获取响应

书接上文,语法如下:

NetVersion send = netVersionRequest.send();

Web3j对每个请求类型都封装了一个对象接收响应信息。响应中包含信息较多,如果不熟练的可以翻翻响应对象的源码。

PS:这里解析org.web3j.protocol.core.methods.response.EthBlock.TransactionResult有个坑,需要强转一下,分享:

代码语言:javascript复制
        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提供的,并没有助记词的内容。据我查到资料,助记词是另外的工具包才有功能,实现也有很多,如需请自取。

代码语言:javascript复制
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:其实地址随便写都没问题。如下:

0 人点赞