Qtum星火网络“水龙头”


  • qtum team

    Qtum星火网络“水龙头”

    作者 Jordan Earlz

    翻译 小龙

    原文链接 (<--- 戳这里)

    我为Qtum测试网络Sparknet写了一个智能合约,实现了一个简单的“水龙头”功能(自动发放测试代币)。你如果一点代币都没有的话,暂时还不能跑这个合约,因为gas还是需要消耗的。当你需要更多代币的时候,可以使用这个水龙头每次生成100个代币。当然,你也可以用这个合约去给其他人发放代币。

    下面是智能合约的代码,很简单:

    pragma solidity ^0.4.11;
    
    contract QtumFaucet {
        uint constant COIN = 100000000;
        function deposit() public payable{
        }
        function withdraw() public{
            uint amount = 100 * COIN;
            if(this.balance < 100 * COIN){
                amount = this.balance;
            }
            if(!msg.sender.send(amount)){
                throw;
            }
        }
        function send(address a) public{
            uint amount = 100 * COIN;
            if(this.balance < 100 * COIN){
                amount = this.balance;
            }
            if(!a.send(amount)){
                throw;
            }
       }
    
       function() payable{}
    }
    

    合约生成如下的ABI JSON文件:

    [{"constant":false,"inputs":[],"name":"withdraw","outputs":[],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"a","type":"address"}],"name":"send","outputs":[],"payable":false,"type":"function"},{"constant":false,"inputs":[],"name":"deposit","outputs":[],"payable":true,"type":"function"},{"payable":true,"type":"fallback"}]
    

    合约发布在Sparknet上,地址是f28aa77dd07ee8a1288ab6f41b23ebf6d605dc3e

    给合约做初始化的时候,我使用了工具"ethabi",命令是这样的:

    ethabi encode function ~/faucet.json deposit
    d0e30db0
    

    我先向合约发送1000个代币,使用sendtocontract来实现:

    ./qtum-cli sendtocontract f28aa77dd07ee8a1288ab6f41b23ebf6d605dc3e d0e30db0 1000
    

    当这个交易被确认之后,我们就可以从水龙头的合约里头提取代币了。先生成一个接收代币的地址:

    ./qtum-cli getaccountaddress x
    QUvMQdxMxUuCQ7zLHvAcfmhFWyP9kkjr8C
    

    接着,继续使用ethabi构造ABI数据:

    ethabi encode function ~/faucet.json send -p QUvMQdxMxUuCQ7zLHvAcfmhFWyP9kkjr8C
    error: Tokenizer(FromHex(Invalid character 'Q' at position 0))
    

    可是我们遇到了一个问题,Solidity跟以太坊一样,使用的是16进制地址,而不是base58。所以,我们先要将base58地址转换成一个16进制地址,为此最近qtum也更新了两个RPC命令:gethexaddressfromhexaddress

    ./qtum-cli gethexaddress QUvMQdxMxUuCQ7zLHvAcfmhFWyP9kkjr8C
    5b3a45e69dbbd7b3a9db31a8c855040f35793929
    

    它所做的事情就是验证base58的地址是否被损坏,大小是否正确,然后将其转换成16进制数据。这个16进制的字符串是Solidity以及ABI所使用的。下面,我们改正了之前的错误,继续:

    ethabi encode function ~/faucet.json send -p 5b3a45e69dbbd7b3a9db31a8c855040f35793929
    3e58c58c0000000000000000000000005b3a45e69dbbd7b3a9db31a8c855040f35793929
    

    现在我们使用命令callcontract,这样我们就知道需要准备多少gas了(当然,如果你确信默认的gas是足够的话也可以跳过这个):

    ./qtum-cli callcontract $FAUCET 3e58c58c0000000000000000000000005b3a45e69dbbd7b3a9db31a8c855040f35793929 
    {
      "address": "f28aa77dd07ee8a1288ab6f41b23ebf6d605dc3e",
      "executionResult": {
        "gasUsed": 55978,
        "excepted": "None",
        "newAddress": "f28aa77dd07ee8a1288ab6f41b23ebf6d605dc3e",
        "output": "",
        "codeDeposit": 0,
        "gasRefunded": 0,
        "depositSize": 0,
        "gasForDeposit": 0
      },
      "transactionReceipt": {
        "stateRoot": "4118b6d0685de70ef82c7905e7ab2d691470285b7c56506ffca9b1db21bcb278",
        "gasUsed": 55978,
        "bloom": "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
        "log": [
        ]
      }
    }
    

    执行结果中,我们最感兴趣的是gasUsed,以防意外,比需要的gas值多发一点点总是安全的,所以我们将gas limit设为60000:

    ./qtum-cli sendtocontract $FAUCET 3e58c58c0000000000000000000000005b3a45e69dbbd7b3a9db31a8c855040f35793929 0 60000
    {
      "txid": "cb7e8ef370a05665d5dd43d1134b8d0833d1c746d2d618162727c54e0f5a6ef5",
      "sender": "QWqFJB4EUhbBJpGnnnjaeR1mdUJdr6fWkV",
      "hash160": "703357de0cad939a528035cd319f849067fce2c7"
    }
    

    你可以在区块浏览器里查询结果,这里就是合约执行结果。如果我们看这个区块的信息可以看到,这笔交易已经包含其中了,在交易执行之后,账户抽象层立即生成了一笔交易给我们的目标地址发送了100个Qtum。更进一步,从coinstake的交易中可以看到,我们的gas refund是最后一个产出,发送了0.0004022个qtum给这个地址QWqFJB4EUhbBJpGnnnjaeR1mdUJdr6fWkV

    最后,从我的钱包中也可以看到这100个Qtum了。

    这个合约现在仍然是有效的,我会关注着并且向账户里放进更多的代币。快过来一起玩玩吧,充一些钱,然后再把它们提出来。这是一个很小的合约,只花了大概10分钟的时间就写完了。


Log in to reply
 

Looks like your connection to QTUM was lost, please wait while we try to reconnect.