Java 类库 web3j 开发以太坊智能合约快速入门 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
Sign Up Now
For Existing Member  Sign In
jimi2018
V2EX    Java

Java 类库 web3j 开发以太坊智能合约快速入门

  •  2
     
  •   jimi2018 Jun 18, 2018 4850 views
    This topic created in 2872 days ago, the information mentioned may be changed or developed.

    web3j 简介

    web3j 是一个轻量级、高度模块化、响应式、类型安全的 Java 和 Android 类库提供丰富 API,用于处理以太坊智能合约及与以太坊网络上的客户端(节点)进行集成。

    可以通过它进行以太坊区块链的开发,而无需为你的 java 应用平台编写集成代码。

    快速启动

    想要快速启动的话,有一个Web3j demo 示例项目可用,演示了通过 Web3j 开发以太坊的许多核心特征,其中包括:

    • 连接到以太网网络上的节点
    • 加载一个以太坊钱包文件
    • 将以太币从一个地址发送到另一个地址
    • 向网络部署智能合约
    • 从部署的智能合约中读取值
    • 更新部署的智能合约中的值
    • 查看由智能合约记录的事件

    web3j 入门

    首先将最新版本的 web3j 安装到项目中。

    Maven

    Java 8:

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

    Android:

    <dependency> <groupId>org.web3j</groupId> <artifactId>core</artifactId> <version>3.3.1-android</version> </dependency> 

    Gradle

    Java 8:

    compile ('org.web3j:core:3.4.0') 

    Android:

    compile ('org.web3j:core:3.3.1-android') 

    启动客户端

    需要启动一个以太坊客户端,当然如果你已经启动了就不需要再次启动。

    如果是geth的话这么启动:

    $ geth --rpcapi personal,db,eth,net,web3 --rpc --rinkeby 

    如果是Parity启动:

    $ parity --chain testnet 

    如果使用Infura客户端提供的免费的云端服务,这么启动:

    Web3j web3 = Web3j.build(new HttpService("https://morden.infura.io/your-token")); 

    如果想进一步的了解 infura,请参阅Using Infura with web3j

    在网络上如何获得以太币的相关文档可以看这个:testnet section of the docs

    当不需要 Web3j 实例时,需要调用shutdown方法来释放它所使用的资源。

    web3.shutdown() 

    发送请求

    发送同步请求

    Web3j web3 = Web3j.build(new HttpService()); // defaults to http://localhost:8545/ Web3ClientVersion web3ClientVersion = web3.web3ClientVersion().send(); String clientVersion = web3ClientVersion.getWeb3ClientVersion(); 

    ** 使用 CompletableFuture (Future on Android) 发送异步请求**

    Web3j web3 = Web3j.build(new HttpService()); // defaults to http://localhost:8545/ Web3ClientVersion web3ClientVersion = web3.web3ClientVersion().sendAsync().get(); String clientVersion = web3ClientVersion.getWeb3ClientVersion(); 

    *使用 RxJava 的 Observable

    Web3j web3 = Web3j.build(new HttpService()); // defaults to http://localhost:8545/ web3.web3ClientVersion().observable().subscribe(x -> { String clientVersion = x.getWeb3ClientVersion(); ... }); 

    注意 Android 使用方式

    Web3j web3 = Web3jFactory.build(new HttpService()); // defaults to http://localhost:8545/ ... 

    IPC

    Web3j 还支持通过文件套接字快速运行进程间通信( IPC ),支持客户端在相同的主机上同时运行 Web3j。在创建服务时,使用相关的IPCService就可以实现而不需要通过HTTPService

    // OS X/Linux/Unix: Web3j web3 = Web3j.build(new UnixIpcService("/path/to/socketfile")); ... // Windows Web3j web3 = Web3j.build(new WindowsIpcService("/path/to/namedpipefile")); ... 

    需要注意:IPC 通信在 web3j-android 中不可用。

    通过 java 打包以太坊智能合约

    Web3j 可以自动打包智能合同代码,以便在不脱离 JVM 的情况下进行以太坊智能合同部署和交互。

    要打包代码,需要先编译智能合同:

    $ solc <contract>.sol --bin --abi --optimize -o <output-dir>/ 

    然后用web3j 的命令行工具打包代码:

    web3j solidity generate /path/to/<smart-contract>.bin /path/to/<smart-contract>.abi -o /path/to/src/main/java -p com.your.organisation.name 

    接下来就可以新建和部署智能合约了:

    Web3j web3 = Web3j.build(new HttpService()); // defaults to http://localhost:8545/ Credentials credentials = WalletUtils.loadCredentials("password", "/path/to/walletfile"); YourSmartContract cOntract= YourSmartContract.deploy( <web3j>, <credentials>, GAS_PRICE, GAS_LIMIT, <param1>, ..., <paramN>).send(); // constructor params 

    或者使用一个现有的智能合约:

    YourSmartContract cOntract= YourSmartContract.load( "0x<address>|<ensName>", <web3j>, <credentials>, GAS_PRICE, GAS_LIMIT); 

    然后就可以进行智能合约的交互了:

    TransactionReceipt transactiOnReceipt= contract.someMethod( <param1>, ...).send(); 

    调用智能合约:

    Type result = contract.someMethod(<param1>, ...).send(); 

    更多关于打包的资料可以看这里:Solidity smart contract wrappers

    Filters

    web3j 的响应式函数可以使观察者通过事件去通知消息订阅者变得很简单,并能够记录在区块链中。接收所有新的区块并把它们添加到区块链中:

    Subscription subscription = web3j.blockObservable(false).subscribe(block -> { ... }); 

    接收所有新的交易并把它们添加到区块链中:

    Subscription subscription = web3j.transactionObservable().subscribe(tx -> { ... }); 

    接收所有已经提交到网络中等待处理的交易。(他们被统一的分配到一个区块之前。)

    Subscription subscription = web3j.pendingTransactionObservable().subscribe(tx -> { ... }); 

    或者你重置所有的区块到最新的位置,那么当有新建区块的时候会通知你。

    Subscription subscription = catchUpToLatestAndSubscribeToNewBlocksObservable( <startBlockNumber>, <fullTxObjects>) .subscribe(block -> { ... }); 

    主题过滤也被支持:

    EthFilter filter = new EthFilter(DefaultBlockParameterName.EARLIEST, DefaultBlockParameterName.LATEST, <contract-address>) .addSingleTopic(...)|.addOptionalTopics(..., ...)|...; web3j.ethLogObservable(filter).subscribe(log -> { ... }); 

    当不再需要时,订阅也应该被取消:

    subscription.unsubscribe(); 

    **注意:Infura 中不支持 filters。 **

    需要了解更多有关过滤器和事件的信息可以查看Filters and EventsWeb3jRx的接口。

    交易

    Web3j 支持使用以太坊钱包文件(推荐的)和用于发送事务的以太坊客户端管理命令。

    使用以太钱包文件发送以太币给其他人:

    Web3j web3 = Web3j.build(new HttpService()); // defaults to http://localhost:8545/ Credentials credentials = WalletUtils.loadCredentials("password", "/path/to/walletfile"); TransactionReceipt transactiOnReceipt= Transfer.sendFunds( web3, credentials, "0x<address>|<ensName>", BigDecimal.valueOf(1.0), Convert.Unit.ETHER) .send(); 

    或者你希望建立你自己定制的交易:

    Web3j web3 = Web3j.build(new HttpService()); // defaults to http://localhost:8545/ Credentials credentials = WalletUtils.loadCredentials("password", "/path/to/walletfile"); // get the next available nonce EthGetTransactionCount ethGetTransactiOnCount= web3j.ethGetTransactionCount( address, DefaultBlockParameterName.LATEST).send(); BigInteger nOnce= ethGetTransactionCount.getTransactionCount(); // create our transaction RawTransaction rawTransaction = RawTransaction.createEtherTransaction( nonce, <gas price>, <gas limit>, <toAddress>, <value>); // sign & send our transaction byte[] signedMessage = TransactinEncoder.signMessage(rawTransaction, credentials); String hexValue = Numeric.toHexString(signedMessage); EthSendTransaction ethSendTransaction = web3j.ethSendRawTransaction(hexValue).send(); // ... 

    使用 Web3j 的Transfer进行以太币交易要简单得多。

    使用以太坊客户端的管理命令(如果你的钱包密钥已经在客户端存储):

    Admin web3j = Admin.build(new HttpService()); // defaults to http://localhost:8545/ PersonalUnlockAccount persOnalUnlockAccount= web3j.personalUnlockAccount("0x000...", "a password").sendAsync().get(); if (personalUnlockAccount.accountUnlocked()) { // send a transaction } 

    如果你想使用 Parity ’ s Personal 或者 Trace 功能, 或者 Geth ’ s Personal 客户端 APIs,可以使用org.web3j:parityorg.web3j:geth模块。

    命令行工具

    web3j 的 jar 包为每一个版本都提供命令行工具。命令行工具允许你直接通过一些命令使用 web3j 的一些功能:

    • 钱包创建
    • 钱包密码管理
    • 资金从钱包转移到另一个
    • solidity 编写的智能合同功能打包

    请参阅文档以获得命令行相关的进一步的信息。

    其他的细节

    java8 bulid:

    • Web3j 提供对所有响应类型的安全访问。可选的或 null 响应 java 8 都支持。
    • 异步请求包在一个 java 8 的CompletableFutures。Web3j 提供了围绕所有异步请求的打包工具,以确保在执行期间可以捕获任何异常,而不只是丢弃。由于在完全检查中会有很多缺少支持的异常情况,这些异常通常被确定为未检测到的异常,导致检测过程出现问题。有关详细信息,请参见 Async.run()及其关联 test

    在 java 8 的 Android 版本:

    • 包数量作为 BigIntegers返回。对于简单的结果,可以通过Response.getResult()获取字符串类型的数量结果。
    • 还可以通过在 HttpService 和 IpcService 类中存在的includeRawResponse参数将原生的 JSON 包放置在响应中。

    原文请访问:web3js开发以太坊智能合约快速入门

    1 replies    2018-07-12 15:11:42 +08:00
    geek123
        1
    geek123  
       Jul 12, 2018
    不错。
    About     Help     Advertise     Blog     API     FAQ     Solana     5357 Online   Highest 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 57ms UTC 09:25 PVG 17:25 LAX 02:25 JFK 05:25
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86