Home | 簡體中文 | 繁體中文 | 雜文 | 知乎專欄 | Github | OSChina 博客 | 雲社區 | 雲棲社區 | Facebook | Linkedin | 視頻教程 | 打賞(Donations) | About
知乎專欄多維度架構 | 微信號 netkiller-ebook | QQ群:128659835 請註明“讀者”

17.14. ERC20合約

17.14.1. balanceOf

				
	@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;
	}			
			
			

17.14.2. name

			
		 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;
	}			
			
			

17.14.3. 合約轉賬

			
	@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;
	}
			
			

17.14.4. 完整的 ERC20 代幣開發庫

這是一個萬能的代幣介面,只要知道合約地址,即可操作該合約。傳統做法是使用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			
			
			

如需代碼,有償提供,請聯繫作者。