赞
踩
普通交易由由节点负责签名,然后发送到以太坊网络中心进行确认。
在 web3j 中,提交一个普通交易,需要使用ethSendTransaction()方法发送一个Transaction对象,该方法对应以太坊提供的eth_sendTransaction这个 RPC 接口。
在发送Transaction对象之前,首先要准备本次交易的相关数据,包括以下四种信息:
信息类型 | 内容 |
---|---|
交易基本信息 | 发送方、接收方、发送金额 |
执行交易的报酬信息 | gas价格、gas用量上限 |
交易识别信息 | nonce(对抗重放攻击) |
补充数据信息 | 额外的数据 |
在以上四种交易信息中,发送方和接收方是not null的,其余信息都可设置为null。
Transaction对象的构造方法(注意是request包下的Transaction对象)
java测试代码(账户一向账户二转账100000wei)
@Test public void submitNormalTransaction() throws IOException { Web3j web3j = Web3j.build(new HttpService("http://localhost:8545"));//实例化web3j对象 List<String> accounts = web3j.ethAccounts().send().getAccounts();//获取所有账户信息 String account1 = accounts.get(0);//获取第一个账户的信息 String account2 = accounts.get(1);//获取第二个账户的信息 String from = account1; //发送方 String to = account2; //接收方 BigInteger nonce = null; BigInteger gasPrice = null; BigInteger gasLimit = null; BigInteger value = new BigInteger("100000"); Transaction transaction = new Transaction(from,nonce,gasPrice,gasLimit,to,value,null); String transactionHash = web3j.ethSendTransaction(transaction).send().getTransactionHash(); System.out.println(transactionHash); BigInteger balance1 = web3j.ethGetBalance(from, DefaultBlockParameterName.LATEST).send().getBalance(); BigInteger balance2 = web3j.ethGetBalance(to, DefaultBlockParameterName.LATEST).send().getBalance(); System.out.println("账户一的余额:"+balance1); System.out.println("账户二的余额:"+balance2); }
执行结果:
产生的区块哈希:
交易后两账户的余额:(这里发现账户二增加了100000wei,但账户一却扣了很多,这部分便是gas消耗的费用)
由于以太坊共识机制的存在,因此我们提交的交易不会即刻生效。要查询交易是否生效,需要使用 ethSendTransaction()方法返回的交易哈希读取交易收据。
根据以太坊的约定,应用需要调用 eth_getTransactionReceipt 接口来检索具有指定哈希交易的收据。在 web3j,该请求对应ethGetTransactionReceipt() 方法,响应则对应 EthGetTransactionReceipt
类。
检验刚才的交易是否生效:(每隔5s检验一次,如果已经生成了Receipt对象,则交易生效;若超过50s仍未检验到,则交易失败。)
@Test public void getTransactionReceipt() throws IOException, InterruptedException { Web3j web3j = Web3j.build(new HttpService("http://localhost:8545")); long timeout = 50000L; long t0 = System.currentTimeMillis(); Optional<TransactionReceipt> receipt = null; while(true){ receipt = web3j.ethGetTransactionReceipt("0xe7fae8c9a1e268d063de3019899ff07291074284d79ba1b42b5bf96e1202bec5").send().getTransactionReceipt(); if(receipt.isPresent()) { System.out.println("交易生效!"); break; } if((System.currentTimeMillis() - t0) > timeout) { System.out.println("超时!交易失败!"); break; } Thread.sleep(1000*5); }
gas:矿工计算区块数据时运行需要相应的报酬,在发送方扣除对应的手续费。
计算区块数据所需运行的步数称为实际运行步数,单步价格则是我们设定的gasPrice,矿工挖矿时也会优先选择gasPrice高的计算数据。
gasLimit则为发送方设定的gas可用上限,若运行步数到达了这个值,则会被取消本次交易,但手续费依然会被扣除。
交易手续费(Tx Fee) = 实际运行步数(Actual Gas Used) * 单步价格(Gas Price)
交易的最高手续费:GasPrice*GasLimit
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。