1 Web3j概述
用于与Ethereum客户端集成的轻量级Java库。
2 区块链基础
对于编程者来说,区块链不是一个很难理解的概念,因为最难懂的部分(包括挖矿,哈希,椭圆加密,P2P网络)都只是提供了一系列的特性和约束,一旦你知道了这些特性和约束,就不必去理解这些特性或是约束背后的实现原理。
2.1 交易
区块链是全局共享,交易数据库。这就意味着任何人只要参与到这个网络中就可以访问到这个数据库。如果要修改数据库中的数据,就需要创建一个被其他所有在这个网络里的人所认可的交易。交易说明对数据的修改要么没有任何进行,要么就全部完成,不会出现部分完成,部分未完成的情况。而且一旦交易完成,被记录在数据库中,谁也无法修改这个交易。
举个例子,想象在一个电子货币里,用表列举出所有账号余额,当进行一个账号和另外一个账号进行交易时,交易数据库要确保交易金额要从交易发送方减去,并且在交易接收方增加同样的交易金额。如果交易过程中出现了任何原因导致交易失败,交易发送方增加金额的行为失败,那接收方的金额也不应该发生变化。
而且发送方都会对发起的交易进行签名加密。这直接地保证了数据库只能被指定的修改所修改。在电子货币的例子中,简单的检查能够确保只有持有这个账号的秘钥者才能对金额进行转移。
3 实战经验
3.1 创建项目
这里创建的是spring boot项目,因为spring boot方便管理,当然你也可以创建普通的maven项目。
3.2 导入依赖关系
主要有几个依赖:
1. 加密解密
2. 快速的JSON序列化和反序列化
3. http的网络连接
4. web3j的依赖
5. spring boot的依赖
3.3 连接以太坊客户端
这样是使用web3j最原始的连接方法,可以打印版本号和以太坊的信息,如果要创建交易,可以使用Admin来进行连接。
3.4 使用admin连接以太坊客户端
Admin admin =Admin.build(new HttpService());
3.5 解锁账号
//解锁账号
PersonalUnlockAccount personalUnlockAccount = admin.personalUnlockAccount(fromAccountId, password,ACCOUNT_UNLOCK_DURATION).
sendAsync().get(5, TimeUnit.MINUTES);
发送交易之前必须先解锁账号,否则可能会发生账号被锁定的情况而无法发生交易,解锁需要输入自己的密码,并且设置时间。
3.6 获取交易手续费
当一个事务发生在Ethereum时,必须向执行事务的客户端支付事务成本,将此事务的输出提交给Ethereum区块链。gas price 和gasLimit影响交易的速度这些参数一起决定了您愿意花费在交易成本上的最大数量的乙醚。即可以花费不超过天然气价格*天然气限制。天然气价格也会影响交易发生的速度,这取决于其他交易对于矿工而言是否有利可图的天然气价格。您可能需要调整这些参数以确保交易及时进行。
交易的gas limit 一定要等于或者大于交易使用的intrinsic gas, intrinsic gas包括:
* 1. 执行交易预订费用为21,000gas.
* 2. 随交易发送的数据的gas费用(每字节数据或代码为0的费用为4gas,每个非零字节的数据或代码费用为68gas)。
* 3. 如果是合约创建交易,还需要额外的32,000gas 目前区块的gas limit是 4,712,357 gas,数据来自于ethstats.net.
* 这表示着大约224笔转账交易(gas limit为21000)可以被塞进一个区块(区块时间大约在15-20秒间波动)。
* 这个协议允许每个区块的矿工调整区块gas limit,任意加减1/2024(0.0976%)。
Nonce
为了防止交易的重播攻击,每笔交易必须有一个nonce随机数,针对每一个账户nonce都是从0开始,当nonce为0的交易处理完之后,才会处理nonce为1的交易,并依次加1的交易才会被处理。以下是nonce使用的几条规则:
当nonce太小,交易会被直接拒绝;
当nonce太大,交易会一直处于队列之中。
3.7 创建交易事务
为了纪念第一次交易,我们把hello eth 作为标记打入到ETH里面。ETH要求打印的标记必须是16进制,而且以0x开头,这里我们使用Numeric类的方法把我们的标记打入进去。
为了纪念第一次交易我们把hello eth 作为标记打入到ETH里面。ETH要求打印的标记必须是16进制,而且以0x开头,这里我们使用Numeric类的方法把我们的标记打入进去。
3.8 获取gas和balance
3.9 发送交易
这里采用的是异步发送交易的方式,tradeHash可以获取我们交易返回的Hash码,最后我们需要根据Hash码找到我们的数据。
3.10 验证交易
EthTransactionethTransaction=admin.ethGetTransactionByHash(tradeHash).send();
org.web3j.protocol.core.methods.response.Transaction transactionResult = ethTransaction.getResult();
System.out.println(transactionResult.getValue());
transactionResult里面是我们返回的数据,可以查看到blockHash,gas,nonce等信息,我们取出input,这是我们的输入参数,然后把16进制转码为10进制就可以看到我们的hello eth.
4 总结
通过web3j 交易接口的调用我们对eth的交易步骤和交易所需要的条件都已经有所了解,这个对于我们以后开发钱包和发送离线交易都有所帮助。