以太坊Web3j插件功能探究(二)

HPB小秘书发表于:2018年01月02日 11:03:45更新于:2018年01月03日 10:14:11

4  以太坊的智能合约

4.1  智能合约语言

开发人员可以选择三种语言来编写智能合约:

  • Solidity,以太坊的首选主流语言,以及最流行的智能合约语言。

  • Serpent,Python语言类似于编写智能合约的语言。

  • LISP语言(LLL),一种低层次的语言,蛇提供了一套超能力的LLL。没有大量的信息可以与LLL合作

为了将智能合约部署到Ethereum区块链上,必须首先将其编译成字节码格式,然后在创建智能合约时将其作为交易请求的一部分发送。


考虑到Solidity是编写智能合约的首选语言,它是web3j所支持的语言,并且适用于所有后续示例。



4.2  开始使用Solidity


4.2.1编译Solidity源代码

编译为字节码是由Solidity 的编译器solc执行的

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

-bin和-abi编译器的参数都需要充分利用web3j的智能合约。


1.  -bin输出一个Solidity的二进制文件包含hex编码的二进制文件,以提供交易请求(根据智能合约的创建)。


2.  -abi输出一个Solidity的应用程序二进制接口(ABI)文件,它详细描述了所有公开的可执行的合约方法及其相关的参数。这些细节以及合约地址对于与智能合约的交互是至关重要的。ABI文件也用于生成Solidity 的智能合约包装器。


-gas参数提供了对创建合约和通过绑定的方法执行所需的gas的估算、


1.  可以通过 Browser-Solidity在浏览器中编写和编译solidity的代码。浏览器的稳定性对于较小的智能合约来说是很好的,但是你可能会遇到更大的合约问题。


2.  也可以通过Geth和Parity的Ethereum 客户端来编译Solidity 的代码,使用jjson-rpc方法eth_compileSolidity,也在web3j中得到了支持。但是,必须在客户端上安装Solidity的编译器以使其工作


4.2.2部署智能合约并与其进行交互


1.  如果您想要避免使用智能合约的底层实现细节,web3j提供了Solidity的智能合约包装器,使您可以通过生成的包装器对象直接与所有智能合约的方法交互。


2.  如果您不希望使用智能合约包装器,并且希望直接与json-rpc调用工作,请参考HumanStandardTokenIT.


4.2.3智能合约包装器


  • Web3j支持从Solidity的ABI文件中自动生成智能合约功能包装器。


1.  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


2.  直接调用Java类:


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


  • 智能合约包装器支持与智能合约一起工作的所有常见操作:


1.创建和部署

2.调用交易和事件

3.调用常量方法

4.演示例子

任何需要进行底层json-rpc调用的方法调用都将返回一个避免阻塞的Future 。


智能合约的构建和部署在部署方法中产生:

                                             

这将使用提供的凭证和构造函数参数值,在Ethereum区块链上创建一个智能合约的新实例, 它返回一个新的智能合约包装器实例,其中包含智能合约的底层地址。如果你想用现有的智能合约来构建一个智能合约包装的实例,只需简单地通过它的地址

如果在提供的地址中,智能合约字节码不匹配所部署的内容,则返回false


使用这种方法,您可能想要确定您所加载的智能合约地址是您所期望的智能合约。为此,您可以使用智能合约方法isValid ,只有在智能合约地址中部署的字节码与智能合约包装器中的字节码匹配时,才会返回true。



4.3  交易管理

Web3j提供了一个TransactionManager抽象来控制您与Ethereum客户端连接的方式。默认的机制使用web3j的RawTransactionManager,它与Ethereum钱包文件一起工作,在将它们提交到网络之前,在脱机状态下签名交易。如果希望修改交易管理器,您可以将交易管理器传递给智能合约部署和创建方法,而不是凭证对象

除了RawTransactionManager之外,web3j还提供了一个ClientTransactionManager,它将把您的交易签名的责任传递给您正在连接的Ethereum客户端。


4.3.1在交易上指定链ID

RawTransactionManager使用一个可选的链id参数来指定要在交易上使用的链id,就像每EIP-155一样。这阻止了一个链的交易被重新广播到另一个链上,比如从Morden到Mainnet:

为了避免必须更改配置或代码来指定使用哪个链,web3j的默认行为是在交易上不指定链id,以简化与库的工作。然而,Ethereum社区的建议是使用它们。


4.3.2调用交易和事件

所有交易型智能合约方法都与它们的Solidity方法相同,它们采用相同的参数值。交易调用不返回任何值,不管方法中指定的返回类型。因此,对于所有交易方法,与交易相关的交易收据都返回了。


TransactionReceipt transactionReceipt = contract.someMethod(new Type(...),...).get();


交易收据是有用的有两个原因:


1.它提供交易被存放的挖掘块的详细信息


2.被调用的Solidity事件将作为交易的一部分记录下来,然后可以提取出来


智能合约中定义的任何事件都将在智能合约包装器中以一个名为process<Event Name>Event的方法来表示,该方法接受交易收据,并从中提取indexed 和non-indexed的事件参数,这些参数在EventValues对象的实例中被返回解码。


EventValues eventValues = contract.processSomeEvent(transactionReceipt);


或者你也可以使用一个可观察的过滤器,它会监听与智能合约相关的事件:

contract.someEventObservable(startBlock, endBlock).subscribe(event -> ...);


请记住,对于任何被索引的数组、字节和字符串Solidity 的参数类型,将返回一个 Keccak-256 散列值,并查看文档以获得进一步的信息。


4.3.3调用常量方法

不变的方法是那些在智能合约中读到价值的人,并且不会改变智能合约的状态。这些方法与它们所生成的智能合约具有相同的方法签名,惟一的补充是该调用被包装在未来。

Type result = contract.someMethod(new Type(...), ...).get();



5  过滤器和事件


5.1  Web3J过滤类型

过滤器提供在Ethereum网络中发生的某些事件的通知。

在Ethereum中有三种类型的过滤器:

  • Block 过滤器

  • Pending transaction过滤器

  • Topic 过滤器

Block 过滤器和Pending transaction过滤器提供了在网络上创建新交易或块的通知,主题过滤器更加灵活。这允许您根据所提供的特定条件创建一个过滤器。


5.2  区块和交易过滤器

除非您使用WebSocket连接Geth,使用过滤器通过JSON-RPC API是一个难受的过程,你需要调查Ethereum客户以便于找出是否有任何更新你的过滤器随着同步HTTP和IPC的本质要求。


另外,区块和交易过滤器只提供交易或区块的hash,因此需要进一步的请求来获取由hash指引的实际交易或区块。


Web3j的管理过滤器实现解决了这些问题,因此您有一个完全基于异步事件的API用于处理过滤器。它使用RxJava的Observables ,它提供了用于处理事件的一致的API,从而通过功能组合促进了JSON-RPC调用的链接。

                                             

5.3  重新播放Replay过滤器


Web3j还提供了重新播放块和交易的历史过滤器。


你还可以让web3j重放当前最新当前的所有块,并在你捕捉到的时候提供通知(通过提交的可观察到的)。


5.4  主题Topic过滤器和EVM事件

主题过滤器捕获了以太坊虚拟机(EVM)事件在网络中发生的细节。这些事件是由智能合约创建的,并存储在与智能合约相关联的交易日志中。


您可以使用EthFilter类型来指定希望应用于过滤器的主题。这可以包括您希望应用过滤器的智能合约的地址。您还可以提供特定的主题来进行过滤。在智能合约中,单个主题代表了索引参数:

然后,可以使用与上面的区块和交易过滤器相似的语法创建这个过滤器:


web3j.ethLogObservable(filter).subscribe(log -> {  });


过滤器主题只能引用被索引的可靠事件参数。在非索引的事件参数上进行过滤是不可能的。此外,对于任何被索引的事件参数,例如字符串和字节,它们值的keccak-256散列存储在EVM日志中。使用它们的全部值存储或过滤是不可能的。


如果您创建了一个没有与之相关的主题的过滤器实例,那么在网络中发生的所有的EVM事件都将被过滤器捕获。


除了send()和sendAsync之外,web3j中的所有JSON-RPC方法实现都支持可观察()方法,以创建可观察的可异步执行请求的方法。这使它非常直接地将JSON-RPC调用组合到新的函数中。


例如,块可观察本身是由许多单独的JSON-RPC调用组成的:

在这里,我们首先创建一个可观察的,它提供每个新创建的块的块hash 的通知。然后,我们使用flatMap来调用对ethGetBlockByHash的调用,以获得完整的块细节,这些细节被传递给可观察的订阅者。



6  Web3J命令行工具

一个Web3j fat jar被分发给每个发行版提供命令行工具。命令行允许您从终端使用web3j的一些功能,命令行工具可以从项目存储库的发布页面,在下载部分,或者是通过Homebrew的OS X用户获得的zipfile/tarball文件。

1.钱包创造

$ web3j wallet create

2.钱包密码管理

$ web3j wallet update <walletfile>

3.从一个钱包转到另一个钱包

$ web3j wallet send <walletfile> <destination-address>

4.Solidity 智能合约包装器

命令行语句如下

brew tap web3j/web3j

brew install web3j

要通过zipfile运行,只需提取压缩文件并运行二进制文件:

$ unzip web3j-<version>.zip

creating: web3j-1.0.2/lib/

inflating: web3j-1.0.2/lib/core-1.0.2-all.jar

creating: web3j-1.0.2/bin/

inflating: web3j-1.0.2/bin/web3j

inflating: web3j-1.0.2/bin/web3j.bat

$ ./web3j-<version>/bin/web3j


HPB(芯链)