欢迎访问比特币_区块链-币链视界!

币链视界

区块链开发之ETH钱包APP

发布时间:2021-02-23区块链开发评论
“我们相信,开放、即时、匿名、低成本、自公信的价值互联网更符合未来社会生态系统的经济机遇和商业价值。”目录基础知识开发准备实战开发总结参考文献基础知识介绍以太坊(

“我们相信,开放、即时、匿名、低成本、自公信的价值互联网更符合未来社会生态系统的经济机遇和商业价值。”目录基础知识

开发准备

实战开发

总结

参考文献

基础知识介绍

以太坊(英文Ethereum)是一个开源的有智能合约功能的公共区块链平台,通过其专用加密货币以太币(Ether,简称“ETH”)提供去中心化的以太虚拟机(EthereumVirtualMachine)来处理点对点合约。

合约

合约是一个活在以太坊系统里的自动代理人,他有一个自己的以太币地址,当用户向合约的地址里发送一笔交易后,该合约就被激活,然后根据交易中的额外信息,合约会运行自身的代码,最后返回一个结果,这个结果可能是从合约的地址发出另外一笔交易。需要指出的是,以太坊中的交易,不单只是发送以太币而已,它还可以嵌入相当多的额外信息。如果一笔交易是发送给合约的,那么这些信息就非常重要,因为合约将根据这些信息来完成自身的业务逻辑。

开发准备Web3J介绍:web3j是一个高度模块化,反应性,类型安全的Java和Android库,用于与智能合约配合并与以太坊网络上的客户端(节点)集成:

功能

通过HTTP和IPC完整实现以太坊的JSON-RPC客户端API

以太坊钱包支持

自动生成Java智能合约包装器,以从本地Java代码创建,部署,处理和调用智能合约(支持Solidity和Truffle定义格式)

响应式API,用于过滤器

以太坊名称服务(ENS)支持

支持Parity的Personal和Geth的Personal客户端API

支持Infura,因此您不必自己运行以太坊客户端

支持ERC20和ERC721令牌标准

全面的集成测试,证明了上述多种情况

命令行工具

兼容Android

通过web3j-quorum支持JPMorgan的Quorum

依赖Java8:

compile('org.web3j:core:4.5.12')Android:

implementation('org.web3j:core:4.2.0-android')web3j基本使用1、同步

Web3jweb3=Web3j.build(newHttpService("节点地址"));//defaultstohttp://localhost:8545/Web3ClientVersionweb3ClientVersion=web3.web3ClientVersion().send();Stringversion=web3ClientVersion.getWeb3ClientVersion();System.out.println("version:"+version);2、异步

Web3jweb3=Web3j.build(newHttpService("节点地址"));//defaultstohttp://localhost:8545/web3.web3ClientVersion().sendAsync().thenAccept(newConsumer(){@Overridepublicvoidaccept(Web3ClientVersionweb3ClientVersion){System.out.println(web3ClientVersion.getWeb3ClientVersion());}}).exceptionally(newFunction(){@OverridepublicVoidapply(Throwablethrowable){throwable.printStackTrace();returnnull;}});实战开发生成账号1、随机生成账号

Stringmnemonic=ChainUtil.genMnemonic();ECKeyecKey=ChainUtil.genECKey(mnemonic,"m/44'/60'/0'/0/0","");ECKeyPairkeyPair=ECKeyPair.create(ecKey.getPrivKeyBytes());Filefile=newFile("Keystore存放的路径");StringwalletFile=WalletUtils.generateWalletFile("你的密码",keyPair,file,false);Stringkeystore=FilesUtils.readFileString(newFile(file,walletFile).getAbsolutePath());Credentialscredentials=WalletUtils.loadCredentials("你的密码",newFile(file,walletFile));Stringaddress=credentials.getAddress();System.out.println("mnemonic:"+mnemonic);System.out.println("privateKey:"+keyPair.getPrivateKey().toString(16));System.out.println("publicKey:"+keyPair.getPublicKey().toString(16));System.out.println("keystore:"+keystore);System.out.println("address:"+address);2、私钥导入

StringprivateKey="你的私钥";Credentialscredentials=Credentials.create(privateKey);Stringaddress=credentials.getAddress();ECKeyPairkeyPair=credentials.getEcKeyPair();Filefile=newFile("Keystore存放的路径");StringwalletFile=WalletUtils.generateWalletFile("你的密码",keyPair,file,false);Stringkeystore=FilesUtils.readFileString(newFile(file,walletFile).getAbsolutePath());System.out.println("privateKey:"+keyPair.getPrivateKey().toString(16));System.out.println("publicKey:"+keyPair.getPublicKey().toString(16));System.out.println("keystore:"+keystore);System.out.println("address:"+address);//私钥是无法推算出助记词的3、KeyStore导入

Stringkeystore="你的keyStore";ObjectMapperobjectMapper=newObjectMapper();objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES,false);WalletFilewalletFile=objectMapper.readValue(keystore,WalletFile.class);ECKeyPairkeyPair=EthWallet.decrypt("你的密码",walletFile);StringprivateKey=keyPair.getPrivateKey().toString(16);StringpublicKey=keyPair.getPublicKey().toString(16);Credentialscredentials=Credentials.create(privateKey,publicKey);Stringaddress=credentials.getAddress();System.out.println("privateKey:"+privateKey);System.out.println("publicKey:"+publicKey);System.out.println("keystore:"+keystore);System.out.println("address:"+address);4、助记词导入

Stringmnemonic="你的助记词,逗号分隔";ECKeyecKey=ChainUtil.genECKey(mnemonic,"m/44'/60'/0'/0/0","");ECKeyPairkeyPair=ECKeyPair.create(ecKey.getPrivKeyBytes());Filefile=newFile("Keystore存放的路径");StringwalletFile=WalletUtils.generateWalletFile("你的密码",keyPair,file,false);Stringkeystore=FilesUtils.readFileString(newFile(file,walletFile).getAbsolutePath());Credentialscredentials=WalletUtils.loadCredentials("你的密码",newFile(file,walletFile));Stringaddress=credentials.getAddress();System.out.println("mnemonic:"+mnemonic);System.out.println("privateKey:"+keyPair.getPrivateKey().toString(16));System.out.println("publicKey:"+keyPair.getPublicKey().toString(16));System.out.println("keystore:"+keystore);System.out.println("address:"+address);转账

Stringfrom="转出地址";Stringto="转入地址";StringprivateKey="你的私钥";BigIntegervalue="转出多少";BigIntegergasPrice="gas价格";BigIntegergasLimit=BigInteger.valueOf(21000);//单笔转账一般取21000Web3jweb3=Web3j.build(newHttpService("节点地址"));//defaultstohttp://localhost:8545/BigIntegernonce=web3.ethGetTransactionCount(from,DefaultBlockParameterName.LATEST).send().getTransactionCount();RawTransactionrawTransaction=RawTransaction.createTransaction(nonce,gasPrice,gasLimit,to,value,"");ECKeyPairecKeyPair=ECKeyPair.create(newBigInteger(privateKey,16));Credentialscredentials=Credentials.create(ecKeyPair);byte[]signMessage=TransactionEncoder.signMessage(rawTransaction,credentials);StringsignData=Numeric.toHexString(signMessage);EthSendTransactionethSendTransaction=web3.ethSendRawTransaction(signData).send();StringtransactionHash=ethSendTransaction.getTransactionHash();System.out.println("hash:"+transactionHash);//获取到hash就可以查询交易状态了。代币转账

Stringfrom="转出地址";Stringto="转入地址";StringprivateKey="你的私钥";BigIntegervalue="转出多少";Stringcontract="";//合约地址BigIntegergasPrice="gas价格";BigIntegergasLimit=BigInteger.valueOf(60000);//代币转账一般取60000Web3jweb3=Web3j.build(newHttpService("节点地址"));//defaultstohttp://localhost:8545/BigIntegernonce=web3.ethGetTransactionCount(from,DefaultBlockParameterName.LATEST).send().getTransactionCount();Functionfunction=newFunction("transfer",Arrays.asList(newAddress(to),newUint256(value)),Collections.singletonList(newTypeReference(){}));StringencodedFunction=FunctionEncoder.encode(function);RawTransactionrawTransaction=RawTransaction.createTransaction(nonce,gasPrice,gasLimit,contract,encodedFunction);ECKeyPairecKeyPair=ECKeyPair.create(newBigInteger(privateKey,16));Credentialscredentials=Credentials.create(ecKeyPair);byte[]signMessage=TransactionEncoder.signMessage(rawTransaction,credentials);StringsignData=Numeric.toHexString(signMessage);EthSendTransactionethSendTransaction=web3.ethSendRawTransaction(signData).send();StringtransactionHash=ethSendTransaction.getTransactionHash();System.out.println("hash:"+transactionHash);//获取到hash就可以查询交易状态了。获取余额

Web3jweb3=Web3j.build(newHttpService("节点地址"));//defaultstohttp://localhost:8545/Stringaddress="获取余额的地址";BigIntegerbalance=web3.ethGetBalance(address,DefaultBlockParameterName.LATEST).send().getBalance();System.out.println("balance:"+balance);获取Token余额

参数:from:钱包地址to:代币地址(智能合约地址)data:0x70a08231000000000000000000000000b60e8dd61c5d32be8058bb8eb970870f07233155//注意data数据格式:最前边的“0x70a08231000000000000000000000000”是固定的,后边的是钱包地址(不带“0x”前缀)QUANTITYTAG,”latest”,“earliest”or“pending”代码示例

Web3jweb3=Web3j.build(newHttpService("节点地址"));//defaultstohttp://localhost:8545/Stringaddress="获取余额的地址";Stringcontract="合约地址";StringtmpAddress=address;if(tmpAddress.startsWith("0x")){tmpAddress=address.substring(2);//去掉0x}Stringdata="0x70a08231000000000000000000000000"+tmpAddress;Transactiontransaction=Transaction.createEthCallTransaction(address,contract,data);Stringbalance=web3.ethCall(transaction,DefaultBlockParameterName.LATEST).send().getValue();System.out.println("balance:"+balance);总结1、导入钱包踩坑导入轻钱包解析失败解决方案OutOfMemoryexceptionwhenusingweb3jinAndroid解决办法

implementation‘com.lambdaworks:scrypt:1.4.0’//解决oom错误的依赖因为在导入keystore解析时,只是这句报错常规的:ECKeyPairkeyPair=ECKeyPair.create(privateKeyByte);报错,这个错误,是因为重钱包不能被解析轻钱包的方法解析,keyStore中crypto.kdfparams.n:262144,这个数值很大,一般常规的轻钱包n值是:4000左右,或者是个四位数。对于解决办法,查了很多资料,最后找到了。替换下面代码即可。

//derivedKey=generateDerivedScryptKey(password.getBytes(Charset.forName("UTF-8")),salt,n,r,p,dklen);derivedKey=com.lambdaworks.crypto.SCrypt.scrypt(password.getBytes(StandardCharsets.UTF_8),salt,n,r,p,dklen);2、实现以太坊钱包相对还是容易一些,毕竟提供了相关的SDK,实现起来也容易,主要是掌握web3j的API使用,如果选择其他的以太坊SDK也是差不多的,只是熟悉API的调用即可。

参考文献ethereumgithub:?

web3jgithub:?

web3j官网:?

感谢代币余额查询文章:

感谢转账和代币转账文章:

感谢解决AndroidOOM文章链鱼科技基于普世价值和科学思考,以去中心化、多中心化信任为核心,结合传统互联网优点,通过底层技术建立起科学、公证、透明的资产增值+再分配生态系统。(ID:lianyujishu)

广告位

热心评论

评论列表