22

使用 Java 和 web3j 进行 Token 开发[概述][译] | 登链社区 | 深入浅出区块链技术

 3 years ago
source link: https://learnblockchain.cn/article/938?
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

使用 Java 和 web3j 进行 Token 开发[概述][译]

使用 Java 和 web3j 进行 Token 开发[概述][译]

学习使用 web3j 部署ERC20 以及与合约进行交互。

题外话, 翻译这篇文章是因为看到 CSDN 公众号这篇外行翻译。 (get balance: 获取账号余额被翻译为取得平衡,transaction 交易翻译为事务 , 等等), CSDN 用自己的流量优势不知道坑了多少开发者。

为了创作本文,我们创建的名为 JavaToken 的基本 ERC20 智能合约,可以在此处找到代码。 我们将使用这个代码库进行演示,请先 Git Clone 到本地进行后续操作! 我们使用 Truffle 创建的本地 Ganache Testnet 网络来部署和运行这个合约。

我(原作者)最近写了一篇有关开始使用 Android 进行以太坊开发的文章,其中演示了如何在 Android 中设置 web3j 以及如何进行以太币转账。发布后收到读者留言想看看如何使用 web3j 与自定义 ERC20 Token 进行交互,因此有了今天这篇文章。

步骤 0.9: 生成智能合约 Java 包装(Wrapper)

这个 0.9 步是获取智能合约的一个 Java 包装器。之所以是 0.9 步,是因为从技术上讲,如果合约已经部署,则可以不需要,但在之后与合约进行交互时,使用 Wrapper 将使事情会更容易。

为了生成 Wrapper, 需要先使用 Solidity 编译器编译 Solidity 合约。如果你使用的是 Truffle,则只需在 JavaToken 代码库的 Truffle 目录中运行以下命令编译即可:

为此,请先使用 Solidity 编译器编译 Solidity 合约。如果你使用的是 Truffle,则只需在 JavaToken 存储库的 Truffle 目录中运行以下命令即可:

truffle compile

接着,安装 web3j 命令行:

Mac/Linux 平台用户:

curl -L get.web3j.io | sh

Windows 平台用户:

Set-ExecutionPolicy Bypass -Scope Process -Force; iex ((New-Object System.Net.WebClient).DownloadString('https://raw.githubusercontent.com/web3j/web3j-installer/master/installer.ps1'))

一切安装就绪之后,运行以下代码:

web3j truffle generate Truffle/build/contracts/JavaToken.json -o src -p com.javaToken

在 JavaToken 目录下,将为 JavaToken 智能合约生成一个 Wrapper,让之后和以太坊交互时更加容易。

步骤 1: 合约部署

为了部署 Token,需要进行一些配置,并调用 deploy()方法。

// The Ganache TestNet listens at port 7545
Web3j w3 = Web3j.build(new HttpService("HTTP://127.0.0.1:7545"));
String privateKey = "你的私钥";
Credentials credentials = Credentials.create(privateKey);
// 初始发行量
BigInteger initialSupply = BigInteger.valueOf(100000);

JavaToken javaToken = JavaToken.deploy(w3, credentials, new DefaultGasProvider(), initialSupply).send()
  

这样就部署好了一个全新的以太坊 Token!

此外,如果你仅仅是需要和一个已经部署的合约交互, 只需要使用下面的代码加载它:

// The Ganache TestNet listens at port 7545
Web3j w3 = Web3j.build(new HttpService("HTTP://127.0.0.1:7545"));
String privateKey = "你的私钥";
Credentials credentials = Credentials.create(privateKey);
String contractAddress = "合约地址";

JavaToken javaToken = JavaToken.load(contractAddress,w3,credentials,new DefaultGasProvider());

步骤 2: 获取余额

根据合约的代买,合约的部署者拥有所有的发行的 token。让我们检查一下部署者账号余额时候正确。如果我们从 0.9 步开始使用 Wrapper,那么很简单:

// With java wrapper
BigInteger balance = javaToken.balanceOf(credentials.getAddress()).send()

// Without java wrapper
String contractAddress = "YourDeployedContractAddress";

// Define the function we want to invoke from the smart contract
Function function = new Function("balanceOf", Arrays.asList(new Address(credentials.getAddress())),
                                 Arrays.asList(new TypeReference<Uint256>() {}));

// Encode it for the contract to understand
String encodedFunction = FunctionEncoder.encode(function);

/*
Send the request and wait for the response using eth call since
it's a read only transaction with no cost associated
*/
EthCall response = w3.ethCall(
  Transaction.createEthCallTransaction(credentials.getAddress(), contractAddress, encodedFunction),
  DefaultBlockParameterName.LATEST).send();

balance = Numeric.toBigInt(response.getValue());

要不能,会有一点复杂:

  1. 首先需要手动输入调用合约函数的详细信息, 如这里函数名是 balanceOf、账号地址作为参数,返回一个 uint256 类型的作为余额;
  2. 然后对这些数据进行一个编码连同调用信息(谁发起、调用哪个合约)一起打包为交易。
  3. 最后,我们将十六进制结果解码为一个 BigInteger 类型。

现在,我们有了 100000 个 JavaToken。让我们发送一些给朋友!

步骤 3: Token 转账

同样,使用 wrapper 和不使用 wrapper 之间的差异非常明显:

String addressTo = "YourFriendsAddress";
BigInteger amount = BigInteger.valueOf(500);

// 使用 wrapper
TransactionReceipt receipt = javaToken.transfer(addressTo,amount).send();

// Without java wrapper

// 定义想要调用的函数
Function function = new Function("transfer", Arrays.asList(new Address(addressTo), new Uint256(amount)),  Collections.emptyList());

// 编码,以便合约可以理解调用哪个函数
String encodedFunction = FunctionEncoder.encode(function);

/*
Need to use a TransactionManager here since transfer actually alters the state of the blockchain and credentials are therefore relevant
*/
TransactionManager transactionManager = new FastRawTransactionManager(w3, credentials);


// Send the transaction off using transactionManager and wait for the hash
String transactionHash = transactionManager.sendTransaction(DefaultGasProvider.GAS_PRICE,
                                                            DefaultGasProvider.GAS_LIMIT, contractAddress, encodedFunction,
                                                            BigInteger.ZERO).getTransactionHash();

// 获取交易收据
Optional<TransactionReceipt> transactionReceipt =
  w3.ethGetTransactionReceipt(transactionHash).send().getTransactionReceipt();
if(transactionReceipt.isEmpty())
  receipt = null;
else
  receipt = transactionReceipt.get();

不是 wrapper 时,现在有一点不同,这次需要更改区块链状态而不仅仅是读取数据,因此需要证明是谁发起的交易。

以同样的方式创建一个函数对象。尽管智能合约 transfer 函数返回的是布尔值,但我们在这里不需要使用,因为得通过交易收据检查交易是否成功,因此我们将返回值指定为一个空列表。接下来,我们创建一个交易管理器(TransactionManager)。

这个区别很关键, 管理器使用签名作为参数,说明是我们发起的交易(和上面 balanceOf 不同),最后通过检查交易收据确认交易是否成功。

通过这篇文章学习了使用 web3j 部署 ERC20, 相关的所有代码在: https://github.com/nschapeler/JavaToken

英文原文

登链社区 - 高质量的区块链技术文章集中地。

本文参与登链社区写作激励计划 ,好文好收益,欢迎正在阅读的你也加入。

  • 发表于 2020-04-27 00:08
  • 阅读 ( 976 )
  • 学分 ( 139 )
  • 分类:以太坊

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK