Erc20代币
public class Erc20BlockChainNode extends Contract {
//说明web3j和contractAddress在项目初始化时候,调用Contract类里面的构造方法,已经赋值
public Erc20BlockChainNode(String contractBinary, String contractAddress, Web3j web3j, Credentials credentials, BigInteger gasPrice, BigInteger gasLimit) { super(contractBinary, contractAddress, web3j, credentials, gasPrice, gasLimit); } private Erc20BlockChainNode(String contractBinary, String contractAddress, Web3j web3j,TransactionManager transactionManager, BigInteger gasPrice, BigInteger gasLimit) { super(contractBinary, contractAddress, web3j, transactionManager, gasPrice, gasLimit); } public static Erc20BlockChainNode load(String contractBinary, String contractAddress, Web3j web3j, TransactionManager transactionManager, BigInteger gasPrice, BigInteger gasLimit) { return new Erc20BlockChainNode(contractBinary, contractAddress, web3j, transactionManager, gasPrice, gasLimit); } //获取交易的随机数 public BigInteger getNonce(String address) throws Exception { return web3j.ethGetTransactionCount(address, DefaultBlockParameterName.PENDING).send().getTransactionCount(); } //监听代币Erc20的交易,订阅 public Erc20Block getBlock(long blockNum) throws Exception { List<TransferEventResponse> result = new ArrayList<>();
//监听链上的代币交易 this.transferEventObservable(DefaultBlockParameter.valueOf(BigInteger.valueOf(blockNum)), DefaultBlockParameter.valueOf(BigInteger.valueOf(blockNum))).subscribe(observer -> { result.add(observer); }); return Erc20Block.fromWeb3(result);//fromWeb3()这个方法只是做了一个对象的转换 } //根据地址获取代币余额 public BigInteger getBalance(String address) throws Exception { String checkedAddr = EthUtils.checkAddress(address); if (StringUtils.isBlank(checkedAddr)) { return BigInteger.ZERO; } Function balanceOf = new Function("balanceOf", Arrays.<Type>asList(new Address(address)), Arrays.<TypeReference<?>>asList(new TypeReference<Uint256>() { })); String value = web3j.ethCall(Transaction.createEthCallTransaction(address, contractAddress, FunctionEncoder.encode(balanceOf)), DefaultBlockParameterName.PENDING).send().getValue(); return new BigInteger(value.substring(2), 16); } //发送代币交易 public SendTransaction transfer(String sourceAddr, String sourcePriKey, String targetAddr, BigInteger amount, BigInteger gasPrice, boolean amountIncludeFee) throws Exception { sourceAddr = EthUtils.checkAddress(sourceAddr); targetAddr = EthUtils.checkAddress(targetAddr); if (StringUtils.isAnyBlank(sourceAddr, targetAddr, sourcePriKey)) { return null; } if (gasPrice == null || gasPrice.compareTo(BigInteger.ZERO) < 0 || amount == null || amount.compareTo(BigInteger.ZERO) < 0) { return null; }
//获取交易的油费 BigInteger gas = EthUtils.calculateGas(null, gasPrice); BigInteger payAmount = amount; if (amountIncludeFee) { payAmount = amount.subtract(gas); if (payAmount.compareTo(BigInteger.ZERO) < 0) { return null; } } // 检查余额 BigInteger balance = this.getBalance(sourceAddr); if (balance.compareTo(payAmount.add(gas)) < 0) { return null; }
//创建地址和密钥对象 Credentials credentials = Credentials.create(sourcePriKey); BigInteger nonce = this.getNonce(sourceAddr);
//创建交易对象 Function function = new Function("transfer", Arrays.<Type>asList(new Address(targetAddr), new Uint256(amount)), Collections.<TypeReference<?>>emptyList()); String encodedFunction = FunctionEncoder.encode(function); RawTransaction rawTransaction = RawTransaction.createTransaction(nonce, gasPrice, gasLimit, contractAddress,encodedFunction); byte[] signMessage = TransactionEncoder.signMessage(rawTransaction, credentials); //发送交易 EthSendTransaction ethSendTransaction = web3j.ethSendRawTransaction(Numeric.toHexString(signMessage)).sendAsync().get(); return new SendTransaction(ethSendTransaction.getTransactionHash(), nonce,Convert.fromWei(gasPrice.toString(), Unit.ETHER)); }
// 根据块号监听代币交易信息
public Observable<TransferEventResponse> transferEventObservable(DefaultBlockParameter startBlock,DefaultBlockParameter endBlock) { //创建交易事件
final Event event = new Event("Transfer", Arrays.<TypeReference<?>>asList(new TypeReference<Address>() { }, new TypeReference<Address>() { }), Arrays.<TypeReference<?>>asList(new TypeReference<Uint256>() { })); EthFilter filter = new EthFilter(startBlock, endBlock, getContractAddress()); filter.addSingleTopic(EventEncoder.encode(event)); return web3j.ethLogObservable(filter).map(new Func1<Log, TransferEventResponse>() { @Override public TransferEventResponse call(Log log) { EventValues eventValues = extractEventParameters(event, log); TransferEventResponse typedResponse = new TransferEventResponse(); eventValues.getIndexedValues().size(); eventValues.getNonIndexedValues().size(); typedResponse._from = (Address) eventValues.getIndexedValues().get(0); typedResponse._to = (Address) eventValues.getIndexedValues().get(1); typedResponse._value = (Uint256) eventValues.getNonIndexedValues().get(0); typedResponse.log = log; return typedResponse; } }); } public static class TransferEventResponse { public Address _from; public Address _to; public Uint256 _value; public Log log; }