web3j學(xué)習(xí)


學(xué)習(xí)一門(mén)知識(shí)、一項(xiàng)技術(shù)都先搞清楚他的概念,才能穩(wěn)固、有目的信心。它是什么,干了什么(處理了什么問(wèn)題)

以太坊是什么?

以太坊(英文Ethereum)是一個(gè)開(kāi)源的有智能合約功能的公共區(qū)塊鏈平臺(tái),通過(guò)其專用加密貨幣以太幣(Ether,簡(jiǎn)稱“ETH”)提供去中心化的以太虛擬機(jī)(Ethereum Virtual Machine)來(lái)處理點(diǎn)對(duì)點(diǎn)合約。

web3j是什么?

??web3j是一種高度模塊化、靈活、安全的Java類庫(kù)和Android類庫(kù),用于處理智能合同,并與以太網(wǎng)絡(luò)中的客戶端(節(jié)點(diǎn))集成??梢酝ㄟ^(guò)它進(jìn)行以太坊區(qū)塊鏈的開(kāi)發(fā),而無(wú)需為你的應(yīng)用平臺(tái)編寫(xiě)集成代碼。

geth

Go-Ethereum簡(jiǎn)稱Geth,用golang語(yǔ)言實(shí)現(xiàn)

其官方GitHub的說(shuō)法,Geth是以太坊協(xié)議的官方實(shí)現(xiàn)(Official golang implementation of the Ethereum protocol),是以太坊基金會(huì)對(duì)外提供的重要官方軟件之一。

所謂以太坊協(xié)議的實(shí)現(xiàn),個(gè)人理解就是對(duì)以太坊協(xié)議范圍內(nèi)的各項(xiàng)能力進(jìn)行封裝,并以簡(jiǎn)單的形式(命令行、API等)提供給用戶使用,我們可以從兩個(gè)使用角度來(lái)理解:

  • Geth可以當(dāng)客戶端來(lái)使用
    打開(kāi)Geth,用戶可以創(chuàng)建自己的以太坊私有鏈、管理賬戶、挖礦、交易、部署執(zhí)行智能合約等,用戶還可以下載以太坊主鏈、解析主鏈上任意交易數(shù)據(jù)等。
  • Geth可以當(dāng)服務(wù)器來(lái)使用
    Geth提供很多服務(wù)和豐富的API,用戶可以開(kāi)發(fā)程序通過(guò)調(diào)用Geth服務(wù),實(shí)現(xiàn)自己想要的功能,比如獲取一段時(shí)間內(nèi)以太幣的所有交易賬戶。
infura

官網(wǎng): https://infura.io/
本地安裝geth的方法需要花比較多的時(shí)間和空間來(lái)同步區(qū)塊,利用infura可以簡(jiǎn)單很多,infura提供公開(kāi)以太坊和測(cè)試節(jié)點(diǎn),可以利用infura提供的api訪問(wèn)以太坊以及IPFS。去官網(wǎng)只需要提供email注冊(cè)得到鏈接即可。
本博客申請(qǐng)到的測(cè)試用例,后面代碼會(huì)用到(測(cè)試用例apikey沒(méi)什么價(jià)值,我在這里貼出來(lái)了)

image.png

安裝

Maven

Java 8:
<dependency>
  <groupId>org.web3j</groupId>
  <artifactId>core</artifactId>
  <version>3.4.0</version>
</dependency>

持續(xù)更新中...

交易機(jī)制

當(dāng)你用一些以太幣Ether創(chuàng)建了一個(gè)有效的帳戶時(shí),你可以使用兩種機(jī)制來(lái)與以太坊進(jìn)行交易。

  • 通過(guò)以太坊ethereum客戶端進(jìn)行認(rèn)證簽名交易
  • 離線交易簽名認(rèn)證
    這兩種機(jī)制都是Web3j所支持的。

這里我們使用第二種方式,不需要管理以太坊客戶端
離線交易簽名認(rèn)證:
為了離線脫機(jī)交易,你需要有你的錢包文件或與私密錢包/賬戶相關(guān)的公共和私人密鑰。
web3j能夠?yàn)槟闵梢粋€(gè)新的安全的以太坊錢包文件Ethereum wallet file,或者與也可以通過(guò)私鑰來(lái)和現(xiàn)有的錢包文件一起工作。

創(chuàng)建新的錢包文件:

  /*************創(chuàng)建一個(gè)錢包文件**************/
    private void creatAccount() throws NoSuchAlgorithmException, NoSuchProviderException, InvalidAlgorithmParameterException, CipherException, IOException {
        String walletFileName0="";//文件名
        String walletFilePath0="D:/my project/mybatis-plus-study/demo-web3j/etc-wallet";
        //錢包文件保持路徑,請(qǐng)?zhí)鎿Q位自己的某文件夾路徑

        walletFileName0 = WalletUtils.generateNewWalletFile("123456", new File(walletFilePath0), false);
        //WalletUtils.generateFullNewWalletFile("password1",new File(walleFilePath1));
        //WalletUtils.generateLightNewWalletFile("password2",new File(walleFilePath2));
        log.info("walletName: "+walletFileName0);

    }

加載憑據(jù)從錢包文件:

  /********加載錢包文件**********/
    private void loadWallet() throws IOException, CipherException {
        // FIXME:  替換為自己的錢包路徑
        String walleFilePath = "D:/my project/demo-web3j/etc-wallet/UTC--2020-04-17T09-39-23.188000000Z--51003b4b5ee042480a6d2ee5f08ffd265ab311cf.json";
        String passWord = "123456";
        credentials = WalletUtils.loadCredentials(passWord, walleFilePath);
        String address = credentials.getAddress();
        BigInteger publicKey = credentials.getEcKeyPair().getPublicKey();
        BigInteger privateKey = credentials.getEcKeyPair().getPrivateKey();

        log.info("address=" + address);
        log.info("public key=" + publicKey);
        log.info("private key=" + privateKey);
    }
17:34:39.186 [main] INFO com.yao.eth.util.Wallet - version=Geth/v1.9.8-omnibus-f14759fb-20191127/linux-amd64/go1.13.4
17:34:39.473 [main] INFO com.yao.eth.util.Wallet - address=0x51003b4b5ee042480a6d2ee5f08ffd265ab311cf
17:34:39.473 [main] INFO com.yao.eth.util.Wallet - public key=2252572073522424835987964408234834980696663221134034915707746353465859237410910323885187508316742508641207135834625486912634365340742976768431135181723788
17:34:39.474 [main] INFO com.yao.eth.util.Wallet - private key=84441263344107740006778209316822253467814847306459083060609524447653087837710

至此,錢包的創(chuàng)建和加載已經(jīng)完成,但這一過(guò)程全部發(fā)生在本地,并未同步到以太坊區(qū)塊鏈。查詢地址余額前,需要連接以太坊結(jié)點(diǎn)。

構(gòu)建Web3j實(shí)體,連接以太坊結(jié)點(diǎn)

web3j是連接java端與以太坊的橋梁,廣播交易,查詢賬戶都需要通過(guò)web3j實(shí)體。web3j支持通過(guò)http進(jìn)行構(gòu)建,而且兼容了infura。在本文中,使用的是infura的測(cè)試網(wǎng)絡(luò)Rinkeby。

/*******連接以太坊客戶端**************/
private void conectETHclient() throws IOException {
    //連接方式1:使用infura 提供的客戶端
    web3j = Web3j.build(new HttpService("https://rinkeby.infura.io/b23bd4d475cd42978a9d29293d7fb317"));// TODO: 2018/4/10 token更改為自己的
    //連接方式2:使用本地客戶端
    //web3j = Web3j.build(new HttpService("127.0.0.1:7545"));
    //測(cè)試是否連接成功
    String web3ClientVersion = web3j.web3ClientVersion().send().getWeb3ClientVersion();
    log.info("version=" + web3ClientVersion);
}

web3j實(shí)體構(gòu)建完成后,可以打印出版本號(hào)以測(cè)試是否連接成功。如果成功,就可以做其他的事情了。

查詢賬戶余額

  /***********查詢指定地址的余額***********/
    private void getBlanceOf() throws IOException {
        if (web3 == null) return;
        String address = "0x51003b4b5ee042480a6d2ee5f08ffd265ab311cf";//等待查詢余額的地址
        //第二個(gè)參數(shù):區(qū)塊的參數(shù),建議選最新區(qū)塊
        EthGetBalance balance = web3.ethGetBalance(address, DefaultBlockParameter.valueOf("latest")).send();
        //格式轉(zhuǎn)化 wei-ether
        String blanceETH = Convert.fromWei(balance.getBalance().toString(), Convert.Unit.ETHER).toPlainString().concat(" ether");
        log.info("blanceETH = "+ blanceETH);
    }

使用錢包轉(zhuǎn)賬

a.在轉(zhuǎn)賬之前我們得獲取一些測(cè)試用的以太幣
首先我們需要使用Twitter、FacebookGoogle Plus發(fā)布新的公開(kāi)內(nèi)
容,內(nèi)容是自己的錢包地址,然后粘貼相應(yīng)的文章的地址到faucet.

image.png

查看是否到賬和賬戶狀態(tài) 我們可以通過(guò)我們的地址去 explorer:https://www.rinkeby.io/#explorer
這樣我們就有可以操作的ETH進(jìn)行轉(zhuǎn)賬等操作了。
b.使用錢包文件來(lái)發(fā)起交易

try {
    Credentials credentials = WalletUtils.loadCredentials(password,filePath);
    TransactionReceipt transferReceipt = Transfer.sendFunds(web3j, credentials, to,amount, Convert.Unit.WEI).send();
    String hash = transferReceipt.getTransactionHash();
    log.info("轉(zhuǎn)賬成功,轉(zhuǎn)賬hash = {}",hash);
} catch (Exception e) {
    log.error("轉(zhuǎn)賬失敗,失敗原因{}",e);
}

這種方式相對(duì)安全一些,這里需要注意的是一些ETH的最小單位——WEI.

1ETH = 1*10^18 wei;

提示:轉(zhuǎn)賬這里存在一些gas的問(wèn)題,所謂gas我們都知道是轉(zhuǎn)賬時(shí)需要花費(fèi)的曠工費(fèi)。這里我們可以通過(guò)gasLimit和gasPrice來(lái)調(diào)整,當(dāng)然我們肯定希望gas小,但是gas一味的小,會(huì)導(dǎo)致沒(méi)有人愿意幫我們打包我們得到交易,導(dǎo)致交易最終無(wú)法成交,形成一個(gè)pending的狀態(tài)。如果gas給的多,那么交易成交速度會(huì)比較快,但是我們花費(fèi)的錢就會(huì)變多。

在之前實(shí)現(xiàn)的基礎(chǔ)上,我們可以拿到自己創(chuàng)建的錢包,和對(duì)應(yīng)錢包的文件和密碼。

相關(guān)問(wèn)題

1.ETH交易模塊的特點(diǎn)

  1. 必須按順序處理事務(wù)(具有1的nonce為1的事務(wù)必須在具有2的nonce的事務(wù)之前處理)
  2. 不跳過(guò)(具有4的nonce的事務(wù)不能包含在塊中,直到具有1,2,3的nonce的事務(wù)

通過(guò)這種方式,網(wǎng)絡(luò)能夠識(shí)別交易的重復(fù)并強(qiáng)制執(zhí)行訂單(這對(duì)于智能合約至關(guān)重要) 這也就上文中說(shuō)過(guò)的nonce, ### 2.如何查看我們轉(zhuǎn)賬的狀態(tài) 我們可以通過(guò)轉(zhuǎn)賬后拿到的TxHash去https://etherscan.io/查詢。

2.如何取消Pending狀態(tài)轉(zhuǎn)賬

上文說(shuō)到了轉(zhuǎn)賬因?yàn)間as設(shè)置的比較小,可能造成無(wú)法成交,一直處于Pending狀態(tài)。 然后我們可以通過(guò)nonce去取消Pending的轉(zhuǎn)賬, 我們通過(guò)nonce的機(jī)制可以得知,我們只要新創(chuàng)建一筆轉(zhuǎn)賬,其中nonce和Pending狀態(tài)的訂單的nonce一樣就可以替換當(dāng)前Pending狀態(tài)得到轉(zhuǎn)賬。

那么最好的操作來(lái)實(shí)現(xiàn)就是發(fā)起一筆向自己轉(zhuǎn)賬的訂單,當(dāng)然gas我們需要設(shè)置得到>合理。 轉(zhuǎn)賬參考以上兩種方法。

3.取消或者取代轉(zhuǎn)賬

通過(guò)之前2中所提到了,我們可以知道,其實(shí)一個(gè)交易發(fā)出后,被覆蓋,代替,取消等操作的幾率很小。但是也不是不可能。只要當(dāng)前交易不被挖礦和包含在區(qū)塊中,是可以做相關(guān)關(guān)操作的。 具體操作方法還是和3相似,但是切記不可更改nonce.(具體情況還要和實(shí)際相比較,畢竟這種操作實(shí)現(xiàn)的概率幾乎為0)

上述過(guò)程需要翻墻

更新補(bǔ)充,(博主的Facebook和Twitter由于發(fā)送上述消息給封禁了,莫名其妙~)上訴過(guò)程測(cè)試網(wǎng)更改成Ropsten(https://infura.io/

)

image.png

這個(gè)端點(diǎn)獲取測(cè)試幣相交簡(jiǎn)單些
所以在構(gòu)建Web3j實(shí)體,連接以太坊結(jié)點(diǎn)時(shí)構(gòu)建web3j客戶端參數(shù)更換一下

 web3j = Web3j.build(new HttpService("https://ropsten.infura.io/v3/b23bd4d475cd42978a9d29293d7fb317"));

獲取測(cè)試幣
https://faucet.ropsten.be/
在網(wǎng)站中輸入錢包地址就ok了

image.png

查詢交易記錄
https://ropsten.etherscan.io/
同樣是輸入錢包地址
image.png

轉(zhuǎn)賬記錄

  /****************交易*****************/
    private void transto() throws Exception {
        if (web3 == null) return;
        if (credentials == null) return;
        //開(kāi)始發(fā)送0.01 =eth到指定地址
        String address_to = "0x41F1dcbC0794BAD5e94c6881E7c04e4F98908a87";
        TransactionReceipt send = Transfer.sendFunds(web3, credentials, address_to, BigDecimal.ONE, Convert.Unit.FINNEY).send();

        log.info("Transaction complete:");
        log.info("trans hash=" + send.getTransactionHash());
        log.info("from :" + send.getFrom());
        log.info("to:" + send.getTo());
        log.info("gas used=" + send.getGasUsed());
        log.info("status: " + send.getStatus());

打印結(jié)果:

19:28:37.062 [main] INFO com.yao.eth.util.Wallet - Transaction complete:
19:28:37.062 [main] INFO com.yao.eth.util.Wallet - trans hash=0xa8dd680b1fa7d82693d922f16f554746bba06ec0558daa0be30e6f50ed620071
19:28:37.062 [main] INFO com.yao.eth.util.Wallet - from :0x51003b4b5ee042480a6d2ee5f08ffd265ab311cf
19:28:37.062 [main] INFO com.yao.eth.util.Wallet - to:0x41f1dcbc0794bad5e94c6881e7c04e4f98908a87
19:28:37.062 [main] INFO com.yao.eth.util.Wallet - gas used=21000
19:28:37.062 [main] INFO com.yao.eth.util.Wallet - status: 0x1

把trans hash復(fù)制到框內(nèi),查詢交易記錄詳情:https://ropsten.etherscan.io

image.png

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 本文列出2019年最新整理的用于區(qū)塊鏈開(kāi)發(fā)的43種流行的開(kāi)發(fā)庫(kù)、開(kāi)發(fā)工具與開(kāi)發(fā)框架。 1、MetaMask 人人都...
    編程狂魔閱讀 2,754評(píng)論 0 1
  • 根據(jù)英文原版整理,內(nèi)容有增刪 1、開(kāi)發(fā)語(yǔ)言、框架與工具 語(yǔ)言 Solidity - 官方推薦以太坊智能合約開(kāi)發(fā)語(yǔ)言...
    Rakutens閱讀 988評(píng)論 0 2
  • 目標(biāo)讀者: 專業(yè)的程序員; 想深入了解以太坊/區(qū)塊鏈及其生態(tài)的讀者; 如果你已經(jīng)有一定的以太坊技術(shù)基礎(chǔ),只想研究一...
    編程狂魔閱讀 1,740評(píng)論 0 11
  • 夜 上 安 瀾 樓 文/安康Mr.車 曲 徑 通 幽 望 江 亭 登 高 望...
    安康Mr車閱讀 450評(píng)論 0 1

友情鏈接更多精彩內(nèi)容