Home > Net >  How can i get transactionHash by blockNumber?
How can i get transactionHash by blockNumber?

Time:07-13

How to get the transactionHash by blockNumber?

I entered block.transactions.0.transactionHash but that didn't catch it (empty string). How can i get the transactionHash?

enter image description here

func GetBlockTransactions(number int) string {
    ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
    var hashHeaders []models.Block
    defer cancel()

    options := options.Find().SetProjection(bson.M{"block.transactions.0.transactionHash": 1})

    options.SetLimit(1)

    results, err := blocksCollections.Find(ctx, bson.M{"block.header.blockNumber": strconv.Itoa(number)}, options)

    if err != nil {
        fmt.Println(err)
    }

    //reading from the db in an optimal way
    defer results.Close(ctx)
    for results.Next(ctx) {
        var singleHashHeader models.Block
        if err = results.Decode(&singleHashHeader); err != nil {
            fmt.Println(err)
        }
        hashHeaders = append(hashHeaders, singleHashHeader)
    }

    fmt.Println("%v", hashHeaders[0].Transactions.TransactionHash)
    return string(hashHeaders[0].Transactions.TransactionHash)
}

Edit:

My structs look like this (edited):

type BlockHeader struct {
    HashHeader       string `json:"hashHeader,omitempty"`
    BlockNumber      string `json:"blockNumber,omitempty"`
    TimestampSeconds string `json:"timestampSeconds,omitempty"`
    HashHeaderPrev   string `json:"hashHeaderPrev,omitempty"`
    RewardBlock      string `json:"rewardBlock,omitempty"`
    MerkleRoot       string `json:"merkleRoot,omitempty"`
    MiningNonce      int    `json:"miningNonce,omitempty"`
    ExtraNonce       string `json:"extraNonce,omitempty"`
}

type Header struct {
    Header BlockHeader
}

type CoinbaseTransaction struct {
    AddrTo string `json:"addrTo,omitempty"`
    Amount string `json:"amount,omitempty"`
}

type BlockTransaction struct {
    MasterAddr      string `json:"masterAddr,omitempty"`
    Nonce           string `json:"nonce,omitempty"`
    TransactionHash string `json:"transactionHash,omitempty"`
    Coinbase        []CoinbaseTransaction
}

type Block struct {
    Block        Header
    Transactions []BlockTransaction
}

Current code:

func GetBlockTransactions(number int) (string, error) {
    ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
    defer cancel()

    // options := options.Find().
    //  SetProjection(bson.M{"block.transactions.transactionHash": 1}).
    //  SetLimit(1)

    results, err := blocksCollections.Find(ctx, bson.M{"block.header.blockNumber": strconv.Itoa(number)})
    if err != nil {
        return "", fmt.Errorf("Find() failed: %w", err)
    }

    var blocks []models.Block
    err = results.All(ctx, &blocks)
    if err != nil {
        return "", fmt.Errorf("Cursor.All() failed: %w", err)
    }

    for _, block := range blocks {
        fmt.Printf("header: %v", block.Block.Header)
        for _, tx := range block.Transactions {
            fmt.Printf("transaction: %v", tx)
        }
    }

    fmt.Printf("hash: %v\n", blocks[0].Transactions[0].TransactionHash)
    return string(blocks[0].Transactions[0].TransactionHash), nil
}

mongo shell output

Here is the document, block number 15 for example. Here are all the details, included below.

{ "_id" : ObjectId("62caea8923ca1b926b789122"), "block" : { "header" : { "hashHeader" : "6WKsUtRXGWqIMs/VcwT8CAU384Uab8NMOwB7wMoAAAA=", "blockNumber" : "15", "timestampSeconds" : "1530015361", "hashHeaderPrev" : "y4G/O/Oj19 AOZNMF4yPL2xVdl/TQI ErBjhihUAAAA=", "rewardBlock" : "6656333953", "rewardFee" : "1000000", "merkleRoot" : "/gRuLu8UGAG621xvGA7M4rZmWbsMophiQ3xPprTVJkU=", "miningNonce" : NumberLong("2781151944"), "extraNonce" : "16980399104" }, "transactions" : [ { "masterAddr" : "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=", "nonce" : "16", "transactionHash" : "Jp8fU6h9yqh6onymq/lFEJq/XRHPKKbj drmvHOi5gY=", "coinbase" : { "addrTo" : "AQYAHTRijaCHM53dZQqEPhMfpKPzsQfptiItYJ9trThgtHmMxbNh", "amount" : "6657333953" } }, { "fee" : "1000000", "publicKey" : "AAYAs6Tt7 YeX6sEZfTeaKUAMF7RAURH7Khcs2vnTW23LrVBf FCFer87crYcsUx9ureHHugTG J/tKwcYPBgMk6vw==", "signature" : "AAAAAH8Tfjt2e/4J xec8eWlgWXPlPOquRu RZz5yT3hXdVF3uwhvbxasw9oj6 SpAwjy1ICSdlBeefasS970ker/DvBzLX93ryAxHI66 WqZQ9aj7gSVEhqTzylMzDj/I4P34ScaQ7kwRF/6Q3DnA/qiG/q4zc5MmHeU/pBp/ ngEMcM/cFSrCNQE Us7B7Sp2Ws6inix3y SGbrznsBDWdTcxIpq4k/0Od9VIBFA09th/svLZCbH5YGfZ7IboT4NQx7hTnANLNTLo4ztkX2u6B8WkFrJ3LV6VS3C7w7pRuhItlSIl/slVMhYizgCjVpzNb0C8JMtZeqb6sarcqSwarQiX65NVrj6ux7pJtJT08gCc2nxh3HwjhYahzjRoCkIGQbHYqfGkKkAyRIig3wu4K NsoG13UKxIaVy/kJSB5NRMEFVG1Xp2JLj3WqlnTeNnIMAGz7V/srVji8EXtcODjuOL0Qoenhesocl5 dbX0lyMu  qhXQuXzcxm dBW4TMSyoI2xSlgCLdqRNuHstOwmAdZ7qnTOKOASp5EsZGj5vPTjnP 9GcLxM5ms  MU57A3ciAjDaVpX2AoShLcP9xW/jBI0/ijGZvzA4mRIIkmwCC EOklXH/c0JB832SrhQy/cc3v1kYYITu4pkqFl7EAzzGCEy3yLdrdhzsYSN6tlTOqO57rHzehu/1xJg9LmT5LyixJVzW58DsO0swSeT dZMNR5AZmyWp4aj633YUEi8p9KKmCgEceF4T 54MZJbIQExwX4CFQ1GLJVQiEZdXy/PR3cr6AFUQGwp5ZJ8 gFLDhWGFVuHPH3HxTstyepTSQQUb8JFv4G0nM/INXpWXHvNdEvOEyDUzkfJ11yhbkCrMLak8AumtPnoNnZQXyxaUa4YX5Z8tkmbNRQWtjC/6NGTcHWQ8IKf6MxVjQCdHtqTRzgfRYOh/ /bzRy7p3o0p95Hn4Yxuf3BBshnJJmg2mKoS6sc8V8cA44YpaA9eP9Ce4G3knJ/wxuWRWzZmxC yl43qgofPU5xGWQEf6vtTS0JJ7fv61mFYhM4REt FocXf3bjifP08qrAFZNDejODjycLNXlmBahqp8mqKTvllofbeLrYnYrcCH9KMfXGGL4PZLKnmh bHlolWEn8Y4hxOlVkfRjYvBakfEsAgS MQEtkN4tGqHwT2Taz1014PAbO90O8HFZb5I146Yb4JpL38wpuvfKMBR161MNn7LLO8vOv4aZE2SBySJE6XoYIxfFL KlP4MXqGGm2kWomR2 HtvSCl7dRwfUapLlrE1xcP44HbYsDYM z5z6mWMvxQHj9WDovi7OvdwoIV3kMChSTA9DR8gqOgtDItZ9UrsDjJdhLF7aZ8/D6vyEJGAwRi3NCUYo4mBLPF5EnhXqHnmogwWh vzW37RiyHHnUxwQWDJPc81RMlXnGjIT6/KCXjrvCeYUr2Lj K8OIaNKgiuRsRjC5h/83btOWJ7PMjLMyyg1aklgkam4Hp13bVZo3zIwNsTlOt9jAn QNPPUtzToKaD twG3m GglN/kaeA6/Bmm10qIKAWkPCNP0xkEDKYDIUhxaix  sZLYSPRWRi/M3sEc79WwSZVc7sunNYWnHOvPhubDgLfO6AjFpbqYU7g6q06A4 zG85bu0vXxRucZMMO7njrHnW30Xw3vU3oFQlpFEmWBZ8S a53wyXBK fNC6PgBIqyF4qhVk8YJDHpkJW9zBwjytE8nSkTV4wCD qexfrvJvREQESDzT3eT2YfWoqEKWqPknwGK0W6TNXwmv7xMWB8zKS2LThAqotZRH6S9V1zJVbSsSrsO2 Ct8kVXGrioWxZ84Wj3R5tGBghwLbOTBlfP/jxKFbUIyEJ6hUiCFhYI/qoayi3j9Tdh1ChhnhF 4Id32QhzMemQvO/ 2uKxvu3CE5grZmRD93TdNRBz751QI EsoAMLT7Gx6LUqHVLd4q1NnO79hQFr YBunt0KYZolVZoEnMqUhkmyPUkSjadoBKHMD6MEViDcGgaqNs7n 0Z Mr7leOJXwg67hG2MX6M23VAANMagEgPw4ub1fZF1p7rpHGakW8j4apLVVHOibJNj8HNWXtElALQI8ZThlIhkdc/e7mSIlio4jiNYkuuhaXd5I8X67u2GYkqGlPibSf 90u/qQ22iRsIBE63fgbjNxv9KN6CR1XEhWaZA jgWCtcFTo46Ge3ZBbEZ7DWL6ExDM/U4 CHnpw8n7RUKV1GUCCzr9KFqFpxqdzCCdBUct9pu6ejcph 5vKH/Gh6H7MBNGVwlwSuxloBBHS6xfb7ho6UFqzvO1qfNjCH3/50Wc3MhLZxftmTf2VO4/emW1XdfFvH9WaA8968Fhr4WJ tuPWSZ/U88drb2siLavdkhGHPOdXWSuDOvnFr9qIK1TlFpylWkNQrHRsrOscDlCgllbS8v9GOg1Yp2X/KDGFXzZa1elaqJazur43Q6ktyA2RIz9O2l//R3ktU2SME9fB2anh Oiz3 VUyNRjJRNF3oC82NxIEt/cRDvcLI qEB/HVBvv1nXQ728Ri0EXocER2EvDr9C1jiBZu2VOuRjPzeo1QMaCABqQCipJBNgWUXMHvTAvK1GwCxQg8q4gSDkfMyKeSlinoJI8vs8oNicFJlnVembWrCYt/ tn9UD2ygguklwXpwbv WypHg3nagpk2bsi0EAZ3wJaAXwvFxwREsxyvq6SWl2u3o loyuu322NbgQeA /HGYvSaKmb7CjSSBl2EtDpQI77LzYcFZmEtD 8DM3JHza85/g0x4VNL5GzZ6UTLtpd1B/g3XxmNcrqBp/ppJYYDBK9NK79FodDpQlAWlPREkWPsV7X8IkxzG7i6jHxTIiuO0Nyrb1yiPWfa/onjOJVRp4wW4yVOY8vWOkTaz1zNBqR3mZ0RnebHWKr4/0wNM0jV3WaZd096es/D1nrDEQytAnb6ORlbxKAqX/2zHWexMgCCgzuj1jz5NJIkMKQxhtKnHBPTbCz1ZUzfL9tPjzFqAQ99shrusUXdueuLXjoIVFVn gULAx5 uDSIU7ERiqtc5LgVeeyzeA35E/gSHNKqu1v822xGg/70csYT69nMzHHVjwSnaC0/GOs5esFS7S4QkaOMgkS6MZiKdAqYkJ9nJN wqY15JNxbmB0tU7C2XjdKGxV1mRcjtxAdxS9JNYurBPw7l4zviAqXzmL/So/rwJUnaw0L/gha92vgECXu16lqDKuKydGSssFvFuCJpA6IzEEIkvuqV CLcEto35nkwrjBl4YZGM/nRmoI1y/qSvqJx9PNoMkeZZGQsoFtPggXYge53v5pX9I2kZ3hgY9zNXOGdzDqEUlqTVVHYLnBddo3eIfRSz31 IoOvG0QCO/Qvu9rwtuZCIltnhQWfRc4FmWsj9JUs=", "nonce" : "1", "transactionHash" : "vGS9M6aerWCoEj0BqbW5IwZ7jyw4jpECEJ/b1uL5oc0=", "token" : { "symbol" : "RnIxdDI=", "name" : "RnIxdDI=", "owner" : "AAYAPHpYp dc/fVXo8Oi3LnaBPDhCCVEh6/H8mBuuoCbMzffYw1r", "decimals" : "10", "initialBalances" : [ { "address" : "AAYAPHpYp dc/fVXo8Oi3LnaBPDhCCVEh6/H8mBuuoCbMzffYw1r", "amount" : "1000000000000000000" } ] } } ] } }

CodePudding user response:

3 errors in your approach.

First, a find() on the blocks collection returns complete documents, not just the block documents (being the block field). So unmarshal results into a value of type that describes the complete documents, e.g.:

type Doc struct {
    ID    primitive.ObjectID `bson:"_id"`
    Block Block              `bson:"block"`
}

And the unmarshaling code:

var doc Doc
if err = results.Decode(&doc); err != nil {
    fmt.Println(err)
}
hashHeaders = append(hashHeaders, doc.Block)

Second, transactions is an array, so in Go you must model it with a slice:

type Block struct {
    Transactions []BlockTransaction
}

Third, Properties of objects array fields in projections and filters are referred to without indices, so use a projection:

options := options.Find().
    SetProjection(bson.M{"block.transactions.transactionHash": 1})

Also note that you can simply decode results using the Cursor.All() method like this:

var docs []Doc
err = results.All(ctx, &docs)
if err != nil {
    fmt.Println(err)
}

Working complete code:

func GetBlockTransactions(number int) string {
    ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
    defer cancel()

    options := options.Find().
        SetProjection(bson.M{"block.transactions.transactionHash": 1}).
        SetLimit(1)

    results, err := blocksCollections.Find(ctx, bson.M{"block.header.blockNumber": strconv.Itoa(number)}, options)

    if err != nil {
        fmt.Println(err)
    }

    var docs []Doc
    err = results.All(ctx, &docs)
    if err != nil {
        fmt.Println(err)
    }

    fmt.Printf("hash: %v\n", docs[0].Block.Transactions[0].TransactionHash)
    return string(docs[0].Block.Transactions[0].TransactionHash)
}

Also note that if an error is encountered, subsequent code is likely to fail, so you should return early. You should also return an annotated error.

Like this:

func GetBlockTransactions(number int) (string, error) {
    ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
    defer cancel()

    options := options.Find().
        SetProjection(bson.M{"block.transactions.transactionHash": 1}).
        SetLimit(1)

    results, err := blocksCollections.Find(ctx, bson.M{"block.header.blockNumber": strconv.Itoa(number)}, options)
    if err != nil {
        return "", fmt.Errorf("Find() failed: %w", err)
    }

    var docs []Doc
    err = results.All(ctx, &docs)
    if err != nil {
        return "", fmt.Errorf("Cursor.All() failed: %w", err)
    }

    fmt.Printf("hash: %v\n", docs[0].Block.Transactions[0].TransactionHash)
    return string(docs[0].Block.Transactions[0].TransactionHash), nil
}

Also note that if you're expected exactly one result, a simpler solution is to use Collection.FindOne().

  • Related