使用web3j構(gòu)建以太坊錢包

創(chuàng)建一個(gè)以太坊錢包有多種方式报账,一般情況下可以通過geth研底、EtherumWallet等客戶端埠偿。對(duì)于前端,可以使用插件MetaMask進(jìn)行創(chuàng)建榜晦。這幾種方式技術(shù)實(shí)現(xiàn)雖然不同,但底層原理是一致的。本文主要介紹如何通過web3j架構(gòu)創(chuàng)建一個(gè)以太坊的冷錢包,從而實(shí)現(xiàn)將這一過程部署在服務(wù)端或者android端。

文中涉及到的技術(shù)棧有:

Web3j :輕量級(jí)java庫,用于連接以太坊客戶端或節(jié)點(diǎn)

Infura :以太坊基礎(chǔ)設(shè)施圆兵,用于訪問以太坊主網(wǎng)絡(luò)或測(cè)試網(wǎng)絡(luò)

Java:編程語言

1.Web3j的安裝

無論是java工程還是android工程超凳,web3j都提供了maven和grade 兩種依賴方式:

  1. java工程
  • manen依賴
<dependency>
  <groupId>org.web3j</groupId>
  <artifactId>core</artifactId>
  <version>3.3.1</version>
</dependency>
  • gradle依賴
compile ('org.web3j:core:3.3.1')
  1. android工程
  • maven依賴
<dependency>
  <groupId>org.web3j</groupId>
  <artifactId>core</artifactId>
  <version>3.3.1-android</version>
</dependency>
  • gradle依賴
compile ('org.web3j:core:3.3.1-android')

值得注意的是杭跪,目前的web3j對(duì)于高版本JDK存在不兼容的問題现斋,如果出現(xiàn)如下類似的問題,直接更換JDK為version 8即可。

<u>Could not determine Java version using executable /Library/Java/JavaVirtualMachines/jdk-10.jdk/Contents/Home/bin/java.</u>

2.關(guān)于Infura

以太坊的客戶端實(shí)現(xiàn)有多種疼约,但很多都需要在本地同步所有的節(jié)點(diǎn)數(shù)據(jù)而占用大量硬盤存儲(chǔ)空間,并且需要消耗同步的時(shí)間。Infura就是提供一種中心化的服務(wù),通過web3.js或者web3j使前端或服務(wù)端能便捷的訪問以太坊所有節(jié)點(diǎn)丘损∮呤唬可以理解為一種以太坊客戶端的云端版本珊皿。使用過程需要注冊(cè)驶兜,一個(gè)專屬的訪問token蝇狼。本文中使用的客戶端都是Infura提供的Rinkeby測(cè)試網(wǎng)絡(luò)。

3.新建錢包文件keyfile

在以太坊中栖秕,錢包(wallet)和賬戶(account)是兩個(gè)不同的概念暑塑。賬戶是以太坊的核心,由一對(duì)秘鑰組成-公鑰和私鑰锅必。賬戶可以分為兩種,外部賬戶和合約賬戶逢捺。而錢包是指保存 地址辉巡、公鑰程梦、私鑰的文件或其他機(jī)構(gòu),每個(gè)錢包文件至少包含一個(gè)賬戶朵你。創(chuàng)建錢包的同時(shí)也是創(chuàng)建一個(gè)以太坊賬戶的過程不同的客戶端創(chuàng)建錢包的方式不一致但原理相同各聘,有關(guān)錢包是具體是如何生成的可以查看另外這篇文章。

  1. 新建一個(gè)java工程撬呢,初始化gradle或者maven
  2. 依賴web3j
  3. 新建Application.java文件伦吠,設(shè)置程序入口main函數(shù)
  4. 調(diào)用錢包工具類生成錢包文件
/*************創(chuàng)建一個(gè)錢包文件**************/
private void creatAccount() throws NoSuchAlgorithmException, NoSuchProviderException, InvalidAlgorithmParameterException, CipherException, IOException {
    String walletFileName0="";//文件名
    String walletFilePath0="/Users/yepeng/MyGitHub/z_wallet_temp";
    //錢包文件保持路徑,請(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);
}

錢包構(gòu)建的過程中需要輸入的三個(gè)參數(shù),分別設(shè)置錢包的密碼毛仪、保存路徑搁嗓、以及是否輕量級(jí)錢包。

執(zhí)行創(chuàng)建函數(shù)后箱靴,會(huì)自動(dòng)在指定路徑生成一個(gè)json 文件腺逛,即錢包keyfiles。


屏幕快照 2018-04-10 上午11.04.24.png

錢包文件結(jié)構(gòu):


屏幕快照 2018-04-10 上午11.14.03.png
  • cipher:加密算法衡怀,AES算法棍矛,用于加密以太坊私鑰
  • cipherparams:cipher算法需要的參數(shù),參數(shù)iv抛杨,是aes-128-ctr加密算法需要的初始化向量
  • ciphertext:加密后的密文够委,aes-128-ctr函數(shù)的加密輸入密文;
  • kdf:秘鑰生成函數(shù)怖现,用于使用密碼加密keystore文件
  • kdfparams:kdf算法所需要的參數(shù)
  • mac:驗(yàn)證密碼的編碼

生成錢包的逆向過程 為加載錢包茁帽。

4.加載錢包文件

加載錢包的過程需要提供錢包文件和密碼

/********加載錢包文件**********/
private void loadWallet() throws IOException, CipherException {
    String walleFilePath="/Users/yepeng/MyGitHub/z_wallet_temp/UTC--2018-04-10T02-51-24.815000000Z--12571f46ec3f81f7ebe79112be5883194d683787.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);

}

函數(shù)運(yùn)行的結(jié)果:


屏幕快照 2018-04-10 上午11.10.19-3417487.png

通過工具類 WalletUtols的函數(shù) loadCredentials(),會(huì)返回一個(gè)對(duì)象Credentials,這個(gè)對(duì)象即包含了錢包文件的所有信息屈嗤,包括地址潘拨、秘鑰對(duì)。

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

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

web3j是連接java端與以太坊的橋梁狰闪,廣播交易,查詢賬戶都需要通過web3j實(shí)體濒生。web3j支持通過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/zmd7VgRt9go0x6qlJ2Mk"));// 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è)試是否連接成功觉义。如果成功雁社,就可以做其他的事情了。值得注意的是晒骇,web3j采用的是RxJava的設(shè)計(jì)霉撵,所以許多函數(shù)的返回值是 Request<?,?>磺浙,這個(gè)對(duì)象有兩種執(zhí)行方式,異步和同步徒坡,即send()和sendAsyn()撕氧。

6.查詢賬戶余額

查詢賬戶的余額的方式:

/***********查詢指定地址的余額***********/
private void getBlanceOf() throws IOException {
    if (web3j == null) return;
    String address = "0x41F1dcbC0794BAD5e94c6881E7c04e4F98908a87";//等待查詢余額的地址
    //第二個(gè)參數(shù):區(qū)塊的參數(shù),建議選最新區(qū)塊
    EthGetBalance balance = web3j.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);
}

其中核心方法 web3j.ethGetBalance(address, defaultBlockParameter) 中的第二個(gè)參數(shù)比較特殊喇完,指默認(rèn)的區(qū)塊參數(shù)伦泥。當(dāng)請(qǐng)求余額的方法作用與以太坊的區(qū)塊網(wǎng)絡(luò)時(shí),這個(gè)參數(shù)決定了查詢區(qū)塊的高度锦溪。

  • HEX String - 一個(gè)整數(shù)塊號(hào)
  • String "earliest" 為最早/起源塊
  • String "latest" - 為最新的采礦塊
  • String "pending" - 待處理狀態(tài)/交易

一般情況下不脯,選擇“l(fā)atest”即可。

以太坊中刻诊,如果沒有特殊標(biāo)示防楷,數(shù)字的單位都是小數(shù)點(diǎn)后18位,因此查詢賬戶余額有必要將wei轉(zhuǎn)化成ether则涯。

6.使用錢包進(jìn)行轉(zhuǎn)賬

作為一個(gè)錢包域帐,除了保存賬戶資產(chǎn)外,最重要的就是轉(zhuǎn)賬或交易了是整,利用web3j可以便捷的實(shí)現(xiàn)eth的轉(zhuǎn)移。

/    /****************交易*****************/
    private void transto() throws Exception {
        if (web3j == null) return;
        if (credentials == null) return;
        //開始發(fā)送0.01 =eth到指定地址
        String address_to = "0x41F1dcbC0794BAD5e94c6881E7c04e4F98908a87";
        TransactionReceipt send = Transfer.sendFunds(web3j, 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());
    }

核心方法需要提供4個(gè)參數(shù):

  • web3j實(shí)體
  • Credentials 源賬戶
  • address 轉(zhuǎn)出地址
  • value 數(shù)量
  • uint 單位

等待片刻后民假,會(huì)返回轉(zhuǎn)賬結(jié)果

屏幕快照 2018-04-11 上午11.32.12.png

可以看到交易hash浮入、轉(zhuǎn)入轉(zhuǎn)出地址、gas消耗等信息羊异。同時(shí)可以在etherscan-rinkeby上進(jìn)行查看本次交易詳情

7.總結(jié)

上面的代碼已經(jīng)完成了一個(gè)以太坊錢包所需的所有基本功能事秀,包括創(chuàng)建、加載野舶、轉(zhuǎn)賬易迹、查詢。本文中采用的網(wǎng)絡(luò)是infura提供的Rinkeby測(cè)試網(wǎng)絡(luò)平道,創(chuàng)建的錢包地址為 0x12571F46Ec3f81F7EbE79112Be5883194d683787睹欲。

在具體的業(yè)務(wù)場(chǎng)景中,只要將測(cè)試網(wǎng)絡(luò)更換為以太坊主網(wǎng)絡(luò)即可一屋。

源碼地址 https://github.com/initsysctrl/we3jdemo

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末窘疮,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子冀墨,更是在濱河造成了極大的恐慌闸衫,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,525評(píng)論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件诽嘉,死亡現(xiàn)場(chǎng)離奇詭異蔚出,居然都是意外死亡弟翘,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,203評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門骄酗,熙熙樓的掌柜王于貴愁眉苦臉地迎上來稀余,“玉大人,你說我怎么就攤上這事酥筝」銮” “怎么了?”我有些...
    開封第一講書人閱讀 164,862評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵嘿歌,是天一觀的道長(zhǎng)掸掏。 經(jīng)常有香客問我,道長(zhǎng)宙帝,這世上最難降的妖魔是什么丧凤? 我笑而不...
    開封第一講書人閱讀 58,728評(píng)論 1 294
  • 正文 為了忘掉前任,我火速辦了婚禮步脓,結(jié)果婚禮上愿待,老公的妹妹穿的比我還像新娘。我一直安慰自己靴患,他們只是感情好仍侥,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,743評(píng)論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著鸳君,像睡著了一般农渊。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上或颊,一...
    開封第一講書人閱讀 51,590評(píng)論 1 305
  • 那天砸紊,我揣著相機(jī)與錄音,去河邊找鬼囱挑。 笑死醉顽,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的平挑。 我是一名探鬼主播游添,決...
    沈念sama閱讀 40,330評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼通熄!你這毒婦竟也來了否淤?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,244評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤棠隐,失蹤者是張志新(化名)和其女友劉穎石抡,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體助泽,經(jīng)...
    沈念sama閱讀 45,693評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡啰扛,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,885評(píng)論 3 336
  • 正文 我和宋清朗相戀三年嚎京,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片隐解。...
    茶點(diǎn)故事閱讀 40,001評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡鞍帝,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出煞茫,到底是詐尸還是另有隱情帕涌,我是刑警寧澤,帶...
    沈念sama閱讀 35,723評(píng)論 5 346
  • 正文 年R本政府宣布续徽,位于F島的核電站蚓曼,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏钦扭。R本人自食惡果不足惜纫版,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,343評(píng)論 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望客情。 院中可真熱鬧其弊,春花似錦、人聲如沸膀斋。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,919評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽仰担。三九已至糊识,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間惰匙,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,042評(píng)論 1 270
  • 我被黑心中介騙來泰國打工铃将, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留项鬼,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,191評(píng)論 3 370
  • 正文 我出身青樓劲阎,卻偏偏與公主長(zhǎng)得像绘盟,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子悯仙,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,955評(píng)論 2 355

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

  • 以太坊(Ethereum ):下一代智能合約和去中心化應(yīng)用平臺(tái) 翻譯:巨蟹 龄毡、少平 譯者注:中文讀者可以到以太坊愛...
    車圣閱讀 3,761評(píng)論 1 7
  • 以太坊白皮書地址:https://github.com/ethereum/wiki/wiki/White-Pape...
    rectinajh閱讀 17,828評(píng)論 0 46
  • app.php Test.php IAuth.php Common.php 緩存位置
    子木同閱讀 176評(píng)論 0 0
  • 2017年9月2日,風(fēng)和日麗锡垄、萬里無云沦零,準(zhǔn)備和一位素未謀面的影友,觀賞《敦刻爾克》货岭。 期待之情路操,無以言表
    奮進(jìn)的小之閱讀 396評(píng)論 0 1
  • 2017.9.4.日記:凌晨睡下疾渴,不宜攪動(dòng)陽氣,和衣而睡屯仗。7點(diǎn)醒來搞坝,未能閱讀,惰性使然魁袜。突然意識(shí)到孩子一年來學(xué)習(xí)的...
    麗華1117閱讀 215評(píng)論 0 1