Skip to content

Instantly share code, notes, and snippets.

@csknk
Last active November 11, 2021 14:31
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save csknk/2e42fe992b43d2d9ddc418b3f336e2b3 to your computer and use it in GitHub Desktop.
Save csknk/2e42fe992b43d2d9ddc418b3f336e2b3 to your computer and use it in GitHub Desktop.
extrinsic_test.go
package main
import (
"bytes"
"fmt"
"math/big"
"testing"
"github.com/centrifuge/go-substrate-rpc-client/v3/scale"
"github.com/centrifuge/go-substrate-rpc-client/v3/types"
"github.com/stretchr/testify/assert"
)
func TestEncodeDecodeExtrinsic(t *testing.T) {
c, err := NewDefaultConnection()
if err != nil {
fmt.Println("No connection to node")
assert.Fail(t, err.Error())
}
AlicePubkey := "0xd43593c715fdd31c61141abd04a99fd6822c8558854ccde39a5684e7a56da27d" // 15oF4uVJwmo4TdGW7VfQxNLavjCXviqxT9S1MgbjMNHr6Sp5
BobPubkey := "0x8eaf04151687736326c9fea17e25fc5287613693c912909cb226aa4794f26a48" // 14E5nqKAp3oAJcmzgZhUD2RcptBeUBScxKHgJKU4HPNcKVf3
var amount uint64 = 4200000000
extrinsic, err := c.NewExtrinsic(AlicePubkey, BobPubkey, amount)
assert.NoError(t, err)
extrinsicString, err := types.EncodeToHexString(extrinsic)
if err != nil {
assert.NoError(t, err)
}
fmt.Println("Signed extrinsic: ", extrinsicString)
_ = DecodeExtrinsic(t, c, extrinsicString)
}
func DecodeExtrinsic(t *testing.T, c *Connection, extrinsicString string) error {
var decodedExtrinsic types.Extrinsic
if err := types.DecodeFromHexString(extrinsicString, &decodedExtrinsic); err != nil {
assert.Fail(t, err.Error())
}
fmt.Printf("%+v\n", decodedExtrinsic.Method.Args)
decoder := scale.NewDecoder(bytes.NewReader(decodedExtrinsic.Method.Args))
// Determine number of calls
// NOTE IT IS NECESSARY TO REMOVE BYTE FROM STREAM - otherwise subsequent decoding won't work properly.
n, err := decoder.DecodeUintCompact()
if err != nil {
assert.Fail(t, err.Error())
}
fmt.Println("CALLS # ", n)
// TODO Maybe loop over n
// Probably should get the metadata for the specific block that contains this extrinsic?
metadata, _ := c.getLatestMetadata()
callFunction := findModule(metadata, decodedExtrinsic.Method.CallIndex)
for _, callArg := range callFunction.Args {
if callArg.Type == "<T::Lookup as StaticLookup>::Source" {
var argValue = types.AccountID{}
decoder.Decode(&argValue)
fmt.Println(callArg.Name, " = ", argValue)
fmt.Printf("%#x\n", argValue)
}
if callArg.Type == "Compact<T::Balance>" {
amount, _ := decoder.DecodeUintCompact()
fmt.Println(callArg.Name, " = ", amount)
}
if callArg.Type == "Vec<u8>" {
var argValue = callArg.Name
_ = decoder.Decode(&argValue)
fmt.Println(callArg.Name, " = ", argValue)
}
}
return nil
}
func findModule(metadata *types.Metadata, index types.CallIndex) types.FunctionMetadataV4 {
for _, mod := range metadata.AsMetadataV13.Modules {
if mod.Index == index.SectionIndex {
return mod.Calls[index.MethodIndex]
}
}
panic("Unknown call")
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment