Commit 261bb43b authored by 袁兴强's avatar 袁兴强

add query db

parent a4b37c31
...@@ -25,6 +25,7 @@ func Cmd() *cobra.Command { ...@@ -25,6 +25,7 @@ func Cmd() *cobra.Command {
cmdCreateContract(), cmdCreateContract(),
cmdUpdateContract(), cmdUpdateContract(),
cmdCallContract(), cmdCallContract(),
cmdQueryContract(),
) )
return cmd return cmd
...@@ -82,21 +83,45 @@ func cmdCallContract() *cobra.Command { ...@@ -82,21 +83,45 @@ func cmdCallContract() *cobra.Command {
return cmd return cmd
} }
func checkContract(cmd *cobra.Command, args []string) { func cmdQueryContract() *cobra.Command {
rpcLaddr, _ := cmd.Flags().GetString("rpc_laddr") cmd := &cobra.Command{
name, _ := cmd.Flags().GetString("name") Use: "query",
Short: "query wasm contract",
Args: cobra.MinimumNArgs(1),
}
params := rpctypes.Query4Jrpc{ cmd.AddCommand(
Execer: wasmtypes.WasmX, cmdQueryStateDB(),
FuncName: "Check", cmdQueryLocalDB(),
Payload: types.MustPBToJSON(&wasmtypes.QueryCheckContract{ )
Name: name,
}), return cmd
}
func cmdQueryStateDB() *cobra.Command {
cmd := &cobra.Command{
Use: "state",
Short: "query kv in state db",
Run: queryStateDB,
} }
cmd.Flags().StringP("contract", "n", "", "contract name")
cmd.Flags().StringP("key", "k", "", "key of state db")
_ = cmd.MarkFlagRequired("contract")
_ = cmd.MarkFlagRequired("key")
return cmd
}
var resp types.Reply func cmdQueryLocalDB() *cobra.Command {
ctx := jsonclient.NewRPCCtx(rpcLaddr, "Chain33.Query", params, &resp) cmd := &cobra.Command{
ctx.Run() Use: "local",
Short: "query kv in local db",
Run: queryLocalDB,
}
cmd.Flags().StringP("contract", "n", "", "contract name")
cmd.Flags().StringP("key", "k", "", "key of local db")
_ = cmd.MarkFlagRequired("contract")
_ = cmd.MarkFlagRequired("key")
return cmd
} }
func createContract(cmd *cobra.Command, args []string) { func createContract(cmd *cobra.Command, args []string) {
...@@ -174,3 +199,58 @@ func callContract(cmd *cobra.Command, args []string) { ...@@ -174,3 +199,58 @@ func callContract(cmd *cobra.Command, args []string) {
ctx := jsonclient.NewRPCCtx(rpcLaddr, "Chain33.CreateTransaction", params, nil) ctx := jsonclient.NewRPCCtx(rpcLaddr, "Chain33.CreateTransaction", params, nil)
ctx.RunWithoutMarshal() ctx.RunWithoutMarshal()
} }
func checkContract(cmd *cobra.Command, args []string) {
rpcLaddr, _ := cmd.Flags().GetString("rpc_laddr")
name, _ := cmd.Flags().GetString("name")
params := rpctypes.Query4Jrpc{
Execer: wasmtypes.WasmX,
FuncName: "Check",
Payload: types.MustPBToJSON(&wasmtypes.QueryCheckContract{
Name: name,
}),
}
var resp types.Reply
ctx := jsonclient.NewRPCCtx(rpcLaddr, "Chain33.Query", params, &resp)
ctx.Run()
}
func queryStateDB(cmd *cobra.Command, args []string) {
rpcLaddr, _ := cmd.Flags().GetString("rpc_laddr")
contract, _ := cmd.Flags().GetString("contract")
key, _ := cmd.Flags().GetString("key")
params := rpctypes.Query4Jrpc{
Execer: wasmtypes.WasmX,
FuncName: "QueryStateDB",
Payload: types.MustPBToJSON(&wasmtypes.QueryContractDB{
Contract: contract,
Key: key,
}),
}
var resp types.ReplyString
ctx := jsonclient.NewRPCCtx(rpcLaddr, "Chain33.Query", params, &resp)
ctx.Run()
}
func queryLocalDB(cmd *cobra.Command, args []string) {
rpcLaddr, _ := cmd.Flags().GetString("rpc_laddr")
contract, _ := cmd.Flags().GetString("contract")
key, _ := cmd.Flags().GetString("key")
params := rpctypes.Query4Jrpc{
Execer: wasmtypes.WasmX,
FuncName: "QueryLocalDB",
Payload: types.MustPBToJSON(&wasmtypes.QueryContractDB{
Contract: contract,
Key: key,
}),
}
var resp types.ReplyString
ctx := jsonclient.NewRPCCtx(rpcLaddr, "Chain33.Query", params, &resp)
ctx.Run()
}
...@@ -32,11 +32,3 @@ func calcLocalPrefix(contract string) []byte { ...@@ -32,11 +32,3 @@ func calcLocalPrefix(contract string) []byte {
prefix = append(prefix, '-') prefix = append(prefix, '-')
return prefix return prefix
} }
func (w *Wasm) contractExist(name string) bool {
_, err := w.GetStateDB().Get(contractKey(name))
if err != nil && err != types.ErrNotFound {
panic(err)
}
return err == nil
}
...@@ -9,5 +9,36 @@ func (w *Wasm) Query_Check(query *types2.QueryCheckContract) (types.Message, err ...@@ -9,5 +9,36 @@ func (w *Wasm) Query_Check(query *types2.QueryCheckContract) (types.Message, err
if query == nil { if query == nil {
return nil, types.ErrInvalidParam return nil, types.ErrInvalidParam
} }
return &types.Reply{IsOk: w.contractExist(query.Name)}, nil _, err := w.GetStateDB().Get(contractKey(query.Name))
if err == nil {
return &types.Reply{IsOk: true}, nil
}
if err == types.ErrNotFound {
return &types.Reply{}, nil
}
return nil, err
}
func (w *Wasm) Query_QueryStateDB(query *types2.QueryContractDB) (types.Message, error) {
if query == nil {
return nil, types.ErrInvalidParam
}
key := append(calcStatePrefix(query.Contract), query.Key...)
v, err := w.GetStateDB().Get(key)
if err != nil {
return nil, err
}
return &types.ReplyString{Data: string(v)}, nil
}
func (w *Wasm) Query_QueryLocalDB(query *types2.QueryContractDB) (types.Message, error) {
if query == nil {
return nil, types.ErrInvalidParam
}
key := append(calcLocalPrefix(query.Contract), query.Key...)
v, err := w.GetLocalDB().Get(key)
if err != nil {
return nil, err
}
return &types.ReplyString{Data: string(v)}, nil
} }
...@@ -32,6 +32,11 @@ message queryCheckContract { ...@@ -32,6 +32,11 @@ message queryCheckContract {
string name = 1; string name = 1;
} }
message queryContractDB {
string contract = 1;
string key = 2;
}
message customLog { message customLog {
repeated string info = 1; repeated string info = 1;
} }
......
...@@ -319,6 +319,53 @@ func (m *QueryCheckContract) GetName() string { ...@@ -319,6 +319,53 @@ func (m *QueryCheckContract) GetName() string {
return "" return ""
} }
type QueryContractDB struct {
Contract string `protobuf:"bytes,1,opt,name=contract,proto3" json:"contract,omitempty"`
Key string `protobuf:"bytes,2,opt,name=key,proto3" json:"key,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *QueryContractDB) Reset() { *m = QueryContractDB{} }
func (m *QueryContractDB) String() string { return proto.CompactTextString(m) }
func (*QueryContractDB) ProtoMessage() {}
func (*QueryContractDB) Descriptor() ([]byte, []int) {
return fileDescriptor_7d78909ad64e3bbb, []int{5}
}
func (m *QueryContractDB) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_QueryContractDB.Unmarshal(m, b)
}
func (m *QueryContractDB) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_QueryContractDB.Marshal(b, m, deterministic)
}
func (m *QueryContractDB) XXX_Merge(src proto.Message) {
xxx_messageInfo_QueryContractDB.Merge(m, src)
}
func (m *QueryContractDB) XXX_Size() int {
return xxx_messageInfo_QueryContractDB.Size(m)
}
func (m *QueryContractDB) XXX_DiscardUnknown() {
xxx_messageInfo_QueryContractDB.DiscardUnknown(m)
}
var xxx_messageInfo_QueryContractDB proto.InternalMessageInfo
func (m *QueryContractDB) GetContract() string {
if m != nil {
return m.Contract
}
return ""
}
func (m *QueryContractDB) GetKey() string {
if m != nil {
return m.Key
}
return ""
}
type CustomLog struct { type CustomLog struct {
Info []string `protobuf:"bytes,1,rep,name=info,proto3" json:"info,omitempty"` Info []string `protobuf:"bytes,1,rep,name=info,proto3" json:"info,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_NoUnkeyedLiteral struct{} `json:"-"`
...@@ -330,7 +377,7 @@ func (m *CustomLog) Reset() { *m = CustomLog{} } ...@@ -330,7 +377,7 @@ func (m *CustomLog) Reset() { *m = CustomLog{} }
func (m *CustomLog) String() string { return proto.CompactTextString(m) } func (m *CustomLog) String() string { return proto.CompactTextString(m) }
func (*CustomLog) ProtoMessage() {} func (*CustomLog) ProtoMessage() {}
func (*CustomLog) Descriptor() ([]byte, []int) { func (*CustomLog) Descriptor() ([]byte, []int) {
return fileDescriptor_7d78909ad64e3bbb, []int{5} return fileDescriptor_7d78909ad64e3bbb, []int{6}
} }
func (m *CustomLog) XXX_Unmarshal(b []byte) error { func (m *CustomLog) XXX_Unmarshal(b []byte) error {
...@@ -370,7 +417,7 @@ func (m *CreateContractLog) Reset() { *m = CreateContractLog{} } ...@@ -370,7 +417,7 @@ func (m *CreateContractLog) Reset() { *m = CreateContractLog{} }
func (m *CreateContractLog) String() string { return proto.CompactTextString(m) } func (m *CreateContractLog) String() string { return proto.CompactTextString(m) }
func (*CreateContractLog) ProtoMessage() {} func (*CreateContractLog) ProtoMessage() {}
func (*CreateContractLog) Descriptor() ([]byte, []int) { func (*CreateContractLog) Descriptor() ([]byte, []int) {
return fileDescriptor_7d78909ad64e3bbb, []int{6} return fileDescriptor_7d78909ad64e3bbb, []int{7}
} }
func (m *CreateContractLog) XXX_Unmarshal(b []byte) error { func (m *CreateContractLog) XXX_Unmarshal(b []byte) error {
...@@ -417,7 +464,7 @@ func (m *UpdateContractLog) Reset() { *m = UpdateContractLog{} } ...@@ -417,7 +464,7 @@ func (m *UpdateContractLog) Reset() { *m = UpdateContractLog{} }
func (m *UpdateContractLog) String() string { return proto.CompactTextString(m) } func (m *UpdateContractLog) String() string { return proto.CompactTextString(m) }
func (*UpdateContractLog) ProtoMessage() {} func (*UpdateContractLog) ProtoMessage() {}
func (*UpdateContractLog) Descriptor() ([]byte, []int) { func (*UpdateContractLog) Descriptor() ([]byte, []int) {
return fileDescriptor_7d78909ad64e3bbb, []int{7} return fileDescriptor_7d78909ad64e3bbb, []int{8}
} }
func (m *UpdateContractLog) XXX_Unmarshal(b []byte) error { func (m *UpdateContractLog) XXX_Unmarshal(b []byte) error {
...@@ -465,7 +512,7 @@ func (m *CallContractLog) Reset() { *m = CallContractLog{} } ...@@ -465,7 +512,7 @@ func (m *CallContractLog) Reset() { *m = CallContractLog{} }
func (m *CallContractLog) String() string { return proto.CompactTextString(m) } func (m *CallContractLog) String() string { return proto.CompactTextString(m) }
func (*CallContractLog) ProtoMessage() {} func (*CallContractLog) ProtoMessage() {}
func (*CallContractLog) Descriptor() ([]byte, []int) { func (*CallContractLog) Descriptor() ([]byte, []int) {
return fileDescriptor_7d78909ad64e3bbb, []int{8} return fileDescriptor_7d78909ad64e3bbb, []int{9}
} }
func (m *CallContractLog) XXX_Unmarshal(b []byte) error { func (m *CallContractLog) XXX_Unmarshal(b []byte) error {
...@@ -519,7 +566,7 @@ func (m *LocalDataLog) Reset() { *m = LocalDataLog{} } ...@@ -519,7 +566,7 @@ func (m *LocalDataLog) Reset() { *m = LocalDataLog{} }
func (m *LocalDataLog) String() string { return proto.CompactTextString(m) } func (m *LocalDataLog) String() string { return proto.CompactTextString(m) }
func (*LocalDataLog) ProtoMessage() {} func (*LocalDataLog) ProtoMessage() {}
func (*LocalDataLog) Descriptor() ([]byte, []int) { func (*LocalDataLog) Descriptor() ([]byte, []int) {
return fileDescriptor_7d78909ad64e3bbb, []int{9} return fileDescriptor_7d78909ad64e3bbb, []int{10}
} }
func (m *LocalDataLog) XXX_Unmarshal(b []byte) error { func (m *LocalDataLog) XXX_Unmarshal(b []byte) error {
...@@ -560,6 +607,7 @@ func init() { ...@@ -560,6 +607,7 @@ func init() {
proto.RegisterType((*WasmUpdate)(nil), "types.wasmUpdate") proto.RegisterType((*WasmUpdate)(nil), "types.wasmUpdate")
proto.RegisterType((*WasmCall)(nil), "types.wasmCall") proto.RegisterType((*WasmCall)(nil), "types.wasmCall")
proto.RegisterType((*QueryCheckContract)(nil), "types.queryCheckContract") proto.RegisterType((*QueryCheckContract)(nil), "types.queryCheckContract")
proto.RegisterType((*QueryContractDB)(nil), "types.queryContractDB")
proto.RegisterType((*CustomLog)(nil), "types.customLog") proto.RegisterType((*CustomLog)(nil), "types.customLog")
proto.RegisterType((*CreateContractLog)(nil), "types.createContractLog") proto.RegisterType((*CreateContractLog)(nil), "types.createContractLog")
proto.RegisterType((*UpdateContractLog)(nil), "types.updateContractLog") proto.RegisterType((*UpdateContractLog)(nil), "types.updateContractLog")
...@@ -570,29 +618,30 @@ func init() { ...@@ -570,29 +618,30 @@ func init() {
func init() { proto.RegisterFile("wasm.proto", fileDescriptor_7d78909ad64e3bbb) } func init() { proto.RegisterFile("wasm.proto", fileDescriptor_7d78909ad64e3bbb) }
var fileDescriptor_7d78909ad64e3bbb = []byte{ var fileDescriptor_7d78909ad64e3bbb = []byte{
// 370 bytes of a gzipped FileDescriptorProto // 388 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x9c, 0x92, 0x4d, 0x4b, 0xfb, 0x40, 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x9c, 0x93, 0x4d, 0x4b, 0xf3, 0x40,
0x10, 0xc6, 0x9b, 0xe6, 0xe5, 0xdf, 0xcc, 0xbf, 0xd8, 0x76, 0x91, 0x12, 0x3c, 0x68, 0x08, 0x08, 0x14, 0x85, 0x9b, 0xe6, 0xe3, 0x6d, 0xee, 0x5b, 0x6c, 0x3b, 0x48, 0x09, 0x2e, 0x34, 0x04, 0x84,
0x01, 0xa1, 0x07, 0x15, 0x2f, 0x3d, 0x69, 0x3d, 0xf4, 0xe0, 0x69, 0xc1, 0xa3, 0x87, 0x75, 0xbb, 0x80, 0xd0, 0x85, 0x8a, 0x9b, 0x2e, 0xc4, 0xb6, 0x8b, 0x2e, 0x5c, 0x0d, 0xb8, 0x74, 0x31, 0x4e,
0xda, 0xd2, 0x4d, 0x36, 0x6e, 0x36, 0x95, 0x7c, 0x21, 0x3f, 0xa7, 0xec, 0x4b, 0xa4, 0xa0, 0x88, 0x47, 0x5b, 0x3a, 0xc9, 0xc4, 0x64, 0x52, 0xc9, 0x1f, 0xf2, 0x77, 0xca, 0x7c, 0x44, 0x0a, 0x4a,
0xf4, 0x36, 0xb3, 0xf3, 0x7b, 0x1e, 0x9e, 0x64, 0x06, 0xe0, 0x9d, 0xd4, 0xc5, 0xac, 0x92, 0x42, 0x91, 0xee, 0xce, 0x9d, 0x79, 0xce, 0xe4, 0x70, 0xef, 0x0d, 0xc0, 0x07, 0xa9, 0xb2, 0x49, 0x51,
0x09, 0x14, 0xaa, 0xb6, 0x62, 0x75, 0xf6, 0xe1, 0xd9, 0xd7, 0x5b, 0xaa, 0x36, 0xa2, 0x44, 0x17, 0x0a, 0x29, 0x90, 0x2f, 0x9b, 0x82, 0x55, 0xc9, 0xa7, 0x63, 0x4e, 0x1f, 0xa8, 0xdc, 0x88, 0x1c,
0x10, 0x51, 0xc9, 0x88, 0x62, 0x89, 0x97, 0x7a, 0xf9, 0xff, 0xcb, 0xc9, 0xcc, 0x60, 0x33, 0x8d, 0x5d, 0x41, 0x40, 0x4b, 0x46, 0x24, 0x8b, 0x9c, 0xd8, 0x49, 0xff, 0x5f, 0x8f, 0x26, 0x1a, 0x9b,
0x2c, 0xcc, 0x60, 0xd9, 0xc3, 0x0e, 0xd1, 0x70, 0x53, 0xad, 0x34, 0xdc, 0xff, 0x06, 0x3f, 0x9a, 0x28, 0x64, 0xae, 0x2f, 0x96, 0x1d, 0x6c, 0x11, 0x05, 0xd7, 0xc5, 0x4a, 0xc1, 0xdd, 0x1f, 0xf0,
0x81, 0x86, 0x2d, 0x82, 0xce, 0x21, 0xa0, 0x84, 0xf3, 0xc4, 0x37, 0xe8, 0x68, 0xdf, 0x97, 0x70, 0x93, 0xbe, 0x50, 0xb0, 0x41, 0xd0, 0x25, 0x78, 0x94, 0x70, 0x1e, 0xb9, 0x1a, 0x1d, 0xec, 0xbf,
0xbe, 0xec, 0x61, 0x33, 0x46, 0x47, 0xd0, 0x57, 0x6d, 0x12, 0xa4, 0x5e, 0x1e, 0xe2, 0xbe, 0x6a, 0x4b, 0x38, 0x5f, 0x76, 0xb0, 0xbe, 0x46, 0x27, 0xd0, 0x95, 0x4d, 0xe4, 0xc5, 0x4e, 0xea, 0xe3,
0xef, 0xfe, 0x41, 0xb8, 0x23, 0xbc, 0x61, 0xd9, 0xb5, 0xcd, 0x69, 0x43, 0x20, 0x04, 0x41, 0x49, 0xae, 0x6c, 0x66, 0xff, 0xc0, 0xdf, 0x11, 0x5e, 0xb3, 0xe4, 0xd6, 0xe4, 0x34, 0x21, 0x10, 0x02,
0x0a, 0x9b, 0x32, 0xc6, 0xa6, 0xd6, 0x6f, 0x54, 0xac, 0x6c, 0x98, 0x21, 0x36, 0x75, 0xa7, 0xb2, 0x2f, 0x27, 0x99, 0x49, 0x19, 0x62, 0xad, 0xd5, 0x19, 0x15, 0x2b, 0x13, 0xa6, 0x8f, 0xb5, 0x6e,
0x69, 0xfe, 0xac, 0xaa, 0x60, 0xd0, 0x05, 0x43, 0x27, 0x30, 0xa0, 0xa2, 0x54, 0x92, 0x50, 0xe5, 0x5d, 0x26, 0xcd, 0x9f, 0x5d, 0x05, 0xf4, 0xda, 0x60, 0xe8, 0x0c, 0x7a, 0x54, 0xe4, 0xb2, 0x24,
0x74, 0x5f, 0x3d, 0x9a, 0x42, 0x54, 0x30, 0xb5, 0x16, 0x2b, 0xa3, 0x8e, 0xb1, 0xeb, 0xd0, 0x29, 0x54, 0x5a, 0xdf, 0x77, 0x8d, 0xc6, 0x10, 0x64, 0x4c, 0xae, 0xc5, 0x4a, 0xbb, 0x43, 0x6c, 0x2b,
0x40, 0x45, 0x24, 0x29, 0x98, 0x62, 0xb2, 0x4e, 0xfc, 0xd4, 0xcf, 0x7d, 0xbc, 0xf7, 0x82, 0xc6, 0x74, 0x0e, 0x50, 0x90, 0x92, 0x64, 0x4c, 0xb2, 0xb2, 0x8a, 0xdc, 0xd8, 0x4d, 0x5d, 0xbc, 0x77,
0xe0, 0xb3, 0x72, 0x97, 0x04, 0xa9, 0x9f, 0xc7, 0x58, 0x97, 0x59, 0x0e, 0xe8, 0xad, 0x61, 0xb2, 0x82, 0x86, 0xe0, 0xb2, 0x7c, 0x17, 0x79, 0xb1, 0x9b, 0x86, 0x58, 0xc9, 0x24, 0x05, 0xf4, 0x5e,
0x5d, 0xac, 0x19, 0xdd, 0x2e, 0x3a, 0xff, 0x1f, 0xf2, 0x66, 0x67, 0x10, 0xd3, 0xa6, 0x56, 0xa2, 0xb3, 0xb2, 0x99, 0xaf, 0x19, 0xdd, 0xce, 0xdb, 0xf7, 0x7f, 0xc9, 0x9b, 0xdc, 0xc3, 0xc0, 0x90,
0x78, 0x10, 0xaf, 0x1a, 0xd8, 0x94, 0x2f, 0x22, 0xf1, 0x8c, 0x93, 0xa9, 0xb3, 0x39, 0x4c, 0xec, 0x16, 0x5a, 0xcc, 0x0e, 0x46, 0x1c, 0x82, 0xbb, 0x65, 0x8d, 0xcd, 0xa7, 0x64, 0x72, 0x01, 0x21,
0x7e, 0x3a, 0x1b, 0x07, 0xfe, 0xfa, 0xe5, 0xb1, 0xfb, 0xf2, 0x39, 0x4c, 0xec, 0xbe, 0x0e, 0x11, 0xad, 0x2b, 0x29, 0xb2, 0x47, 0xf1, 0xa6, 0xbe, 0xb0, 0xc9, 0x5f, 0x45, 0xe4, 0xe8, 0x28, 0x5a,
0x3f, 0xc1, 0x48, 0xef, 0x70, 0x5f, 0x7a, 0xc8, 0xdf, 0x9b, 0x42, 0x24, 0x59, 0xdd, 0x70, 0x65, 0x27, 0x53, 0x18, 0x99, 0x01, 0xb7, 0x9f, 0xb0, 0xe0, 0xc1, 0xd6, 0x85, 0xb6, 0x75, 0x53, 0x18,
0x6e, 0x25, 0xc4, 0xae, 0xcb, 0x6e, 0x60, 0xc8, 0x05, 0x25, 0xfc, 0x9e, 0x28, 0xa2, 0xbd, 0xc7, 0x99, 0x81, 0x1f, 0x63, 0x7e, 0x86, 0x81, 0x5a, 0x82, 0x7d, 0xeb, 0x31, 0xed, 0x1f, 0x43, 0x50,
0xe0, 0x6f, 0x59, 0x6b, 0x6c, 0x87, 0x58, 0x97, 0xe8, 0xd8, 0x1d, 0x8b, 0x5b, 0xa6, 0x6d, 0x9e, 0xb2, 0xaa, 0xe6, 0x52, 0x2f, 0x9b, 0x8f, 0x6d, 0x95, 0xdc, 0x41, 0x9f, 0x0b, 0x4a, 0xf8, 0x82,
0x23, 0x73, 0xf0, 0x57, 0x9f, 0x01, 0x00, 0x00, 0xff, 0xff, 0x8e, 0x95, 0x09, 0x33, 0xfe, 0x02, 0x48, 0xa2, 0xde, 0xb6, 0xbd, 0x71, 0xf4, 0xe4, 0x95, 0x44, 0xa7, 0x76, 0xdb, 0xec, 0x36, 0x98,
0x00, 0x00, 0xe2, 0x25, 0xd0, 0x7f, 0xcc, 0xcd, 0x57, 0x00, 0x00, 0x00, 0xff, 0xff, 0xf2, 0xc4, 0xdc, 0xc3,
0x3f, 0x03, 0x00, 0x00,
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment