Borsh JS 和 Borsh Rust 序列化输出略有不同
Borsh JS and Borsh Rust slightly different serialized output
我正在尝试将 borsh 序列化数据从 JS 发送到 Rust 应用程序。但是,当在 javascript 和 rust 中序列化数据(以比较输出)时,我在 rust 序列化输出中得到了 4 个额外的字节。这是代码:
Borsh JS代码
// class
class Poll {
id: string = '';
question: string = '';
options: string[] = [];
votes: number[] = [];
constructor(fields?: {
id: string;
question: string;
options: string[];
votes: number[];
}) {
if (fields) {
this.id = fields.id;
this.question = fields.question;
this.options = fields.options;
this.votes = fields.votes;
}
}
}
// Schema
const schema: Schema = new Map([
[
Poll,
{
kind: 'struct',
fields: [
['id', 'string'],
['question', 'string'],
['options', ['string']],
['votes', ['u32', 1]],
],
},
],
]);
// class object
const testPoll = new Poll({
id: '1',
question: 'What is your favorite color?',
options: ['a', 'b', 'c'],
votes: [100],
});
//object serialization
let serializedPoll: Uint8Array = new Uint8Array();
serializedPoll = serialize(schema, testPoll); // this succeeds
// output
[1, 0, 0, 0, 49, 28, 0, 0, 0, 87, 104, 97, 116, 32, 105, 115, 32, 121, 111, 117, 114, 32, 102, 97, 118, 111, 114, 105, 116, 101, 32, 99, 111, 108, 111, 114, 63, 3, 0, 0, 0, 1, 0, 0, 0, 97, 1, 0, 0, 0, 98, 1, 0, 0, 0, 99, 100, 0, 0, 0]
Borsh Rust 代码
#[derive(BorshDeserialize, BorshSerialize, Debug)]
pub struct Poll {
pub id: String,
pub question: String,
pub options: Vec<String>,
pub votes: Vec<u32>,
}
// poll object - with same values as that in JS code above
let p = Poll {
id: "1".to_string(),
question: "What is your favorite color?".to_string(),
options: vec!["a".to_string(), "b".to_string(), "c".to_string()],
votes: vec![100],
};
// serialization
let serialized_data = p.try_to_vec().unwrap(); // this succeeds
//output
[1, 0, 0, 0, 49, 28, 0, 0, 0, 87, 104, 97, 116, 32, 105, 115, 32, 121, 111, 117, 114, 32, 102, 97, 118, 111, 114, 105, 116, 101, 32, 99, 111, 108, 111, 114, 63, 3, 0, 0, 0, 1, 0, 0, 0, 97, 1, 0, 0, 0, 98, 1, 0, 0, 0, 99, 1, 0, 0, 0, 100, 0, 0, 0]
比较两者的输出
- 博尔什 JS
- Borsh Rust
[1, 0, 0, 0, 49, 28, 0, 0, 0, 87, 104, 97, 116, 32, 105, 115, 32, 121, 111, 117, 114, 32, 102, 97, 118, 111, 114, 105, 116, 101, 32, 99, 111, 108, 111, 114, 63, 3, 0, 0, 0, 1, 0, 0, 0, 97, 1, 0, 0, 0, 98, 1, 0, 0, 0, 99, 100, 0, 0, 0]
[1, 0, 0, 0, 49, 28, 0, 0, 0, 87, 104, 97, 116, 32, 105, 115, 32, 121, 111, 117, 114, 32, 102, 97, 118, 111, 114, 105, 116, 101, 32, 99, 111, 108, 111, 114, 63, 3, 0, 0, 0, 1, 0, 0, 0, 97, 1, 0, 0, 0, 98, 1, 0, 0, 0, 99, 1, 0, 0, 0, 100, 0, 0, 0]
rust 序列化输出中有额外的 4 个字节 (1, 0, 0, 0)。
我相信这是因为 Vec<u32>
用于 votes
字段(它适用于 u32
)。但是我无法理解为什么会这样。
任何形式的 help/insights 都表示赞赏。
谢谢!
A Vec<u32>
必须对数据的长度进行编码,因为 Vec
表示可变大小。相反,您在 JS 中将模式设计为 ['u32', 1]
,这是一个长度为 1 的数组,因此它不需要编码长度,因为它是固定大小。
要解决差异,请将架构设置为可变大小数组:['u32']
。或者将 Rust 中的类型更改为 fixed-size 数组:votes: [u32; 1]
.
我正在尝试将 borsh 序列化数据从 JS 发送到 Rust 应用程序。但是,当在 javascript 和 rust 中序列化数据(以比较输出)时,我在 rust 序列化输出中得到了 4 个额外的字节。这是代码:
Borsh JS代码
// class
class Poll {
id: string = '';
question: string = '';
options: string[] = [];
votes: number[] = [];
constructor(fields?: {
id: string;
question: string;
options: string[];
votes: number[];
}) {
if (fields) {
this.id = fields.id;
this.question = fields.question;
this.options = fields.options;
this.votes = fields.votes;
}
}
}
// Schema
const schema: Schema = new Map([
[
Poll,
{
kind: 'struct',
fields: [
['id', 'string'],
['question', 'string'],
['options', ['string']],
['votes', ['u32', 1]],
],
},
],
]);
// class object
const testPoll = new Poll({
id: '1',
question: 'What is your favorite color?',
options: ['a', 'b', 'c'],
votes: [100],
});
//object serialization
let serializedPoll: Uint8Array = new Uint8Array();
serializedPoll = serialize(schema, testPoll); // this succeeds
// output
[1, 0, 0, 0, 49, 28, 0, 0, 0, 87, 104, 97, 116, 32, 105, 115, 32, 121, 111, 117, 114, 32, 102, 97, 118, 111, 114, 105, 116, 101, 32, 99, 111, 108, 111, 114, 63, 3, 0, 0, 0, 1, 0, 0, 0, 97, 1, 0, 0, 0, 98, 1, 0, 0, 0, 99, 100, 0, 0, 0]
Borsh Rust 代码
#[derive(BorshDeserialize, BorshSerialize, Debug)]
pub struct Poll {
pub id: String,
pub question: String,
pub options: Vec<String>,
pub votes: Vec<u32>,
}
// poll object - with same values as that in JS code above
let p = Poll {
id: "1".to_string(),
question: "What is your favorite color?".to_string(),
options: vec!["a".to_string(), "b".to_string(), "c".to_string()],
votes: vec![100],
};
// serialization
let serialized_data = p.try_to_vec().unwrap(); // this succeeds
//output
[1, 0, 0, 0, 49, 28, 0, 0, 0, 87, 104, 97, 116, 32, 105, 115, 32, 121, 111, 117, 114, 32, 102, 97, 118, 111, 114, 105, 116, 101, 32, 99, 111, 108, 111, 114, 63, 3, 0, 0, 0, 1, 0, 0, 0, 97, 1, 0, 0, 0, 98, 1, 0, 0, 0, 99, 1, 0, 0, 0, 100, 0, 0, 0]
比较两者的输出
- 博尔什 JS
- Borsh Rust
[1, 0, 0, 0, 49, 28, 0, 0, 0, 87, 104, 97, 116, 32, 105, 115, 32, 121, 111, 117, 114, 32, 102, 97, 118, 111, 114, 105, 116, 101, 32, 99, 111, 108, 111, 114, 63, 3, 0, 0, 0, 1, 0, 0, 0, 97, 1, 0, 0, 0, 98, 1, 0, 0, 0, 99, 100, 0, 0, 0]
[1, 0, 0, 0, 49, 28, 0, 0, 0, 87, 104, 97, 116, 32, 105, 115, 32, 121, 111, 117, 114, 32, 102, 97, 118, 111, 114, 105, 116, 101, 32, 99, 111, 108, 111, 114, 63, 3, 0, 0, 0, 1, 0, 0, 0, 97, 1, 0, 0, 0, 98, 1, 0, 0, 0, 99, 1, 0, 0, 0, 100, 0, 0, 0]
rust 序列化输出中有额外的 4 个字节 (1, 0, 0, 0)。
我相信这是因为 Vec<u32>
用于 votes
字段(它适用于 u32
)。但是我无法理解为什么会这样。
任何形式的 help/insights 都表示赞赏。
谢谢!
A Vec<u32>
必须对数据的长度进行编码,因为 Vec
表示可变大小。相反,您在 JS 中将模式设计为 ['u32', 1]
,这是一个长度为 1 的数组,因此它不需要编码长度,因为它是固定大小。
要解决差异,请将架构设置为可变大小数组:['u32']
。或者将 Rust 中的类型更改为 fixed-size 数组:votes: [u32; 1]
.