写点什么

Ethereum 第一笔转账

作者:FunTester
  • 2023-08-14
    北京
  • 本文字数:2702 字

    阅读完需:约 9 分钟

大概是个反射弧巨长,区块链的概念火了这么久,最近才开始学习区块链相关的技术。基础概念学完了,朋友推荐了宇宙第一链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转账已经完成。

发布于: 刚刚阅读数: 5
用户头像

FunTester

关注

公众号:FunTester,800篇原创,欢迎关注 2020-10-20 加入

Fun·BUG挖掘机·性能征服者·头顶锅盖·Tester

评论

发布
暂无评论
Ethereum第一笔转账_FunTester_InfoQ写作社区