【ETH錢包開發(fā)04】web3j轉(zhuǎn)賬ERC-20 Token

在上一篇文章中講解了ETH轉(zhuǎn)賬,這一篇講一下ERC-20 Token轉(zhuǎn)賬。
【ETH錢包開發(fā)03】web3j轉(zhuǎn)賬ETH

ERC-20 Token轉(zhuǎn)賬的2種方式

1、直接用web3j的API
2、java/Android調(diào)用合約的transfer方法

不管用哪種方式來轉(zhuǎn)賬,你都需要先寫一個(gè)solidity智能合約文件來創(chuàng)建ERC-20 Token,然后部署合約,最后才是通過客戶端來調(diào)用。

web3j API轉(zhuǎn)賬ERC-20 Token

/**
     * ERC-20Token交易
     *
     * @param from
     * @param to
     * @param value
     * @param privateKey
     * @param data       附加信息需要轉(zhuǎn)換成16進(jìn)制數(shù)
     * @return
     * @throws Exception
     */
    public EthSendTransaction transferERC20Token(String from,
                                                 String to,
                                                 BigInteger value,
                                                 String privateKey,
                                                 String contractAddress) throws Exception {
        //加載轉(zhuǎn)賬所需的憑證总寻,用私鑰
        Credentials credentials = Credentials.create(privateKey);
        //獲取nonce铸董,交易筆數(shù)
        BigInteger nonce = getNonce(from);
        //get gasPrice
        BigInteger gasPrice = requestCurrentGasPrice();
        BigInteger gasLimit = Contract.GAS_LIMIT;

        //創(chuàng)建RawTransaction交易對(duì)象
        Function function = new Function(
                "transfer",
                Arrays.asList(new Address(to), new Uint256(value)),
                Arrays.asList(new TypeReference<Type>() {
                }));

        String encodedFunction = FunctionEncoder.encode(function);

        RawTransaction rawTransaction = RawTransaction.createTransaction(nonce,
                gasPrice,
                gasLimit,
                contractAddress, encodedFunction);


        //簽名Transaction,這里要對(duì)交易做簽名
        byte[] signMessage = TransactionEncoder.signMessage(rawTransaction, credentials);
        String hexValue = Numeric.toHexString(signMessage);
        //發(fā)送交易
        EthSendTransaction ethSendTransaction = web3j.ethSendRawTransaction(hexValue).sendAsync().get();
        return ethSendTransaction;
    }
   /**
     * 獲取nonce沉衣,交易筆數(shù)
     *
     * @param from
     * @return
     * @throws ExecutionException
     * @throws InterruptedException
     */
    private BigInteger getNonce(String from) throws ExecutionException, InterruptedException {
        EthGetTransactionCount transactionCount = web3j.ethGetTransactionCount(from, DefaultBlockParameterName.LATEST).sendAsync().get();
        BigInteger nonce = transactionCount.getTransactionCount();
        Log.i(TAG, "transfer nonce : " + nonce);
        return nonce;
    }

注意:erc-20 token轉(zhuǎn)賬和eth轉(zhuǎn)賬的區(qū)別如下:
1肥隆、erc-20 token創(chuàng)建交易對(duì)象用的是這個(gè)方法createTransaction

2吸占、erc-20 token需要構(gòu)建Function初厚,它其實(shí)對(duì)應(yīng)的就是erc-20 token合約中的那些方法。它的第一個(gè)參數(shù)就是ERC20中那幾個(gè)方法的名稱,第二個(gè)參數(shù)的話就是對(duì)應(yīng)合約方法中的參數(shù)僧著,第三個(gè)參數(shù)是和第二個(gè)參數(shù)對(duì)應(yīng)的皆怕,按照我那樣就行了岂津。轉(zhuǎn)賬的話就是transfer,我們從合約的transfer可以看到第一個(gè)參數(shù)是收款地址,第二個(gè)參數(shù)是金額,所以Function這里對(duì)應(yīng)起來就好。

      //創(chuàng)建Function對(duì)象
        Function function = new Function(
                "transfer",
                Arrays.asList(new Address(to), new Uint256(value)),
                Arrays.asList(new TypeReference<Type>() {
                }));

        String encodedFunction = FunctionEncoder.encode(function);
// 如下為 ERC20 Token 標(biāo)準(zhǔn)接口:-----------
 // ERC20 Token Standard Interface
 // https://github.com/ethereum/EIPs/blob/master/EIPS/eip-20-token-standard.md
 // ----------------------------------------------------------------------------
contract ERC20 {
      function name() constant returns (string name)
      function symbol() constant returns (string symbol)
      function decimals() constant returns (uint8 decimals)
      function totalSupply() constant returns (uint totalSupply);
      function balanceOf(address _owner) constant returns (uint balance);
      function transfer(address _to, uint _value) returns (bool success);
      function transferFrom(address _from, address _to, uint _value) returns (bool success);
      function approve(address _spender, uint _value) returns (bool success);
      function allowance(address _owner, address _spender) constant returns (uint remaining);
      event Transfer(address indexed _from, address indexed _to, uint _value);
      event Approval(address indexed _owner, address indexed _spender, uint _value);
}

java/Android調(diào)用合約的transfer方法

這種方法不需要使用web3j封裝的方法拙泽,而是直接調(diào)用solidity合約的方法。

步驟
1移稳、web3j加載一個(gè)已經(jīng)部署的合約
2都许、驗(yàn)證合約是否加載成功isValid
3桨仿、如何加載合約成功伴嗡,則調(diào)用合約的transfer方法

  /**
     * ERC-20Token交易(調(diào)用solidity合約方式) 推薦使用
     *
     * @param contractAddress 合約地址
     * @param to              收款地址
     * @param value           轉(zhuǎn)賬金額
     * @param privateKey      私鑰
     * @throws ExecutionException
     * @throws InterruptedException
     */
    public void transferERC20Token(String contractAddress,
                                   String to,
                                   BigInteger value,
                                   String privateKey) throws ExecutionException, InterruptedException {

        //加載轉(zhuǎn)賬所需的憑證,用私鑰
        Credentials credentials = Credentials.create(privateKey);

        TokenERC20 contract = TokenERC20.load(
                contractAddress, web3j, credentials, Contract.GAS_PRICE, Contract.GAS_LIMIT);

        TransactionReceipt transactionReceipt = contract.transfer(to, value).sendAsync().get();
        String transactionHash = transactionReceipt.getTransactionHash();
        Log.i(TAG, "transferERC20Token transactionHash : " + transactionHash);
    }

注意:
1、這里的TokenERC20是根據(jù)solidity智能合約生成的對(duì)應(yīng)的Java類,用于java/Android和智能合約交互的,如果你對(duì)這里不太清楚,不妨看看我之前的一篇文章浅碾。
以太坊Web3j命令行生成Java版本的智能合約

2埂陆、如果加載合約失敗鹃栽,可能的一個(gè)原因是合約對(duì)應(yīng)的Java類中的BINARY的值不對(duì)蓬抄,這個(gè)值是你部署合約成功之后的bytecode阅爽,你最好檢查對(duì)比一下。

我發(fā)送一筆交易仍翰,可以通過這個(gè)地址查詢
https://rinkeby.etherscan.io/tx/0x05bd947e73068badbd9937854169f020980795da8a8182a67e9c2c1888f1874d

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖樊销,帶你破解...
    沈念sama閱讀 218,858評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件丈氓,死亡現(xiàn)場(chǎng)離奇詭異闰歪,居然都是意外死亡论矾,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,372評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門幅恋,熙熙樓的掌柜王于貴愁眉苦臉地迎上來零渐,“玉大人银还,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 165,282評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵蹄溉,是天一觀的道長(zhǎng)餐弱。 經(jīng)常有香客問我,道長(zhǎng),這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,842評(píng)論 1 295
  • 正文 為了忘掉前任整份,我火速辦了婚禮讲冠,結(jié)果婚禮上玻熙,老公的妹妹穿的比我還像新娘称杨。我一直安慰自己呜舒,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,857評(píng)論 6 392
  • 文/花漫 我一把揭開白布啤咽。 她就那樣靜靜地躺著鳞青,像睡著了一般埃儿。 火紅的嫁衣襯著肌膚如雪威鹿。 梳的紋絲不亂的頭發(fā)上科雳,一...
    開封第一講書人閱讀 51,679評(píng)論 1 305
  • 那天蕉堰,我揣著相機(jī)與錄音须教,去河邊找鬼约计。 笑死,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 40,406評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了令漂?” 一聲冷哼從身側(cè)響起妹窖,我...
    開封第一講書人閱讀 39,311評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤澄峰,失蹤者是張志新(化名)和其女友劉穎魂毁,沒想到半個(gè)月后烦秩,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體铆农,經(jīng)...
    沈念sama閱讀 45,767評(píng)論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,945評(píng)論 3 336
  • 正文 我和宋清朗相戀三年猾昆,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了贴见。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片吞琐。...
    茶點(diǎn)故事閱讀 40,090評(píng)論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡剖张,死狀恐怖顾犹,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 35,785評(píng)論 5 346
  • 正文 年R本政府宣布栏账,位于F島的核電站,受9級(jí)特大地震影響闭翩,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜者疤,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,420評(píng)論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,988評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背糠排。 一陣腳步聲響...
    開封第一講書人閱讀 33,101評(píng)論 1 271
  • 我被黑心中介騙來泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人铅乡。 一個(gè)月前我還...
    沈念sama閱讀 48,298評(píng)論 3 372
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像蔑鹦,于是被迫代替她去往敵國(guó)和親哟忍。 傳聞我的和親對(duì)象是個(gè)殘疾皇子爆安,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,033評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容