知乎專欄 | 多維度架構 | | | 微信號 netkiller-ebook | | | QQ群:128659835 請註明“讀者” |
@SuppressWarnings("rawtypes") public BigInteger getTokenBalance(String account, String contractAddress) throws InterruptedException, ExecutionException { Function function = new Function("balanceOf", Arrays.<Type>asList(new Address(account)), Arrays.<TypeReference<?>>asList(new TypeReference<Uint256>() { })); String encodedFunction = FunctionEncoder.encode(function); EthCall response = web3.ethCall(Transaction.createEthCallTransaction(account, contractAddress, encodedFunction), DefaultBlockParameterName.LATEST).sendAsync().get(); List<Type> result = FunctionReturnDecoder.decode(response.getValue(), function.getOutputParameters()); BigInteger balance = BigInteger.ZERO; if (result.size() == 1) { balance = (BigInteger) result.get(0).getValue(); } return balance; }
合約 balance 是不含小數點的,因為不同合約採用的小數點位數不同,無法使用以太坊單位直接換算。可以使用下面方法添加小數:
public BigDecimal formatBalance(BigInteger balance, int decimal) { BigDecimal value = new BigDecimal(balance); value = value.divide(BigDecimal.TEN.pow(decimal)); return value; }
String methodName = "name"; String fromAddr = emptyAddress; List<Type> inputParameters = new ArrayList<>(); List<TypeReference<?>> outputParameters = new ArrayList<>(); TypeReference<Utf8String> typeReference = new TypeReference<Utf8String>() {}; outputParameters.add(typeReference); Function function = new Function(methodName, inputParameters,outputParameters);
@SuppressWarnings("rawtypes") public String getName(String contractAddress) { String name = null; Function function = new Function("name", Arrays.<Type>asList(), Arrays.<TypeReference<?>>asList(new TypeReference<Utf8String>() { })); String data = FunctionEncoder.encode(function); Transaction transaction = Transaction.createEthCallTransaction(null, contractAddress, data); EthCall ethCall; try { ethCall = web3.ethCall(transaction, DefaultBlockParameterName.LATEST).sendAsync().get(); List<Type> results = FunctionReturnDecoder.decode(ethCall.getValue(), function.getOutputParameters()); name = results.get(0).getValue().toString(); } catch (InterruptedException | ExecutionException e) { e.printStackTrace(); } return name; }
@SuppressWarnings("rawtypes") public String sendTokenTransaction(String fromAddress, String password, String toAddress, BigInteger amount) { String txHash = null; try { PersonalUnlockAccount personalUnlockAccount = admin.personalUnlockAccount(fromAddress, password, BigInteger.valueOf(10)).send(); if (personalUnlockAccount.accountUnlocked()) { String methodName = "transfer"; List<Type> inputParameters = new ArrayList<>(); List<TypeReference<?>> outputParameters = new ArrayList<>(); Address tAddress = new Address(toAddress); Uint256 value = new Uint256(amount); inputParameters.add(tAddress); inputParameters.add(value); TypeReference<Bool> typeReference = new TypeReference<Bool>() { }; outputParameters.add(typeReference); Function function = new Function(methodName, inputParameters, outputParameters); String data = FunctionEncoder.encode(function); EthGetTransactionCount ethGetTransactionCount = web3.ethGetTransactionCount(fromAddress, DefaultBlockParameterName.PENDING).sendAsync().get(); BigInteger nonce = ethGetTransactionCount.getTransactionCount(); BigInteger gasPrice = Convert.toWei(BigDecimal.valueOf(5), Convert.Unit.GWEI).toBigInteger(); Transaction transaction = Transaction.createFunctionCallTransaction(fromAddress, nonce, gasPrice, BigInteger.valueOf(60000), this.contractAddress, data); EthSendTransaction ethSendTransaction = web3.ethSendTransaction(transaction).sendAsync().get(); txHash = ethSendTransaction.getTransactionHash(); } } catch (Exception e) { e.printStackTrace(); } return txHash; }
這是一個萬能的代幣介面,只要知道合約地址,即可操作該合約。傳統做法是使用web3j 命令將 .sol 編譯成 Java Class 但這種類只能操作自己的合約。
package cn.netkiller.wallet.ethereum; import java.io.IOException; import java.math.BigDecimal; import java.math.BigInteger; import java.util.concurrent.ExecutionException; import org.web3j.protocol.core.methods.request.Transaction; import org.web3j.protocol.core.methods.response.TransactionReceipt; import org.web3j.tx.Contract; public class TestToken { public TestToken() { // TODO Auto-generated constructor stub } @SuppressWarnings("deprecation") public static void main(String[] args) { // TODO Auto-generated method stub try { Token token = new Token("0xb3cedc76e75fcd278c988b22963c2f35c99c10b7", "166970EDB022C717B3ECCADAB6558537228FFBDE1F68AC063A06790967F2BC3A"); String owner = token.getOwner(); System.out.println("代幣創建者:" + owner); String name = token.getName(); System.out.println("代幣名稱:" + name); String symbol = token.getSymbol(); System.out.println("代幣符號:" + symbol); int decimal = token.getDecimals(); System.out.println("小數位數:" + decimal); BigInteger totalSupply = token.getTotalSupply(); System.out.println("發行總量:" + totalSupply); BigInteger tokenBalance = token.getTokenBalance("0x22c57F0537414FD95b9f0f08f1E51d8b96F14029"); System.out.println("代幣餘額:" + tokenBalance); BigDecimal val = token.formatBalance(tokenBalance, decimal); System.out.println("格式化後:" + val); String transactionHash = token.sendTransaction("0xCdF0253d8362d6c3334c8F28A6BFd74c90d03d92", BigInteger.valueOf(10)); System.out.println("代幣轉賬:" + transactionHash); TransactionReceipt transactionReceipt = token.getTransactionReceipt("0xece52bdbc6d4fa0c8eba7578a7c6e537883265199fa07ef8e5b1038e4bcdefb9"); System.out.println("轉賬狀態:" + transactionReceipt.toString()); String hash = token.setApprove("0xCdF0253d8362d6c3334c8F28A6BFd74c90d03d92", BigInteger.valueOf(100)); System.out.println("設置授信:" + hash); BigInteger value = token.getAllowance("0x22c57F0537414FD95b9f0f08f1E51d8b96F14029", "0xCdF0253d8362d6c3334c8F28A6BFd74c90d03d92"); System.out.println("查詢授信:" + value); Token token1 = new Token("0xb3cedc76e75fcd278c988b22963c2f35c99c10b7", "8D160B668E63CC04CEE44C398C184121D63C3F5D189671D985A6FB3719FB1B5E"); System.out.println("授信轉出:" + token1.sendTransactionFrom("0x22c57F0537414FD95b9f0f08f1E51d8b96F14029", "0xCdF0253d8362d6c3334c8F28A6BFd74c90d03d92", BigInteger.valueOf(20))); // System.out.println(token1.getAllowance("0x22c57F0537414FD95b9f0f08f1E51d8b96F14029", "0xCdF0253d8362d6c3334c8F28A6BFd74c90d03d92")); } catch (InterruptedException | ExecutionException | IOException e) { e.printStackTrace(); } } }
運行結果
代幣創建者:0x22c57f0537414fd95b9f0f08f1e51d8b96f14029 代幣名稱:Netkiller Test Coin 代幣符號:NTC 小數位數:4 發行總量:1000000000000 代幣餘額:999999999430 格式化後:99999999.943 代幣轉賬:0xe851f682457672f2ca5ddbc3ad276dd9fa56ea81e838cf9a4b1eb8c97d0d98fd 轉賬狀態:TransactionReceipt{transactionHash='0xece52bdbc6d4fa0c8eba7578a7c6e537883265199fa07ef8e5b1038e4bcdefb9', transactionIndex='0x13', blockHash='0x2642b35670872a0e024d30ab2393b6bd4f7dab449bf4fc3eac067e2677cbc085', blockNumber='0x344a79', cumulativeGasUsed='0x806f54', gasUsed='0x8fee', contractAddress='null', root='null', status='0x1', from='0x22c57f0537414fd95b9f0f08f1e51d8b96f14029', to='0xb3cedc76e75fcd278c988b22963c2f35c99c10b7', logs=[Log{removed=false, logIndex='0xa', transactionIndex='0x13', transactionHash='0xece52bdbc6d4fa0c8eba7578a7c6e537883265199fa07ef8e5b1038e4bcdefb9', blockHash='0x2642b35670872a0e024d30ab2393b6bd4f7dab449bf4fc3eac067e2677cbc085', blockNumber='0x344a79', address='0xb3cedc76e75fcd278c988b22963c2f35c99c10b7', data='0x000000000000000000000000000000000000000000000000000000000000000a', type='null', topics=[0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef, 0x00000000000000000000000022c57f0537414fd95b9f0f08f1e51d8b96f14029, 0x000000000000000000000000cdf0253d8362d6c3334c8f28a6bfd74c90d03d92]}], logsBloom='0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000008020000001000000000000000000000000000800000000000000000000000000000000000000000000000000000000010000000000000000000004000000000000000000000000000800000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000002000000000000000400000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000'} 設置授信:0x2a6c32b5939de91d9f06f7b73913433ee0b28642a3afc095454a7dcd59da3234 查詢授信:100 授信轉出:0x29f4824b35c47a0fc18adf2d8c72c902a3c518f249bc4235aace804e5a9f17df
如需代碼,有償提供,請聯繫作者。