tendermint/go-amino

How does slice decoding is done?

Closed this issue · 2 comments

func (cdc *Codec) decodeReflectBinaryByteSlice(bz []byte, info *TypeInfo, rv reflect.Value, fopts FieldOptions) (n int, err error) {

Hi, I'm trying to decode an StdTx obtained from a node using the go-sdk for the Binance Chain. The StdTx is encoded so using codec.UnmarshalBinaryLengthPrefixed I'm able to decode it to an str json (following this example: bnb-chain/node-binary#53). Now I'm trying to code my own function to decode the tx (to read the outputs of a transaction on a system where I can't use UnmarshalBinaryLengthPrefixed or any library).
The Output struct looks like this:

type AccAddress []byte

// Coin def
type Coin struct {
	Denom  string `json:"denom"`
	Amount int64  `json:"amount"`
}

// Coins def
type Coins []Coin

// Transaction Output
type Output struct {
	Address AccAddress `json:"address"`
	Coins   Coins      `json:"coins"`
}

I have managed to decode the Amount (int64) and the Denom (string) but I have difficulty understanding how the Address ([]byte) is decoded.

Looking into the function that is called to decode it I can see the following steps:
Initially I have:

bz -> [20 210 70 25 113 160 90 159 247 12 180 104 194 51 29 152 47 90 15 172 236 18 10 10 3 66 78 66 16 128 225 235 23] (encoded value)
rv -> bnb1wr3j9g (I think is the default value, but I'm not sure)

Then is called DecodeByteSlice(bz) and returns:

byteslice -> [210 70 25 113 160 90 159 247 12 180 104 194 51 29 152 47 90 15 172 236]
_n -> 21

Then is called rv.Set(reflect.ValueOf(byteslice)) and I got in rv the Address decoded:

reflect.ValueOf(byteslice) returns -> [210 70 25 113 160 90 159 247 12 180 104 194 51 29 152 47 90 15 172 236] //the same value as byteslice
rv -> bnb16frpjudqt20lwr95drprx8vc9adqlt8vzpmukw

I don't understand how from byteslice I can obtain the final value of rv.

Can someone help me or guide me? I appreciate any response. Thanks in advance

Looks like you're printing the .String() value of rv.Elem()?
How are you printing rv -> ...?
What is rv.Type? See if there is a .String() method implemented there.
This is using bech32 to encode the 20 bytes starting with [210, 70, ...] using the bech32 prefix of "bnb". Good luck, sorry for the late reply.

This was the key

This is using bech32 to encode the 20 bytes

Could solve it, thanks for replying anyway!