-
Notifications
You must be signed in to change notification settings - Fork 181
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
submit batch transaction #304
Comments
Hi @bhaagiKenpachi, Please see the below example:
|
@cdamian Thanks for your quick response. Will try and let you know. |
@cdamian In the code you got hash of block 0. Should I also do the same for any scenario or should I get latest block? |
@bhaagiKenpachi for the genesis hash you always need the first block. |
@cdamian So it should always be genesis hash at blockhash or I should include latest block hash near blockhash? signOpts := types.SignatureOptions{
BlockHash: genesisHash, // using genesis since we're using immortal era
Era: types.ExtrinsicEra{IsMortalEra: false},
GenesisHash: genesisHash,
Nonce: types.NewUCompactFromUInt(uint64(accountInfo.Nonce)),
SpecVersion: rv.SpecVersion,
Tip: types.NewUCompactFromUInt(0),
TransactionVersion: rv.TransactionVersion,
} is genesis hash field is compulsory in signature options? |
@bhaagiKenpachi for signature options, yes. |
|
@cdamian So it should always be genesis hash at blockhash or I should include latest block hash near blockhash? |
@bhaagiKenpachi genesis hash is mandatory in the signature opts.
If you are using immortal eras, that one should be the genesis hash. If you were using mortal eras then a different block hash would have to be used. |
@cdamian I want to go with mortal tx for now. Can you suggest the what can be the changes? |
@bhaagiKenpachi mortal eras are a WIP for us at this point - #286. We have yet to test the changes in this PR and eventually merge it. You are more than welcome to try it out and also contribute to it. |
@cdamian why did you use storage here? |
To retrieve the account info that is required in the signature opts. |
@cdamian I have sent friend request on discord. Can you please accept?. For faster communication. |
@bhaagiKenpachi lets try to keep this conversation as public as possible in case that other people run into the same questions later on. |
package main
import (
"fmt"
gsrpc "github.com/centrifuge/go-substrate-rpc-client/v4"
"github.com/centrifuge/go-substrate-rpc-client/v4/signature"
gsrpcTypes "github.com/centrifuge/go-substrate-rpc-client/v4/types"
"github.com/centrifuge/go-substrate-rpc-client/v4/types/codec"
"time"
)
const (
endpoint = "ws://localhost:9944"
westend = "wss://westend-rpc.polkadot.io"
)
func main() {
api, err := gsrpc.NewSubstrateAPI(westend)
if err != nil {
fmt.Errorf("error %w", err)
}
meta, err := api.RPC.State.GetMetadataLatest()
if err != nil {
fmt.Errorf("error %w", err)
}
genesisHash, err := api.RPC.Chain.GetBlockHash(0)
if err != nil {
fmt.Errorf("error %w", err)
}
kp, err := signature.KeyringPairFromSecret(mnemonic, 42)
aliceStorageKey, err := gsrpcTypes.CreateStorageKey(meta, "System", "Account", kp.PublicKey)
if err != nil {
panic(err)
}
var accountInfo gsrpcTypes.AccountInfo
ok, err := api.RPC.State.GetStorageLatest(aliceStorageKey, &accountInfo)
if err != nil || !ok {
panic(err)
}
rv, err := api.RPC.State.GetRuntimeVersionLatest()
if err != nil {
panic(err)
}
memo := gsrpcTypes.NewData([]byte("memo:ADD:DOT.DOT:dojima1nh4y3gqxsn7ymm9t45zwsz3h8p9tm7pev8my62"))
memoBytes, err := codec.Encode(memo)
if err != nil {
panic(err)
}
call1, err := gsrpcTypes.NewCall(meta, "System.remark", memoBytes)
if err != nil {
panic(err)
}
//keyringPair := signature.KeyringPair{Address: kp.Public().Hex(), PublicKey: kp.Public().Encode(), URI: mnemonic}
if err != nil {
panic(err)
}
dest, err := gsrpcTypes.NewAddressFromHexAccountID("0x8eaf04151687736326c9fea17e25fc5287613693c912909cb226aa4794f26a48")
if err != nil {
panic(err)
}
call2, err := gsrpcTypes.NewCall(meta, "Balances.transfer", dest, gsrpcTypes.NewUCompactFromUInt(10000000000))
if err != nil {
panic(err)
}
batchCall, err := gsrpcTypes.NewCall(meta, "Utility.batch_all", []gsrpcTypes.Call{call1, call2})
if err != nil {
panic(err)
}
ext := gsrpcTypes.NewExtrinsic(batchCall)
signOpts := gsrpcTypes.SignatureOptions{
BlockHash: genesisHash, // using genesis since we're using immortal era
Era: gsrpcTypes.ExtrinsicEra{IsMortalEra: false},
GenesisHash: genesisHash,
Nonce: gsrpcTypes.NewUCompactFromUInt(uint64(accountInfo.Nonce)),
SpecVersion: rv.SpecVersion,
Tip: gsrpcTypes.NewUCompactFromUInt(0),
TransactionVersion: rv.TransactionVersion,
}
if err := ext.Sign(kp, signOpts); err != nil {
panic(err)
}
sub, err := api.RPC.Author.SubmitAndWatchExtrinsic(ext)
if err != nil {
panic(err)
}
defer sub.Unsubscribe()
select {
case <-time.After(1 * time.Minute):
panic("Timeout reached")
case st := <-sub.Chan():
extStatus, _ := st.MarshalJSON()
fmt.Println("Done with status -", string(extStatus))
case err := <-sub.Err():
panic(err)
}
}
goroutine 1 [running]: ` |
@bhaagiKenpachi try using Also, please make sure you keep any credentials such as seeds/mnemonics safe, you don't have to share those for debugging since we can use our own accounts for testing. |
@cdamian call2, err := gsrpcTypes.NewCall(meta, "Balances.transfer", dest, gsrpcTypes.NewU128(*big.NewInt(100000000))) Still same error Error: Runtime error: Execution failed: Execution aborted due to trap: wasm trap: wasm
panic: runtime error: invalid memory address or nil pointer dereference |
@cdamian When I'm trying to submit above code transaction. Im getting "invalid transaction" error. Do you know what are the cases that we get above error. |
@bhaagiKenpachi In the last example that you posted above, use a multi address for the destination account:
|
https://gist.github.com/cdamian/cdfe38c7d858f8c899977fcc9ef41b99 - this works on our chain, adding the remark and transferring some amount from Alice to Bob. |
Furthermore, if you are unsure about specific extrinsic related details, you can always use something like - https://polkadot.js.org/apps/?rpc=wss%3A%2F%2Fwestend.api.onfinality.io%2Fpublic-ws#/extrinsics to confirm the args, signature and so on. |
@cdamian Its working with gsrpcTypes.NewAddressFromHexAccountID. I was giving wrong input to get error. After providing correct input its working. |
I want to submit a batch tx which consists of 2 txs. One tx is system::remark and balances::transfer. Is there any function to submit batch tx?
The text was updated successfully, but these errors were encountered: