java 监听 ERC20 Token 交易

作者: 编程狂魔 | 来源:发表于2018-08-28 14:38 被阅读0次

    你可以在web3j库的帮助下使用java轻松监听以太坊交易,但此库无法监听Erc20 Token交易。

    要监听Erc20Token交易,你必须使用在合约(token)创建时的token封装类。我假设你已经使用最少的功能部署了合约,因此你的封装类看起来像这样:

    package com.bolenum.util;
    
    import java.io.IOException;
    import java.math.BigInteger;
    import java.util.ArrayList;
    import java.util...;
    
    import org.web3j.abi.EventEncoder;
    import org.web3j.abi...
    import org.web3j.crypto.Credentials;
    import org.web3j.protocol.Web3j;
    import org.web3j.protocol...;
    import org.web3j.tx.Contract;
    import org.web3j.tx.TransactionManager;
    
    import rx.Observable;
    import rx.functions.Func1;
    
    ...
    
    public final class Erc20TokenWrapper extends Contract {
    
        private static final String BINARY = "contract binary key";
    
        private Erc20TokenWrapper(String contractAddress, Web3j web3j, Credentials credentials, BigInteger gasPrice, BigInteger gasLimit) {
            super(BINARY, contractAddress, web3j, credentials, gasPrice, gasLimit);
        }
    
        private Erc20TokenWrapper(String contractAddress, Web3j web3j, TransactionManager transactionManager, BigInteger gasPrice, BigInteger gasLimit) {
            super(BINARY, contractAddress, web3j, transactionManager, gasPrice, gasLimit);
        }
    
        public List<TransferEventResponse> getTransferEvents(TransactionReceipt transactionReceipt) {
            ...
            return responses;
        }
    
        public Observable<TransferEventResponse> transferEventObservable(DefaultBlockParameter startBlock, DefaultBlockParameter endBlock) {
            ...
        }
    
        ...
        
        public Uint256 balanceOf(Address _owner) throws IOException {
            Function function = new Function("balanceOf", 
                    Arrays.<Type>asList(_owner), 
                    Arrays.<TypeReference<?>>asList(new TypeReference<Uint256>() {}));
            return executeCallSingleValueReturn(function);
        }
    
        ...
        
        public TransactionReceipt transfer(Address _to, Uint256 _amount) throws IOException, TransactionException {
            Function function = new Function("transfer", Arrays.<Type>asList(_to, _amount), Collections.<TypeReference<?>>emptyList());
            return executeTransaction(function);
        }
    
        ...
       
        public static Erc20TokenWrapper load(String contractAddress, Web3j web3j, TransactionManager transactionManager, BigInteger gasPrice, BigInteger gasLimit) {
            return new Erc20TokenWrapper(contractAddress, web3j, transactionManager, gasPrice, gasLimit);
        }
    
        public static class TransferEventResponse {
            public Address _from;
            public Address _to;
            public Uint256 _value;
            public String _transactionHash;
        }
        
        ...
    }
    

    现在你必须使用这个类函数来加载合约然后监听交易。使用下面的代码加载和监听交易:

    Web3j web3j = Web3j.build(new HttpService("url of your ethereum blockchain"))    
    ClientTransactionManager transactionManager = new ClientTransactionManager(web3j,
                        "your deployed contract addess");
                Erc20TokenWrapper token = Erc20TokenWrapper.load("your deployed contract addess", web3j, transactionManager,
                        Contract.GAS_PRICE, Contract.GAS_LIMIT);
                token.transferEventObservable(DefaultBlockParameterName.EARLIEST, DefaultBlockParameterName.LATEST)
                        .subscribe(tx -> {
                                       String toAddress = tx._to.getValue();
                                       String fromAddress = tx._from.getValue();
                                       String txHash = tx._transactionHash.getValue();
                                   }
    

    如果你已经部署了合约,它由第三人部署,那么你可以直接使用我的包装类,只需更改你可以从https://etherscan.io/tokens很容易获得的二进制密钥。

    结论:因此你可以将此代码用于任何token的监听交易。此代码为你提供addressfromAddresstransactionHash。所以这些东西你可以根据你的要求使用,你可以将它们保存在你的数据库中,或者你只保存地址是你的钱包地址的交易。

    谢谢,我希望这会有所帮助。

    如果希望快速进行web3j、java、以太坊开发,那请看我们精心打造的教程:
    java以太坊开发教程,主要是针对java和android程序员进行区块链以太坊开发的web3j详解。

    这里是原文

    完整代码如下:

    package com.bolenum.util;
    
    import java.io.IOException;
    import java.math.BigInteger;
    import java.util.ArrayList;
    import java.util.Arrays;
    import java.util.Collections;
    import java.util.List;
    import java.util.concurrent.Future;
    
    import org.web3j.abi.EventEncoder;
    import org.web3j.abi.EventValues;
    import org.web3j.abi.FunctionEncoder;
    import org.web3j.abi.TypeReference;
    import org.web3j.abi.datatypes.Address;
    import org.web3j.abi.datatypes.Event;
    import org.web3j.abi.datatypes.Function;
    import org.web3j.abi.datatypes.Type;
    import org.web3j.abi.datatypes.Utf8String;
    import org.web3j.abi.datatypes.generated.Uint256;
    import org.web3j.abi.datatypes.generated.Uint8;
    import org.web3j.crypto.Credentials;
    import org.web3j.protocol.Web3j;
    import org.web3j.protocol.core.DefaultBlockParameter;
    import org.web3j.protocol.core.RemoteCall;
    import org.web3j.protocol.core.methods.request.EthFilter;
    import org.web3j.protocol.core.methods.response.Log;
    import org.web3j.protocol.core.methods.response.TransactionReceipt;
    import org.web3j.protocol.exceptions.TransactionException;
    import org.web3j.tx.Contract;
    import org.web3j.tx.TransactionManager;
    
    import rx.Observable;
    import rx.functions.Func1;
    
    /**
     * Auto generated code.<br>
     * <strong>Do not modify!</strong><br>
     * Please use the <a href="https://docs.web3j.io/command_line.html">web3j command line tools</a>, or {@link org.web3j.codegen.SolidityFunctionWrapperGenerator} to update.
     *
     * <p>Generated with web3j version 2.3.1.
     */
    public final class Erc20TokenWrapper extends Contract {
    
        private static final String BINARY = "contract binary key";
    
        private Erc20TokenWrapper(String contractAddress, Web3j web3j, Credentials credentials, BigInteger gasPrice, BigInteger gasLimit) {
            super(BINARY, contractAddress, web3j, credentials, gasPrice, gasLimit);
        }
    
        private Erc20TokenWrapper(String contractAddress, Web3j web3j, TransactionManager transactionManager, BigInteger gasPrice, BigInteger gasLimit) {
            super(BINARY, contractAddress, web3j, transactionManager, gasPrice, gasLimit);
        }
    
        public List<TransferEventResponse> getTransferEvents(TransactionReceipt transactionReceipt) {
            final Event event = new Event("Transfer", 
                    Arrays.<TypeReference<?>>asList(new TypeReference<Address>() {}, new TypeReference<Address>() {}),
                    Arrays.<TypeReference<?>>asList(new TypeReference<Uint256>() {}));
            List<EventValues> valueList = extractEventParameters(event, transactionReceipt);
            ArrayList<TransferEventResponse> responses = new ArrayList<TransferEventResponse>(valueList.size());
            for (EventValues eventValues : valueList) {
                TransferEventResponse typedResponse = new TransferEventResponse();
                typedResponse._from = (Address) eventValues.getIndexedValues().get(0);
                typedResponse._to = (Address) eventValues.getIndexedValues().get(1);
                typedResponse._value = (Uint256) eventValues.getNonIndexedValues().get(0);
                responses.add(typedResponse);
            }
            return responses;
        }
    
        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();
                    typedResponse._from = (Address) eventValues.getIndexedValues().get(0);
                    typedResponse._to = (Address) eventValues.getIndexedValues().get(1);
                    typedResponse._value = (Uint256) eventValues.getNonIndexedValues().get(0);
                    typedResponse._transactionHash = log.getTransactionHash();
                    return typedResponse;
                }
            });
        }
    
        public List<ApprovalEventResponse> getApprovalEvents(TransactionReceipt transactionReceipt) {
            final Event event = new Event("Approval", 
                    Arrays.<TypeReference<?>>asList(new TypeReference<Address>() {}, new TypeReference<Address>() {}),
                    Arrays.<TypeReference<?>>asList(new TypeReference<Uint256>() {}));
            List<EventValues> valueList = extractEventParameters(event, transactionReceipt);
            ArrayList<ApprovalEventResponse> responses = new ArrayList<ApprovalEventResponse>(valueList.size());
            for (EventValues eventValues : valueList) {
                ApprovalEventResponse typedResponse = new ApprovalEventResponse();
                typedResponse._owner = (Address) eventValues.getIndexedValues().get(0);
                typedResponse._spender = (Address) eventValues.getIndexedValues().get(1);
                typedResponse._value = (Uint256) eventValues.getNonIndexedValues().get(0);
                responses.add(typedResponse);
            }
            return responses;
        }
    
        public Observable<ApprovalEventResponse> approvalEventObservable(DefaultBlockParameter startBlock, DefaultBlockParameter endBlock) {
            final Event event = new Event("Approval", 
                    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, ApprovalEventResponse>() {
                @Override
                public ApprovalEventResponse call(Log log) {
                    EventValues eventValues = extractEventParameters(event, log);
                    ApprovalEventResponse typedResponse = new ApprovalEventResponse();
                    typedResponse._owner = (Address) eventValues.getIndexedValues().get(0);
                    typedResponse._spender = (Address) eventValues.getIndexedValues().get(1);
                    typedResponse._value = (Uint256) eventValues.getNonIndexedValues().get(0);
                    typedResponse._transactionHash = log.getTransactionHash();
                    return typedResponse;
                }
            });
        }
    
        public Future<Utf8String> name() throws IOException {
            Function function = new Function("name", 
                    Arrays.<Type>asList(), 
                    Arrays.<TypeReference<?>>asList(new TypeReference<Utf8String>() {}));
            return executeCallSingleValueReturn(function);
        }
    
        public TransactionReceipt approve(Address _spender, Uint256 _amount) throws IOException, TransactionException {
            Function function = new Function("approve", Arrays.<Type>asList(_spender, _amount), Collections.<TypeReference<?>>emptyList());
            return executeTransaction(function);
        }
    
        public Future<Uint256> totalSupply() throws IOException {
            Function function = new Function("totalSupply", 
                    Arrays.<Type>asList(), 
                    Arrays.<TypeReference<?>>asList(new TypeReference<Uint256>() {}));
            return executeCallSingleValueReturn(function);
        }
    
        public TransactionReceipt transferFrom(Address _from, Address _to, Uint256 _amount) throws IOException, TransactionException {
            Function function = new Function("transferFrom", Arrays.<Type>asList(_from, _to, _amount), Collections.<TypeReference<?>>emptyList());
            return  executeTransaction(function);
        }
    
        public Uint8 decimals() throws IOException {
            Function function = new Function("decimals", 
                    Arrays.<Type>asList(), 
                    Arrays.<TypeReference<?>>asList(new TypeReference<Uint8>() {}));
            return executeCallSingleValueReturn(function);
        }
    
        public Uint256 balanceOf(Address _owner) throws IOException {
            Function function = new Function("balanceOf", 
                    Arrays.<Type>asList(_owner), 
                    Arrays.<TypeReference<?>>asList(new TypeReference<Uint256>() {}));
            return executeCallSingleValueReturn(function);
        }
    
        public Future<Address> owner() throws IOException {
            Function function = new Function("owner", 
                    Arrays.<Type>asList(), 
                    Arrays.<TypeReference<?>>asList(new TypeReference<Address>() {}));
            return executeCallSingleValueReturn(function);
        }
    
        public Future<Utf8String> symbol() throws IOException {
            Function function = new Function("symbol", 
                    Arrays.<Type>asList(), 
                    Arrays.<TypeReference<?>>asList(new TypeReference<Utf8String>() {}));
            return executeCallSingleValueReturn(function);
        }
    
        public TransactionReceipt transfer(Address _to, Uint256 _amount) throws IOException, TransactionException {
            Function function = new Function("transfer", Arrays.<Type>asList(_to, _amount), Collections.<TypeReference<?>>emptyList());
            return executeTransaction(function);
        }
    
        public Future<Uint256> allowance(Address _owner, Address _spender) throws IOException {
            Function function = new Function("allowance", 
                    Arrays.<Type>asList(_owner, _spender), 
                    Arrays.<TypeReference<?>>asList(new TypeReference<Uint256>() {}));
            return executeCallSingleValueReturn(function);
        }
    
        public static RemoteCall<Erc20TokenWrapper> deploy(Web3j web3j, Credentials credentials, BigInteger gasPrice, BigInteger gasLimit, BigInteger initialWeiValue, Uint256 totalSupply, Utf8String tokenName, Uint8 decimalUnits, Utf8String tokenSymbol) {
            String encodedConstructor = FunctionEncoder.encodeConstructor(Arrays.<Type>asList(totalSupply, tokenName, decimalUnits, tokenSymbol));
            return deployRemoteCall(Erc20TokenWrapper.class, web3j, credentials, gasPrice, gasLimit, BINARY, encodedConstructor, initialWeiValue);
        }
    
        public static RemoteCall<Erc20TokenWrapper> deploy(Web3j web3j, TransactionManager transactionManager, BigInteger gasPrice, BigInteger gasLimit, BigInteger initialWeiValue, Uint256 totalSupply, Utf8String tokenName, Uint8 decimalUnits, Utf8String tokenSymbol) {
            String encodedConstructor = FunctionEncoder.encodeConstructor(Arrays.<Type>asList(totalSupply, tokenName, decimalUnits, tokenSymbol));
            return deployRemoteCall(Erc20TokenWrapper.class, web3j, transactionManager, gasPrice, gasLimit, BINARY, encodedConstructor, initialWeiValue);
        }
    
        public static Erc20TokenWrapper load(String contractAddress, Web3j web3j, Credentials credentials, BigInteger gasPrice, BigInteger gasLimit) {
            return new Erc20TokenWrapper(contractAddress, web3j, credentials, gasPrice, gasLimit);
        }
    
        public static Erc20TokenWrapper load(String contractAddress, Web3j web3j, TransactionManager transactionManager, BigInteger gasPrice, BigInteger gasLimit) {
            return new Erc20TokenWrapper(contractAddress, web3j, transactionManager, gasPrice, gasLimit);
        }
    
        public static class TransferEventResponse {
            public Address _from;
    
            public Address _to;
    
            public Uint256 _value;
    
            public String _transactionHash;
        }
    
        public static class ApprovalEventResponse {
            public Address _owner;
    
            public Address _spender;
    
            public Uint256 _value;
    
            public String _transactionHash;
        }
    }
    

    相关文章

      网友评论

        本文标题:java 监听 ERC20 Token 交易

        本文链接:https://www.haomeiwen.com/subject/ylafwftx.html