美文网首页
05-web3j智能合约(Smart Contracts)

05-web3j智能合约(Smart Contracts)

作者: jection | 来源:发表于2018-06-26 11:00 被阅读0次
    
    文章是本人学习过程翻译,原文来自官方文档:https://web3j.readthedocs.io/en/latest/#
    
    官网:https://web3j.io/
    
    官方GitHub:https://github.com/web3j/web3j
    
    官方demo:https://github.com/web3j/web3j/tree/master/integration-tests
    
    文档版本v3.4.0。
    
    
    

    有三种语言可以开发智能合约:

    1. solidity
    2. serpent
    3. LISP Like Language (LLL)

    开始solidity(Getting started with Solidity)

    编译solidity(Compiling Solidity source code)

    你也可以编译solidityt的代码通过Ethereum客户Geth和Parity等,solidty编译器安装在这些客户端,通过使用json - rpc的方法eth_compileSolidity,web3j也支持这个方法。
    更多编译solidity,请参考solidity文档

    部署合约和交互(Deploying and interacting with smart contracts)

    有两种方式来部署合约和交互:

    1. 使用Solidity smart contract wrappers 可以让你使用生成的类包快速与合约交互。
    2. 原始的交易方法,创建合约与合约交互查询合约状态

    智能合约例子

    我们在项目目录codegen/src/test/resources/solidity提供了一些solidity智能合约例子。

    也提供一些代码演示部署合约、与合约交互,在integration-tests/src/test/java/org/web3j/protocol/scenarios

    ERC-20代币合约标准

    有两个组织提供了ERC-20合约的实现:

    1. ConsenSys - ConsenSys的Tokens project.
    2. Open Zepplin - Open Zepplin的GitHub地址

    web3j提供了ConsenSys合约的实现,合约代码在目录codegen/src/test/resources/solidity/contracts

    下面是Solidity smart contract wrappers生成类包的方式调用代币合约的实现:

    如果你不想使用生成的类包,可以使用JSON-RPC calls的方式实现合约调用,参考HumanStandardTokenIT

    solidity智能合约类包(Solidity smart contract wrappers)

    自动生成的类包支持所有与智能合约的操作,包括

    • 构建和部署合约
    • 发起交易和事件
    • 调用constant函数
    • 合约校验

    构建和部署合约(Construction and deployment)

    创建一个新的合约对象

    YourSmartContract contract = YourSmartContract.deploy(
            <web3j>, <credentials>, GAS_PRICE, GAS_LIMIT,
            [<initialValue>,]
            <param1>, ..., <paramN>).send();
    

    构建一个已经存在的合约对象

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

    合约校验(Contract validity)

    如果你要校验你的合约对象是否存在以太坊和有效,你可以通过校验合约的字节码与合约地址是否匹配。使用下面方法就可以完成:

    contract.isValid();
    

    交易管理(Transaction Managers)

    Transaction Managers类是设置web3j连接到以太坊客户端的方式,有如下几个类:

    指定交易的Chain Id(Specifying the Chain Id on Transactions (EIP-155))

    RawTransactionManager 类带有一个可选的参数 chainId 来指定交易是的链id,用来区分不同的链(主网/测试网),防止一个链的交易被广播到另外一个链。

    TransactionManager transactionManager = new RawTransactionManager(
            web3j, credentials, ChainId.MAIN_NET);
    

    默认情况下,web3j没有指定chain id,推荐你手动指定。
    如下方法可以获取你连接的客户端的chain id:

    web3j.netVersion().send().getNetVersion();
    

    交易收据处理(Transaction Receipt Processors)

    默认情况下,提交一个交易到客户端后,web3j将会轮询客户端直到收到TransactionReceipt对象,表示交易已经被区块链打包确认。

    如果你发送异步交易,会有一个并行的线程去轮询客户单。

    如果你想减少轮询消耗,web3j提供了TransactionReceiptProcessors.

    web3j提供了一些交易收据的处理器:

    注意:在QueuingTransactionReceiptProcessor初始化时也提供了一个只有交易哈希的EmptyTransactionReceipt。

    如果你不想使用默认的PollingTransactionReceiptProcessor处理器,可以修改处理器:

    TransactionReceiptProcessor transactionReceiptProcessor = new QueuingTransactionReceiptProcessor(web3j, new Callback() {
    @Override
    public void accept(TransactionReceipt transactionReceipt) {
    // process transactionReceipt
    }
    @Override
    public void exception(Exception exception) {
    // handle exception
    }
    TransactionManager transactionManager = new RawTransactionManager(
            web3j, credentials, ChainId.MAIN_NET, transactionReceiptProcessor);
    

    如果你想获得更进一步的了解,FastRawTransactionManagerIT演示了轮询和队列处理。

    调用交易和事件(Invoking transactions and events)

    直接调用与合约函数同名的方法就可以发起交易,虽然因为打包延迟的问题无法获得合约调用的返回值,但通过Transaction Receipt来关联交易,一样可以获取交易结果。

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

    交易收据有以下两个作用:

    1. 可以获取打包交易的区块信息
    2. solidity event可以被触发来记录交易的日志,这些日志可以被提取。

    在生成的类包里面也有<Event Name>的事件,可以使用索引参数和非索引参数来提取收据,返回值是 EventValues 对象.

    EventValues eventValues = contract.processSomeEvent(transactionReceipt);
    

    也可以使用过滤器

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

    更进一步的了解,请查看Filters and Events.

    注意:索引的array,bytes和string等solidity参数类型,keccak - 256的散列值将被返回,看到文档了解更多信息。

    调用静态函数(Calling constant methods)

    使用生成的函数可以直接调用合约的constant函数
    Type result = contract.someMethod(<param1>, ...).send();

    动态的Gas Price和Limit(Dynamic gas price and limit)

    你可以创建 ContractGasProvider ,根据调用不同的函数来指定不同的gas price和limit。
    例子:

    Greeter greeter = new Greeter(...);
    greeter.setGasProvider(new DefaultGasProvider() {
        @Override
        public BigInteger getGasPrice(String contractFunc) {
            switch (contractFunc) {
                case Greeter.FUNC_GREET: return BigInteger.valueOf(22_000_000_000L);
                case Greeter.FUNC_KILL: return BigInteger.valueOf(44_000_000_000L);
                default: throw new NotImplementedException();
            }
        }
    
        @Override
        public BigInteger getGasLimit(String contractFunc) {
            switch (contractFunc) {
                case Greeter.FUNC_GREET: return BigInteger.valueOf(4_300_000);
                case Greeter.FUNC_KILL: return BigInteger.valueOf(5_300_000);
                default: throw new NotImplementedException();
            }
        }
    });
    

    案例(Examples)

    https://github.com/web3j/web3j/tree/master/integration-tests

    相关文章

      网友评论

          本文标题:05-web3j智能合约(Smart Contracts)

          本文链接:https://www.haomeiwen.com/subject/ihhdyftx.html