Open jekabolt opened 2 years ago
We solved this by decode the correct tx signed message from PolkadotJS. And we found out the go-rpc code writes the TX message in a wrong sequence
0x390284005675bfca5d558c0df741ce6017beb274d97f262144441f8d622f7e62bb0e411c0168d01fbd9c7849bfdb51cde9d7a3494e1e7af22160f2a361f3672168f5d9085db91a24ea9d9a9d3c9bdaa8f7a347c28a0e4f930aa7e8f0af484547086b9aca89002400000f00009425ad96a3583bfe7de1f0a722ee7bbe9ddcaf3b4b79468ca74fe1b6b99c540c0284d717
https://polkadot.js.org/apps/?rpc=wss%3A%2F%2Ftanganika.datahighway.com#/extrinsics/decode
After sorting it right, we can submit this extrinsic correctly.
@sheenhx Hey I didn't get what do you mean I found that SectionIndex & MethodIndex are in wrong places and for browser generated tx they push SectionIndex in front of args
func NewCall(m *types.Metadata, call string, args ...interface{}) (types.Call, error) {
c, err := m.FindCallIndex(call)
if err != nil {
return types.Call{}, err
}
c = types.CallIndex{
SectionIndex: c.MethodIndex,
MethodIndex: c.SectionIndex,
}
var a []byte
ci, err := types.Encode(c.SectionIndex)
if err != nil {
return types.Call{}, err
}
a = append(a, ci...)
for _, arg := range args {
e, err := types.Encode(arg)
if err != nil {
return types.Call{}, err
}
a = append(a, e...)
}
return types.Call{
CallIndex: c,
Args: a,
}, nil
}
here I got two nearly identical txs
0x4d028400d624d7a4c7ad34cdd007428709b610d529649e273567c4d7ea37854cec44152601f0a0af61cfc657295bc22cb93e07272b00679edbc21d3cfeb9d188782d5fcd6a9f448bb998109b98a3461e037a915f6596e71b2f646bcb48bc14ba6cb0d49389002800000f00005675bfca5d558c0df741ce6017beb274d97f262144441f8d622f7e62bb0e411c13000064a7b3b6e00d ```
this one from browser
0x4d028400d624d7a4c7ad34cdd007428709b610d529649e273567c4d7ea37854cec441526011232c17b4a23edfeb8cda558721c8892af458ceccf0e17a618d31f6c7a66d43d64ddcaed7fa1cbe0593fd340958c7129ac9ca10eac86ff8f8fff7715cd5cf884002800000f00005675bfca5d558c0df741ce6017beb274d97f262144441f8d622f7e62bb0e411c13000064a7b3b6e00d```
and one I generate from code only difference in them is sig field and if I try to submit em via browser it gives error :
1010: Invalid Transaction: Transaction has a bad signature
@sheenhx I took payload from generated tx
payload 0x000f00005675bfca5d558c0df741ce6017beb274d97f262144441f8d622f7e62bb0e411c13000064a7b3b6e00d0028000400000001000000eacdd2d5b42de9769ccbb6e8d9013ab0d90ab105bf601d4aac53e874c145ec21eacdd2d5b42de9769ccbb6e8d9013ab0d90ab105bf601d4aac53e874c145
and signature
0x1232c17b4a23edfeb8cda558721c8892af458ceccf0e17a618d31f6c7a66d43d64ddcaed7fa1cbe0593fd340958c7129ac9ca10eac86ff8f8fff7715cd5cf884
they are totally fine and pass
ok, err := signature.Verify(b, sig[:], signature.TestKeyringPairAlice.URI)
and browser verification
How can I resolve this error?
Thanks
I have the same issue. Any solutions?
I am using the latest version 4.1.0
My blockchain node version: polkadot-v0.9.36
This is my code example:
package main
import (
"fmt"
"github.com/centrifuge/go-substrate-rpc-client/v4/signature"
"github.com/centrifuge/go-substrate-rpc-client/v4/types"
gsrpc "github.com/centrifuge/go-substrate-rpc-client/v4"
)
func main(){
err := SendData();
if err != nil {
fmt.Println("error:",err)
}
}
func SendData() error {
//Alice private key
nemo := "0xe5be9a5092b81bca64be81d212e7f2f9eba183bb7a90954f7b76361f6edb5c0a"
api, err := gsrpc.NewSubstrateAPI("ws://127.0.0.1:9944")
if err != nil {
return err
}
fmt.Println("connected")
keypair, err := signature.KeyringPairFromSecret(nemo, 42)
fmt.Println("keypair", keypair.Address, keypair.PublicKey, keypair.URI)
if err != nil {
fmt.Println("keypair", err)
}
meta, err := api.RPC.State.GetMetadataLatest()
if err != nil {
return err
}
amount := types.NewUCompactFromUInt(2000000000000000000)
bob, err := types.NewMultiAddressFromHexAccountID("0x8eaf04151687736326c9fea17e25fc5287613693c912909cb226aa4794f26a48")
c, err := types.NewCall(meta, "Balances.transfer",bob, amount)
if err != nil {
fmt.Println("err call", err)
return err
}
fmt.Println("done1")
// Create the extrinsic
ext := types.NewExtrinsic(c)
fmt.Println("ext:",ext.Version)
genesisHash, err := api.RPC.Chain.GetBlockHash(0)
if err != nil {
fmt.Println("genesisHash, err", err)
return err
}
fmt.Println("done 2 genesisHash", genesisHash)
rv, err := api.RPC.State.GetRuntimeVersionLatest()
if err != nil {
fmt.Println("GetRuntimeVersionLatest, err", err)
return err
}
fmt.Println("done 3")
key, err := types.CreateStorageKey(meta, "System", "Account", keypair.PublicKey)
if err != nil {
return err
}
fmt.Println("done 4 key ", key)
var accountInfo types.AccountInfo
ok, err := api.RPC.State.GetStorageLatest(key, &accountInfo)
fmt.Println("done 5", ok, err, accountInfo)
if err != nil || !ok {
return 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(100),
TransactionVersion: rv.TransactionVersion,
}
fmt.Println("before sign:",o)
// Sign the transaction using Alice's default account
err = ext.Sign(keypair, o)
if err != nil {
return err
}
fmt.Println("before submission")
// Send the extrinsic
txnHash, err := api.RPC.Author.SubmitAndWatchExtrinsic(ext)
if err != nil {
return err
}
fmt.Println("after submission txnHash", txnHash)
return nil
}
My go.mod
module test-sign-transaction
go 1.18
require github.com/centrifuge/go-substrate-rpc-client/v4 v4.1.0
require (
github.com/ChainSafe/go-schnorrkel v1.0.0 // indirect
github.com/cosmos/go-bip39 v1.0.0 // indirect
github.com/deckarep/golang-set v1.8.0 // indirect
github.com/decred/base58 v1.0.4 // indirect
github.com/decred/dcrd/crypto/blake256 v1.0.0 // indirect
github.com/ethereum/go-ethereum v1.10.20 // indirect
github.com/go-stack/stack v1.8.1 // indirect
github.com/gorilla/websocket v1.5.0 // indirect
github.com/gtank/merlin v0.1.1 // indirect
github.com/gtank/ristretto255 v0.1.2 // indirect
github.com/mimoo/StrobeGo v0.0.0-20220103164710-9a04d6ca976b // indirect
github.com/pierrec/xxHash v0.1.5 // indirect
github.com/rs/cors v1.8.2 // indirect
github.com/vedhavyas/go-subkey v1.0.4 // indirect
golang.org/x/crypto v0.7.0 // indirect
golang.org/x/sys v0.6.0 // indirect
gopkg.in/natefinch/npipe.v2 v2.0.0-20160621034901-c1b8fa8bdcce // indirect
)
It could be that other chains use different kind of tips for signature options, or different signatures, one example can be found here - https://github.com/centrifuge/go-substrate-rpc-client/blob/master/registry/retriever/extrinsic_retriever_live_test.go#L24
The polkadot JS endpoint that you provided, https://polkadot.js.org/apps/?rpc=wss%3A%2F%2Ftanganika.datahighway.com#/extrinsics/decode, does not seem to work. Is there another endpoint that we can use to check this particular issue?
Im using chain DataHighway Tanganika Kusama Parachain using DataHighway Collator v3.6.0-b938f49-x86_64-linux-gnu
trying to SubmitExtrinsic
my code below
Im getting
any ideas what is wrong