go-substrate-rpc-client icon indicating copy to clipboard operation
go-substrate-rpc-client copied to clipboard

Invalid Transaction on custom pallets

Open kevinjanada opened this issue 3 years ago • 8 comments

When submitting an extrinsic to a custom pallet rpc, it always returns the error "Invalid Transaction" without any other explanation.

If possible could an example be provided? I couldn't find an example of making transactions using custom types.

kevinjanada avatar May 19 '21 12:05 kevinjanada

@kevinjanada this doesn't give any info on how to reproduce this. Please provide more info on what you are doing and What custom types you are using

vedhavyas avatar May 19 '21 13:05 vedhavyas

package main

import (
	"encoding/hex"
	"fmt"

	gsrpc "github.com/centrifuge/go-substrate-rpc-client/v3"
	//"github.com/centrifuge/go-substrate-rpc-client/v3/config"
	"github.com/centrifuge/go-substrate-rpc-client/v3/signature"
	"github.com/centrifuge/go-substrate-rpc-client/v3/types"
	// "github.com/vedhavyas/go-subkey"
	// "github.com/vedhavyas/go-subkey/sr25519"
)

func main() {
	api, err := gsrpc.NewSubstrateAPI("wss://debio.theapps.dev/node")
	if err != nil {
		panic(err)
	}

	meta, err := api.RPC.State.GetMetadataLatest()
	if err != nil {
		panic(err)
	}

	serviceId, err := hex.DecodeString("67e7db53a9872c3da338233586a5977cda92f6db4425ebb2b6804af106a76190")
	if err != nil {
		panic(err)
	}
	c, err := types.NewCall(meta, "Orders.create_order", serviceId)
	if err != nil {
		panic(err)
	}

	// Create the extrinsic
	ext := types.NewExtrinsic(c)

	genesisHash, err := api.RPC.Chain.GetBlockHash(0)
	if err != nil {
		panic(err)
	}

	rv, err := api.RPC.State.GetRuntimeVersionLatest()
	if err != nil {
		panic(err)
	}

	// Initiate account -----
	uri := "0xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" // Private Key
	kr, err := signature.KeyringPairFromSecret(uri, 42)
	if err != nil {
		panic(err)
	}
	// -----

	// Get the nonce for Account ---
	key, err := types.CreateStorageKey(meta, "System", "Account", kr.PublicKey, nil)
	if err != nil {
		panic(err)
	}
	var accountInfo types.AccountInfo
	ok, err := api.RPC.State.GetStorageLatest(key, &accountInfo)
	if err != nil || !ok {
		panic(err)
	}
	nonce := uint32(accountInfo.Nonce)
	// ------

	o := types.SignatureOptions{
		BlockHash:          genesisHash,
		Era:                types.ExtrinsicEra{IsMortalEra: false},
		GenesisHash:        genesisHash,
		Nonce:              types.NewUCompactFromUInt(uint64(nonce)),
		SpecVersion:        rv.SpecVersion,
		Tip:                types.NewUCompactFromUInt(0),
		TransactionVersion: rv.TransactionVersion,
	}

	// Sign the transaction
	err = ext.Sign(kr, o)
	if err != nil {
		panic(err)
	}

	fmt.Printf("Is Extrinsic signed ? -> %v \n", ext.IsSigned())

	// Do the transaction and track the actual status
	sub, err := api.RPC.Author.SubmitExtrinsic(ext)
	if err != nil {
		fmt.Println("Failed in submitting extrinsic \n")
		fmt.Printf("Error is %v \n", err)
		panic(err)
	}
	fmt.Printf("Hash : %v \n", sub)
}

kevinjanada avatar May 20 '21 01:05 kevinjanada

Basically i followed the example on transfer balance from alice to bob, and change the Call to a custom pallet on my substrate chain. Maybe i have to inject the custom type somwhere before sending the transaction?

kevinjanada avatar May 20 '21 01:05 kevinjanada

c, err := types.NewCall(meta, "Orders.create_order", serviceId)

What is the type you are expecting on the Extrinsic? Seem like you are sending in Vec<U8> here.

o := types.SignatureOptions{ BlockHash: genesisHash, Era: types.ExtrinsicEra{IsMortalEra: false}, GenesisHash: genesisHash, Nonce: types.NewUCompactFromUInt(uint64(nonce)), SpecVersion: rv.SpecVersion, Tip: types.NewUCompactFromUInt(0), TransactionVersion: rv.TransactionVersion, }

Is your chain using MultiAddress and on V3 ? If not, this would not work. If your chain is on Substrate V2, then use V2 gsrpc :)

vedhavyas avatar May 20 '21 08:05 vedhavyas

What is the type you are expecting on the Extrinsic? Seem like you are sending in Vec here.

serviceId is just a hash from this part of the code

serviceId, err := hex.DecodeString("67e7db53a9872c3da338233586a5977cda92f6db4425ebb2b6804af106a76190")
if err != nil {
     panic(err)
}

Is your chain using MultiAddress and on V3 ? If not, this would not work. If your chain is on Substrate V2, then use V2 gsrpc :)

Yes my chain is using Multiaddress and on V3.

I tested the balance transfer example and it worked

kevinjanada avatar May 20 '21 08:05 kevinjanada

Any updates on this?

kevinjanada avatar May 28 '21 05:05 kevinjanada

@kevinjanada Unfortunately no. here is an example in V2. I do not have any for v3 but it shouldn't change much. I'll see if I can look at during weekend.

Example: https://github.com/centrifuge/go-centrifuge/blob/develop/anchors/service.go#L106 The call implementation: https://github.com/centrifuge/centrifuge-chain/blob/master/runtime/src/anchor/mod.rs#L159

vedhavyas avatar May 28 '21 10:05 vedhavyas

It could also be related to https://github.com/centrifuge/go-substrate-rpc-client/issues/159 Can you confirm which metadata version your node implementation uses?

vedhavyas avatar May 28 '21 10:05 vedhavyas

Closing this for now, please let us know if you still need help here @kevinjanada.

cdamian avatar Dec 05 '23 11:12 cdamian