-
Notifications
You must be signed in to change notification settings - Fork 10
Decode can not decodeSignedVarint invalid input #44
Comments
Thanks for reporting the bug, I will check it |
Hi @Onefox Could you please show me the full code that you encode/decode and register data type ? |
I only decode since I get the base64 tx from the cosmos block, here is the code: const {
Codec,
FieldOtions,
TypeFactory,
Utils,
Types,
WireTypes,
} = require('js-amino');
let StdTx = TypeFactory.create('StdTx', [{
name: 'msg',
type: Types.ArrayInterface,
},
{
name: 'fee',
type: Types.Struct,
},
{
name: 'signatures',
type: Types.ArrayStruct,
},
{
name: 'memo',
type: Types.String,
},
]);
let MsgSend = TypeFactory.create('MsgSend', [{
name: "to_address",
type: Types.String,
},
{
name: "from_address",
type: Types.String,
},
{
name: "amount",
type: Types.ArrayStruct
}
]);
let Amount = TypeFactory.create('amount', [{
name: 'denom',
type: Types.String,
},
{
name: 'amount',
type: Types.String,
}
]);
let PubKeySecp256k1 = TypeFactory.create('PubKeySecp256k1', [{
name: 's',
type: Types.ByteSlice,
}], Types.ByteSlice)
let Signature = TypeFactory.create('signature', [{
name: 'pub_key',
type: Types.Interface,
},
{
name: 'signature',
type: Types.ByteSlice,
}
])
let codec = new Codec();
codec.registerConcrete(new StdTx(), 'auth/StdTx', {});
codec.registerConcrete(new MsgSend(), 'cosmos-sdk/MsgSend', {});
codec.registerConcrete(new PubKeySecp256k1(), 'tendermint/PubKeySecp256k1', {});
codec.unMarshalBinary(Buffer.from('xAHwYl3uCj6oo2GaChRp2UcQysMQdAX91qLuFkeYvlgpxxIUsRTzjmx2DzAcx4pEDWVipkbNrWEaDAoFc3Rha2USAzMwMhISCgwKBXN0YWtlEgMzMDAQwLgCGmoKJuta6YchA9+gi7GTQ9HhHFc+l4gvmw9ZqoOpeAtAEJYQDcg8NnMYEkApheX7+WmfOuYXE1tHtSxden6zlzUxcWxzNWTCEMr0km3lvMmS7oC4sgkclESaVtnbatebN3G74cO/cZ1gXtW9', 'base64'), decodedDataTx);
console.log("TESTunMarshalBinary");
console.log(JSON.stringify(decodedDataTx)); This is the complete tx when I get it from the api via the node: {"height":"370","txhash":"56801A023B7EC5E9C7A848E288658251A7627EE774711428CF89B61A08A6CD74","raw_log":"[{\"msg_index\":\"0\",\"success\":true,\"log\":\"\"}]","logs":[{"msg_index":"0","success":true,"log":""}],"gas_wanted":"40000","gas_used":"29113","tags":[{"key":"action","value":"send"},{"key":"sender","value":"cosmos1d8v5wyx2cvg8gp0a663wu9j8nzl9s2w8l8qe9q"},{"key":"recipient","value":"cosmos1ky208rnvwc8nq8x83fzq6etz5ervmttpyelefq"}],"tx":{"type":"auth/StdTx","value":{"msg":[{"type":"cosmos-sdk/MsgSend","value":{"from_address":"cosmos1d8v5wyx2cvg8gp0a663wu9j8nzl9s2w8l8qe9q","to_address":"cosmos1ky208rnvwc8nq8x83fzq6etz5ervmttpyelefq","amount":[{"denom":"stake","amount":"302"}]}}],"fee":{"amount":[{"denom":"stake","amount":"300"}],"gas":"40000"},"signatures":[{"pub_key":{"type":"tendermint/PubKeySecp256k1","value":"A9+gi7GTQ9HhHFc+l4gvmw9ZqoOpeAtAEJYQDcg8NnMY"},"signature":"KYXl+/lpnzrmFxNbR7UsXXp+s5c1MXFsczVkwhDK9JJt5bzJku6AuLIJHJREmlbZ22rXmzdxu+HDv3GdYF7VvQ=="}],"memo":""}} |
So I rebuild the tx that I see on chain with the tools and get the following hex value: This is working with the following code, where hexTx is the string above. codec.unMarshalBinary(Utils.fromHex(hexTx), decodedDataTx2);
console.log("TESTunMarshalBinary");
console.log(JSON.stringify(decodedDataTx2.JsObject())); Still when I use a hex string from the blockchain that I got with: Which should result in a very simular tx. I am getting the error TypeError: Can not decodeSignedVarint invalid input length
at decodeUVarint (node_modules/js-amino/src/decoder.js:26:31)
at Object.decodeFieldNumberAndType (node_modules/js-amino/src/decoder.js:99:23)
at decodeBinaryField (node_modules/js-amino/src/binaryDecoder.js:87:36)
at Reflection.ownKeys.forEach (node_modules/js-amino/src/binaryDecoder.js:144:13)
at Array.forEach (<anonymous>)
at decodeBinaryStruct (node_modules/js-amino/src/binaryDecoder.js:138:34)
at Object.decodeBinary (node_modules/js-amino/src/binaryDecoder.js:40:31)
at Codec.unMarshalBinary (node_modules/js-amino/src/codec.js:136:23) |
Sorry for my late reply. This problem maybe relating to stateful problem of codec. Due to dynamic typing feature of JS. You can not know the exactly the type you want to decode if you don't do this:
|
It could be it but I don't know what properties I am missing. Since when I build a very identical tx with the objects and codec.marshalBinary I am getting a different binary output. |
Actually, at least you need to know the right structure of your object you wanted to decode, if not, it does not work. |
So now I was able to generate kind of the same tx only signature and address bytes are different. {
"type": "auth/StdTx",
"value": {
"msg": [{
"type": "cosmos-sdk/MsgSend",
"value": {
"to_address": [94, 222, 114, 42, 196, 107, 51, 203, 139, 142, 219, 243, 137, 60, 54, 250, 139, 153, 46, 168],
"from_address": [59, 58, 243, 13, 132, 163, 164, 202, 233, 7, 236, 93, 136, 166, 181, 175, 236, 69, 48, 186],
"amount": [{
"denom": "stake",
"amount": "301"
}]
}
}],
"fee": {
"amount": [{
"denom": "stake",
"amount": "300"
}],
"gas": "40000"
},
"signatures": [{
"pub_key": {
"type": "tendermint/PubKeySecp256k1",
"value": "AhsYAP9gkxVAHYTAbNs7hs7JfuA/oBjsqnykXyu0Bvb6"
},
"signature": "pUxtPTWBvpM04CJq69DgJL4ZzCTigWFtI4LZ5JBqCoYOt1/82+sWXCU1A1lvrQyekkdScezxqnnZFOwXgyNQHQ=="
}],
"memo": ""
}
} And when I try to decode the tx from chain I am getting the error. Both binary hex have the same length and except for the signatory private key and addresses kind of the same values. I am not sure what I am missing here :/ |
Have you tried to decode the tx from chain with Go-Amino/Cosmos and the result is ..? |
So I ran both the fresh generated one that is working with en/decoding and the one from the chain through the decode of the gaiacli (Go-Amino/Cosmos). Both worked and generate the same json schemas. Here for the working one The result is {
"msg": [
{
"type": "cosmos-sdk/MsgSend",
"value": {
"from_address": "cosmos1tm08y2kydveuhzuwm0ecj0pkl29ejt4gghxw35",
"to_address": "cosmos18va0xrvy5wjv46g8a3wc3f444lky2v96luase3",
"amount": [
{
"denom": "stake",
"amount": "301"
}
]
}
}
],
"fee": {
"amount": [
{
"denom": "stake",
"amount": "300"
}
],
"gas": "40000"
},
"signatures": [
{
"pub_key": {
"type": "tendermint/PubKeySecp256k1",
"value": "AhsYAP9gkxVAHYTAbNs7hs7JfuA/oBjsqnykXyu0Bvb6"
},
"signature": "pUxtPTWBvpM04CJq69DgJL4ZzCTigWFtI4LZ5JBqCoYOt1/82+sWXCU1A1lvrQyekkdScezxqnnZFOwXgyNQHQ=="
}
],
"memo": ""
} And here for the on chain tx {
"msg": [
{
"type": "cosmos-sdk/MsgSend",
"value": {
"from_address": "cosmos1d8v5wyx2cvg8gp0a663wu9j8nzl9s2w8l8qe9q",
"to_address": "cosmos1ky208rnvwc8nq8x83fzq6etz5ervmttpyelefq",
"amount": [
{
"denom": "stake",
"amount": "302"
}
]
}
}
],
"fee": {
"amount": [
{
"denom": "stake",
"amount": "300"
}
],
"gas": "40000"
},
"signatures": [
{
"pub_key": {
"type": "tendermint/PubKeySecp256k1",
"value": "A9+gi7GTQ9HhHFc+l4gvmw9ZqoOpeAtAEJYQDcg8NnMY"
},
"signature": "nF3PxZvCfejFjrl+pHpplkwA2H/Cc8tq/Seb9P0XdGsqzZ8WOD6fWq3CbWsl0RjYppsbMh5fgkDXe+QPUyAaJg=="
}
],
"memo": ""
} |
Could you please post full code for encode and decode here(you can change the privatekey value) |
First of thanks for your time and trying! Here goes the code: const {
Codec,
FieldOtions,
TypeFactory,
Utils,
Types,
WireTypes,
} = require('js-amino');
let StdTx = TypeFactory.create('StdTx', [{
name: 'msg',
type: Types.ArrayInterface,
},
{
name: 'fee',
type: Types.Struct,
},
{
name: 'signatures',
type: Types.ArrayStruct,
},
{
name: 'memo',
type: Types.String,
},
]);
let MsgSend = TypeFactory.create('MsgSend', [{
name: "to_address",
type: Types.String,
},
{
name: "from_address",
type: Types.String,
},
{
name: "amount",
type: Types.ArrayStruct
}
]);
let MsgMultiSend = TypeFactory.create('MsgMultiSend', [{
name: "inputs",
type: Types.ArrayStruct
},
{
name: "outputs",
type: Types.ArrayStruct
}
]);
let Coin = TypeFactory.create('coin', [{
name: 'denom',
type: Types.String,
},
{
name: 'amount',
type: Types.String,
}
]);
let Input = TypeFactory.create('input', [{
name: 'address',
type: Types.String,
},
{
name: 'coins',
type: Types.ArrayStruct,
}
]);
let Output = TypeFactory.create('output', [{
name: 'address',
type: Types.String,
},
{
name: 'coins',
type: Types.ArrayStruct,
}
]);
let Fee = TypeFactory.create('fee', [{
name: 'amount',
type: Types.ArrayStruct,
},
{
name: 'gas',
type: Types.Int64,
}
]);
let Amount = TypeFactory.create('amount', [{
name: 'denom',
type: Types.String,
},
{
name: 'amount',
type: Types.String,
}
]);
let PubKeySecp256k1 = TypeFactory.create('PubKeySecp256k1', [{
name: 's',
type: Types.ByteSlice,
}], Types.ByteSlice)
let Signature = TypeFactory.create('signature', [{
name: 'pub_key',
type: Types.Interface,
},
{
name: 'signature',
type: Types.ByteSlice,
}
])
let codec = new Codec();
codec.registerConcrete(new StdTx(), 'auth/StdTx', {});
codec.registerConcrete(new MsgSend(), 'cosmos-sdk/MsgSend', {});
//codec.registerConcrete(new MsgMultiSend(), 'cosmos-sdk/MsgMultiSend', {});
codec.registerConcrete(new PubKeySecp256k1(), 'tendermint/PubKeySecp256k1', {});
let amount = new Amount('stake', "301");
let addressFrom = [ 59,58,243,13,132,163,164,202,233,7,236,93,136,166,181,175,236,69,48,186 ]
let addressTo = [ 94,222,114,42,196,107,51,203,139,142,219,243,137,60,54,250,139,153,46,168 ]
let sendMsg = new MsgSend(addressTo, addressFrom, [amount]);
let fee = new Fee([new Amount('stake', '300')], 40000);
let pubKey = new PubKeySecp256k1([2,27,24,0,255,96,147,21,64,29,132,192,108,219,59,134,206,201,126,224,63,160,24,236,170,124,164,95,43,180,6,246,250]);
let signature = [165,76,109,61,53,129,190,147,52,224,34,106,235,208,224,36,190,25,204,36,226,129,97,109,35,130,217,228,144,106,10,134,14,183,95,252,219,235,22,92,37,53,3,89,111,173,12,158,146,71,82,113,236,241,170,121,217,20,236,23,131,35,80,29];
let sig = new Signature(pubKey, signature);
let stdTx = new StdTx([sendMsg], fee, [sig], '');
let jsonTx = codec.marshalJson(stdTx);
let decodedDataTx = new StdTx();
const toHex = (buffer) => {
let s = ''
buffer.forEach((b) => {
b = b.toString(16)
if (b.length == 1) {
b = '0' + b
}
s += b
})
return s
}
console.log("Binary stdTx:\n", (codec.marshalBinary(stdTx)).toString());
console.log("Json:\n", jsonTx);
const binaryData = codec.marshalBinary(stdTx);
//c401f0625dee0a3ea8a3619a0a145ede722ac46b33cb8b8edbf3893c36fa8b992ea812143b3af30d84a3a4cae907ec5d88a6b5afec4530ba1a0c0a057374616b65120333303112120a0c0a057374616b65120333303010c0b8021a6a0a26eb5ae98721021b1800ff609315401d84c06cdb3b86cec97ee03fa018ecaa7ca45f2bb406f6fa1240a54c6d3d3581be9334e0226aebd0e024be19cc24e281616d2382d9e4906a0a860eb75ffcdbeb165c253503596fad0c9e92475271ecf1aa79d914ec178323501d
console.log("hex:\n", toHex(binaryData));
console.log("base64:\n", Buffer.from(toHex(binaryData), 'hex').toString('base64'));
// a tx from on chain
//c401f0625dee0a3ea8a3619a0a1469d94710cac3107405fdd6a2ee164798be5829c71214b114f38e6c760f301cc78a440d6562a646cdad611a0c0a057374616b65120333303212120a0c0a057374616b65120333303010c0b8021a6a0a26eb5ae9872103dfa08bb19343d1e11c573e97882f9b0f59aa83a9780b401096100dc83c36731812409c5dcfc59bc27de8c58eb97ea47a69964c00d87fc273cb6afd279bf4fd17746b2acd9f16383e9f5aadc26d6b25d118d8a69b1b321e5f8240d77be40f53201a26
const base64OnChain = 'xAHwYl3uCj6oo2GaChRp2UcQysMQdAX91qLuFkeYvlgpxxIUsRTzjmx2DzAcx4pEDWVipkbNrWEaDAoFc3Rha2USAzMwMhISCgwKBXN0YWtlEgMzMDAQwLgCGmoKJuta6YchA9+gi7GTQ9HhHFc+l4gvmw9ZqoOpeAtAEJYQDcg8NnMYEkCcXc/Fm8J96MWOuX6kemmWTADYf8Jzy2r9J5v0/Rd0ayrNnxY4Pp9arcJtayXRGNimmxsyHl+CQNd75A9TIBom';
const hexOnChainTx = Buffer.from(base64OnChain, 'base64').toString('hex');
console.log("hex:\n", hexOnChainTx);
codec.unMarshalBinary(Utils.fromHex(hexOnChainTx), decodedDataTx);
console.log("Decoded data:\n", JSON.stringify(decodedDataTx.JsObject())); For the go encode I used the rest endpoint |
I have updated the code. This problem is occured due to empty array. I tested your code and it worked. Could you please check again by pulling from github? |
So first of thank you very much that fixed this :) So the return is: {
"msg": [{
"to_address": "i�G\u0010��\u0010t\u0005�֢�\u0016G��X)�",
"from_address": "�\u0014�lv\u000f0\u001cNJD\reb�Fͭa",
"amount": [{
"denom": "stake",
"amount": "302"
}]
}],
"fee": {
"amount": [{
"denom": "stake",
"amount": "300"
}],
"gas": 40000
},
"signatures": [{
"pub_key": [3, 223, 160, 139, 177, 147, 67, 209, 225, 28, 87, 62, 151, 136, 47, 155, 15, 89, 170, 131, 169, 120, 11, 64, 16, 150, 16, 13, 200, 60, 54, 115, 24],
"signature": [156, 93, 207, 197, 155, 194, 125, 232, 197, 142, 185, 126, 164, 122, 105, 150, 76, 0, 216, 127, 194, 115, 203, 106, 253, 39, 155, 244, 253, 23, 116, 107, 42, 205, 159, 22, 56, 62, 159, 90, 173, 194, 109, 107, 37, 209, 24, 216, 166, 155, 27, 50, 30, 95, 130, 64, 215, 123, 228, 15, 83, 32, 26, 38]
}],
"memo": []
} So what I don't understand is why is the memo from type array? should it not be a empty string? since its defined as Types.String ? |
thanks for reporting, I'm fixing it |
Current Behavior
When trying to decode a tx that I got within a cosmos block I am getting the following error
TypeError: Can not decodeSignedVarint invalid input
at Object.decodeUVarint (node_modules/js-amino/src/decoder.js:25:49) at Codec.unMarshalBinary (node_modules/js-amino/src/codec.js:127:21)
The base64 tx payload is:
xAHwYl3uCj6oo2GaChRp2UcQysMQdAX91qLuFkeYvlgpxxIUsRTzjmx2DzAcx4pEDWVipkbNrWEaDAoFc3Rha2USAzMwMhISCgwKBXN0YWtlEgMzMDAQwLgCGmoKJuta6YchA9+gi7GTQ9HhHFc+l4gvmw9ZqoOpeAtAEJYQDcg8NnMYEkAiyY/l3V/zU/sZ1ntPt6ouWvDY2OV8sVzmD8NWvgJBQR2wLwCuLz/Z/sOUSyYIw5OV2yGnx1fwIZDvREhiCZFw
My execution code is:
codec.unMarshalBinary(Buffer.from(encodedTx, 'base64'), decodedDataTx);
Additional Information
js-amino npm version 1.0.0
The text was updated successfully, but these errors were encountered: