github.com/mavryk-network/mvgo@v1.19.9/examples/fa12/main.go (about)

     1  // Copyright (c) 2020-2021 Blockwatch Data Inc.
     2  // Author: alex@blockwatch.cc
     3  
     4  // RPC examples
     5  package main
     6  
     7  import (
     8  	"context"
     9  	"encoding/json"
    10  	"flag"
    11  	"fmt"
    12  	"os"
    13  	"strconv"
    14  
    15  	"github.com/mavryk-network/mvgo/mavryk"
    16  	"github.com/mavryk-network/mvgo/micheline"
    17  	"github.com/mavryk-network/mvgo/rpc"
    18  
    19  	"github.com/echa/log"
    20  )
    21  
    22  var (
    23  	flags   = flag.NewFlagSet("fa12", flag.ContinueOnError)
    24  	verbose bool
    25  	node    string
    26  )
    27  
    28  func init() {
    29  	flags.Usage = func() {}
    30  	flags.BoolVar(&verbose, "v", false, "be verbose")
    31  	flags.StringVar(&node, "node", "https://rpc.tzpro.io", "Tezos node URL")
    32  }
    33  
    34  func main() {
    35  	if err := flags.Parse(os.Args[1:]); err != nil {
    36  		if err == flag.ErrHelp {
    37  			fmt.Println("Usage: fa12 [args] <block> <pos>")
    38  			fmt.Println("\n  Decodes FA1.2 transfer info from transaction.")
    39  			fmt.Println("\nArguments")
    40  			flags.PrintDefaults()
    41  			os.Exit(0)
    42  		}
    43  		log.Fatal("Error:", err)
    44  	}
    45  
    46  	if err := run(); err != nil {
    47  		log.Fatal("Error:", err)
    48  	}
    49  }
    50  
    51  func run() error {
    52  	if flags.NArg() < 2 {
    53  		return fmt.Errorf("Argument required")
    54  	}
    55  
    56  	switch {
    57  	case verbose:
    58  		log.SetLevel(log.LevelInfo)
    59  	default:
    60  		log.SetLevel(log.LevelWarn)
    61  	}
    62  	rpc.UseLogger(log.Log)
    63  
    64  	hash, err := mavryk.ParseBlockHash(flags.Arg(0))
    65  	if err != nil {
    66  		return err
    67  	}
    68  	op_n, err := strconv.ParseInt(flags.Arg(1), 10, 64)
    69  	if err != nil {
    70  		return err
    71  	}
    72  
    73  	ctx, cancel := context.WithCancel(context.Background())
    74  	defer cancel()
    75  
    76  	c, err := rpc.NewClient(node, nil)
    77  	if err != nil {
    78  		return err
    79  	}
    80  
    81  	b, err := c.GetBlock(ctx, hash)
    82  	if err != nil {
    83  		return err
    84  	}
    85  
    86  	tx := b.Operations[3][op_n].Contents[0].(*rpc.Transaction)
    87  
    88  	// you need the contract's script for type info
    89  	script, err := c.GetContractScript(ctx, tx.Destination)
    90  	if err != nil {
    91  		return err
    92  	}
    93  
    94  	// unwind params for nested entrypoints
    95  	ep, prim, err := tx.Parameters.MapEntrypoint(script.ParamType())
    96  	if err != nil {
    97  		return err
    98  	}
    99  
   100  	// convert Micheline params into human-readable form
   101  	val := micheline.NewValue(ep.Type(), prim)
   102  
   103  	// use Value interface to access data, you have multiple options
   104  	// 1/ get a decoded `map[string]interface{}`
   105  	m, err := val.Map()
   106  	if err != nil {
   107  		return err
   108  	}
   109  
   110  	buf, err := json.MarshalIndent(m, "", "  ")
   111  	if err != nil {
   112  		return err
   113  	}
   114  	fmt.Println("Map=", string(buf))
   115  	fmt.Printf("Value=%s %[1]T\n", m.(map[string]interface{})["transfer"].(map[string]interface{})["value"])
   116  
   117  	// 2/ access individual fields (ok is true when the field exists and
   118  	//    has the correct type)
   119  	from, ok := val.GetAddress("transfer.from")
   120  	if !ok {
   121  		return fmt.Errorf("No from param")
   122  	}
   123  	fmt.Println("Sent from", from)
   124  
   125  	// 3/ unmarshal the decoded Micheline parameters into a Go struct
   126  	type FA12Transfer struct {
   127  		From  mavryk.Address `json:"from"`
   128  		To    mavryk.Address `json:"to"`
   129  		Value mavryk.Z       `json:"value"`
   130  	}
   131  	type FA12TransferWrapper struct {
   132  		Transfer FA12Transfer `json:"transfer"`
   133  	}
   134  
   135  	var transfer FA12TransferWrapper
   136  	err = val.Unmarshal(&transfer)
   137  	if err != nil {
   138  		return err
   139  	}
   140  	buf, _ = json.MarshalIndent(transfer, "", "  ")
   141  	fmt.Printf("FA transfer %s\n", string(buf))
   142  
   143  	return nil
   144  }