github.com/nspcc-dev/neo-go@v0.105.2-0.20240517133400-6be757af3eba/pkg/rpcclient/invoker/doc_test.go (about) 1 package invoker_test 2 3 import ( 4 "context" 5 "errors" 6 7 "github.com/nspcc-dev/neo-go/pkg/core/transaction" 8 "github.com/nspcc-dev/neo-go/pkg/encoding/address" 9 "github.com/nspcc-dev/neo-go/pkg/rpcclient" 10 "github.com/nspcc-dev/neo-go/pkg/rpcclient/invoker" 11 "github.com/nspcc-dev/neo-go/pkg/rpcclient/neo" 12 "github.com/nspcc-dev/neo-go/pkg/rpcclient/unwrap" 13 "github.com/nspcc-dev/neo-go/pkg/util" 14 "github.com/nspcc-dev/neo-go/pkg/vm/vmstate" 15 ) 16 17 func ExampleInvoker() { 18 // No error checking done at all, intentionally. 19 c, _ := rpcclient.New(context.Background(), "url", rpcclient.Options{}) 20 21 // A simple invoker with no signers, perfectly fine for reads from safe methods. 22 inv := invoker.New(c, nil) 23 24 // Get the NEO token supply (notice that unwrap is used to get the result). 25 supply, _ := unwrap.BigInt(inv.Call(neo.Hash, "totalSupply")) 26 _ = supply 27 28 acc, _ := address.StringToUint160("NVTiAjNgagDkTr5HTzDmQP9kPwPHN5BgVq") 29 // Get the NEO balance for account NVTiAjNgagDkTr5HTzDmQP9kPwPHN5BgVq. 30 balance, _ := unwrap.BigInt(inv.Call(neo.Hash, "balanceOf", acc)) 31 _ = balance 32 33 // Test-invoke transfer call. 34 res, _ := inv.Call(neo.Hash, "transfer", acc, util.Uint160{1, 2, 3}, 1, nil) 35 if res.State == vmstate.Halt.String() { 36 panic("NEO is broken!") // inv has no signers and transfer requires a witness to be performed. 37 } else { // nolint:revive // superfluous-else: if block ends with call to panic function, so drop this else and outdent its block (revive) 38 println("ok") // this actually should fail 39 } 40 41 // A historic invoker with no signers at block 1000000. 42 inv = invoker.NewHistoricAtHeight(1000000, c, nil) 43 44 // It's the same call as above, but the data is for a state at block 1000000. 45 balance, _ = unwrap.BigInt(inv.Call(neo.Hash, "balanceOf", acc)) 46 _ = balance 47 48 // This invoker has a signer for NVTiAjNgagDkTr5HTzDmQP9kPwPHN5BgVq account with 49 // CalledByEntry scope, which is sufficient for most operation. It uses current 50 // state which is exactly what you need if you want to then create a transaction 51 // with the same action. 52 inv = invoker.New(c, []transaction.Signer{{Account: acc, Scopes: transaction.CalledByEntry}}) 53 54 // Now test invocation should be fine (if NVTiAjNgagDkTr5HTzDmQP9kPwPHN5BgVq has 1 NEO of course). 55 res, _ = inv.Call(neo.Hash, "transfer", acc, util.Uint160{1, 2, 3}, 1, nil) 56 if res.State == vmstate.Halt.String() { 57 // transfer actually returns a value, so check it too. 58 ok, _ := unwrap.Bool(res, nil) 59 if ok { 60 // OK, as expected. 61 // res.Script contains the corresponding script. 62 _ = res.Script 63 // res.GasConsumed has an appropriate system fee required for a transaction. 64 _ = res.GasConsumed 65 } 66 } 67 68 // Now let's try working with iterators. 69 nep11Contract := util.Uint160{1, 2, 3} 70 71 var tokens [][]byte 72 73 // Try doing it the right way, by traversing the iterator. 74 sess, iter, err := unwrap.SessionIterator(inv.Call(nep11Contract, "tokensOf", acc)) 75 76 // The server doesn't support sessions and doesn't perform iterator expansion, 77 // iterators can't be used. 78 if err != nil { 79 if errors.Is(err, unwrap.ErrNoSessionID) { 80 // But if we expect some low number of elements, CallAndExpandIterator 81 // can help us in this case. If the account has more than 10 elements, 82 // some of them will be missing from the response. 83 tokens, _ = unwrap.ArrayOfBytes(inv.CallAndExpandIterator(nep11Contract, "tokensOf", 10, acc)) 84 } else { 85 panic("some error") 86 } 87 } else { 88 items, err := inv.TraverseIterator(sess, &iter, 100) 89 // Keep going until there are no more elements 90 for err == nil && len(items) != 0 { 91 for _, itm := range items { 92 tokenID, _ := itm.TryBytes() 93 tokens = append(tokens, tokenID) 94 } 95 items, err = inv.TraverseIterator(sess, &iter, 100) 96 } 97 // Let the server release the session. 98 _ = inv.TerminateSession(sess) 99 } 100 _ = tokens 101 }