Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
YottaChain
YTBP
提交
f45f2664
Y
YTBP
项目概览
YottaChain
/
YTBP
通知
0
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
Y
YTBP
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
f45f2664
编写于
2月 09, 2018
作者:
D
Daniel Larimer
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
remove eosio::string and vector, switch to std
上级
fa95e965
变更
12
隐藏空白更改
内联
并排
Showing
12 changed file
with
34 addition
and
514 deletion
+34
-514
contracts/eosiolib/datastream.hpp
contracts/eosiolib/datastream.hpp
+19
-0
contracts/eosiolib/generic_currency.hpp
contracts/eosiolib/generic_currency.hpp
+3
-2
contracts/eosiolib/reflect.hpp
contracts/eosiolib/reflect.hpp
+0
-1
contracts/eosiolib/string.hpp
contracts/eosiolib/string.hpp
+0
-346
contracts/eosiolib/transaction.hpp
contracts/eosiolib/transaction.hpp
+0
-1
contracts/eosiolib/utility.hpp
contracts/eosiolib/utility.hpp
+0
-12
contracts/eosiolib/vector.hpp
contracts/eosiolib/vector.hpp
+3
-140
contracts/identity/identity.hpp
contracts/identity/identity.hpp
+3
-4
contracts/identity/test/identity_test.cpp
contracts/identity/test/identity_test.cpp
+2
-2
contracts/noop/noop.hpp
contracts/noop/noop.hpp
+3
-3
contracts/stltest/stltest.cpp
contracts/stltest/stltest.cpp
+0
-1
contracts/test.system/test.system.cpp
contracts/test.system/test.system.cpp
+1
-2
未找到文件。
contracts/eosiolib/datastream.hpp
浏览文件 @
f45f2664
...
...
@@ -7,6 +7,7 @@
#include <eosiolib/memory.h>
#include <eosiolib/vector.hpp>
#include <eosiolib/varint.hpp>
#include <string>
namespace
eosio
{
...
...
@@ -383,6 +384,24 @@ inline datastream<Stream>& operator>>(datastream<Stream>& ds, uint8_t& d) {
return
ds
;
}
template
<
typename
DataStream
>
DataStream
&
operator
<<
(
DataStream
&
ds
,
const
std
::
string
&
v
)
{
ds
<<
unsigned_int
(
v
.
size
()
);
for
(
const
auto
&
i
:
v
)
ds
<<
i
;
return
ds
;
}
template
<
typename
DataStream
>
DataStream
&
operator
>>
(
DataStream
&
ds
,
std
::
string
&
v
)
{
unsigned_int
s
;
ds
>>
s
;
v
.
resize
(
s
.
value
);
for
(
auto
&
i
:
v
)
ds
>>
i
;
return
ds
;
}
template
<
typename
DataStream
,
typename
T
>
DataStream
&
operator
<<
(
DataStream
&
ds
,
const
vector
<
T
>&
v
)
{
ds
<<
unsigned_int
(
v
.
size
()
);
...
...
contracts/eosiolib/generic_currency.hpp
浏览文件 @
f45f2664
...
...
@@ -5,9 +5,10 @@
#include <eosiolib/dispatcher.hpp>
#include <eosiolib/serialize.hpp>
#include <eosiolib/action.hpp>
#include <
eosiolib/string.hpp
>
#include <
string
>
namespace
eosio
{
using
std
::
string
;
template
<
typename
Token
>
class
generic_currency
{
...
...
@@ -49,7 +50,7 @@ namespace eosio {
struct
transfer_memo
:
public
transfer
{
transfer_memo
(){}
transfer_memo
(
account_name
f
,
account_name
t
,
token_type
q
,
string
m
)
:
transfer
(
f
,
t
,
q
),
memo
(
move
(
m
)
){}
:
transfer
(
f
,
t
,
q
),
memo
(
std
::
move
(
m
)
){}
string
memo
;
...
...
contracts/eosiolib/reflect.hpp
浏览文件 @
f45f2664
#pragma once
#include <eosiolib/utility.hpp>
#include <eosiolib/preprocessor/seq/for_each.hpp>
#include <eosiolib/preprocessor/seq/enum.hpp>
#include <eosiolib/preprocessor/seq/size.hpp>
...
...
contracts/eosiolib/string.hpp
已删除
100644 → 0
浏览文件 @
fa95e965
#pragma once
#include <eosiolib/string.h>
#include <eosiolib/types.hpp>
#include <eosiolib/system.h>
#include <eosiolib/memory.hpp>
#include <eosiolib/print.hpp>
#include <eosiolib/varint.hpp>
namespace
eosio
{
/**
* @brief Count the length of null terminated string (excluding the null terminated symbol)
* Non-null terminated string need to be passed here,
* Otherwise it will not give the right length
* @param cstr - null terminated string
*/
inline
size_t
cstrlen
(
const
char
*
cstr
)
{
size_t
len
=
0
;
while
(
*
cstr
!=
'\0'
)
{
len
++
;
cstr
++
;
}
return
len
;
}
class
string
{
private:
size_t
size
=
0
;
// size of the string
char
*
data
=
nullptr
;
// underlying data
bool
own_memory
=
false
;
// true if the object is responsible to clean the memory
uint32_t
*
refcount
=
nullptr
;
// shared reference count to the underlying data
// Release data if no more string reference to it
void
release_data_if_needed
()
{
if
(
own_memory
&&
refcount
!=
nullptr
)
{
(
*
refcount
)
--
;
if
(
*
refcount
==
0
)
{
free
(
data
);
}
}
}
public:
/**
* Default constructor
*/
string
()
:
size
(
0
),
data
(
nullptr
),
own_memory
(
false
),
refcount
(
nullptr
)
{
}
/**
* Constructor to create string with reserved space
* @param s size to be reserved (in number o)
*/
string
(
size_t
s
)
:
size
(
s
)
{
if
(
s
==
0
)
{
data
=
nullptr
;
own_memory
=
false
;
refcount
=
nullptr
;
}
else
{
data
=
(
char
*
)
malloc
(
s
*
sizeof
(
char
));
own_memory
=
true
;
refcount
=
(
uint32_t
*
)
malloc
(
sizeof
(
uint32_t
));
*
refcount
=
1
;
}
}
/**
* Constructor to create string with given data and size
* @param d data
* @param s size of the string (in number of bytes)
* @param copy true to have the data copied and owned by the object
*/
string
(
char
*
d
,
size_t
s
,
bool
copy
)
{
assign
(
d
,
s
,
copy
);
}
// Copy constructor
string
(
const
string
&
obj
)
{
if
(
this
!=
&
obj
)
{
data
=
obj
.
data
;
size
=
obj
.
size
;
own_memory
=
obj
.
own_memory
;
refcount
=
obj
.
refcount
;
if
(
refcount
!=
nullptr
)
(
*
refcount
)
++
;
}
}
/**
* @brief Constructor for string literal
* Non-null terminated string need to be passed here,
* Otherwise it will have extraneous data
* @param cstr - null terminated string
*/
string
(
const
char
*
cstr
)
{
size
=
cstrlen
(
cstr
)
+
1
;
data
=
(
char
*
)
malloc
(
size
*
sizeof
(
char
));
memcpy
(
data
,
cstr
,
size
*
sizeof
(
char
));
own_memory
=
true
;
refcount
=
(
uint32_t
*
)
malloc
(
sizeof
(
uint32_t
));
*
refcount
=
1
;
}
// Destructor
~
string
()
{
release_data_if_needed
();
}
void
resize
(
size_t
newsize
)
{
if
(
newsize
==
0
)
{
release_data_if_needed
();
refcount
=
nullptr
;
own_memory
=
true
;
data
=
nullptr
;
size
=
0
;
}
else
if
(
newsize
<
size
)
{
size
=
newsize
;
data
[
newsize
]
=
0
;
}
else
if
(
newsize
>
size
)
{
char
*
newbuf
=
(
char
*
)
malloc
(
newsize
);
memcpy
(
newbuf
,
data
,
size
);
release_data_if_needed
();
size
=
newsize
;
data
=
newbuf
;
own_memory
=
true
;
refcount
=
nullptr
;
}
}
// Get size of the string (in number of bytes)
const
size_t
get_size
()
const
{
return
size
;
}
// Get the underlying data of the string
const
char
*
get_data
()
const
{
return
data
;
}
char
*
get_data
()
{
return
data
;
}
// Check if it owns memory
const
bool
is_own_memory
()
const
{
return
own_memory
;
}
// Get the ref count
const
uint32_t
get_refcount
()
const
{
return
*
refcount
;
}
/**
* Assign string with new data and size
* @param d data
* @param s size (in number of bytes)
* @param copy true to have the data copied and owned by the object
* @return the current string
*/
string
&
assign
(
char
*
d
,
size_t
s
,
bool
copy
)
{
if
(
s
==
0
)
{
clear
();
}
else
{
release_data_if_needed
();
if
(
copy
)
{
data
=
(
char
*
)
malloc
(
s
*
sizeof
(
char
));
memcpy
(
data
,
d
,
s
*
sizeof
(
char
));
own_memory
=
true
;
refcount
=
(
uint32_t
*
)
malloc
(
sizeof
(
uint32_t
));
*
refcount
=
1
;
}
else
{
data
=
d
;
own_memory
=
false
;
refcount
=
nullptr
;
}
size
=
s
;
}
return
*
this
;
}
/**
* Clear the content of the string
*/
void
clear
()
{
release_data_if_needed
();
data
=
nullptr
;
size
=
0
;
own_memory
=
false
;
refcount
=
nullptr
;
}
/**
* Create substring from current string
* @param offset offset from the current string's data
* @param substr_size size of the substring
* @param copy true to have the data copied and owned by the object
* @return substring of the current string
*/
string
substr
(
size_t
offset
,
size_t
substr_size
,
bool
copy
)
{
eos_assert
((
offset
<
size
)
&&
(
offset
+
substr_size
<
size
),
"out of bound"
);
return
string
(
data
+
offset
,
substr_size
,
copy
);
}
char
operator
[]
(
const
size_t
index
)
{
eos_assert
(
index
<
size
,
"index out of bound"
);
return
*
(
data
+
index
);
}
// Assignment operator
string
&
operator
=
(
const
string
&
obj
)
{
if
(
this
!=
&
obj
)
{
release_data_if_needed
();
data
=
obj
.
data
;
size
=
obj
.
size
;
own_memory
=
obj
.
own_memory
;
refcount
=
obj
.
refcount
;
if
(
refcount
!=
nullptr
)
(
*
refcount
)
++
;
}
return
*
this
;
}
/**
* @brief Assignment operator for string literal
* Non-null terminated string need to be passed here,
* Otherwise it will have extraneous data
* @param cstr - null terminated string
*/
string
&
operator
=
(
const
char
*
cstr
)
{
release_data_if_needed
();
size
=
cstrlen
(
cstr
)
+
1
;
data
=
(
char
*
)
malloc
(
size
*
sizeof
(
char
));
memcpy
(
data
,
cstr
,
size
*
sizeof
(
char
));
own_memory
=
true
;
refcount
=
(
uint32_t
*
)
malloc
(
sizeof
(
uint32_t
));
*
refcount
=
1
;
return
*
this
;
}
string
&
operator
+=
(
const
string
&
str
){
eos_assert
((
size
+
str
.
size
>
size
)
&&
(
size
+
str
.
size
>
str
.
size
),
"overflow"
);
char
*
new_data
;
size_t
new_size
;
if
(
size
>
0
&&
*
(
data
+
size
-
1
)
==
'\0'
)
{
// Null terminated string, remove the \0 when concatenates
new_size
=
size
-
1
+
str
.
size
;
new_data
=
(
char
*
)
malloc
(
new_size
*
sizeof
(
char
));
memcpy
(
new_data
,
data
,
(
size
-
1
)
*
sizeof
(
char
));
memcpy
(
new_data
+
size
-
1
,
str
.
data
,
str
.
size
*
sizeof
(
char
));
}
else
{
new_size
=
size
+
str
.
size
;
new_data
=
(
char
*
)
malloc
(
new_size
*
sizeof
(
char
));
memcpy
(
new_data
,
data
,
size
*
sizeof
(
char
));
memcpy
(
new_data
+
size
,
str
.
data
,
str
.
size
*
sizeof
(
char
));
}
// Release old data
release_data_if_needed
();
// Assign new data
data
=
new_data
;
size
=
new_size
;
own_memory
=
true
;
refcount
=
(
uint32_t
*
)
malloc
(
sizeof
(
uint32_t
));
*
refcount
=
1
;
return
*
this
;
}
// Compare two strings
// Return an integral value indicating the relationship between strings
// >0 if the first string is greater than the second string
// 0 if both strings are equal
// <0 if the first string is smaller than the second string
// The return value also represents the difference between the first character that doesn't match of the two strings
int32_t
compare
(
const
string
&
str
)
const
{
int32_t
result
;
if
(
size
==
str
.
size
)
{
result
=
memcmp
(
data
,
str
.
data
,
size
);
}
else
if
(
size
<
str
.
size
)
{
result
=
memcmp
(
data
,
str
.
data
,
size
);
if
(
result
==
0
)
{
// String is equal up to size of the shorter string, return the difference in byte of the next character
result
=
0
-
(
unsigned
char
)
str
.
data
[
size
];
}
}
else
if
(
size
>
str
.
size
)
{
result
=
memcmp
(
data
,
str
.
data
,
str
.
size
);
if
(
result
==
0
)
{
// String is equal up to size of the shorter string, return the difference in byte of the next character
result
=
(
unsigned
char
)
data
[
str
.
size
];
}
}
return
result
;
}
friend
bool
operator
<
(
const
string
&
lhs
,
const
string
&
rhs
)
{
return
lhs
.
compare
(
rhs
)
<
0
;
}
friend
bool
operator
>
(
const
string
&
lhs
,
const
string
&
rhs
)
{
return
lhs
.
compare
(
rhs
)
>
0
;
}
friend
bool
operator
==
(
const
string
&
lhs
,
const
string
&
rhs
)
{
return
lhs
.
compare
(
rhs
)
==
0
;
}
friend
bool
operator
!=
(
const
string
&
lhs
,
const
string
&
rhs
)
{
return
lhs
.
compare
(
rhs
)
!=
0
;
}
friend
string
operator
+
(
string
lhs
,
const
string
&
rhs
)
{
return
lhs
+=
rhs
;
}
template
<
typename
DataStream
>
friend
DataStream
&
operator
<<
(
DataStream
&
ds
,
const
string
&
t
){
ds
<<
unsigned_int
(
t
.
get_size
()
);
if
(
t
.
get_size
()
)
ds
.
write
(
t
.
get_data
(),
t
.
get_size
()
);
return
ds
;
}
template
<
typename
DataStream
>
friend
DataStream
&
operator
>>
(
DataStream
&
ds
,
string
&
t
){
unsigned_int
size
;
ds
>>
size
;
t
.
resize
(
size
);
if
(
size
.
value
)
ds
.
read
(
t
.
get_data
(),
size
.
value
);
return
ds
;
}
void
print
()
const
{
if
(
size
>
0
&&
*
(
data
+
size
-
1
)
==
'\0'
)
{
// Null terminated string
prints
(
data
);
}
else
{
// Non null terminated string
// We need to specify the size of string so it knows where to stop
prints_l
(
data
,
size
);
}
}
};
/// class string
}
contracts/eosiolib/transaction.hpp
浏览文件 @
f45f2664
...
...
@@ -6,7 +6,6 @@
#include <eosiolib/transaction.h>
#include <eosiolib/action.hpp>
#include <eosiolib/print.hpp>
#include <eosiolib/string.hpp>
#include <eosiolib/types.hpp>
#include <eosiolib/serialize.hpp>
...
...
contracts/eosiolib/utility.hpp
已删除
100644 → 0
浏览文件 @
fa95e965
#pragma once
#include <eosiolib/types.hpp>
namespace
eosio
{
template
<
typename
T
,
typename
U
>
inline
T
&&
forward
(
U
&&
u
)
{
return
static_cast
<
T
&&>
(
u
);
}
template
<
typename
T
>
inline
typename
remove_reference
<
T
>::
type
&&
move
(
T
&&
arg
)
{
return
(
typename
remove_reference
<
T
>::
type
&&
)
arg
;
}
}
/// namespace eosio
contracts/eosiolib/vector.hpp
浏览文件 @
f45f2664
#pragma once
#include <eosiolib/utility.hpp>
#include <eosiolib/memory.hpp>
#include <eosiolib/stdlib.hpp>
#include <vector>
namespace
eosio
{
/**
* This class provides an interface similar to std::vector
*/
template
<
typename
T
>
class
vector
{
public:
vector
(){}
using
std
::
vector
;
vector
(
size_t
s
,
const
T
&
value
)
{
reserve
(
s
);
for
(
uint32_t
i
=
0
;
i
<
s
;
++
i
)
emplace_back
(
value
);
}
vector
(
const
vector
&
copy
)
{
reserve
(
copy
.
size
()
);
for
(
uint32_t
i
=
0
;
i
<
copy
.
size
();
++
i
)
{
emplace_back
(
copy
[
i
]
);
}
}
vector
(
vector
&&
mv
)
{
_data
=
mv
.
_data
;
_size
=
mv
.
_size
;
_capacity
=
mv
.
_capacity
;
mv
.
_data
=
nullptr
;
mv
.
_size
=
0
;
mv
.
_capacity
=
0
;
}
vector
(
std
::
initializer_list
<
T
>
init
)
{
resize
(
0
);
reserve
(
init
.
size
()
);
int
i
=
0
;
for
(
auto
itr
=
init
.
begin
();
itr
!=
init
.
end
();
itr
++
)
{
emplace_back
(
*
itr
);
}
}
~
vector
()
{
for
(
uint32_t
i
=
0
;
i
<
_size
;
++
i
)
_data
[
i
].
~
T
();
free
(
_data
);
_data
=
nullptr
;
_size
=
0
;
_capacity
=
0
;
}
vector
&
operator
=
(
const
vector
&
copy
)
{
if
(
this
!=
&
copy
)
{
resize
(
0
);
reserve
(
copy
.
size
()
);
for
(
uint32_t
i
=
0
;
i
<
copy
.
size
();
++
i
)
{
new
(
&
_data
[
i
])
T
(
copy
[
i
]
);
}
_size
=
copy
.
size
();
}
return
*
this
;
}
vector
&
operator
=
(
vector
&&
mv
)
{
resize
(
0
);
_data
=
mv
.
_data
;
_size
=
mv
.
_size
;
_capacity
=
mv
.
_capacity
;
mv
.
_data
=
nullptr
;
mv
.
_size
=
0
;
mv
.
_capacity
=
0
;
return
*
this
;
}
T
&
operator
[](
uint32_t
index
)
{
return
_data
[
index
];
}
const
T
&
operator
[](
uint32_t
index
)
const
{
return
_data
[
index
];
}
T
*
begin
()
{
return
_data
;
}
T
*
end
()
{
return
_data
+
_size
;
}
const
T
*
begin
()
const
{
return
_data
;
}
const
T
*
end
()
const
{
return
_data
+
_size
;
}
const
T
*
data
()
const
{
return
_data
;
}
T
*
data
()
{
return
_data
;
}
uint32_t
size
()
const
{
return
_size
;
}
uint32_t
capacity
()
const
{
return
_capacity
;
}
void
push_back
(
const
T
&
value
)
{
if
(
_size
==
_capacity
)
reserve
(
_size
+
1
);
new
(
&
_data
[
_size
])
T
(
value
);
++
_size
;
}
template
<
typename
...
Args
>
void
emplace_back
(
Args
&&
...
value
)
{
if
(
_size
==
_capacity
)
reserve
(
_size
+
1
);
new
(
&
_data
[
_size
])
T
(
forward
<
Args
>
(
value
)...
);
++
_size
;
}
void
resize
(
uint32_t
new_size
)
{
reserve
(
new_size
);
if
(
new_size
>
_size
)
{
for
(
uint32_t
i
=
_size
;
i
<
new_size
;
++
i
)
{
new
(
&
_data
[
i
])
T
();
}
}
else
if
(
new_size
<
_size
)
{
for
(
uint32_t
i
=
new_size
;
i
<
_size
;
++
i
)
{
_data
[
i
].
~
T
();
}
}
_size
=
new_size
;
}
/// resize
void
reserve
(
uint32_t
new_capacity
)
{
if
(
new_capacity
>
_capacity
)
{
T
*
new_data
=
(
T
*
)
malloc
(
sizeof
(
T
)
*
new_capacity
);
for
(
uint32_t
i
=
0
;
i
<
_size
;
++
i
)
{
new
(
new_data
+
i
)
T
(
move
(
_data
[
i
]
)
);
_data
[
i
].
~
T
();
}
free
(
_data
);
_data
=
new_data
;
_capacity
=
new_capacity
;
}
}
private:
T
*
_data
=
nullptr
;
uint32_t
_size
=
0
;
uint32_t
_capacity
=
0
;
};
/// class vector
typedef
eosio
::
vector
<
char
>
bytes
;
typedef
std
::
vector
<
char
>
bytes
;
}
/// namespace eosio
contracts/identity/identity.hpp
浏览文件 @
f45f2664
...
...
@@ -5,15 +5,14 @@
#include <eosiolib/singleton.hpp>
#include <eosiolib/table.hpp>
#include <eosiolib/vector.hpp>
#include <eosiolib/string.hpp>
namespace
identity
{
using
eosio
::
action_meta
;
using
eosio
::
table_i64i64i64
;
using
eosio
::
table64
;
using
eosio
::
singleton
;
using
eosio
::
string
;
using
eosio
::
vector
;
using
std
::
string
;
using
std
::
vector
;
/**
* This contract maintains a graph database of certified statements about an
...
...
@@ -331,7 +330,7 @@ namespace identity {
row
.
trusted
=
is_trusted
(
cert
.
certifier
);
row
.
certifier
=
cert
.
certifier
;
row
.
confidence
=
value
.
confidence
;
eos_assert
(
value
.
type
.
get_
size
()
<=
32
,
"certrow::type should be not longer than 32 bytes"
);
eos_assert
(
value
.
type
.
size
()
<=
32
,
"certrow::type should be not longer than 32 bytes"
);
row
.
type
=
value
.
type
;
row
.
data
=
value
.
data
;
...
...
contracts/identity/test/identity_test.cpp
浏览文件 @
f45f2664
...
...
@@ -10,8 +10,8 @@ namespace identity_test {
using
eosio
::
action_meta
;
using
eosio
::
singleton
;
using
eosio
::
string
;
using
eosio
::
vector
;
using
std
::
string
;
using
std
::
vector
;
class
contract
{
public:
...
...
contracts/noop/noop.hpp
浏览文件 @
f45f2664
...
...
@@ -6,18 +6,18 @@
#include <eosiolib/eosio.hpp>
#include <eosiolib/dispatcher.hpp>
#include <eosiolib/string.hpp>
using
namespace
eosio
;
namespace
noop
{
using
std
::
string
;
/**
noop contract
All it does is require sender authorization.
Actions: anyaction
*/
class
noop
{
public:
...
...
contracts/stltest/stltest.cpp
浏览文件 @
f45f2664
...
...
@@ -149,7 +149,6 @@
*/
//include <eosiolib/eos.hpp>
#include <eosiolib/token.hpp>
#include <eosiolib/string.hpp>
#include <eosiolib/dispatcher.hpp>
using
namespace
eosio
;
...
...
contracts/test.system/test.system.cpp
浏览文件 @
f45f2664
...
...
@@ -6,7 +6,6 @@
#include <eosiolib/action.hpp>
#include <eosiolib/types.hpp>
#include <eosiolib/serialize.hpp>
#include <eosiolib/string.hpp>
#include <eosiolib/system.h>
using
namespace
eosio
;
...
...
@@ -42,7 +41,7 @@ namespace testsystem {
struct
producer_key
{
account_name
account
;
st
ring
public_key
;
st
d
::
string
public_key
;
EOSLIB_SERIALIZE
(
producer_key
,
(
account
)(
public_key
)
);
};
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录