美文网首页互联网就业技术指南
用Go来做以太坊开发⑦测试

用Go来做以太坊开发⑦测试

作者: Chole121 | 来源:发表于2018-12-14 17:40 被阅读1次

    水龙头

    水龙头是免费在测试网获得ETH的方式。

    这里罗列了各个测试网的龙头。

    使用模拟客户端

    您可以使用模拟客户端来快速轻松地在本地测试您的交易,非常适合单元测试。为了开始,我们需要一个带有初始ETH的账户。为此,首先生成一个账户私钥。

    privateKey, err := crypto.GenerateKey()
    if err != nil {
      log.Fatal(err)
    }
    

    接着从accounts/abi/bind包创建一个NewKeyedTransactor,并为其传递私钥。

    auth := bind.NewKeyedTransactor(privateKey)
    

    下一步是创建一个创世账户并为其分配初始余额。我们将使用core包的GenesisAccount类型。

    balance := new(big.Int)
    balance.SetString("10000000000000000000", 10) // 10 eth in wei
    
    address := auth.From
    genesisAlloc := map[common.Address]core.GenesisAccount{
        address: {
            Balance: balance,
        },
    }
    

    现在我们将创世分配结构体和配置好的汽油上限传给account/abi/bind/backends包的NewSimulatedBackend方法,该方法将返回一个新的模拟以太坊客户端。

    blockGasLimit := uint64(4712388)
    client := backends.NewSimulatedBackend(genesisAlloc, blockGasLimit)
    

    您可以像往常一样使用此客户端。作为一个示例,我们将构造一个新的交易并进行广播。

    fromAddress := auth.From
    nonce, err := client.PendingNonceAt(context.Background(), fromAddress)
    if err != nil {
      log.Fatal(err)
    }
    
    value := big.NewInt(1000000000000000000) // in wei (1 eth)
    gasLimit := uint64(21000)                // in units
    gasPrice, err := client.SuggestGasPrice(context.Background())
    if err != nil {
      log.Fatal(err)
    }
    
    toAddress := common.HexToAddress("0x4592d8f8d7b001e72cb26a73e4fa1806a51ac79d")
    var data []byte
    tx := types.NewTransaction(nonce, toAddress, value, gasLimit, gasPrice, data)
    chainID := big.NewInt(1)
    signedTx, err := types.SignTx(tx, types.NewEIP155Signer(chainID), privateKey)
    if err != nil {
      log.Fatal(err)
    }
    
    err = client.SendTransaction(context.Background(), signedTx)
    if err != nil {
      log.Fatal(err)
    }
    
    fmt.Printf("tx sent: %s\n", signedTx.Hash().Hex()) // tx sent: 0xec3ceb05642c61d33fa6c951b54080d1953ac8227be81e7b5e4e2cfed69eeb51
    

    到现在为止,您可能想知道交易何时才会被开采。为了“开采”它,您还必须做一件额外的事情,在客户端调用Commit提交新开采的区块。

    client.Commit()
    

    现在您可以获取交易收据并看见其已被处理。

    receipt, err := client.TransactionReceipt(context.Background(), signedTx.Hash())
    if err != nil {
      log.Fatal(err)
    }
    if receipt == nil {
      log.Fatal("receipt is nil. Forgot to commit?")
    }
    
    fmt.Printf("status: %v\n", receipt.Status) // status: 1
    

    因此,请记住:模拟客户端允许您使用模拟客户端的Commit方法手动开采区块。

    完整代码

    client_simulated.go

    package main
    
    import (
        "context"
        "fmt"
        "log"
        "math/big"
    
        "github.com/ethereum/go-ethereum/accounts/abi/bind"
        "github.com/ethereum/go-ethereum/accounts/abi/bind/backends"
        "github.com/ethereum/go-ethereum/common"
        "github.com/ethereum/go-ethereum/core"
        "github.com/ethereum/go-ethereum/core/types"
        "github.com/ethereum/go-ethereum/crypto"
    )
    
    func main() {
        privateKey, err := crypto.GenerateKey()
        if err != nil {
            log.Fatal(err)
        }
    
        auth := bind.NewKeyedTransactor(privateKey)
    
        balance := new(big.Int)
        balance.SetString("10000000000000000000", 10) // 10 eth in wei
    
        address := auth.From
        genesisAlloc := map[common.Address]core.GenesisAccount{
            address: {
                Balance: balance,
            },
        }
    
        blockGasLimit := uint64(4712388)
        client := backends.NewSimulatedBackend(genesisAlloc, blockGasLimit)
    
        fromAddress := auth.From
        nonce, err := client.PendingNonceAt(context.Background(), fromAddress)
        if err != nil {
            log.Fatal(err)
        }
    
        value := big.NewInt(1000000000000000000) // in wei (1 eth)
        gasLimit := uint64(21000)                // in units
        gasPrice, err := client.SuggestGasPrice(context.Background())
        if err != nil {
            log.Fatal(err)
        }
    
        toAddress := common.HexToAddress("0x4592d8f8d7b001e72cb26a73e4fa1806a51ac79d")
        var data []byte
        tx := types.NewTransaction(nonce, toAddress, value, gasLimit, gasPrice, data)
    
        chainID := big.NewInt(1)
        signedTx, err := types.SignTx(tx, types.NewEIP155Signer(chainID), privateKey)
        if err != nil {
            log.Fatal(err)
        }
    
        err = client.SendTransaction(context.Background(), signedTx)
        if err != nil {
            log.Fatal(err)
        }
    
        fmt.Printf("tx sent: %s\n", signedTx.Hash().Hex()) // tx sent: 0xec3ceb05642c61d33fa6c951b54080d1953ac8227be81e7b5e4e2cfed69eeb51
    
        client.Commit()
    
        receipt, err := client.TransactionReceipt(context.Background(), signedTx.Hash())
        if err != nil {
            log.Fatal(err)
        }
        if receipt == nil {
            log.Fatal("receipt is nil. Forgot to commit?")
        }
    
        fmt.Printf("status: %v\n", receipt.Status) // status: 1
    }
    

    添加小编微信:grey0805,加入知识学习小分队~!

    相关文章

      网友评论

        本文标题:用Go来做以太坊开发⑦测试

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