I have a string representing a transaction data from the bitcoin network. I wish I could decode the string (named my_data) in such a way that I can retrieve only the value of the "hash" field. I have tried a small example (in the real situation I would have an array which each position contain a transfer data like the one you may see in the code):
package main
import (
"encoding/json"
"fmt"
)
func main() {
var my_data = []byte(`{
"ver":1,
"inputs":[
{
"sequence":4294967295,
"prev_out":{
"spent":true,
"tx_index":156978299,
"type":0,
"addr":"34cXotJvHAz1RVFtmK2vU29E9d5hF2manG",
"value":848231245,
"n":1,
"script":"a914200f3e946fcf58d3f0787034a610860f0b96332d87"
},
"script":"004730440220149e4cd90c7b2648e89d357162f383098504eea21d390f02e5a289e114ed36520220556da97f0e6789d34f4fb1faf7a1c1055368c01ede85b8101be5007f7b9f3c190147304402200d72e1b91684cdb0e63ea2a24d6ae0b9e38dacdf068e2e08e46ce7f951cdc9dd0220242be0131722287bc15e3d802ba3dea9df0c18f3ec0ac6913b4146f7deb717c90147522102dfd3c8864cddd4d88a8f602d016a656132f89f66450966f9a4a45dea11ec6eb92102c5f064226fcd75fdcae289118b0c4d20e1bafbf4068e7102baec66fade94e3b952ae"
}
],
"block_height":417695,
"relayed_by":"138.201.2.34",
"out":[
{
"spent":false,
"tx_index":156978302,
"type":0,
"addr":"1PWDLsx73qfyCUga29ffAjc2UVdWEeeHDL",
"value":3123438,
"n":0,
"script":"76a914f6d92221d499bf8c01a0dc6f0c04b82d6b62301f88ac"
},
{
"spent":true,
"tx_index":156978302,
"type":0,
"addr":"34cXotJvHAz1RVFtmK2vU29E9d5hF2manG",
"value":845057807,
"n":1,
"script":"a914200f3e946fcf58d3f0787034a610860f0b96332d87"
}
],
"lock_time":0,
"size":334,
"double_spend":false,
"time":1466725723,
"tx_index":156978302,
"vin_sz":1,
"hash":"fae2577ff2a1cfa977c7a883ea4e594c91bd67c767ef1b7870475022c08a453b",
"vout_sz":2
}`)
type Tx struct {
hash string
}
var txs []Tx
err := json.Unmarshal(my_data, &txs)
if err != nil {
fmt.Println("error:", err)
}
for i:=0; i<len(txs); i++{
fmt.Printf("%s
", txs[i].hash)
}
}
but i keep getting the following error:
error: json: cannot unmarshal object into Go value of type []main.Tx
is there an easier way I could try that doesn't need the "encoding/json" library ?
Thanks in advance!
EDIT:
The code I have was adapted from an example I extracted from here.
I believe the issue lies within the string I'm trying to decode, since the pattern it's built on allows nested lists and field values with or without quotes. Though I'm not sure.
Kaedys is right on both counts.
Your JSON is an object, not an array.
You aren't exporting the "hash" field in your struct, which the encoding/json
library requires.
If you put square brackets around the input JSON (to make it an array) and capitalize the "hash" field name, the code will work.
Your JSON isn't a list, which is what it would have to be to marshal to a slice.
However, if your input data is actually a list, you're probably running into problems with the destination structure (and more specifically, the hash
field) not being exported. It also may be easier to use an anonymous struct (which is by nature exported) rather than a type definition. Instead of:
type Tx struct {
hash string
}
var txs []Tx
err := json.Unmarshal(my_data, &txs)
use:
var txs []struct {
Hash string `json:"hash"` // tag not strictly necessary, but useful for clarity
}
err := json.Unmarshal(my_data, &txs)