go-substrate-rpc-client
go-substrate-rpc-client copied to clipboard
MakeASimpleTransfer Error
package main
import (
"fmt"
"math/big"
gsrpc "github.com/centrifuge/go-substrate-rpc-client/v4"
"github.com/centrifuge/go-substrate-rpc-client/v4/signature"
"github.com/centrifuge/go-substrate-rpc-client/v4/types"
)
func main() {
// This sample shows how to create a transaction to make a transfer from one an account to another.
// Instantiate the API
api, err := gsrpc.NewSubstrateAPI("wss://mainnet-node.dock.io")
if err != nil {
panic(err)
}
meta, err := api.RPC.State.GetMetadataLatest()
if err != nil {
panic(err)
}
// Create a call, transferring 12345 units to Bob
// address : 3EbS8cbBoUmd23TrxRavif4S922xxq2AtfjXHqeoFRR7RghX
// publicKey : 0x649d0efed4358bb99e3de015487accb56765b68322e18225bf9fef0a8766ef03
bob, err := types.NewMultiAddressFromHexAccountID("0x649d0efed4358bb99e3de015487accb56765b68322e18225bf9fef0a8766ef03")
if err != nil {
panic(err)
}
// 1 unit of transfer
bal, ok := new(big.Int).SetString("100000000000000", 10)
if !ok {
panic(fmt.Errorf("failed to convert balance"))
}
c, err := types.NewCall(meta, "Balances.transfer", bob, types.NewUCompact(bal))
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)
}
fromKey, err := signature.KeyringPairFromSecret("0xxxxxxx", 22)
if err != nil {
panic(err)
}
key, err := types.CreateStorageKey(meta, "System", "Account", fromKey.PublicKey)
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(100),
TransactionVersion: rv.TransactionVersion,
}
// Sign the transaction using Alice's default account
err = ext.Sign(fromKey, o)
if err != nil {
panic(err)
}
// Send the extrinsic
_, err = api.RPC.Author.SubmitExtrinsic(ext)
if err != nil {
panic(err)
}
fmt.Printf("Balance transferred from Alice to Bob: %v\n", bal.String())
}
My Address : 3FShsMXRytNXrVFAXzD5L5vCMapbRMhwzpdBK3urgBLVcQJT
Error:
type *types.AccountInfo does not support Decodeable interface and could not be decoded field by field, error: type *struct { Free types.U128; Reserved types.U128; MiscFrozen types.U128; FreeFrozen types.U128 } does not support Decodeable interface and could not be decoded field by field, error: Cannot read the required number of bytes 16, only 4 available
How can I resolve this error?
Thanks
Hi @ygcool,
Please try creating a different entity for AccountInfo, that is using U64 instead of U128, as seen below:
// AccountInfo contains information of an account
type AccountInfo struct {
Nonce U32
Refcount U8
Data struct {
Free U64
Reserved U64
MiscFrozen U64
FreeFrozen U64
}
}
Reason for this being the fact that the parachain implementation that you are connecting to, is using U64 for Balance instead of U128, based on the following:
https://github.com/docknetwork/dock-substrate/blob/4a2c69b26ab0446cac7ee6196db70461a36dc175/runtime/src/lib.rs#L416
https://github.com/docknetwork/dock-substrate/blob/4a2c69b26ab0446cac7ee6196db70461a36dc175/runtime/src/lib.rs#L134
Please let me know if this works for you.
Can be solved. thank you!
When I send a transaction,New error: Example unable to decode field 4 event #1 with EventID [2 2], field Balances_Transfer: expected more bytes, but could not decode any more
@ygcool same reason as before, the current Value field that we have for that event is U128 when the parachain sends it as U64.
Making the following adjustment will fix that issue:
// EventBalancesTransfer is emitted when a transfer succeeded (from, to, value)
type EventBalancesTransfer struct {
Phase Phase
From AccountID
To AccountID
Value U64
Topics []Hash
}
The same applies to any event, call or storage entries that use the Balance defined in that parachain.
@ygcool same reason as before, the current
Valuefield that we have for that event isU128when the parachain sends it asU64.Making the following adjustment will fix that issue:
// EventBalancesTransfer is emitted when a transfer succeeded (from, to, value) type EventBalancesTransfer struct { Phase Phase From AccountID To AccountID Value U64 Topics []Hash }The same applies to any event, call or storage entries that use the
Balancedefined in that parachain.
thank you.
and, how to convert accountID to address string?
- If I use this example listen transactions, I passed balances_ Transfer can get from/to/value, How to get transaction hash and block number? Or how to make sure the deal is successful
- and, In other codes, how can I get details through transaction hash?
- How to get address balance?
you can find basically all your answers in the types repo or RPC repo
type AccountInfo struct {
Nonce types.U32
Refcount types.U8
Data struct {
Free types.U64
Reserved types.U64
MiscFrozen types.U64
FreeFrozen types.U64
}
}
var accountInfo AccountInfo
ok, err = api.RPC.State.GetStorageLatest(key, &accountInfo)
if err != nil || !ok {
panic(err)
}
However, the free I obtained is different from the actual balance.
Like this: https://dock.subscan.io/account/3FShsMXRytNXrVFAXzD5L5vCMapbRMhwzpdBK3urgBLVcQJT balance is: 3.269 But the value obtained is always 16777216
type AccountInfo struct { Nonce types.U32 Refcount types.U8 Data struct { Free types.U64 Reserved types.U64 MiscFrozen types.U64 FreeFrozen types.U64 } } var accountInfo AccountInfo ok, err = api.RPC.State.GetStorageLatest(key, &accountInfo) if err != nil || !ok { panic(err) }However, the free I obtained is different from the actual balance.
Like this: https://dock.subscan.io/account/3FShsMXRytNXrVFAXzD5L5vCMapbRMhwzpdBK3urgBLVcQJT balance is: 3.269 But the value obtained is always 16777216
Solved this problem, AccountInfo :
type AccountInfo struct {
Nonce types.U64
Refcount types.U64
Data struct {
Free types.U64
Reserved types.U64
MiscFrozen types.U64
FreeFrozen types.U64
}
}
No solution has been found to these two problems:
- If I use this example listen transactions, I passed balances_ Transfer can get from/to/value, How to get transaction hash and block number? Or how to make sure the deal is successful
- and, In other codes, how can I get details through transaction hash?
@ygcool I'm not sure I understand you last questions. Do you still need help executing a transfer here or is there something else that's not working for you?