使用Web3j管理Java中的ERC20令牌

在本文中,我們將學習如何使用Web3j庫管理Java中的ERC20(Fungible)令牌。

ERC20是一個以符合標準的方式實現令牌的以太坊智能合約標準,因此可以輕鬆地與任何應用程序(dapps,錢包,交易所等)進行交互和集成令牌。

有關ERC20的更多詳細信息,請參閱ERC-20令牌標準一文

先決條件

要學習本教程,您需要在計算機上安裝以下軟體:

  • Java編程語言(> 8)
  • 包和依賴關係管理器,例如MavenGradle
  • IDE(集成開發環境),對於本教程,我們使用Eclipse
  • Truffle:開發,測試和部署以太坊智能合約的開發框架
  • Ganache-cli:您用於以太坊開發的本地個人區塊鏈。

通過運行命令啟動ganache:

ganache-cli

合約部署

在開始之前,我們需要在以太坊區塊鏈上部署ERC20令牌合約(在我們的案例中為Ganache)。有很多方法可以做到這一點(閱讀開發你的ERC-20令牌解釋OpenZeppelin第3部分:令牌標準)。為了本教程的目的,我們使用最簡單的解決方案,使用OpenZeppelin可重用合約,Truffle和Ganache。

1.首先為我們的ERC20創建一個名為JVM的項目文件夾,並初始化一個Truffle項目

$mkdir JVM
$cd JVM
$truffle init

2.然後我們安裝Open-Zeppelin Solidity庫,其中包含大量高質量,經過全面測試和審核的可重用智能合約

使用npm包導入OpenZeppelin智能合約。

$npm init -y
$npm install openzeppelin-solidity --save-exact

3.創建合約文件 ./contracts/JavaToken.sol

智能合約繼承了可重用的OpenZeppelin合約中的所有功能和規則ERC20Mintable。我們只需要配置以下常量變數,如下所示:

// JavaToken.sol
pragma solidity ^0.5.8;

import "openzeppelin-solidity/contracts/token/ERC20/ERC20Mintable.sol";

contract JavaToken is ERC20Mintable {
 string public constant name = "Java代幣";
 string public constant symbol = "JVM";
 uint8 public constant decimals = 18;
}

4.在我們當地的Ganache網路上部署智能合約

我們需要先完成遷移腳本。創建一個名為的文件./migrations/2_deploy_contract.js,並將以下代碼添加到該文件中:

// 2_deploy_contract.js
const JavaToken = artifacts.require("./JavaToken.sol");

module.exports = function(deployer, network, accounts) {
 // Deploy the smart contract
 deployer.deploy(JavaToken, {from: accounts[0]}).then(function(instance) {
 // Mint 100 tokens
 return instance.mint(accounts[0], web3.utils.toBN("100"), {from: accounts[0]});
 });
};

遷移腳本部署合約,mints並將100個JVM令牌分發到部署者帳戶(Ganache第一個帳戶)。

下一步是配置與Ganache網路的連接以部署智能合約。將文件更改./truffle-config.js為以下代碼:

// truffle-config.js
module.exports = {
  networks: {
    development: {
      host: "localhost",
      port: 8545,
      network_id: "*"
    }
  }
};

要在Ganache網路上部署智能合約,請運行以下命令(不要忘記事先啟動ganache-cli):

$truffle migrate --network development

Compiling your contracts...
===========================
> Compiling ./contracts/JavaToken.sol
> Compiling ./contracts/Migrations.sol
> Compiling openzeppelin-solidity/contracts/access/Roles.sol
> Compiling openzeppelin-solidity/contracts/access/roles/MinterRole.sol
> Compiling openzeppelin-solidity/contracts/math/SafeMath.sol
> Compiling openzeppelin-solidity/contracts/token/ERC20/ERC20.sol
> Compiling openzeppelin-solidity/contracts/token/ERC20/ERC20Mintable.sol
> Compiling openzeppelin-solidity/contracts/token/ERC20/IERC20.sol
> Artifacts written to /home/gjeanmart/workspace/tutorials/kauri-content/java-erc20/JVM/build/contracts
> Compiled successfully using:
 - solc: 0.5.8+commit.23d335f2.Emscripten.clang


Starting migrations...
======================
> Network name: 'development'
> Network id: 1565778588423
> Block gas limit: 0x6691b7


1_initial_migration.js
======================

 Deploying 'Migrations'
 ----------------------
 > transaction hash: 0x6161e15461a5c748a532b2191600986b8798be4842e78791238e9e77af5e1310
 > Blocks: 0 Seconds: 0
 > contract address: 0xC59fC6035859Dd35871c5d9211a0713ed608d59D
 > block number: 6
 > block timestamp: 1565778631
 > account: 0xB0C24796Fc9212AB371c8Caf1ea3F33cC1d4c8a0
 > balance: 99.95438236
 > gas used: 261393
 > gas price: 20 gwei
 > value sent: 0 ETH
 > total cost: 0.00522786 ETH


 > Saving migration to chain.
 > Saving artifacts
 -------------------------------------
 > Total cost: 0.00522786 ETH


2_deploy_contract.js
====================

 Deploying 'JavaToken'
 ---------------------
 > transaction hash: 0xfc5b214cbd56ecd4d24795aacefe1fdaf27b1b223ebff78299fd47f302cb374c
 > Blocks: 0 Seconds: 0
 > contract address: 0x9339a071cB9C1E3BbBA50E5E298f234c5095f012
 > block number: 8
 > block timestamp: 1565778631
 > account: 0xB0C24796Fc9212AB371c8Caf1ea3F33cC1d4c8a0
 > balance: 99.92109908
 > gas used: 1622141
 > gas price: 20 gwei
 > value sent: 0 ETH
 > total cost: 0.03244282 ETH


 > Saving migration to chain.
 > Saving artifacts
 -------------------------------------
 > Total cost: 0.03244282 ETH


Summary
=======
> Total deployments: 2
> Final cost: 0.03767068 ETH

命令完成後請注意合約地址。

如果您想了解有關此步驟的更多信息,我建議您閱讀以下有關Truffle和Ganache的文章,以便部署智能合約:Truffle:智能合約編製和部署以及Truffle 101 – 智能合約開發工具

使用Web3j載入合約

現在我們在Ganache本地區塊鏈上部署了一個ERC20智能合約,我們可以使用Web3j ERC20實用程序類開始在Java中與它進行交互。

1.創建一個新項目並導入Web3j依賴項

在您喜歡的IDE中創建一個新的Maven項目並導入Web3j依賴項(core以及contractsEIP支持):

"http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  4.0.0
  io.kauri.tutorials.java-ethereum
  java-erc20
  0.0.1-SNAPSHOT

  
    1.8
    1.8
    4.2.0
  

  
    
      org.web3j
      core
      ${web3j.version}
    
    
      org.web3j
      contracts
      ${web3j.version}
    
  


2.創建一個新類以載入ERC20智能合約盤點器

ERC20是標準,因此無需手動生成智能合約盤點器,Web3j默認包含它。

但是,您需要將Web3j連接到以太坊區塊鏈並配置錢包以簽署交易。

在本文中,我們連接到本地Ganache區塊鏈(默認情況下公開http://localhost:8545)並使用第一個Ganache測試帳戶(讀取Ganache啟動日誌以查找此信息),在部署期間收到100個JVM令牌。

// Connect Web3j to the區塊鏈
String rpcEndpoint = "http://localhost:8545";
Web3j web3j = Web3j.build(new HttpService(rpcEndpoint));

// Prepare a wallet
String pk = "0x5bbbef76458bf30511c9ee6ed56783644eb339258d02656755c68098c4809130";
// Account address: 0x1583c05d6304b6651a7d9d723a5c32830f53a12f
Credentials credentials = Credentials.create(pk);

// Load the contract
String contractAddress = "0xe4F275cE131eF87Cb8bF425E02D9215055e9F875";
ERC20 javaToken = ERC20.load(contractAddress, web3j, credentials, new DefaultGasProvider());

對於更複雜的方案,您可以使用特定的TransactionManagerGas參數載入合約ERC20.load(contractAddress, web3j, transactionManager, gasPrice, gasLimit)

3.獲取令牌信息

一旦我們載入了ERC20令牌合約,我們就可以開始請求存儲在此合約上的信息,例如JVM令牌中的小數或餘額。

以下代碼檢索我們之前在合約中配置的信息。

String symbol = javaToken.symbol().send();
String name = javaToken.name().send();
BigInteger decimal = javaToken.decimals().send();

System.out.println("symbol: " + symbol);
System.out.println("name: " + name);
System.out.println("decimal: " + decimal.intValueExact());

更重要的是,我們可以檢索帳戶的令牌餘額。

BigInteger balance1 = javaToken.balanceOf("0x1583c05d6304b6651a7d9d723a5c32830f53a12f").send();
System.out.println("balance (0x1583c05d6304b6651a7d9d723a5c32830f53a12f)="+balance1.toString());

BigInteger balance2 = javaToken.balanceOf("0x0db6b797e64666d4b36b13e5dc6fcd4661893ac8").send();
System.out.println("balance (0x0db6b797e64666d4b36b13e5dc6fcd4661893ac8)="+balance2.toString());

該帳戶0x1583c05d6304b6651a7d9d723a5c32830f53a12f是Ganache的第一個帳戶,即部署合約並在部署期間收到100個令牌的帳戶。雖然0x0db6b797e64666d4b36b13e5dc6fcd4661893ac8代表Ganache的第二個帳戶沒有收到任何令牌。

轉移代幣

要與令牌交互,該ERC20班提供所需的像所有功能transfertransferFrom以及approve

例如,我們可以0x0db6b797e64666d4b36b13e5dc6fcd4661893ac8通過從配置為Credentials(0x1583c05d6304b6651a7d9d723a5c32830f53a12f)的帳戶簽名並發送一個事務來傳輸25個JVM令牌。

TransactionReceipt receipt = javaToken.transfer("0x0db6b797e64666d4b36b13e5dc6fcd4661893ac8", new BigInteger("25")).send();
System.out.println("Transaction hash: "+receipt.getTransactionHash());

BigInteger balance1 = javaToken.balanceOf("0x1583c05d6304b6651a7d9d723a5c32830f53a12f").send();
System.out.println("balance (0x1583c05d6304b6651a7d9d723a5c32830f53a12f)="+balance1.toString());

BigInteger balance2 = javaToken.balanceOf("0x0db6b797e64666d4b36b13e5dc6fcd4661893ac8").send();
System.out.println("balance (0x0db6b797e64666d4b36b13e5dc6fcd4661893ac8)="+balance2.toString());

收到轉移事件的通知

最後,我們將介紹如何訂閱ERC20合約生成的特定事件,以便我們可以對其中的任何活動做出反應。

您可以通過以下方法檢索給定事務的特定事件getTransferEvents

List events = javaToken.getTransferEvents(receipt);
events.forEach(event
 -> System.out.println("from: " + event._from + ", to: " + event._to + ", value: " + event._value));

我們還可以添加RxJava作為依賴項,以便通過連續訂閱任何新事件transferEventFlowable

javaToken.transferEventFlowable(DefaultBlockParameterName.EARLIEST, DefaultBlockParameterName.LATEST)
 .subscribe(event
 -> System.out.println("from: " + event._from + ", to: " + event._to + ", value: " + event._value));

提示:投資有風險,入市需謹慎,本資訊不作為投資理財建議。請理性投資,切實提高風險防範意識;如有發現的違法犯罪線索,可積極向有關部門舉報反映。
你可能還喜歡