前言

因为Golang的以太坊协议更新了,所以耽误了些功夫,太草了

Github地址:Ethereum_GolangStudy


Eth查询区块

    // 这里用测试网,本地节点没有区块
    client, _ := ethclient.Dial("https://cloudflare-eth.com")
    // 获取区块头信息
    HeadBlock, _ := client.BlockByNumber(context.Background(), nil)
    // 获取区块查询的头信息 2022-10-03 14:32 是 15665850
    logrus.Info("Query BlockHead:", HeadBlock.Number().String())
    // 获取完整区块信息 ,这里用自动查询的api
    NewBlockNumber, _ := client.BlockByNumber(context.Background(), HeadBlock.Number())
    // 只打印交易地址信息
    logrus.Info("Block Address:", NewBlockNumber.Hash().Hex())
    // 获取交易的数目
    QueryCount, _ := client.TransactionCount(context.Background(), NewBlockNumber.Hash())
    logrus.Info("Block TransactionCount:", QueryCount)

查询ETH交易信息

    // 先获取区块的信息事务
    client, _ := ethclient.Dial("https://cloudflare-eth.com")
    // * 自动获取块查询区块事务信息
    // HeadBlock, _ := client.BlockByNumber(context.Background(), nil)
    // NewBlockNumber, _ := client.BlockByNumber(context.Background(), HeadBlock.Number())
    // for _, tx := range NewBlockNumber.Transactions() {
    //     // // 使用tx获取发送方地址 EIP155S
    //     // ChanID, _ := client.NetworkID(context.Background())
    //     // // AsMessage 获取信息 新版AsMessage 缺少一个类型Signer https://github.com/ethereum/go-ethereum/issues/23890
    //     // if message, err := tx.AsMessage(types.LatestSignerForChainID(ChanID), ChanID); err != nil {
    //     //     // logrus.Error(message.From().Hash())
    //     // } else {
    //     // // 地址当前信息 0x009BD41feaA4FF711a41b05ff69fc65f14d16f6D
    //     //     logrus.Info(message.From().String())
    //     // }
    //
    //     // 获取事务是否成功
    //     receipt, _ := client.TransactionReceipt(context.Background(), tx.Hash())
    //     logrus.Info("Transaction Receipt Bool:", receipt.Status)
    // }

    // // 不自动获取块,指定获取块事务信息
    // blockHash := common.HexToHash("0x9e8751ebb5069389b855bba72d94902cc385042661498a415979b7b6ee9ba4b9")
    // count, _ := client.TransactionCount(context.Background(), blockHash)
    // // 遍历获取所有事务
    // for index := uint(0); index < count; index++ {
    //     tx, _ := client.TransactionInBlock(context.Background(), blockHash, index)
    //     logrus.Info("Block address:", tx.Hash().String())
    // }

    // 使用指定哈希获取事务
    txHash := common.HexToHash("0x5d49fcaa394c97ec8a9c3e7bd9e8388d420fb050a52083ca52ff24b3b65bc9c2")
    tx, is, _ := client.TransactionByHash(context.Background(), txHash)
    logrus.Info(tx.Hash().String(), ",is ", is)

这里有些坑。

tx.AsMessage(types.LatestSignerForChainID(ChanID), ChanID)

tx.AsMessage 按照教程会缺少一个叫Signer的传参,我们从这一步开始跳转查询源码:

image.png

这里明确表示想要获取信息需要传入S。

image.png

这里则是和我们说这个接口的函数方法,从这里往下翻可以看见几个生成Signer的函数方法。

// LatestSignerForChainID returns the 'most permissive' Signer available. Specifically,
// this enables support for EIP-155 replay protection and all implemented EIP-2718
// transaction types if chainID is non-nil.
//
// Use this in transaction-handling code where the current block number and fork
// configuration are unknown. If you have a ChainConfig, use LatestSigner instead.
// If you have a ChainConfig and know the current block number, use MakeSigner instead.

image.png

经过源码注释我们会发现这是一个较为宽松的协议生成方法,所以我们采用这种。

types.LatestSignerForChainID(ChanID)

ChanID则是在上文我们通过eth的测试网获取的链路ID。


另外一种方法,需要拥有配置参数才可以,这里暂且不适用。

// LatestSigner returns the 'most permissive' Signer available for the given chain
// configuration. Specifically, this enables support of EIP-155 replay protection and
// EIP-2930 access list transactions when their respective forks are scheduled to occur at
// any block number in the chain config.
//
// Use this in transaction-handling code where the current block number is unknown. If you
// have the current block number available, use MakeSigner instead.

image.png


Eth账号转账

    // 此次测试使用本地
    client, _ := ethclient.Dial("http://127.0.0.1:8545")
    // 0x7c93ba33296e75fa18cb0ac13bab727273f0f213cd331ac0b16a7dd86e4a390d100Eth
    // 加载私钥-需要去除0x
    privateKey, _ := crypto.HexToECDSA("7c93ba33296e75fa18cb0ac13bab727273f0f213cd331ac0b16a7dd86e4a390d")
    // 获取公共地址
    publicKey := privateKey.Public()
    publicKeyECDSA := publicKey.(*ecdsa.PublicKey)
    PublicAddress := crypto.PubkeyToAddress(*publicKeyECDSA)
    logrus.Info("PublicAddress:", PublicAddress.String())
    // 获取账户交易随机数
    Nonce, _ := client.PendingNonceAt(context.Background(), PublicAddress)
    value := big.NewInt(1000000000000000000) // in wei (1 eth)
    gasLimit := uint64(21000)                // in units
    // gasPrice := big.NewInt(30000000000)      // in wei (30 gwei)
    // 通过市场获取燃气价格
    gasPricer, _ := client.SuggestGasPrice(context.Background())
    // 接收地址 0xE280029a7867BA5C9154434886c241775ea87e53
    ToAddress := common.HexToAddress("0xE280029a7867BA5C9154434886c241775ea87e53")
    // 智能合约通信
    tx := types.NewTx(&types.LegacyTx{
        Nonce:    Nonce,
        GasPrice: gasPricer,
        Gas:      gasLimit,
        To:       &ToAddress,
        Value:    value,
        Data:     make([]byte, 0),
    })
    // 利用私钥进行签名
    ChanID, _ := client.NetworkID(context.Background())
    SignedTx, _ := types.SignTx(tx, types.LatestSignerForChainID(ChanID), privateKey)
    // 广播节点
    if err := client.SendTransaction(context.Background(), SignedTx); err != nil {
        logrus.Error("SendTransaction error:", err)
        return
    }
    logrus.Info("Transaction Success Address:", SignedTx.Hash().Hex())

    /*  交易成功
    time="2022-10-03T16:01:22+08:00" level=info msg="PublicAddress:0x002cFA2FD8423Cf2728961EF014AD2e9126118BE"
    time="2022-10-03T16:01:22+08:00" level=info msg="Transaction Success Address:0xb13eee5b299e81afb90a8a9252d264e23dd947667f88ffb5011f1b1f3c9aa6ec"
    ganache-cli 提示:
      Gas usage: 21000
      Block Number: 1
      Block Time: Mon Oct 03 2022 16:01:22 GMT+0800 (中国标准时间)
    */

我的注释也写的很明白了,但是还是有一部分小坑,因为教程书没有更新的问题。

tx := types.NewTransaction(nonce, toAddress, value, gasLimit, gasPrice, nil)

这个方法在目前更新的协议已经弃用了。

// NewTransaction creates an unsigned legacy transaction.
// Deprecated: use NewTx instead.

这里弃用了,告诉我们换成NewTx。

我们再翻源码看一看:

image.png

这里告诉我们需要一个叫TxData的接口传参

image.png

这里告诉我们要么用LegacyTx,要么用AccessListTx生成传参信息,我这里使用的是LegacyTx。

    // 智能合约通信
    tx := types.NewTx(&types.LegacyTx{
        Nonce:    Nonce,
        GasPrice: gasPricer,
        Gas:      gasLimit,
        To:       &ToAddress,
        Value:    value,
        Data:     make([]byte, 0),
    })

小声逼逼

image.png

本来还差这些,但是因为遇见了点坑就耽误了点时间,剩下时间还得去学德语,暂时更新这些。

明天更新第二章下。

最后修改:2023 年 03 月 26 日
如果觉得我的文章对你有用,请随意赞赏