Blockchain 在承印物和油墨中使用“u8”的问题

Blockchain 在承印物和油墨中使用“u8”的问题,blockchain,substrate,parity-io,rust-ink,Blockchain,Substrate,Parity Io,Rust Ink,我正在尝试向我的底层运行时模块添加一个简单的u8: decl\u存储!{ 模块的特征存储为TemplateModule{ MyByte:u8; } } 但是,我得到一个编译器错误,它没有实现奇偶校验编解码器的编码或解码: error[E0277]: the trait bound `u8: _IMPL_DECODE_FOR_Event::_parity_codec::Encode` is not satisfied --> /Users/shawntabrizi/Documents/

我正在尝试向我的底层运行时模块添加一个简单的
u8

decl\u存储!{
模块的特征存储为TemplateModule{
MyByte:u8;
}
}
但是,我得到一个编译器错误,它没有实现奇偶校验编解码器的
编码
解码

error[E0277]: the trait bound `u8: _IMPL_DECODE_FOR_Event::_parity_codec::Encode` is not satisfied
  --> /Users/shawntabrizi/Documents/GitHub/substrate-package/substrate-node-template/runtime/src/template.rs:23:1
   |
23 | / decl_storage! {
24 | |     trait Store for Module<T: Trait> as TemplateModule {
25 | |         MyByte: u8;
26 | |     }
27 | | }
   | |_^ the trait `_IMPL_DECODE_FOR_Event::_parity_codec::Encode` is not implemented for `u8`
错误:

error[E0277]: the trait bound `u8: parity_codec::codec::Encode` is not satisfied
  --> src/lib.rs:26:1
   |
26 | / contract! {
27 | |     struct MyContract {
28 | |         value: storage::Value<u8>,
29 | |     }
...  |
49 | |     }
50 | | }
   | |_^ the trait `parity_codec::codec::Encode` is not implemented for `u8`
error[E0277]:未满足特性绑定`u8:parity_codec::codec::Encode`的要求
-->src/lib.rs:26:1
|
26 |/合同!{
27 | |结构我合同{
28 | |值:存储::值,
29 | |     }
...  |
49 | |     }
50 | | }
|| ^未为`u8实现特性`parity`u codec::codec::Encode``

为什么会这样?我能做些什么来解决这个问题?

今天,由于避免类型冲突,
Vec
Vec
中的一个特例,因此
parity\u codec
不支持
u8
的编码

见:

gavofyork:

因为它会导致两种编码:
Vec
Vec
冲突

这可能在将来通过附加的Rust功能得到修复,但现在,您需要将单个字节存储为
[u8;1]
并使用该类型


基板运行模块 基板运行时模块的一个黑客解决方案如下所示:

使用支持:{decl_模块,decl_存储,decl_事件,StorageValue,dispatch::Result};
使用系统::确保签名;
发布特性:系统::特性{
类型事件:从+到;
}
U8型=[U8;1];
decl_仓库!{
模块的特征存储为TemplateModule{
MyByte get(my_byte):U8;
}
}
decl_模块!{
用于枚举调用的发布结构模块,其中origin:T::origin{
fn存款事件()=默认值;
pub fn set_my_字节(原点,输入:U8)->结果{
让谁来确保签名(原产地)?;
::输入;
Self::deposit_事件(RawEvent::mybytestor(输入,who));
好(())
}
pub fn向字节添加字节(原点,输入:U8)->结果{
让谁来确保签名(原产地)?;
让my_byte=Self::my_byte()[0];
让my_new_byte=my_byte.checked_add(输入[0])。ok_或(“溢出”)?;
::put([my_new_byte]);
Self::deposit_事件(RawEvent::MyByTestOrder([my_new_byte],who));
好(())
}
}
}
十二月事件!(
发布枚举事件,其中AccountId=::AccountId{
MyByTestOrder(U8,帐户ID),
}
);
其中,我们分配了一个新类型
类型U8=[U8;1]。新类型名称的选择很重要,因为它会欺骗Polkadt UI,使其将该值简单地视为其生成的任何输入/输出字段的
u8
。如果您尝试使用自定义类型,如
type Byte=[u8;1]
,则UI将要求您导入该自定义类型的定义。如果您试图直接使用
[u8;1]
,Polkadt UI将不知道如何呈现该值的输入/输出

此外,在撰写本文时,
declu事件宏直接存放
[u8;1]
时出现问题

请注意,在使用该类型时,需要将其视为数组<代码>添加到字节()
显示了一个例子。因此,最终需要提取数组的第一项以提取字节,并且需要将字节包装在数组中以设置
U8

let my_byte = Self::my_byte()[0];
...
<MyByte<T>>::put([my_new_byte]);
让my_byte=Self::my_byte()[0];
...
::put([my_new_byte]);
其他解决方案可能涉及使用本机支持的其他类型,如
Vec
u16
,并在运行时进行适当的检查,确保将其视为单个
u8
,但用户界面对此并不清楚


智能合约 我还没有找到一个很好的
墨水解决方案,但您应该能够在所有代码中直接使用
[u8;1]
。同样,您需要将其视为getter和setter的数组。但在生成ABI时,您需要手动将
[u8;1]
的实例更改为
u8
,以诱使UI执行您想要的操作

let my_byte = Self::my_byte()[0];
...
<MyByte<T>>::put([my_new_byte]);