Ethereum第一笔转账

大概是个反射弧巨长,区块链的概念火了这么久,最近才开始学习区块链相关的技术。基础概念学完了,朋友推荐了宇宙第一链Ethereum。经过了周末的学习,终于完成了第一个目标:第一笔转账。

分享一下学习过程和成果,仅供参考。文中涉及的知识均来源于官方文档,地址可以自行搜索。文档有中文版本,但是在代码实践部分还是英文居多。建议初学者把概念性的文档也看一遍,不要直接上手代码。

测试链

首先呢,我们需要在本地搭建一条测试链,就好像HTTP接口测试,我们需要一个本地的测试服务器一样。这个po一下官方提醒:

您应该先理解以太坊堆栈和以太坊网络基础知识才能进入开发网络。

在官方给出的开发工具中,我选择了Ganache,无他,因为它排在第一位。可以部署测试链,部署智能合约,完全满足了我的需求。

安装同其他软件,然后启动就可以界面:

安装页面

对于新手而言,选择QUICKSTART即可,就可以看到主页面。这里就不放图片占用篇幅了。启动成功后你就得到一个本地服务的IP和端口,这个就是代码中的host值。关于如何获取主网的查询的host这块,我建议小白先跳过,没必要在本地搞一个Ethereum的客户端。

创建Java项目

由于我习惯用了Java,所以先从Java开始。当然后面等我熟练了之后还是会尝试使用Groovy实现。后期计划用Golang再写一遍,这里不多说了。

我用了Java依赖Web3j,就我看到的资料很多jsonrpc的实现,本质上还是HTTP的请求。本来想着用FunTester框架实现。但是目下的场景不太允许我这个区块链小白这么搞。

依赖配置:

        <dependency>
            <groupId>org.web3j</groupId>
            <artifactId>core</artifactId>
            <version>4.3.0</version>
        </dependency>

然后需要个类和main方法,其他无。

验证Demo

当准备工作就绪,我们编写一些代码调用Ethereum的API验证本地测试链是否有效。

import com.funtester.frame.SourceCode;  
import org.web3j.protocol.Web3j;  
import org.web3j.protocol.core.methods.response.EthProtocolVersion;  
import org.web3j.protocol.http.HttpService;  
  
import java.io.IOException;  
  
public class Demo extends SourceCode {  
  
    static Web3j drive = Web3j.build(new HttpService("http://127.0.0.1:7545"));  
  
    public static void main(String[] args) throws IOException {  
        EthProtocolVersion send = drive.ethProtocolVersion().send();  
        output(parse(send));  
    }  
  
}

当控制台输出一下格式信息,表示环境搭建工作已经完成了。

~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~ JSON ~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~
♨ ♨ {
♨ ♨ ① ➤ "result":"0x3f",
♨ ♨ ① ➤ "protocolVersion":"0x3f",
♨ ♨ ① ➤ "id":0,
♨ ♨ ① ➤ "jsonrpc":"2.0"
♨ ♨ }
~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~ JSON ~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~

转账

Ethereum的API很多,Web3j都有对应的实现方法,虽然文档写测试链公共不全,但是就我目前使用来看,用来学习足够,没有遇到缺失的功能。

账号之前的转账是个非常重要的API,相比其他查询API也是比较麻烦的,因为涉及到签名加密。PS:有文档写Ganache允许无签名转账,这个我没试过,毕竟将来是要去主网冲浪的。

下面是转账的Demo,其中key均为测试链上测试账号的,可以通过Ganache页面上小钥匙按钮获得。

package com.funtester.ethereum;

import com.funtester.frame.SourceCode;
import org.web3j.crypto.Credentials;
import org.web3j.crypto.RawTransaction;
import org.web3j.crypto.TransactionEncoder;
import org.web3j.protocol.Web3j;
import org.web3j.protocol.core.DefaultBlockParameterName;
import org.web3j.protocol.core.methods.response.*;
import org.web3j.protocol.http.HttpService;
import org.web3j.utils.Convert;
import org.web3j.utils.Numeric;

import java.io.IOException;
import java.math.BigInteger;
import java.util.Optional;

public class Demo extends SourceCode {

    static Web3j drive = Web3j.build(new HttpService("http://127.0.0.1:7545"));

    public static void main(String[] args) throws IOException, InterruptedException {
        String privateKey = "0x04c02dc2381e1f69a274fa7cc4851c9eb01358fae8753dd4273014b43e34ab0c";
        Credentials credentials = Credentials.create(privateKey);
        EthGetTransactionCount ethGetTransactionCount = drive.ethGetTransactionCount(credentials.getAddress(), DefaultBlockParameterName.LATEST).send();
        BigInteger nonce = ethGetTransactionCount.getTransactionCount();
        String recipientAddress = "0x9483df5Bb8183548B4D7eb66B44C41FccD7c40A6";
        BigInteger value = Convert.toWei("1", Convert.Unit.ETHER).toBigInteger();
        BigInteger gasLimit = BigInteger.valueOf(22100);
        BigInteger gasPrice = Convert.toWei("11", Convert.Unit.GWEI).toBigInteger();
        RawTransaction rawTransaction = RawTransaction.createEtherTransaction(
                nonce,
                gasPrice,
                gasLimit,
                recipientAddress,
                value);
        byte[] signedMessage = TransactionEncoder.signMessage(rawTransaction, credentials);
        String hexValue = Numeric.toHexString(signedMessage);
        EthSendTransaction ethSendTransaction = drive.ethSendRawTransaction(hexValue).send();
        String transactionHash = ethSendTransaction.getTransactionHash();
        Optional<TransactionReceipt> transactionReceipt = null;
        do {
            EthGetTransactionReceipt ethGetTransactionReceiptResp = drive.ethGetTransactionReceipt(transactionHash).send();
            transactionReceipt = ethGetTransactionReceiptResp.getTransactionReceipt();
            Thread.sleep(3000);
        } while (!transactionReceipt.isPresent());
        System.out.println("deal confirm");
    }

}

后面循环等待响应写得不够优雅,等熟练了封装一个趁手的方法。

控制台输出deal confirm的话,说明转账已经被确认了。可以去Ganache确认一下余额是否正确。当然可以通过Ethereum的API查询对应账户的余额前后变化量是否与预期一致。

年轻人的第一笔Ethereum转账

年轻人的第一笔Ethereum转账

年轻人的第一笔Ethereum转账已经完成。

posted @   FunTester  阅读(19)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· .NET10 - 预览版1新功能体验(一)
历史上的今天:
2020-08-14 httpclient使用HTTP代理实践
点击右上角即可分享
微信分享提示