学习使用 web3j 部署ERC20 以及与合约进行交互。
题外话, 翻译这篇文章是因为看到 CSDN 公众号这篇 奇烂无比的翻译
。 ( get balance
: 获取账号余额被翻译为取得平衡, transaction
交易翻译为事务 , 等等), CSDN 用自己的流量优势不知道坑了多少开发者。
为了创作本文,我们创建的名为JavaToken的基本ERC20智能合约,可以在 此处 找到代码。 我们将使用这个代码库进行演示,请先 Git Clone到本地进行后续操作! 我们使用Truffle创建的本地Ganache Testnet网络来部署和运行这个合约。
我(原作者)最近写了一篇有关开始 使用Android进行以太坊开发 的文章,其中演示了如何在Android中设置web3j以及如何进行以太币转账。发布后收到读者留言想看看如何使用web3j与自定义ERC20 Token进行交互,因此有了今天这篇文章。
这个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,让之后和以太坊交互时更加容易。
为了部署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());
根据合约的代买,合约的部署者拥有所有的发行的 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());
要不能,会有一点复杂:
现在,我们有了100000个 JavaToken。让我们发送一些给朋友!
同样,使用 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
英文原文
登链社区 - 高质量的区块链技术文章集中地。
题外话, 翻译这篇文章是因为看到 CSDN 公众号这篇 奇烂无比的翻译
。 ( get balance
: 获取账号余额被翻译为取得平衡, transaction
交易翻译为事务 , 等等), CSDN 用自己的流量优势不知道坑了多少开发者。
为了创作本文,我们创建的名为JavaToken的基本ERC20智能合约,可以在 此处 找到代码。 我们将使用这个代码库进行演示,请先 Git Clone到本地进行后续操作! 我们使用Truffle创建的本地Ganache Testnet网络来部署和运行这个合约。
我(原作者)最近写了一篇有关开始 使用Android进行以太坊开发 的文章,其中演示了如何在Android中设置web3j以及如何进行以太币转账。发布后收到读者留言想看看如何使用web3j与自定义ERC20 Token进行交互,因此有了今天这篇文章。
这个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,让之后和以太坊交互时更加容易。
为了部署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());
根据合约的代买,合约的部署者拥有所有的发行的 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());
要不能,会有一点复杂:
现在,我们有了100000个 JavaToken。让我们发送一些给朋友!
同样,使用 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
英文原文
登链社区 - 高质量的区块链技术文章集中地。
本文参与登链社区写作激励计划 ,好文好收益,欢迎正在阅读的你也加入。