Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
P
plugin
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
JIRA
JIRA
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
link33
plugin
Commits
17b6b5f4
Commit
17b6b5f4
authored
Dec 04, 2019
by
pengjun
Browse files
Options
Browse Files
Download
Plain Diff
Merge remote-tracking branch 'remotes/origin/master' into issue-627-collateralize-v2
parents
34bc0575
9f95ccab
Show whitespace changes
Inline
Side-by-side
Showing
46 changed files
with
3466 additions
and
282 deletions
+3466
-282
dapp-test-common.sh
build/dapp-test-common.sh
+5
-1
dapp-test-rpc.sh
build/dapp-test-rpc.sh
+6
-5
chain33.para.toml
chain33.para.toml
+1
-0
init.go
plugin/dapp/init/init.go
+1
-0
oracle_test.go
plugin/dapp/oracle/executor/oracle_test.go
+498
-0
Dockerfile
plugin/dapp/paracross/cmd/scripts/autodeploy/Dockerfile
+10
-0
Makefile
plugin/dapp/paracross/cmd/scripts/autodeploy/Makefile
+17
-0
config
plugin/dapp/paracross/cmd/scripts/autodeploy/config
+40
-0
docker-compose.sh
...n/dapp/paracross/cmd/scripts/autodeploy/docker-compose.sh
+267
-0
docker-compose.yml
.../dapp/paracross/cmd/scripts/autodeploy/docker-compose.yml
+4
-0
entrypoint.sh
plugin/dapp/paracross/cmd/scripts/autodeploy/entrypoint.sh
+2
-0
test-rpc.sh
plugin/dapp/paracross/cmd/test/test-rpc.sh
+121
-31
paracross.go
plugin/dapp/paracross/commands/paracross.go
+30
-0
action.go
plugin/dapp/paracross/executor/action.go
+67
-22
asset.go
plugin/dapp/paracross/executor/asset.go
+18
-0
exec_local.go
plugin/dapp/paracross/executor/exec_local.go
+1
-0
query.go
plugin/dapp/paracross/executor/query.go
+32
-7
paracross.proto
plugin/dapp/paracross/proto/paracross.proto
+19
-1
rpc.go
plugin/dapp/paracross/rpc/rpc.go
+3
-3
rpc_test.go
plugin/dapp/paracross/rpc/rpc_test.go
+4
-4
paracross.pb.go
plugin/dapp/paracross/types/paracross.pb.go
+331
-208
type.go
plugin/dapp/paracross/types/type.go
+4
-0
Makefile
plugin/dapp/storage/cmd/Makefile
+3
-0
build.sh
plugin/dapp/storage/cmd/build.sh
+11
-0
commands.go
plugin/dapp/storage/commands/commands.go
+23
-0
aes.go
plugin/dapp/storage/crypto/aes.go
+47
-0
aes_test.go
plugin/dapp/storage/crypto/aes_test.go
+23
-0
crypto.go
plugin/dapp/storage/crypto/crypto.go
+33
-0
des.go
plugin/dapp/storage/crypto/des.go
+84
-0
des_test.go
plugin/dapp/storage/crypto/des_test.go
+59
-0
exec.go
plugin/dapp/storage/executor/exec.go
+36
-0
exec_del_local.go
plugin/dapp/storage/executor/exec_del_local.go
+20
-0
exec_local.go
plugin/dapp/storage/executor/exec_local.go
+49
-0
kv.go
plugin/dapp/storage/executor/kv.go
+21
-0
query.go
plugin/dapp/storage/executor/query.go
+16
-0
storage.go
plugin/dapp/storage/executor/storage.go
+58
-0
storage_test.go
plugin/dapp/storage/executor/storage_test.go
+326
-0
storagedb.go
plugin/dapp/storage/executor/storagedb.go
+108
-0
plugin.go
plugin/dapp/storage/plugin.go
+23
-0
Makefile
plugin/dapp/storage/proto/Makefile
+2
-0
create_protobuf.sh
plugin/dapp/storage/proto/create_protobuf.sh
+4
-0
storage.proto
plugin/dapp/storage/proto/storage.proto
+94
-0
rpc.go
plugin/dapp/storage/rpc/rpc.go
+7
-0
types.go
plugin/dapp/storage/rpc/types.go
+34
-0
storage.go
plugin/dapp/storage/types/storage.go
+102
-0
storage.pb.go
plugin/dapp/storage/types/storage.pb.go
+802
-0
No files found.
build/dapp-test-common.sh
View file @
17b6b5f4
...
...
@@ -116,8 +116,12 @@ chain33_SignRawTx() {
local
txHex
=
"
$1
"
local
priKey
=
"
$2
"
local
MAIN_HTTP
=
$3
local
expire
=
"120s"
if
[
-n
"
$4
"
]
;
then
expire
=
$4
fi
local
req
=
'"method":"Chain33.SignRawTx","params":[{"privkey":"'
"
$priKey
"
'","txHex":"'
"
$txHex
"
'","expire":"
120s
"}]'
local
req
=
'"method":"Chain33.SignRawTx","params":[{"privkey":"'
"
$priKey
"
'","txHex":"'
"
$txHex
"
'","expire":"
'
"
$expire
"
'
"}]'
signedTx
=
$(
curl
-ksd
"{
$req
}"
"
${
MAIN_HTTP
}
"
| jq
-r
".result"
)
if
[
"
$signedTx
"
!=
null
]
;
then
...
...
build/dapp-test-rpc.sh
View file @
17b6b5f4
...
...
@@ -10,17 +10,18 @@ function dapp_test_rpc() {
if
[
-d
dapptest
]
;
then
cp
"
$DAPP_TEST_COMMON
"
dapptest/
cd
dapptest
||
return
rm
-f
"retries.log"
rm
-f
"jobs.log"
rm
-rf
"outdir"
dapps
=
$(
find
.
-maxdepth
1
-type
d
!
-name
dapptest
!
-name
.
|
sed
's/^\.\///'
|
sort
)
echo
"dapps list:
$dapps
"
set
+e
parallel
-k
--
joblog
./jobs.log
'echo tried {} >>./retries.log; ./{}/"'
"
${
RPC_TESTFILE
}
"
'" "'
"
$ip
"
'"'
:::
"
$dapps
"
parallel
-k
--
results
outdir
--joblog
./jobs.log ./
{}
/
"
${
RPC_TESTFILE
}
"
"
$ip
"
:::
"
$dapps
"
local
ret
=
$?
# retries 3 times if one dapp fail
echo
"============ # retried dapps log: ============="
cat
./retries.log
if
[
$ret
-ne
0
]
;
then
wrongdapps
=
$(
awk
'{print $7,$9 }'
jobs.log |
grep
-a
1 |
awk
-F
'/'
'{print $2}'
)
parallel
-k
'cat ./outdir/1/{}/stderr; cat ./outdir/1/{}/stdout'
:::
"
$wrongdapps
"
fi
echo
"============ # check dapps test log: ============="
cat
./jobs.log
set
-e
...
...
chain33.para.toml
View file @
17b6b5f4
...
...
@@ -255,6 +255,7 @@ ForkParacrossCommitTx=0
ForkLoopCheckCommitTxDone
=
0
#平行链分阶段自共识支持合约配置,缺省是0
ForkParaSelfConsStages
=
0
ForkParaAssetTransferRbk
=
0
[fork.sub.evm]
Enable
=
0
...
...
plugin/dapp/init/init.go
View file @
17b6b5f4
...
...
@@ -22,6 +22,7 @@ import (
_
"github.com/33cn/plugin/plugin/dapp/privacy"
//auto gen
_
"github.com/33cn/plugin/plugin/dapp/relay"
//auto gen
_
"github.com/33cn/plugin/plugin/dapp/retrieve"
//auto gen
_
"github.com/33cn/plugin/plugin/dapp/storage"
//auto gen
_
"github.com/33cn/plugin/plugin/dapp/ticket"
//auto gen
_
"github.com/33cn/plugin/plugin/dapp/token"
//auto gen
_
"github.com/33cn/plugin/plugin/dapp/trade"
//auto gen
...
...
plugin/dapp/oracle/executor/oracle_test.go
0 → 100644
View file @
17b6b5f4
package
executor
import
(
"fmt"
"math/rand"
"testing"
"time"
"github.com/33cn/chain33/account"
"github.com/33cn/chain33/client"
"github.com/33cn/chain33/common/address"
"github.com/33cn/chain33/types"
"github.com/33cn/chain33/util"
"github.com/33cn/chain33/common"
"github.com/33cn/chain33/common/crypto"
dbm
"github.com/33cn/chain33/common/db"
"github.com/33cn/chain33/queue"
oty
"github.com/33cn/plugin/plugin/dapp/oracle/types"
"github.com/stretchr/testify/assert"
//"github.com/33cn/chain33/types/jsonpb"
"strings"
)
type
execEnv
struct
{
blockTime
int64
blockHeight
int64
difficulty
uint64
}
var
(
PrivKeyA
=
"0x6da92a632ab7deb67d38c0f6560bcfed28167998f6496db64c258d5e8393a81b"
// 1KSBd17H7ZK8iT37aJztFB22XGwsPTdwE4
Nodes
=
[][]
byte
{
[]
byte
(
"1KSBd17H7ZK8iT37aJztFB22XGwsPTdwE4"
),
[]
byte
(
"1JRNjdEqp4LJ5fqycUBm9ayCKSeeskgMKR"
),
[]
byte
(
"1NLHPEcbTWWxxU3dGUZBhayjrCHD3psX7k"
),
[]
byte
(
"1MCftFynyvG2F4ED5mdHYgziDxx6vDrScs"
),
}
)
var
(
r
*
rand
.
Rand
)
func
init
()
{
r
=
rand
.
New
(
rand
.
NewSource
(
types
.
Now
()
.
UnixNano
()))
}
func
TestOrace
(
t
*
testing
.
T
)
{
cfg
:=
types
.
NewChain33Config
(
strings
.
Replace
(
types
.
GetDefaultCfgstring
(),
"Title=
\"
local
\"
"
,
"Title=
\"
chain33
\"
"
,
1
))
Init
(
oty
.
OracleX
,
cfg
,
nil
)
total
:=
100
*
types
.
Coin
accountA
:=
types
.
Account
{
Balance
:
total
,
Frozen
:
0
,
Addr
:
string
(
Nodes
[
0
]),
}
accountB
:=
types
.
Account
{
Balance
:
total
,
Frozen
:
0
,
Addr
:
string
(
Nodes
[
1
]),
}
accountC
:=
types
.
Account
{
Balance
:
total
,
Frozen
:
0
,
Addr
:
string
(
Nodes
[
2
]),
}
accountD
:=
types
.
Account
{
Balance
:
total
,
Frozen
:
0
,
Addr
:
string
(
Nodes
[
3
]),
}
execAddr
:=
address
.
ExecAddress
(
oty
.
OracleX
)
stateDB
,
_
:=
dbm
.
NewGoMemDB
(
"1"
,
"2"
,
1000
)
_
,
_
,
kvdb
:=
util
.
CreateTestDB
()
accA
,
_
:=
account
.
NewAccountDB
(
cfg
,
"coins"
,
"bty"
,
stateDB
)
accA
.
SaveExecAccount
(
execAddr
,
&
accountA
)
accB
,
_
:=
account
.
NewAccountDB
(
cfg
,
"coins"
,
"bty"
,
stateDB
)
accB
.
SaveExecAccount
(
execAddr
,
&
accountB
)
accC
,
_
:=
account
.
NewAccountDB
(
cfg
,
"coins"
,
"bty"
,
stateDB
)
accC
.
SaveExecAccount
(
execAddr
,
&
accountC
)
accD
,
_
:=
account
.
NewAccountDB
(
cfg
,
"coins"
,
"bty"
,
stateDB
)
accD
.
SaveExecAccount
(
execAddr
,
&
accountD
)
env
:=
execEnv
{
10
,
cfg
.
GetDappFork
(
oty
.
OracleX
,
"Enable"
),
1539918074
,
}
// set config key 授权
item
:=
&
types
.
ConfigItem
{
Key
:
"mavl-manage-oracle-publish-event"
,
Value
:
&
types
.
ConfigItem_Arr
{
Arr
:
&
types
.
ArrayConfig
{
Value
:
[]
string
{
"1KSBd17H7ZK8iT37aJztFB22XGwsPTdwE4"
}},
},
}
stateDB
.
Set
([]
byte
(
item
.
Key
),
types
.
Encode
(
item
))
// publish event
ety
:=
types
.
LoadExecutorType
(
oty
.
OracleX
)
tx
,
err
:=
ety
.
Create
(
"EventPublish"
,
&
oty
.
EventPublish
{
Type
:
"football"
,
SubType
:
"Premier League"
,
Time
:
time
.
Now
()
.
AddDate
(
0
,
0
,
1
)
.
Unix
(),
Content
:
fmt
.
Sprintf
(
"{
\"
team%d
\"
:
\"
ChelSea
\"
,
\"
team%d
\"
:
\"
Manchester
\"
,
\"
resultType
\"
:
\"
score
\"
}"
,
r
.
Int
()
%
10
,
r
.
Int
()
%
10
),
Introduction
:
"guess the sore result of football game between ChelSea and Manchester in 2019-01-21 14:00:00"
})
assert
.
Nil
(
t
,
err
)
tx
,
err
=
types
.
FormatTx
(
cfg
,
oty
.
OracleX
,
tx
)
assert
.
Nil
(
t
,
err
)
tx
,
err
=
signTx
(
tx
,
PrivKeyA
)
assert
.
Nil
(
t
,
err
)
t
.
Log
(
"tx"
,
tx
)
exec
:=
newOracle
()
q
:=
queue
.
New
(
"channel"
)
q
.
SetConfig
(
cfg
)
api
,
_
:=
client
.
New
(
q
.
Client
(),
nil
)
exec
.
SetAPI
(
api
)
exec
.
SetStateDB
(
stateDB
)
exec
.
SetLocalDB
(
kvdb
)
exec
.
SetEnv
(
1
,
env
.
blockTime
,
env
.
difficulty
)
receipt
,
err
:=
exec
.
Exec
(
tx
,
int
(
1
))
if
err
!=
nil
{
t
.
Error
(
err
)
}
for
_
,
kv
:=
range
receipt
.
KV
{
stateDB
.
Set
(
kv
.
Key
,
kv
.
Value
)
}
receiptDate
:=
&
types
.
ReceiptData
{
Ty
:
receipt
.
Ty
,
Logs
:
receipt
.
Logs
}
set
,
err
:=
exec
.
ExecLocal
(
tx
,
receiptDate
,
int
(
1
))
if
err
!=
nil
{
t
.
Error
(
err
)
}
for
_
,
kv
:=
range
set
.
KV
{
kvdb
.
Set
(
kv
.
Key
,
kv
.
Value
)
}
var
eventID
string
//获取eventID
for
_
,
log
:=
range
receipt
.
Logs
{
if
log
.
Ty
>=
oty
.
TyLogEventPublish
&&
log
.
Ty
<=
oty
.
TyLogResultPublish
{
status
:=
oty
.
ReceiptOracle
{}
err
:=
types
.
Decode
(
log
.
Log
,
&
status
)
assert
.
Nil
(
t
,
err
)
eventID
=
status
.
EventID
}
}
t
.
Log
(
"eventID:"
,
eventID
)
//查询事件
msg
,
err
:=
exec
.
Query
(
oty
.
FuncNameQueryOracleListByIDs
,
types
.
Encode
(
&
oty
.
QueryOracleInfos
{
EventID
:
[]
string
{
eventID
}}))
if
err
!=
nil
{
t
.
Error
(
err
)
}
t
.
Log
(
msg
)
reply
:=
msg
.
(
*
oty
.
ReplyOracleStatusList
)
assert
.
Equal
(
t
,
int32
(
oty
.
EventPublished
),
reply
.
Status
[
0
]
.
Status
.
Status
)
//通过状态查询eventID
msg
,
err
=
exec
.
Query
(
oty
.
FuncNameQueryEventIDByStatus
,
types
.
Encode
(
&
oty
.
QueryEventID
{
Status
:
int32
(
oty
.
EventPublished
)}))
if
err
!=
nil
{
t
.
Error
(
err
)
}
t
.
Log
(
msg
)
reply2
:=
msg
.
(
*
oty
.
ReplyEventIDs
)
assert
.
Equal
(
t
,
eventID
,
reply2
.
EventID
[
0
])
//通过状态和地址查询
msg
,
err
=
exec
.
Query
(
oty
.
FuncNameQueryEventIDByAddrAndStatus
,
types
.
Encode
(
&
oty
.
QueryEventID
{
Status
:
int32
(
oty
.
EventPublished
),
Addr
:
string
(
Nodes
[
0
])}))
if
err
!=
nil
{
t
.
Error
(
err
)
}
t
.
Log
(
msg
)
reply3
:=
msg
.
(
*
oty
.
ReplyEventIDs
)
assert
.
Equal
(
t
,
eventID
,
reply3
.
EventID
[
0
])
//通过类型和状态查询
msg
,
err
=
exec
.
Query
(
oty
.
FuncNameQueryEventIDByTypeAndStatus
,
types
.
Encode
(
&
oty
.
QueryEventID
{
Status
:
int32
(
oty
.
EventPublished
),
Type
:
"football"
}))
if
err
!=
nil
{
t
.
Error
(
err
)
}
t
.
Log
(
msg
)
reply4
:=
msg
.
(
*
oty
.
ReplyEventIDs
)
assert
.
Equal
(
t
,
eventID
,
reply4
.
EventID
[
0
])
//pre publish result
tx
,
err
=
ety
.
Create
(
"ResultPrePublish"
,
&
oty
.
ResultPrePublish
{
EventID
:
eventID
,
Result
:
fmt
.
Sprintf
(
"%d:%d"
,
r
.
Int
()
%
10
,
r
.
Int
()
%
10
),
Source
:
"sina sport"
})
assert
.
Nil
(
t
,
err
)
tx
,
err
=
types
.
FormatTx
(
cfg
,
oty
.
OracleX
,
tx
)
assert
.
Nil
(
t
,
err
)
tx
,
err
=
signTx
(
tx
,
PrivKeyA
)
assert
.
Nil
(
t
,
err
)
exec
.
SetEnv
(
env
.
blockHeight
+
1
,
env
.
blockTime
+
20
,
env
.
difficulty
+
1
)
receipt
,
err
=
exec
.
Exec
(
tx
,
int
(
1
))
if
err
!=
nil
{
t
.
Error
(
err
)
}
for
_
,
kv
:=
range
receipt
.
KV
{
stateDB
.
Set
(
kv
.
Key
,
kv
.
Value
)
}
receiptDate
=
&
types
.
ReceiptData
{
Ty
:
receipt
.
Ty
,
Logs
:
receipt
.
Logs
}
set
,
err
=
exec
.
ExecLocal
(
tx
,
receiptDate
,
int
(
1
))
if
err
!=
nil
{
t
.
Error
(
err
)
}
for
_
,
kv
:=
range
set
.
KV
{
kvdb
.
Set
(
kv
.
Key
,
kv
.
Value
)
}
msg
,
err
=
exec
.
Query
(
oty
.
FuncNameQueryOracleListByIDs
,
types
.
Encode
(
&
oty
.
QueryOracleInfos
{
EventID
:
[]
string
{
eventID
}}))
if
err
!=
nil
{
t
.
Error
(
err
)
}
t
.
Log
(
msg
)
reply
=
msg
.
(
*
oty
.
ReplyOracleStatusList
)
assert
.
Equal
(
t
,
int32
(
oty
.
ResultPrePublished
),
reply
.
Status
[
0
]
.
Status
.
Status
)
//publish result
tx
,
err
=
ety
.
Create
(
"ResultPublish"
,
&
oty
.
ResultPublish
{
EventID
:
eventID
,
Result
:
fmt
.
Sprintf
(
"%d:%d"
,
r
.
Int
()
%
10
,
r
.
Int
()
%
10
),
Source
:
"sina sport"
})
assert
.
Nil
(
t
,
err
)
tx
,
err
=
types
.
FormatTx
(
cfg
,
oty
.
OracleX
,
tx
)
assert
.
Nil
(
t
,
err
)
tx
,
err
=
signTx
(
tx
,
PrivKeyA
)
assert
.
Nil
(
t
,
err
)
exec
.
SetEnv
(
env
.
blockHeight
+
1
,
env
.
blockTime
+
20
,
env
.
difficulty
+
1
)
receipt
,
err
=
exec
.
Exec
(
tx
,
int
(
1
))
if
err
!=
nil
{
t
.
Error
(
err
)
}
for
_
,
kv
:=
range
receipt
.
KV
{
stateDB
.
Set
(
kv
.
Key
,
kv
.
Value
)
}
receiptDate
=
&
types
.
ReceiptData
{
Ty
:
receipt
.
Ty
,
Logs
:
receipt
.
Logs
}
set
,
err
=
exec
.
ExecLocal
(
tx
,
receiptDate
,
int
(
1
))
if
err
!=
nil
{
t
.
Error
(
err
)
}
for
_
,
kv
:=
range
set
.
KV
{
kvdb
.
Set
(
kv
.
Key
,
kv
.
Value
)
}
msg
,
err
=
exec
.
Query
(
oty
.
FuncNameQueryOracleListByIDs
,
types
.
Encode
(
&
oty
.
QueryOracleInfos
{
EventID
:
[]
string
{
eventID
}}))
if
err
!=
nil
{
t
.
Error
(
err
)
}
t
.
Log
(
msg
)
reply
=
msg
.
(
*
oty
.
ReplyOracleStatusList
)
assert
.
Equal
(
t
,
int32
(
oty
.
ResultPublished
),
reply
.
Status
[
0
]
.
Status
.
Status
)
// publish event
tx
,
err
=
ety
.
Create
(
"EventPublish"
,
&
oty
.
EventPublish
{
Type
:
"football"
,
SubType
:
"Premier League"
,
Time
:
time
.
Now
()
.
AddDate
(
0
,
0
,
1
)
.
Unix
(),
Content
:
fmt
.
Sprintf
(
"{
\"
team%d
\"
:
\"
ChelSea
\"
,
\"
team%d
\"
:
\"
Manchester
\"
,
\"
resultType
\"
:
\"
score
\"
}"
,
r
.
Int
()
%
10
,
r
.
Int
()
%
10
),
Introduction
:
"guess the sore result of football game between ChelSea and Manchester in 2019-03-21 14:00:00"
})
assert
.
Nil
(
t
,
err
)
tx
,
err
=
types
.
FormatTx
(
cfg
,
oty
.
OracleX
,
tx
)
assert
.
Nil
(
t
,
err
)
tx
,
err
=
signTx
(
tx
,
PrivKeyA
)
assert
.
Nil
(
t
,
err
)
t
.
Log
(
"tx"
,
tx
)
receipt
,
err
=
exec
.
Exec
(
tx
,
int
(
1
))
if
err
!=
nil
{
t
.
Error
(
err
)
}
for
_
,
kv
:=
range
receipt
.
KV
{
stateDB
.
Set
(
kv
.
Key
,
kv
.
Value
)
}
receiptDate
=
&
types
.
ReceiptData
{
Ty
:
receipt
.
Ty
,
Logs
:
receipt
.
Logs
}
set
,
err
=
exec
.
ExecLocal
(
tx
,
receiptDate
,
int
(
1
))
if
err
!=
nil
{
t
.
Error
(
err
)
}
for
_
,
kv
:=
range
set
.
KV
{
kvdb
.
Set
(
kv
.
Key
,
kv
.
Value
)
}
//var eventID string
//获取eventID
for
_
,
log
:=
range
receipt
.
Logs
{
if
log
.
Ty
>=
oty
.
TyLogEventPublish
&&
log
.
Ty
<=
oty
.
TyLogResultPublish
{
status
:=
oty
.
ReceiptOracle
{}
err
:=
types
.
Decode
(
log
.
Log
,
&
status
)
assert
.
Nil
(
t
,
err
)
eventID
=
status
.
EventID
}
}
t
.
Log
(
"eventID:"
,
eventID
)
//查询事件
msg
,
err
=
exec
.
Query
(
oty
.
FuncNameQueryOracleListByIDs
,
types
.
Encode
(
&
oty
.
QueryOracleInfos
{
EventID
:
[]
string
{
eventID
}}))
if
err
!=
nil
{
t
.
Error
(
err
)
}
t
.
Log
(
msg
)
reply
=
msg
.
(
*
oty
.
ReplyOracleStatusList
)
assert
.
Equal
(
t
,
int32
(
oty
.
EventPublished
),
reply
.
Status
[
0
]
.
Status
.
Status
)
//EventAbort
tx
,
err
=
ety
.
Create
(
"EventAbort"
,
&
oty
.
EventAbort
{
EventID
:
eventID
})
assert
.
Nil
(
t
,
err
)
tx
,
err
=
types
.
FormatTx
(
cfg
,
oty
.
OracleX
,
tx
)
assert
.
Nil
(
t
,
err
)
tx
,
err
=
signTx
(
tx
,
PrivKeyA
)
assert
.
Nil
(
t
,
err
)
exec
.
SetEnv
(
env
.
blockHeight
+
1
,
env
.
blockTime
+
20
,
env
.
difficulty
+
1
)
receipt
,
err
=
exec
.
Exec
(
tx
,
int
(
1
))
if
err
!=
nil
{
t
.
Error
(
err
)
}
for
_
,
kv
:=
range
receipt
.
KV
{
stateDB
.
Set
(
kv
.
Key
,
kv
.
Value
)
}
receiptDate
=
&
types
.
ReceiptData
{
Ty
:
receipt
.
Ty
,
Logs
:
receipt
.
Logs
}
set
,
err
=
exec
.
ExecLocal
(
tx
,
receiptDate
,
int
(
1
))
if
err
!=
nil
{
t
.
Error
(
err
)
}
for
_
,
kv
:=
range
set
.
KV
{
kvdb
.
Set
(
kv
.
Key
,
kv
.
Value
)
}
msg
,
err
=
exec
.
Query
(
oty
.
FuncNameQueryOracleListByIDs
,
types
.
Encode
(
&
oty
.
QueryOracleInfos
{
EventID
:
[]
string
{
eventID
}}))
if
err
!=
nil
{
t
.
Error
(
err
)
}
t
.
Log
(
msg
)
reply
=
msg
.
(
*
oty
.
ReplyOracleStatusList
)
assert
.
Equal
(
t
,
int32
(
oty
.
EventAborted
),
reply
.
Status
[
0
]
.
Status
.
Status
)
//pre publish result
tx
,
err
=
ety
.
Create
(
"ResultPrePublish"
,
&
oty
.
ResultPrePublish
{
EventID
:
eventID
,
Result
:
fmt
.
Sprintf
(
"%d:%d"
,
r
.
Int
()
%
10
,
r
.
Int
()
%
10
),
Source
:
"sina sport"
})
assert
.
Nil
(
t
,
err
)
tx
,
err
=
types
.
FormatTx
(
cfg
,
oty
.
OracleX
,
tx
)
assert
.
Nil
(
t
,
err
)
tx
,
err
=
signTx
(
tx
,
PrivKeyA
)
assert
.
Nil
(
t
,
err
)
exec
.
SetEnv
(
env
.
blockHeight
+
1
,
env
.
blockTime
+
20
,
env
.
difficulty
+
1
)
receipt
,
err
=
exec
.
Exec
(
tx
,
int
(
1
))
assert
.
Equal
(
t
,
oty
.
ErrResultPrePublishNotAllowed
,
err
)
// publish event
tx
,
err
=
ety
.
Create
(
"EventPublish"
,
&
oty
.
EventPublish
{
Type
:
"football"
,
SubType
:
"Premier League"
,
Time
:
time
.
Now
()
.
AddDate
(
0
,
0
,
1
)
.
Unix
(),
Content
:
fmt
.
Sprintf
(
"{
\"
team%d
\"
:
\"
ChelSea
\"
,
\"
team%d
\"
:
\"
Manchester
\"
,
\"
resultType
\"
:
\"
score
\"
}"
,
r
.
Int
()
%
10
,
r
.
Int
()
%
10
),
Introduction
:
"guess the sore result of football game between ChelSea and Manchester in 2019-03-21 14:00:00"
})
assert
.
Nil
(
t
,
err
)
tx
,
err
=
types
.
FormatTx
(
cfg
,
oty
.
OracleX
,
tx
)
assert
.
Nil
(
t
,
err
)
tx
,
err
=
signTx
(
tx
,
PrivKeyA
)
assert
.
Nil
(
t
,
err
)
t
.
Log
(
"tx"
,
tx
)
receipt
,
err
=
exec
.
Exec
(
tx
,
int
(
1
))
if
err
!=
nil
{
t
.
Error
(
err
)
}
for
_
,
kv
:=
range
receipt
.
KV
{
stateDB
.
Set
(
kv
.
Key
,
kv
.
Value
)
}
receiptDate
=
&
types
.
ReceiptData
{
Ty
:
receipt
.
Ty
,
Logs
:
receipt
.
Logs
}
set
,
err
=
exec
.
ExecLocal
(
tx
,
receiptDate
,
int
(
1
))
if
err
!=
nil
{
t
.
Error
(
err
)
}
for
_
,
kv
:=
range
set
.
KV
{
kvdb
.
Set
(
kv
.
Key
,
kv
.
Value
)
}
//var eventID string
//获取eventID
for
_
,
log
:=
range
receipt
.
Logs
{
if
log
.
Ty
>=
oty
.
TyLogEventPublish
&&
log
.
Ty
<=
oty
.
TyLogResultPublish
{
status
:=
oty
.
ReceiptOracle
{}
err
:=
types
.
Decode
(
log
.
Log
,
&
status
)
assert
.
Nil
(
t
,
err
)
eventID
=
status
.
EventID
}
}
t
.
Log
(
"eventID:"
,
eventID
)
//查询事件
msg
,
err
=
exec
.
Query
(
oty
.
FuncNameQueryOracleListByIDs
,
types
.
Encode
(
&
oty
.
QueryOracleInfos
{
EventID
:
[]
string
{
eventID
}}))
if
err
!=
nil
{
t
.
Error
(
err
)
}
t
.
Log
(
msg
)
reply
=
msg
.
(
*
oty
.
ReplyOracleStatusList
)
assert
.
Equal
(
t
,
int32
(
oty
.
EventPublished
),
reply
.
Status
[
0
]
.
Status
.
Status
)
//pre publish result
tx
,
err
=
ety
.
Create
(
"ResultPrePublish"
,
&
oty
.
ResultPrePublish
{
EventID
:
eventID
,
Result
:
fmt
.
Sprintf
(
"%d:%d"
,
r
.
Int
()
%
10
,
r
.
Int
()
%
10
),
Source
:
"sina sport"
})
assert
.
Nil
(
t
,
err
)
tx
,
err
=
types
.
FormatTx
(
cfg
,
oty
.
OracleX
,
tx
)
assert
.
Nil
(
t
,
err
)
tx
,
err
=
signTx
(
tx
,
PrivKeyA
)
assert
.
Nil
(
t
,
err
)
exec
.
SetEnv
(
env
.
blockHeight
+
1
,
env
.
blockTime
+
20
,
env
.
difficulty
+
1
)
receipt
,
err
=
exec
.
Exec
(
tx
,
int
(
1
))
if
err
!=
nil
{
t
.
Error
(
err
)
}
for
_
,
kv
:=
range
receipt
.
KV
{
stateDB
.
Set
(
kv
.
Key
,
kv
.
Value
)
}
receiptDate
=
&
types
.
ReceiptData
{
Ty
:
receipt
.
Ty
,
Logs
:
receipt
.
Logs
}
set
,
err
=
exec
.
ExecLocal
(
tx
,
receiptDate
,
int
(
1
))
if
err
!=
nil
{
t
.
Error
(
err
)
}
for
_
,
kv
:=
range
set
.
KV
{
kvdb
.
Set
(
kv
.
Key
,
kv
.
Value
)
}
msg
,
err
=
exec
.
Query
(
oty
.
FuncNameQueryOracleListByIDs
,
types
.
Encode
(
&
oty
.
QueryOracleInfos
{
EventID
:
[]
string
{
eventID
}}))
if
err
!=
nil
{
t
.
Error
(
err
)
}
t
.
Log
(
msg
)
reply
=
msg
.
(
*
oty
.
ReplyOracleStatusList
)
assert
.
Equal
(
t
,
int32
(
oty
.
ResultPrePublished
),
reply
.
Status
[
0
]
.
Status
.
Status
)
//ResultAbort
tx
,
err
=
ety
.
Create
(
"ResultAbort"
,
&
oty
.
ResultAbort
{
EventID
:
eventID
})
assert
.
Nil
(
t
,
err
)
tx
,
err
=
types
.
FormatTx
(
cfg
,
oty
.
OracleX
,
tx
)
assert
.
Nil
(
t
,
err
)
tx
,
err
=
signTx
(
tx
,
PrivKeyA
)
assert
.
Nil
(
t
,
err
)
exec
.
SetEnv
(
env
.
blockHeight
+
1
,
env
.
blockTime
+
20
,
env
.
difficulty
+
1
)
receipt
,
err
=
exec
.
Exec
(
tx
,
int
(
1
))
if
err
!=
nil
{
t
.
Error
(
err
)
}
for
_
,
kv
:=
range
receipt
.
KV
{
stateDB
.
Set
(
kv
.
Key
,
kv
.
Value
)
}
receiptDate
=
&
types
.
ReceiptData
{
Ty
:
receipt
.
Ty
,
Logs
:
receipt
.
Logs
}
set
,
err
=
exec
.
ExecLocal
(
tx
,
receiptDate
,
int
(
1
))
if
err
!=
nil
{
t
.
Error
(
err
)
}
for
_
,
kv
:=
range
set
.
KV
{
kvdb
.
Set
(
kv
.
Key
,
kv
.
Value
)
}
msg
,
err
=
exec
.
Query
(
oty
.
FuncNameQueryOracleListByIDs
,
types
.
Encode
(
&
oty
.
QueryOracleInfos
{
EventID
:
[]
string
{
eventID
}}))
if
err
!=
nil
{
t
.
Error
(
err
)
}
t
.
Log
(
msg
)
reply
=
msg
.
(
*
oty
.
ReplyOracleStatusList
)
assert
.
Equal
(
t
,
int32
(
oty
.
ResultAborted
),
reply
.
Status
[
0
]
.
Status
.
Status
)
}
func
signTx
(
tx
*
types
.
Transaction
,
hexPrivKey
string
)
(
*
types
.
Transaction
,
error
)
{
signType
:=
types
.
SECP256K1
c
,
err
:=
crypto
.
New
(
types
.
GetSignName
(
oty
.
OracleX
,
signType
))
if
err
!=
nil
{
return
tx
,
err
}
bytes
,
err
:=
common
.
FromHex
(
hexPrivKey
[
:
])
if
err
!=
nil
{
return
tx
,
err
}
privKey
,
err
:=
c
.
PrivKeyFromBytes
(
bytes
)
if
err
!=
nil
{
return
tx
,
err
}
tx
.
Sign
(
int32
(
signType
),
privKey
)
return
tx
,
nil
}
plugin/dapp/paracross/cmd/scripts/autodeploy/Dockerfile
0 → 100644
View file @
17b6b5f4
FROM
ubuntu:16.04
WORKDIR
/root
COPY
chain33 chain33
COPY
chain33-cli chain33-cli
COPY
entrypoint.sh entrypoint.sh
COPY
chain33.toml chain33*.toml ./
CMD
["/root/chain33", "-f", "/root/chain33.toml"]
plugin/dapp/paracross/cmd/scripts/autodeploy/Makefile
0 → 100644
View file @
17b6b5f4
op
:=
"start"
.PHONY
:
docker-compose help
docker-compose
:
##
build docker-compose for chain33 run
@
./docker-compose.sh
$(op)
docker-compose-down
:
##
build docker-compose for chain33 run
@
cd
temp
;
docker-compose down
;
cd
..
help
:
##
Display this help screen
@
printf
"Help doc:
\n
Usage: make docker-compose op=[command]
\n
"
@
printf
"[command]
\n
"
@
printf
"[nodegroup]: create super node group if not create
\n
"
@
printf
"[wallet]: set node wallet private key if not set
\n
"
\ No newline at end of file
plugin/dapp/paracross/cmd/scripts/autodeploy/config
0 → 100755
View file @
17b6b5f4
paraName="test"
#genesisAccount=""
#genesisAmount=100000000
#mainStartHeight=4800000
#authAccount=()
#authPrikey=()
##docker8901端口暴露到宿主机的端口
#authPort=("18901" "18902" "18903" "18904")
#
##需要和chain33 主链保持一致
#superManager="['1JmFaA6unrCFYEWPGRi7uuXY1KthTJxJEP']"
#
##nodegroup create
##申请超级账户需要在主链冻结币数量
#authFrozenCoins=0
#nodeGroupApplier=""
#applierPrikey=""
#superManagerPrikey=""
#### 测试链配置,主链配置需要把如下测试链配置屏蔽 ##########
genesisAccount="14KEKbYtKKQm4wMthSK9J4La4nAiidGozt"
genesisAmount=100000000
mainStartHeight=4000000
authAccount=( "1KSBd17H7ZK8iT37aJztFB22XGwsPTdwE4" "1JRNjdEqp4LJ5fqycUBm9ayCKSeeskgMKR" "1NLHPEcbTWWxxU3dGUZBhayjrCHD3psX7k" "1MCftFynyvG2F4ED5mdHYgziDxx6vDrScs")
authPrikey=("0x6da92a632ab7deb67d38c0f6560bcfed28167998f6496db64c258d5e8393a81b" "0x19c069234f9d3e61135fefbeb7791b149cdf6af536f26bebb310d4cd22c3fee4" "0x7a80a1f75d7360c6123c32a78ecf978c1ac55636f87892df38d8b85a9aeff115" "0xcacb1f5d51700aea07fca2246ab43b0917d70405c65edea9b5063d72eb5c6b71")
authPort=("18901" "18902" "18903" "18904")
#需要和chain33 主链保持一致
superManager="['12qyocayNF7Lv6C9qW4avxs2E7U41fKSfv']"
tokenApprs="['12qyocayNF7Lv6C9qW4avxs2E7U41fKSfv']"
#nodegroup create
authFrozenCoins=0
nodeGroupApplier="1KSBd17H7ZK8iT37aJztFB22XGwsPTdwE4"
applierPrikey="0x6da92a632ab7deb67d38c0f6560bcfed28167998f6496db64c258d5e8393a81b"
superManagerPrikey="4257D8692EF7FE13C68B65D6A52F03933DB2FA5CE8FAF210B5B8B80C721CED01"
\ No newline at end of file
plugin/dapp/paracross/cmd/scripts/autodeploy/docker-compose.sh
0 → 100755
View file @
17b6b5f4
#!/usr/bin/env bash
# shellcheck disable=SC2154
set
-e
PWD
=
$(
cd
"
$(
dirname
"
$0
"
)
"
&&
pwd
)
export
PATH
=
"
$PWD
:
$PATH
"
buildpath
=
"temp"
NODE1
=
"
$buildpath
""_parachain1_1"
CLI
=
"docker exec
${
NODE1
}
/root/chain33-cli"
NODE2
=
"
$buildpath
""_parachain2_1"
NODE3
=
"
$buildpath
""_parachain3_1"
NODE4
=
"
$buildpath
""_parachain4_1"
CHAIN33_CLI
=
"chain33-cli"
containers
=(
"
${
NODE1
}
"
"
${
NODE2
}
"
"
${
NODE3
}
"
"
${
NODE4
}
"
)
## global config ###
sedfix
=
""
if
[
"
$(
uname
)
"
==
"Darwin"
]
;
then
sedfix
=
".bak"
fi
# shellcheck source=/dev/null
source
config
####################
function
para_init
()
{
local
index
=
1
for
auth
in
"
${
authAccount
[@]
}
"
;
do
tomlfile
=
"chain33.para.
$index
.toml"
para_set_toml
"
$tomlfile
"
sed
-i
$sedfix
's/^authAccount=.*/authAccount="'''
"
$auth
"
'''"/g'
"
$tomlfile
"
((
index++
))
done
}
function
para_set_toml
()
{
cp
chain33.para.toml
"
${
1
}
"
sed
-i
$sedfix
's/^Title.*/Title="user.p.'''
"
$paraName
"
'''."/g'
"
${
1
}
"
sed
-i
$sedfix
's/^startHeight=.*/startHeight='''
"
$mainStartHeight
"
'''/g'
"
${
1
}
"
# rpc
sed
-i
$sedfix
's/^jrpcBindAddr=.*/jrpcBindAddr="0.0.0.0:8901"/g'
"
${
1
}
"
sed
-i
$sedfix
's/^grpcBindAddr=.*/grpcBindAddr="0.0.0.0:8902"/g'
"
${
1
}
"
sed
-i
$sedfix
's/^whitelist=.*/whitelist=["localhost","127.0.0.1","0.0.0.0"]/g'
"
${
1
}
"
if
[
-n
"
$superManager
"
]
;
then
# shellcheck disable=SC1004
sed
-i
$sedfix
's/^superManager=.*/superManager='''
"
$superManager
"
'''/g'
"
${
1
}
"
fi
if
[
-n
"
$tokenApprs
"
]
;
then
# shellcheck disable=SC1004
sed
-i
$sedfix
's/^tokenApprs=.*/tokenApprs='''
"
$tokenApprs
"
'''/g'
"
${
1
}
"
fi
}
function
para_set_wallet
()
{
echo
"=========== # para set wallet ============="
for
((
i
=
0
;
i <
${#
authAccount
[@]
}
;
i++
))
;
do
para_import_wallet
"
${
authPort
[
$i
]
}
"
"
${
authPrikey
[
$i
]
}
"
done
}
function
para_import_wallet
()
{
local
key
=
$2
local
port
=
$1
echo
"=========== # save seed to wallet ============="
./
$CHAIN33_CLI
--rpc_laddr
"http://localhost:
$port
"
seed save
-p
1314fuzamei
-s
"tortoise main civil member grace happy century convince father cage beach hip maid merry rib"
echo
"=========== # unlock wallet ============="
./
$CHAIN33_CLI
--rpc_laddr
"http://localhost:
$port
"
wallet unlock
-p
1314fuzamei
-t
0
echo
"=========== # import private key ============="
echo
"key:
${
key
}
"
./
$CHAIN33_CLI
--rpc_laddr
"http://localhost:
$port
"
account import_key
-k
"
${
key
}
"
-l
"paraAuthAccount"
echo
"=========== # close auto mining ============="
./
$CHAIN33_CLI
--rpc_laddr
"http://localhost:
$port
"
wallet auto_mine
-f
0
echo
"=========== # wallet status ============="
./
$CHAIN33_CLI
--rpc_laddr
"http://localhost:
$port
"
wallet status
}
function
start
()
{
echo
"=========== # docker-compose ps ============="
docker-compose ps
docker-compose down
# create and run docker-compose container
docker-compose up
--build
-d
local
SLEEP
=
10
echo
"=========== sleep
${
SLEEP
}
s ============="
sleep
${
SLEEP
}
docker-compose ps
# query node run status
echo
"status"
check_docker_status
# ./chain33-cli --rpc_laddr http://localhost:18901 block last_header
$CLI
--rpc_laddr
http://localhost:8901 block last_header
}
function
check_docker_status
()
{
status
=
$(
docker-compose ps |
grep
parachain1_1 |
awk
'{print $6}'
)
statusPara
=
$(
docker-compose ps |
grep
parachain1_1 |
awk
'{print $3}'
)
if
[
"
${
status
}
"
==
"Exit"
]
||
[
"
${
statusPara
}
"
==
"Exit"
]
;
then
echo
"=========== chain33 service Exit logs ========== "
docker-compose logs parachain1
echo
"=========== chain33 service Exit logs End========== "
fi
}
function
check_docker_container
()
{
echo
"============== check_docker_container ==============================="
for
con
in
"
${
containers
[@]
}
"
;
do
runing
=
$(
docker inspect
"
${
con
}
"
| jq
'.[0].State.Running'
)
if
[
!
"
${
runing
}
"
]
;
then
docker inspect
"
${
con
}
"
echo
"check
${
con
}
not actived!"
exit
1
fi
done
}
function
query_tx
()
{
sleep
5
local times
=
100
while
true
;
do
ret
=
$(${
CLI
}
--rpc_laddr
http://localhost:8901 tx query
-s
"
${
1
}
"
| jq
-r
".tx.hash"
)
echo
"query hash is
${
1
}
, return
${
ret
}
"
if
[
"
${
ret
}
"
!=
"
${
1
}
"
]
;
then
sleep
5
times
=
$((
times
-
1
))
if
[
$times
-le
0
]
;
then
echo
"query tx=
$1
failed"
exit
1
fi
else
echo
"query tx=
$1
success"
break
fi
done
}
function
create_yml
()
{
touch
docker-compose.yml
cat
>>
docker-compose.yml
<<
EOF
version: '3'
services:
EOF
for
((
i
=
1
;
i <
=
${#
authAccount
[@]
}
;
i++
))
;
do
cat
>>
docker-compose.yml
<<
EOF
parachain
$i
:
build:
context: .
entrypoint: /root/entrypoint.sh
environment:
PARAFILE: "/root/chain33.para.
$i
.toml"
ports:
- "1890
$i
:8901"
volumes:
- "../storage/parachain
$i
/paradatadir:/root/paradatadir"
- "../storage/parachain
$i
/logs:/root/logs"
EOF
done
}
function
create_storage
()
{
mkdir
-p
storage
cd
storage
for
((
i
=
0
;
i <
${#
authAccount
[@]
}
;
i++
))
;
do
dirfile
=
"parachain
$i
"
mkdir
-p
"
$dirfile
"
done
cd
..
}
function
create_build
()
{
rm
-rf
$buildpath
mkdir
-p
$buildpath
cp
chain33
*
Dockerfile ./
*
.sh
"
$buildpath
"
/
cd
$buildpath
create_yml
}
function
para_create_nodegroup
()
{
echo
"=========== # para chain create node group ============="
local
auths
=
""
for
auth
in
"
${
authAccount
[@]
}
"
;
do
if
[
-z
$auths
]
;
then
auths
=
"
$auth
"
else
auths
=
"
$auths
,
$auth
"
fi
done
echo
"auths=
$auths
"
##apply
txhash
=
$(${
CLI
}
--rpc_laddr
http://localhost:8901
--paraName
"user.p.
$paraName
."
send para nodegroup apply
-a
"
$auths
"
-c
"
${
authFrozenCoins
}
"
-k
"
$applierPrikey
"
)
echo
"tx=
$txhash
"
query_tx
"
${
txhash
}
"
id
=
$txhash
echo
"need super manager approve id=
$txhash
"
if
[
-n
"
$superManagerPrikey
"
]
;
then
echo
"=========== # para chain approve node group ============="
##approve
txhash
=
$(${
CLI
}
--rpc_laddr
http://localhost:8901
--paraName
"user.p.
$paraName
."
send para nodegroup approve
-i
"
$id
"
-c
"
${
authFrozenCoins
}
"
-k
"
$superManagerPrikey
"
)
echo
"tx=
$txhash
"
query_tx
"
${
CLI
}
"
"
${
txhash
}
"
status
=
$(${
CLI
}
--rpc_laddr
http://localhost:8901
--paraName
"user.p.
$paraName
."
para nodegroup status | jq
-r
".status"
)
if
[
"
$status
"
!=
2
]
;
then
echo
"status not approve status=
$status
"
exit
1
fi
${
CLI
}
--rpc_laddr
http://localhost:8901
--paraName
"user.p.
$paraName
."
para nodegroup addrs
fi
echo
"======== super node group config end ==================="
}
function
main
()
{
echo
"==============================parachain startup op=
$1
========================================================"
### init para ####
if
[
"
$1
"
==
"start"
]
;
then
create_storage
create_build
para_init
### start docker ####
start
### finish ###
check_docker_container
fi
if
[
"
$1
"
==
"nodegroup"
]
;
then
para_create_nodegroup
fi
if
[
"
$1
"
==
"wallet"
]
;
then
para_set_wallet
fi
echo
"===============================parachain startup end========================================================="
}
# run script
main
"
$1
"
plugin/dapp/paracross/cmd/scripts/autodeploy/docker-compose.yml
0 → 100644
View file @
17b6b5f4
version
:
'
3'
services
:
\ No newline at end of file
plugin/dapp/paracross/cmd/scripts/autodeploy/entrypoint.sh
0 → 100755
View file @
17b6b5f4
#!/usr/bin/env bash
/root/chain33
-f
"
$PARAFILE
"
plugin/dapp/paracross/cmd/test/test-rpc.sh
View file @
17b6b5f4
...
...
@@ -293,36 +293,26 @@ function paracross_ListNodeStatus() {
para_test_addr
=
"1MAuE8QSbbech3bVKK2JPJJxYxNtT95oSU"
para_test_prikey
=
"0x24d1fad138be98eebee31440f144aa38c404533f40862995282162bc538e91c8"
function
paracross_testTxGroup
()
{
local
para_ip
=
$1
ispara
=
$(
echo
'"'
"
${
para_ip
}
"
'"'
| jq
'.|contains("8901")'
)
echo
"ipara=
$ispara
"
local
paracross_addr
=
""
local
main_ip
=
${
para_ip
//8901/8801
}
function
paracross_txgroupex
()
{
local
amount_transfer
=
$1
local
amount_trade
=
$2
local
para_ip
=
$3
paracross_addr
=
$(
curl
-ksd
'{"method":"Chain33.ConvertExectoAddr","params":[{"execname":"paracross"}]}'
"
${
main_ip
}
"
| jq
-r
".result"
)
echo
"paracross_addr=
$paracross_addr
"
#execer
local
paracross_execer_name
=
"user.p.para.paracross"
local
trade_exec_name
=
"user.p.para.trade"
local
trade_exec_addr
=
"12bihjzbaYWjcpDiiy9SuAWeqNksQdiN13"
local
amount_trade
=
100000000
local
amount_transfer
=
800000000
chain33_ImportPrivkey
"
${
para_test_prikey
}
"
"
${
para_test_addr
}
"
"paracross-transfer6"
"
${
main_ip
}
"
# tx fee + transfer 10 coins
chain33_applyCoins
"
${
para_test_addr
}
"
1000000000
"
${
main_ip
}
"
chain33_QueryBalance
"
${
para_test_addr
}
"
"
$main_ip
"
#deposit 8 coins to paracross
chain33_SendToAddress
"
${
para_test_addr
}
"
"
$paracross_addr
"
"
$amount_transfer
"
"
${
main_ip
}
"
chain33_QueryExecBalance
"
${
para_test_addr
}
"
"paracross"
"
${
main_ip
}
"
# 资产从主链转移到平行链
tx_hash_asset
=
$(
curl
-ksd
'{"method":"Chain33.CreateTransaction","params":[{"execer":"'
"
${
paracross_execer_name
}
"
'","actionName":"ParacrossAssetTransfer","payload":{"execName":"'
"
${
paracross_execer_name
}
"
'","to":"'
"
$para_test_addr
"
'","amount":'
${
amount_transfer
}
'}}]}'
"
${
para_ip
}
"
| jq
-r
".result"
)
#curl -ksd '{"method":"Chain33.CreateTransaction","params":[{"execer":"user.p.para.paracross","actionName":"ParacrossAssetTransfer","payload":{"execName":"user.p.para.paracross","to":"1MAuE8QSbbech3bVKK2JPJJxYxNtT95oSU","amount":100000000}}]}' http://172.20.0.5:8901
req
=
'"method":"Chain33.CreateTransaction","params":[{"execer":"'
"
${
paracross_execer_name
}
"
'","actionName":"ParacrossAssetTransfer","payload":{"execName":"'
"
${
paracross_execer_name
}
"
'","to":"'
"
$para_test_addr
"
'","amount":'
${
amount_transfer
}
'}}]'
echo
"
$req
"
resp
=
$(
curl
-ksd
"{
$req
}"
"
${
para_ip
}
"
)
# echo "$resp"
err
=
$(
jq
'(.error)'
<<<
"
$resp
"
)
if
[
"
$err
"
!=
null
]
;
then
echo
"
$resp
"
exit
1
fi
tx_hash_asset
=
$(
jq
-r
".result"
<<<
"
$resp
"
)
# tx_hash_asset=$(curl -ksd '{"method":"Chain33.CreateTransaction","params":[{"execer":"'"${paracross_execer_name}"'","actionName":"ParacrossAssetTransfer","payload":{"execName":"'"${paracross_execer_name}"'","to":"'"$para_test_addr"'","amount":'${amount_transfer}'}}]}' "${para_ip}" | jq -r ".result")
# 资产从平行链转移到平行链合约
req
=
'"method":"Chain33.CreateTransaction","params":[{"execer":"'
"
${
paracross_execer_name
}
"
'","actionName":"TransferToExec","payload":{"execName":"'
"
${
paracross_execer_name
}
"
'","to":"'
"
${
trade_exec_addr
}
"
'","amount":'
${
amount_trade
}
', "cointoken":"coins.bty"}}]'
...
...
@@ -348,19 +338,107 @@ function paracross_testTxGroup() {
#sign 1
tx_sign
=
$(
curl
-ksd
'{"method":"Chain33.SignRawTx","params":[{"privkey":"'
"
$para_test_prikey
"
'","txHex":"'
"
$tx_hash_group
"
'","index":2,"expire":"120s"}]}'
"
${
para_ip
}
"
| jq
-r
".result"
)
#curl -ksd '{"method":"Chain33.SignRawTx","params":[{"privkey":"0x24d1fad138be98eebee31440f144aa38c404533f40862995282162bc538e91c8","txHex":"0a10757365722e702e706172612e6e6f6e6512126e6f2d6665652d7472616e73616374696f6e1a6e080112210320bbac09528e19c55b0f89cb37ab265e7e856b1a8c388780322dbbfd194b52ba1a473045022100fe7763b2fa5b42eddccf1a3434cb6d6bb60a5c5c32e5498219e99be01bb94ad302201ecb9931a2bb4e1b0d49ec50ee552a774c1db8a1eb9b2dff47e4b931625e3af220e0a71230a89780b2a5b187990a3a2231466a58697076505142754e6f7a4133506150724b6846703854343166717141707640034a8c050a8e020a10757365722e702e706172612e6e6f6e6512126e6f2d6665652d7472616e73616374696f6e1a6e080112210320bbac09528e19c55b0f89cb37ab265e7e856b1a8c388780322dbbfd194b52ba1a473045022100fe7763b2fa5b42eddccf1a3434cb6d6bb60a5c5c32e5498219e99be01bb94ad302201ecb9931a2bb4e1b0d49ec50ee552a774c1db8a1eb9b2dff47e4b931625e3af220e0a71230a89780b2a5b187990a3a2231466a58697076505142754e6f7a4133506150724b6846703854343166717141707640034a2054ba4451fb8f226dd54b52ec086f4eaa4990d66876899b1badec8ce96ef55208522000f2e5970b5b1854da143f4f3e91bf7eb87d1d62869ef08a2ce3b109994ec3650abb010a15757365722e702e706172612e7061726163726f7373122e10904e22291080c2d72f2222314d41754538515362626563683362564b4b324a504a4a7859784e745439356f535530d195faf7d3a1ec9a4c3a223139574a4a7639366e4b4155347348465771476d7371666a786433376a617a71696940034a2054ba4451fb8f226dd54b52ec086f4eaa4990d66876899b1badec8ce96ef5520852208fb7939bf2701e5af9cef05da33020be682e10c84fde9bd8d24765031fad530b0aba010a15757365722e702e706172612e7061726163726f7373124f1004424b0a09636f696e732e6274791080ade2042215757365722e702e706172612e7061726163726f73732a2231326269686a7a626159576a637044696979395375415765714e6b735164694e313330a8c984ebb2bb90a5613a223139574a4a7639366e4b4155347348465771476d7371666a786433376a617a71696940034a2054ba4451fb8f226dd54b52ec086f4eaa4990d66876899b1badec8ce96ef55208522000f2e5970b5b1854da143f4f3e91bf7eb87d1d62869ef08a2ce3b109994ec365","index":2,"expire":"120s"}]}' http://172.20.0.5:8901
#sign 2
tx_sign2
=
$(
curl
-ksd
'{"method":"Chain33.SignRawTx","params":[{"privkey":"'
"
$para_test_prikey
"
'","txHex":"'
"
$tx_sign
"
'","index":3,"expire":"120s"}]}'
"
${
para_ip
}
"
| jq
-r
".result"
)
#curl -ksd '{"method":"Chain33.SignRawTx","params":[{"privkey":"0x24d1fad138be98eebee31440f144aa38c404533f40862995282162bc538e91c8","txHex":"0a10757365722e702e706172612e6e6f6e6512126e6f2d6665652d7472616e73616374696f6e1a6e080112210320bbac09528e19c55b0f89cb37ab265e7e856b1a8c388780322dbbfd194b52ba1a473045022100fe7763b2fa5b42eddccf1a3434cb6d6bb60a5c5c32e5498219e99be01bb94ad302201ecb9931a2bb4e1b0d49ec50ee552a774c1db8a1eb9b2dff47e4b931625e3af220e0a71230a89780b2a5b187990a3a2231466a58697076505142754e6f7a4133506150724b6846703854343166717141707640034afc050a8e020a10757365722e702e706172612e6e6f6e6512126e6f2d6665652d7472616e73616374696f6e1a6e080112210320bbac09528e19c55b0f89cb37ab265e7e856b1a8c388780322dbbfd194b52ba1a473045022100fe7763b2fa5b42eddccf1a3434cb6d6bb60a5c5c32e5498219e99be01bb94ad302201ecb9931a2bb4e1b0d49ec50ee552a774c1db8a1eb9b2dff47e4b931625e3af220e0a71230a89780b2a5b187990a3a2231466a58697076505142754e6f7a4133506150724b6846703854343166717141707640034a2054ba4451fb8f226dd54b52ec086f4eaa4990d66876899b1badec8ce96ef55208522000f2e5970b5b1854da143f4f3e91bf7eb87d1d62869ef08a2ce3b109994ec3650aab020a15757365722e702e706172612e7061726163726f7373122e10904e22291080c2d72f2222314d41754538515362626563683362564b4b324a504a4a7859784e745439356f53551a6e0801122103589ebf581958aeb8a72ff517f823c878aee16139ecbf0001a4611e9c004fecdf1a473045022100da5ad2bdc6e1e43a01d32c44f116e5d0bf96aa4c16debad49381ea5d11a49835022055a510460df9b63f8f585393d6603abf1388fac0e122b53ef3533f242287915730d195faf7d3a1ec9a4c3a223139574a4a7639366e4b4155347348465771476d7371666a786433376a617a71696940034a2054ba4451fb8f226dd54b52ec086f4eaa4990d66876899b1badec8ce96ef5520852208fb7939bf2701e5af9cef05da33020be682e10c84fde9bd8d24765031fad530b0aba010a15757365722e702e706172612e7061726163726f7373124f1004424b0a09636f696e732e6274791080ade2042215757365722e702e706172612e7061726163726f73732a2231326269686a7a626159576a637044696979395375415765714e6b735164694e313330a8c984ebb2bb90a5613a223139574a4a7639366e4b4155347348465771476d7371666a786433376a617a71696940034a2054ba4451fb8f226dd54b52ec086f4eaa4990d66876899b1badec8ce96ef55208522000f2e5970b5b1854da143f4f3e91bf7eb87d1d62869ef08a2ce3b109994ec365","index":3,"expire":"120s"}]}' http://172.20.0.5:8901
#send
chain33_SendTx
"
${
tx_sign2
}
"
"
${
para_ip
}
"
#tx_rst=$(curl -ksd '{"method":"Chain33.SendTransaction","params":[{"token":"BTY","data":"${tx_sign2}"}]'} "${para_ip}" | jq -r ".result" )
local
transfer_expect
=
"700000000"
}
//测试平行链交易组跨链失败,主链自动恢复原值
function
paracross_testTxGroupFail
()
{
local
para_ip
=
$1
ispara
=
$(
echo
'"'
"
${
para_ip
}
"
'"'
| jq
'.|contains("8901")'
)
echo
"ipara=
$ispara
"
local
paracross_addr
=
""
local
main_ip
=
${
para_ip
//8901/8801
}
paracross_addr
=
$(
curl
-ksd
'{"method":"Chain33.ConvertExectoAddr","params":[{"execname":"paracross"}]}'
"
${
main_ip
}
"
| jq
-r
".result"
)
echo
"paracross_addr=
$paracross_addr
"
#execer
local
trade_exec_addr
=
"12bihjzbaYWjcpDiiy9SuAWeqNksQdiN13"
//测试跨链过去1个,交易组转账8个失败的场景,主链应该还保持原来的
local
amount_trade
=
800000000
local
amount_transfer
=
100000000
local
amount_left
=
500000000
left_exec_val
=
$(
paracross_QueryMainBalance
"
${
para_test_addr
}
"
)
if
[
"
${
left_exec_val
}
"
!=
$amount_left
]
;
then
echo
"paracross_testTxGroupFail left main paracross failed, get=
$left_exec_val
,expec=
$amount_left
"
exit
1
fi
paracross_txgroupex
"
${
amount_transfer
}
"
"
${
amount_trade
}
"
"
${
para_ip
}
"
local
count
=
0
local times
=
100
local
paracross_execer_name
=
"user.p.para.paracross"
local
trade_exec_name
=
"user.p.para.trade"
local
transfer_expect
=
"200000000"
local
exec_expect
=
"100000000"
while
true
;
do
transfer_val
=
$(
paracross_QueryParaBalance
"
${
para_test_addr
}
"
"
$paracross_execer_name
"
)
transfer_exec_val
=
$(
paracross_QueryParaBalance
"
${
para_test_addr
}
"
"
$trade_exec_name
"
)
left_exec_val
=
$(
paracross_QueryMainBalance
"
${
para_test_addr
}
"
)
if
[
"
${
left_exec_val
}
"
!=
$amount_left
]
||
[
"
${
transfer_val
}
"
!=
$transfer_expect
]
||
[
"
${
transfer_exec_val
}
"
!=
$exec_expect
]
;
then
echo
"trans=
${
transfer_val
}
-expect=
${
transfer_expect
}
,trader=
${
transfer_exec_val
}
-expect=
${
exec_expect
}
,left=
${
left_exec_val
}
-expect=
${
amount_left
}
"
chain33_BlockWait 2
${
UNIT_HTTP
}
times
=
$((
times
-
1
))
if
[
$times
-le
0
]
;
then
echo
"para_cross_transfer_testfail failed"
exit
1
fi
echo
"paracross_testTxGroupFail left main paracross failed, get=
$left_exec_val
,expec=
$amount_left
"
else
count
=
$((
count
+
1
))
break
fi
done
[
"
$count
"
-eq
1
]
local
rst
=
$?
echo_rst
"
$FUNCNAME
"
"
$rst
"
}
function
paracross_testTxGroup
()
{
local
para_ip
=
$1
ispara
=
$(
echo
'"'
"
${
para_ip
}
"
'"'
| jq
'.|contains("8901")'
)
echo
"ipara=
$ispara
"
local
paracross_addr
=
""
local
main_ip
=
${
para_ip
//8901/8801
}
paracross_addr
=
$(
curl
-ksd
'{"method":"Chain33.ConvertExectoAddr","params":[{"execname":"paracross"}]}'
"
${
main_ip
}
"
| jq
-r
".result"
)
echo
"paracross_addr=
$paracross_addr
"
#execer
local
paracross_execer_name
=
"user.p.para.paracross"
local
trade_exec_name
=
"user.p.para.trade"
local
trade_exec_addr
=
"12bihjzbaYWjcpDiiy9SuAWeqNksQdiN13"
local
amount_trade
=
100000000
local
amount_deposit
=
800000000
local
amount_transfer
=
300000000
local
amount_left
=
500000000
chain33_ImportPrivkey
"
${
para_test_prikey
}
"
"
${
para_test_addr
}
"
"paracross-transfer6"
"
${
main_ip
}
"
# tx fee + transfer 10 coins
chain33_applyCoins
"
${
para_test_addr
}
"
1000000000
"
${
main_ip
}
"
chain33_QueryBalance
"
${
para_test_addr
}
"
"
$main_ip
"
#deposit 8 coins to paracross
chain33_SendToAddress
"
${
para_test_addr
}
"
"
$paracross_addr
"
"
$amount_deposit
"
"
${
main_ip
}
"
chain33_QueryExecBalance
"
${
para_test_addr
}
"
"paracross"
"
${
main_ip
}
"
paracross_txgroupex
"
${
amount_transfer
}
"
"
${
amount_trade
}
"
"
${
para_ip
}
"
local
transfer_expect
=
"200000000"
local
exec_expect
=
"100000000"
transfer_val
=
$(
paracross_QueryParaBalance
"
${
para_test_addr
}
"
"
$paracross_execer_name
"
)
transfer_exec_val
=
$(
paracross_QueryParaBalance
"
${
para_test_addr
}
"
"
$trade_exec_name
"
)
left_exec_val
=
$(
paracross_QueryMainBalance
"
${
para_test_addr
}
"
)
if
[
"
${
transfer_val
}
"
!=
$transfer_expect
]
;
then
echo
"paracross_testTxGroup trasfer failed, get=
$transfer_val
,expec=
$transfer_expect
"
exit
1
...
...
@@ -369,6 +447,10 @@ function paracross_testTxGroup() {
echo
"paracross_testTxGroup toexec failed, get=
$transfer_exec_val
,expec=
$exec_expect
"
exit
1
fi
if
[
"
${
left_exec_val
}
"
!=
$amount_left
]
;
then
echo
"paracross_testTxGroup left main paracross failed, get=
$left_exec_val
,expec=
$amount_left
"
exit
1
fi
echo_rst
"
$FUNCNAME
"
0
...
...
@@ -396,6 +478,10 @@ paracross_testSelfConsensStages() {
resp
=
$(
curl
-ksd
"{
$req
}"
"
${
para_ip
}
"
)
echo
"
$resp
"
id
=
$(
jq
-r
".result.stageInfo[0].id"
<<<
"
$resp
"
)
if
[
-z
"
$id
"
]
;
then
echo
"paracross stage apply id null"
exit
1
fi
echo
"vote id"
KS_PRI
=
"0x6da92a632ab7deb67d38c0f6560bcfed28167998f6496db64c258d5e8393a81b"
...
...
@@ -405,9 +491,12 @@ paracross_testSelfConsensStages() {
req
=
'"method":"Chain33.CreateTransaction","params":[{"execer" : "user.p.para.paracross","actionName" : "selfConsStageConfig","payload":{"title":"user.p.para.","op":"2","vote":{"id":"'
"
$id
"
'","value":1} }}]'
resp
=
$(
curl
-ksd
"{
$req
}"
"
${
para_ip
}
"
)
rawtx
=
$(
jq
-r
".result"
<<<
"
$resp
"
)
echo
"send vote 1"
chain33_SignRawTx
"
$rawtx
"
"
$KS_PRI
"
"
${
para_ip
}
"
chain33_SignRawTx
"
$rawtx
"
"
$JR_PRI
"
"
${
para_ip
}
"
chain33_SignRawTx
"
$rawtx
"
"
$NL_PRI
"
"
${
para_ip
}
"
echo
"send vote 2"
chain33_SignRawTx
"
$rawtx
"
"
$JR_PRI
"
"
${
para_ip
}
"
"110s"
echo
"send vote 3"
chain33_SignRawTx
"
$rawtx
"
"
$NL_PRI
"
"
${
para_ip
}
"
"111s"
echo
"query status"
req
=
'"method":"paracross.ListSelfStages","params":[{"status":3,"count":1}]'
...
...
@@ -446,6 +535,7 @@ function run_testcases() {
paracross_ListNodeStatus
paracross_Transfer_Withdraw
paracross_testTxGroup
"
$UNIT_HTTP
"
paracross_testTxGroupFail
"
$UNIT_HTTP
"
paracross_testSelfConsensStages
"
$UNIT_HTTP
"
}
...
...
plugin/dapp/paracross/commands/paracross.go
View file @
17b6b5f4
...
...
@@ -37,6 +37,7 @@ func ParcCmd() *cobra.Command {
paraConfigCmd
(),
GetParaInfoCmd
(),
GetParaListCmd
(),
GetParaAssetTransCmd
(),
IsSyncCmd
(),
GetHeightCmd
(),
GetBlockInfoCmd
(),
...
...
@@ -936,6 +937,35 @@ func getNodeGroupAddrsCmd() *cobra.Command {
return
cmd
}
func
addParaAssetTranCmdFlags
(
cmd
*
cobra
.
Command
)
{
cmd
.
Flags
()
.
StringP
(
"hash"
,
"s"
,
""
,
"asset transfer tx hash"
)
cmd
.
MarkFlagRequired
(
"hash"
)
}
func
paraAssetTransfer
(
cmd
*
cobra
.
Command
,
args
[]
string
)
{
rpcLaddr
,
_
:=
cmd
.
Flags
()
.
GetString
(
"rpc_laddr"
)
hash
,
_
:=
cmd
.
Flags
()
.
GetString
(
"hash"
)
params
:=
types
.
ReqString
{
Data
:
hash
,
}
var
res
pt
.
ParacrossAssetRsp
ctx
:=
jsonclient
.
NewRPCCtx
(
rpcLaddr
,
"paracross.GetAssetTxResult"
,
params
,
&
res
)
ctx
.
Run
()
}
// GetParaAssetTransCmd get para chain asset transfer info
func
GetParaAssetTransCmd
()
*
cobra
.
Command
{
cmd
:=
&
cobra
.
Command
{
Use
:
"asset_tranfer"
,
Short
:
"Get para chain cross asset transfer info"
,
Run
:
paraAssetTransfer
,
}
addParaAssetTranCmdFlags
(
cmd
)
return
cmd
}
func
nodeGroup
(
cmd
*
cobra
.
Command
,
args
[]
string
)
{
rpcLaddr
,
_
:=
cmd
.
Flags
()
.
GetString
(
"rpc_laddr"
)
paraName
,
_
:=
cmd
.
Flags
()
.
GetString
(
"paraName"
)
...
...
plugin/dapp/paracross/executor/action.go
View file @
17b6b5f4
...
...
@@ -318,10 +318,10 @@ func updateCommitAddrs(stat *pt.ParacrossHeightStatus, nodes map[string]struct{}
func
(
a
*
action
)
Commit
(
commit
*
pt
.
ParacrossCommitAction
)
(
*
types
.
Receipt
,
error
)
{
cfg
:=
a
.
api
.
GetConfig
()
if
cfg
.
IsPara
()
&&
cfg
.
IsDappFork
(
a
.
h
eight
,
pt
.
ParaX
,
pt
.
ForkParaSelfConsStages
)
{
if
cfg
.
IsPara
()
&&
cfg
.
IsDappFork
(
commit
.
Status
.
H
eight
,
pt
.
ParaX
,
pt
.
ForkParaSelfConsStages
)
{
//分叉之后,key不存在,自共识没配置也认为不支持自共识
isSelfConsOn
,
err
:=
isSelfConsOn
(
a
.
db
,
commit
.
Status
.
Height
)
if
err
!=
nil
{
if
err
!=
nil
&&
errors
.
Cause
(
err
)
!=
pt
.
ErrKeyNotExist
{
return
nil
,
err
}
if
!
isSelfConsOn
{
...
...
@@ -748,7 +748,7 @@ func (a *action) isAllowConsensJump(commit *pt.ParacrossCommitAction, titleStatu
}
func
(
a
*
action
)
execCrossTx
(
tx
*
types
.
TransactionDetail
,
crossTxHash
[]
byte
)
(
*
types
.
Receipt
,
error
)
{
func
execCrossTx
(
a
*
action
,
tx
*
types
.
TransactionDetail
,
crossTxHash
[]
byte
)
(
*
types
.
Receipt
,
error
)
{
if
!
bytes
.
HasSuffix
(
tx
.
Tx
.
Execer
,
[]
byte
(
pt
.
ParaX
))
{
return
nil
,
nil
}
...
...
@@ -762,7 +762,7 @@ func (a *action) execCrossTx(tx *types.TransactionDetail, crossTxHash []byte) (*
if
payload
.
Ty
==
pt
.
ParacrossActionAssetWithdraw
{
receiptWithdraw
,
err
:=
a
.
assetWithdraw
(
payload
.
GetAssetWithdraw
(),
tx
.
Tx
)
if
err
!=
nil
{
clog
.
Crit
(
"paracross.Commit
Decode
Tx failed"
,
"error"
,
err
,
"txHash"
,
hex
.
EncodeToString
(
crossTxHash
))
clog
.
Crit
(
"paracross.Commit
withdraw
Tx failed"
,
"error"
,
err
,
"txHash"
,
hex
.
EncodeToString
(
crossTxHash
))
return
nil
,
errors
.
Cause
(
err
)
}
...
...
@@ -773,6 +773,31 @@ func (a *action) execCrossTx(tx *types.TransactionDetail, crossTxHash []byte) (*
}
func
rollbackCrossTx
(
a
*
action
,
tx
*
types
.
TransactionDetail
,
crossTxHash
[]
byte
)
(
*
types
.
Receipt
,
error
)
{
if
!
bytes
.
HasSuffix
(
tx
.
Tx
.
Execer
,
[]
byte
(
pt
.
ParaX
))
{
return
nil
,
nil
}
var
payload
pt
.
ParacrossAction
err
:=
types
.
Decode
(
tx
.
Tx
.
Payload
,
&
payload
)
if
err
!=
nil
{
clog
.
Crit
(
"paracross.Commit.rollbackCrossTx Decode Tx failed"
,
"error"
,
err
,
"txHash"
,
hex
.
EncodeToString
(
crossTxHash
))
return
nil
,
err
}
if
payload
.
Ty
==
pt
.
ParacrossActionAssetTransfer
{
receipt
,
err
:=
a
.
assetTransferRollback
(
payload
.
GetAssetTransfer
(),
tx
.
Tx
)
if
err
!=
nil
{
clog
.
Crit
(
"paracross.Commit rbk Tx failed"
,
"error"
,
err
,
"txHash"
,
hex
.
EncodeToString
(
crossTxHash
))
return
nil
,
errors
.
Cause
(
err
)
}
clog
.
Debug
(
"paracross.Commit rollbackCrossTx"
,
"txHash"
,
hex
.
EncodeToString
(
crossTxHash
),
"mainHeight"
,
a
.
height
)
return
receipt
,
nil
}
return
nil
,
nil
}
func
getCrossTxHashsByRst
(
api
client
.
QueueProtocolAPI
,
status
*
pt
.
ParacrossNodeStatus
)
([][]
byte
,
[]
byte
,
error
)
{
//只获取跨链tx
cfg
:=
api
.
GetConfig
()
...
...
@@ -781,11 +806,13 @@ func getCrossTxHashsByRst(api client.QueueProtocolAPI, status *pt.ParacrossNodeS
clog
.
Error
(
"getCrossTxHashs decode rst"
,
"CrossTxResult"
,
string
(
status
.
TxResult
),
"paraHeight"
,
status
.
Height
)
return
nil
,
nil
,
types
.
ErrInvalidParam
}
clog
.
Debug
(
"getCrossTxHashsByRst"
,
"height"
,
status
.
Height
,
"txResult"
,
string
(
status
.
TxResult
))
//空块
if
!
cfg
.
IsDappFork
(
status
.
MainBlockHeight
,
pt
.
ParaX
,
pt
.
ForkParaAssetTransferRbk
)
{
if
len
(
rst
)
==
0
{
return
nil
,
nil
,
nil
}
}
blockDetail
,
err
:=
GetBlock
(
api
,
status
.
MainBlockHash
)
if
err
!=
nil
{
...
...
@@ -800,6 +827,7 @@ func getCrossTxHashsByRst(api client.QueueProtocolAPI, status *pt.ParacrossNodeS
}
paraCrossHashs
:=
FilterParaCrossTxHashes
(
paraAllTxs
)
crossRst
:=
util
.
CalcBitMapByBitMap
(
paraCrossHashs
,
baseHashs
,
rst
)
clog
.
Debug
(
"getCrossTxHashsByRst.crossRst"
,
"height"
,
status
.
Height
,
"txResult"
,
hex
.
EncodeToString
(
crossRst
),
"len"
,
len
(
paraCrossHashs
))
return
paraCrossHashs
,
crossRst
,
nil
...
...
@@ -858,6 +886,24 @@ func getCrossTxHashs(api client.QueueProtocolAPI, status *pt.ParacrossNodeStatus
}
func
crossTxProc
(
a
*
action
,
txHash
[]
byte
,
fn
func
(
*
action
,
*
types
.
TransactionDetail
,
[]
byte
)
(
*
types
.
Receipt
,
error
))
(
*
types
.
Receipt
,
error
)
{
tx
,
err
:=
GetTx
(
a
.
api
,
txHash
)
if
err
!=
nil
{
clog
.
Crit
(
"paracross.Commit Load Tx failed"
,
"error"
,
err
,
"txHash"
,
hex
.
EncodeToString
(
txHash
))
return
nil
,
err
}
if
tx
==
nil
{
clog
.
Error
(
"paracross.Commit Load Tx nil"
,
"error"
,
err
,
"txHash"
,
hex
.
EncodeToString
(
txHash
))
return
nil
,
types
.
ErrHashNotExist
}
receiptCross
,
err
:=
fn
(
a
,
tx
,
txHash
)
if
err
!=
nil
{
clog
.
Error
(
"paracross.Commit execCrossTx"
,
"error"
,
err
)
return
nil
,
errors
.
Cause
(
err
)
}
return
receiptCross
,
nil
}
func
(
a
*
action
)
execCrossTxs
(
status
*
pt
.
ParacrossNodeStatus
)
(
*
types
.
Receipt
,
error
)
{
var
receipt
types
.
Receipt
...
...
@@ -866,28 +912,30 @@ func (a *action) execCrossTxs(status *pt.ParacrossNodeStatus) (*types.Receipt, e
clog
.
Error
(
"paracross.Commit getCrossTxHashs"
,
"err"
,
err
.
Error
())
return
nil
,
err
}
if
len
(
crossTxHashs
)
==
0
{
return
&
receipt
,
nil
}
for
i
:=
0
;
i
<
len
(
crossTxHashs
);
i
++
{
clog
.
Debug
(
"paracross.Commit commitDone"
,
"do cross number"
,
i
,
"hash"
,
hex
.
EncodeToString
(
crossTxHashs
[
i
]),
"res"
,
util
.
BitMapBit
(
crossTxResult
,
uint32
(
i
)))
if
util
.
BitMapBit
(
crossTxResult
,
uint32
(
i
))
{
tx
,
err
:=
GetTx
(
a
.
api
,
crossTxHashs
[
i
]
)
receiptCross
,
err
:=
crossTxProc
(
a
,
crossTxHashs
[
i
],
execCrossTx
)
if
err
!=
nil
{
clog
.
Crit
(
"paracross.Commit Load Tx failed"
,
"para title"
,
t
itle
,
"para height"
,
status
.
Height
,
"para tx index"
,
i
,
"error"
,
err
,
"txHash"
,
hex
.
EncodeToString
(
crossTxHashs
[
i
])
)
return
nil
,
err
clog
.
Error
(
"paracross.Commit execCrossTx"
,
"para title"
,
status
.
T
itle
,
"para height"
,
status
.
Height
,
"para tx index"
,
i
,
"error"
,
err
)
return
nil
,
err
ors
.
Cause
(
err
)
}
if
tx
==
nil
{
clog
.
Error
(
"paracross.Commit Load Tx failed"
,
"para title"
,
title
,
"para height"
,
status
.
Height
,
"para tx index"
,
i
,
"error"
,
err
,
"txHash"
,
hex
.
EncodeToString
(
crossTxHashs
[
i
]))
return
nil
,
types
.
ErrHashNotExist
if
receiptCross
==
nil
{
continue
}
receiptCross
,
err
:=
a
.
execCrossTx
(
tx
,
crossTxHashs
[
i
])
receipt
.
KV
=
append
(
receipt
.
KV
,
receiptCross
.
KV
...
)
receipt
.
Logs
=
append
(
receipt
.
Logs
,
receiptCross
.
Logs
...
)
}
else
{
clog
.
Error
(
"paracross.Commit commitDone"
,
"do cross number"
,
i
,
"hash"
,
hex
.
EncodeToString
(
crossTxHashs
[
i
]),
"para res"
,
util
.
BitMapBit
(
crossTxResult
,
uint32
(
i
)))
cfg
:=
a
.
api
.
GetConfig
()
if
cfg
.
IsDappFork
(
a
.
height
,
pt
.
ParaX
,
pt
.
ForkParaAssetTransferRbk
)
{
receiptCross
,
err
:=
crossTxProc
(
a
,
crossTxHashs
[
i
],
rollbackCrossTx
)
if
err
!=
nil
{
clog
.
Error
(
"paracross.Commit execCrossTx"
,
"para title"
,
t
itle
,
"para height"
,
status
.
Height
,
clog
.
Error
(
"paracross.Commit rollbackCrossTx"
,
"para title"
,
status
.
T
itle
,
"para height"
,
status
.
Height
,
"para tx index"
,
i
,
"error"
,
err
)
return
nil
,
errors
.
Cause
(
err
)
}
...
...
@@ -896,10 +944,7 @@ func (a *action) execCrossTxs(status *pt.ParacrossNodeStatus) (*types.Receipt, e
}
receipt
.
KV
=
append
(
receipt
.
KV
,
receiptCross
.
KV
...
)
receipt
.
Logs
=
append
(
receipt
.
Logs
,
receiptCross
.
Logs
...
)
}
else
{
clog
.
Error
(
"paracross.Commit commitDone"
,
"do cross number"
,
i
,
"hash"
,
hex
.
EncodeToString
(
crossTxHashs
[
i
]),
"para res"
,
util
.
BitMapBit
(
crossTxResult
,
uint32
(
i
)))
}
}
}
...
...
plugin/dapp/paracross/executor/asset.go
View file @
17b6b5f4
...
...
@@ -87,6 +87,24 @@ func (a *action) assetWithdraw(withdraw *types.AssetsWithdraw, withdrawTx *types
return
assetWithdrawBalance
(
paraAcc
,
a
.
fromaddr
,
withdraw
.
Amount
)
}
func
(
a
*
action
)
assetTransferRollback
(
transfer
*
types
.
AssetsTransfer
,
transferTx
*
types
.
Transaction
)
(
*
types
.
Receipt
,
error
)
{
cfg
:=
a
.
api
.
GetConfig
()
isPara
:=
cfg
.
IsPara
()
//主链处理分支
if
!
isPara
{
accDB
,
err
:=
createAccount
(
cfg
,
a
.
db
,
transfer
.
Cointoken
)
if
err
!=
nil
{
return
nil
,
errors
.
Wrap
(
err
,
"assetTransferToken call account.NewAccountDB failed"
)
}
execAddr
:=
address
.
ExecAddress
(
pt
.
ParaX
)
fromAcc
:=
address
.
ExecAddress
(
string
(
transferTx
.
Execer
))
clog
.
Debug
(
"paracross.AssetTransferRbk "
,
"execer"
,
string
(
transferTx
.
Execer
),
"transfer.txHash"
,
hex
.
EncodeToString
(
transferTx
.
Hash
()),
"curTx"
,
hex
.
EncodeToString
(
a
.
tx
.
Hash
()))
return
accDB
.
ExecTransfer
(
fromAcc
,
transferTx
.
From
(),
execAddr
,
transfer
.
Amount
)
}
return
nil
,
nil
}
func
createAccount
(
cfg
*
types
.
Chain33Config
,
db
db
.
KV
,
symbol
string
)
(
*
account
.
DB
,
error
)
{
var
accDB
*
account
.
DB
var
err
error
...
...
plugin/dapp/paracross/executor/exec_local.go
View file @
17b6b5f4
...
...
@@ -228,6 +228,7 @@ func setMinerTxResultFork(cfg *types.Chain33Config, status *pt.ParacrossNodeStat
//主链自己过滤平行链tx, 对平行链执行失败的tx主链无法识别,主链和平行链需要获取相同的最初的tx map
//全部平行链tx结果
status
.
TxResult
=
[]
byte
(
hex
.
EncodeToString
(
util
.
CalcSingleBitMap
(
curTxHashs
,
receipts
)))
clog
.
Debug
(
"setMinerTxResultFork"
,
"height"
,
status
.
Height
,
"txResult"
,
string
(
status
.
TxResult
))
//ForkLoopCheckCommitTxDone 后只保留全部txreseult 结果
if
!
pt
.
IsParaForkHeight
(
cfg
,
status
.
MainBlockHeight
,
pt
.
ForkLoopCheckCommitTxDone
)
{
...
...
plugin/dapp/paracross/executor/query.go
View file @
17b6b5f4
...
...
@@ -218,11 +218,15 @@ func (p *Paracross) Query_GetDoneTitleHeight(in *pt.ReqParacrossTitleHeight) (ty
}
// Query_GetAssetTxResult query get asset tx reseult
func
(
p
*
Paracross
)
Query_GetAssetTxResult
(
in
*
types
.
Req
Hash
)
(
types
.
Message
,
error
)
{
if
in
==
nil
{
func
(
p
*
Paracross
)
Query_GetAssetTxResult
(
in
*
types
.
Req
String
)
(
types
.
Message
,
error
)
{
if
in
==
nil
||
in
.
Data
==
""
{
return
nil
,
types
.
ErrInvalidParam
}
return
p
.
paracrossGetAssetTxResult
(
in
.
Hash
)
hash
,
err
:=
common
.
FromHex
(
in
.
Data
)
if
err
!=
nil
{
return
nil
,
errors
.
Wrap
(
err
,
"fromHex"
)
}
return
p
.
paracrossGetAssetTxResult
(
hash
)
}
// Query_GetMainBlockHash query get mainblockHash by tx
...
...
@@ -296,7 +300,7 @@ func listLocalTitles(db dbm.KVDB) (types.Message, error) {
MostSameCommit
:
st
.
MostSameCommit
,
Title
:
st
.
Title
,
Height
:
st
.
Height
,
TxResult
:
hex
.
EncodeToS
tring
(
st
.
TxResult
),
TxResult
:
s
tring
(
st
.
TxResult
),
}
resp
.
Titles
=
append
(
resp
.
Titles
,
rst
)
...
...
@@ -400,13 +404,34 @@ func (p *Paracross) paracrossGetAssetTxResult(hash []byte) (types.Message, error
return
nil
,
err
}
var
r
esul
t
pt
.
ParacrossAsset
err
=
types
.
Decode
(
value
,
&
r
esul
t
)
var
r
s
t
pt
.
ParacrossAsset
err
=
types
.
Decode
(
value
,
&
r
s
t
)
if
err
!=
nil
{
return
nil
,
err
}
return
&
result
,
nil
rsp
:=
&
pt
.
ParacrossAssetRsp
{
From
:
rst
.
From
,
To
:
rst
.
To
,
Amount
:
rst
.
Amount
,
Exec
:
rst
.
Exec
,
Symbol
:
rst
.
Symbol
,
Height
:
rst
.
Height
,
CommitDoneHeight
:
rst
.
CommitDoneHeight
,
ParaHeight
:
rst
.
ParaHeight
,
}
rsp
.
TxHash
=
common
.
ToHex
(
rst
.
TxHash
)
rsp
.
IsWithdraw
=
"false"
if
rst
.
IsWithdraw
{
rsp
.
IsWithdraw
=
"true"
}
rsp
.
Success
=
"false"
if
rst
.
Success
{
rsp
.
Success
=
"true"
}
return
rsp
,
nil
}
//Query_GetSelfConsStages get self consensus stages configed
...
...
plugin/dapp/paracross/proto/paracross.proto
View file @
17b6b5f4
...
...
@@ -385,6 +385,23 @@ message ParacrossAsset {
bool
success
=
23
;
}
message
ParacrossAssetRsp
{
// input
string
from
=
1
;
string
to
=
2
;
string
isWithdraw
=
3
;
string
txHash
=
4
;
int64
amount
=
5
;
string
exec
=
6
;
string
symbol
=
7
;
// 主链部分
int64
height
=
10
;
// 平行链部分
int64
commitDoneHeight
=
21
;
int64
paraHeight
=
22
;
string
success
=
23
;
}
message
ParaLocalDbBlock
{
int64
height
=
1
;
bytes
mainHash
=
2
;
...
...
@@ -408,6 +425,6 @@ service paracross {
rpc
ListTitles
(
ReqNil
)
returns
(
RespParacrossTitles
)
{}
rpc
GetDoneTitleHeight
(
ReqParacrossTitleHeight
)
returns
(
RespParacrossDone
)
{}
rpc
GetTitleHeight
(
ReqParacrossTitleHeight
)
returns
(
ParacrossHeightStatusRsp
)
{}
rpc
GetAssetTxResult
(
Req
Hash
)
returns
(
ParacrossAsset
)
{}
rpc
GetAssetTxResult
(
Req
String
)
returns
(
ParacrossAssetRsp
)
{}
rpc
IsSync
(
ReqNil
)
returns
(
IsCaughtUp
)
{}
}
\ No newline at end of file
plugin/dapp/paracross/rpc/rpc.go
View file @
17b6b5f4
...
...
@@ -118,20 +118,20 @@ func (c *channelClient) GetDoneTitleHeight(ctx context.Context, req *pt.ReqParac
return
nil
,
types
.
ErrDecode
}
func
(
c
*
channelClient
)
GetAssetTxResult
(
ctx
context
.
Context
,
req
*
types
.
Req
Hash
)
(
*
pt
.
ParacrossAsset
,
error
)
{
func
(
c
*
channelClient
)
GetAssetTxResult
(
ctx
context
.
Context
,
req
*
types
.
Req
String
)
(
*
pt
.
ParacrossAssetRsp
,
error
)
{
cfg
:=
c
.
GetConfig
()
data
,
err
:=
c
.
Query
(
pt
.
GetExecName
(
cfg
),
"GetAssetTxResult"
,
req
)
if
err
!=
nil
{
return
nil
,
err
}
if
resp
,
ok
:=
data
.
(
*
pt
.
ParacrossAsset
);
ok
{
if
resp
,
ok
:=
data
.
(
*
pt
.
ParacrossAsset
Rsp
);
ok
{
return
resp
,
nil
}
return
nil
,
types
.
ErrDecode
}
// GetAssetTxResult get asset tx result
func
(
c
*
Jrpc
)
GetAssetTxResult
(
req
*
types
.
Req
Hash
,
result
*
interface
{})
error
{
func
(
c
*
Jrpc
)
GetAssetTxResult
(
req
*
types
.
Req
String
,
result
*
interface
{})
error
{
if
req
==
nil
{
return
types
.
ErrInvalidParam
}
...
...
plugin/dapp/paracross/rpc/rpc_test.go
View file @
17b6b5f4
...
...
@@ -124,8 +124,8 @@ func TestChannelClient_GetAssetTxResult(t *testing.T) {
api
.
On
(
"GetConfig"
,
mock
.
Anything
)
.
Return
(
cfg
,
nil
)
client
:=
newGrpc
(
api
)
client
.
Init
(
"paracross"
,
nil
,
nil
,
nil
)
req
:=
&
types
.
Req
Hash
{}
api
.
On
(
"Query"
,
pt
.
GetExecName
(
cfg
),
"GetAssetTxResult"
,
req
)
.
Return
(
&
pt
.
ParacrossAsset
{},
nil
)
req
:=
&
types
.
Req
String
{}
api
.
On
(
"Query"
,
pt
.
GetExecName
(
cfg
),
"GetAssetTxResult"
,
req
)
.
Return
(
&
pt
.
ParacrossAsset
Rsp
{},
nil
)
_
,
err
:=
client
.
GetAssetTxResult
(
context
.
Background
(),
req
)
assert
.
Nil
(
t
,
err
)
}
...
...
@@ -135,9 +135,9 @@ func TestJrpc_GetAssetTxResult(t *testing.T) {
api
:=
new
(
mocks
.
QueueProtocolAPI
)
api
.
On
(
"GetConfig"
,
mock
.
Anything
)
.
Return
(
cfg
,
nil
)
j
:=
newJrpc
(
api
)
req
:=
&
types
.
Req
Hash
{}
req
:=
&
types
.
Req
String
{}
var
result
interface
{}
api
.
On
(
"Query"
,
pt
.
GetExecName
(
cfg
),
"GetAssetTxResult"
,
req
)
.
Return
(
&
pt
.
ParacrossAsset
{},
nil
)
api
.
On
(
"Query"
,
pt
.
GetExecName
(
cfg
),
"GetAssetTxResult"
,
req
)
.
Return
(
&
pt
.
ParacrossAsset
Rsp
{},
nil
)
err
:=
j
.
GetAssetTxResult
(
req
,
&
result
)
assert
.
Nil
(
t
,
err
)
}
...
...
plugin/dapp/paracross/types/paracross.pb.go
View file @
17b6b5f4
...
...
@@ -41,7 +41,7 @@ func (m *ParacrossStatusDetails) Reset() { *m = ParacrossStatusDetails{}
func
(
m
*
ParacrossStatusDetails
)
String
()
string
{
return
proto
.
CompactTextString
(
m
)
}
func
(
*
ParacrossStatusDetails
)
ProtoMessage
()
{}
func
(
*
ParacrossStatusDetails
)
Descriptor
()
([]
byte
,
[]
int
)
{
return
fileDescriptor_paracross_
e0081cf2748ff01a
,
[]
int
{
0
}
return
fileDescriptor_paracross_
313193799a5638f5
,
[]
int
{
0
}
}
func
(
m
*
ParacrossStatusDetails
)
XXX_Unmarshal
(
b
[]
byte
)
error
{
return
xxx_messageInfo_ParacrossStatusDetails
.
Unmarshal
(
m
,
b
)
...
...
@@ -88,7 +88,7 @@ func (m *ParacrossStatusBlockDetails) Reset() { *m = ParacrossStatusBloc
func
(
m
*
ParacrossStatusBlockDetails
)
String
()
string
{
return
proto
.
CompactTextString
(
m
)
}
func
(
*
ParacrossStatusBlockDetails
)
ProtoMessage
()
{}
func
(
*
ParacrossStatusBlockDetails
)
Descriptor
()
([]
byte
,
[]
int
)
{
return
fileDescriptor_paracross_
e0081cf2748ff01a
,
[]
int
{
1
}
return
fileDescriptor_paracross_
313193799a5638f5
,
[]
int
{
1
}
}
func
(
m
*
ParacrossStatusBlockDetails
)
XXX_Unmarshal
(
b
[]
byte
)
error
{
return
xxx_messageInfo_ParacrossStatusBlockDetails
.
Unmarshal
(
m
,
b
)
...
...
@@ -140,7 +140,7 @@ func (m *ParacrossHeightStatus) Reset() { *m = ParacrossHeightStatus{} }
func
(
m
*
ParacrossHeightStatus
)
String
()
string
{
return
proto
.
CompactTextString
(
m
)
}
func
(
*
ParacrossHeightStatus
)
ProtoMessage
()
{}
func
(
*
ParacrossHeightStatus
)
Descriptor
()
([]
byte
,
[]
int
)
{
return
fileDescriptor_paracross_
e0081cf2748ff01a
,
[]
int
{
2
}
return
fileDescriptor_paracross_
313193799a5638f5
,
[]
int
{
2
}
}
func
(
m
*
ParacrossHeightStatus
)
XXX_Unmarshal
(
b
[]
byte
)
error
{
return
xxx_messageInfo_ParacrossHeightStatus
.
Unmarshal
(
m
,
b
)
...
...
@@ -226,7 +226,7 @@ func (m *ParacrossHeightStatusRsp) Reset() { *m = ParacrossHeightStatusR
func
(
m
*
ParacrossHeightStatusRsp
)
String
()
string
{
return
proto
.
CompactTextString
(
m
)
}
func
(
*
ParacrossHeightStatusRsp
)
ProtoMessage
()
{}
func
(
*
ParacrossHeightStatusRsp
)
Descriptor
()
([]
byte
,
[]
int
)
{
return
fileDescriptor_paracross_
e0081cf2748ff01a
,
[]
int
{
3
}
return
fileDescriptor_paracross_
313193799a5638f5
,
[]
int
{
3
}
}
func
(
m
*
ParacrossHeightStatusRsp
)
XXX_Unmarshal
(
b
[]
byte
)
error
{
return
xxx_messageInfo_ParacrossHeightStatusRsp
.
Unmarshal
(
m
,
b
)
...
...
@@ -310,7 +310,7 @@ func (m *ParacrossStatus) Reset() { *m = ParacrossStatus{} }
func
(
m
*
ParacrossStatus
)
String
()
string
{
return
proto
.
CompactTextString
(
m
)
}
func
(
*
ParacrossStatus
)
ProtoMessage
()
{}
func
(
*
ParacrossStatus
)
Descriptor
()
([]
byte
,
[]
int
)
{
return
fileDescriptor_paracross_
e0081cf2748ff01a
,
[]
int
{
4
}
return
fileDescriptor_paracross_
313193799a5638f5
,
[]
int
{
4
}
}
func
(
m
*
ParacrossStatus
)
XXX_Unmarshal
(
b
[]
byte
)
error
{
return
xxx_messageInfo_ParacrossStatus
.
Unmarshal
(
m
,
b
)
...
...
@@ -379,7 +379,7 @@ func (m *ParacrossConsensusStatus) Reset() { *m = ParacrossConsensusStat
func
(
m
*
ParacrossConsensusStatus
)
String
()
string
{
return
proto
.
CompactTextString
(
m
)
}
func
(
*
ParacrossConsensusStatus
)
ProtoMessage
()
{}
func
(
*
ParacrossConsensusStatus
)
Descriptor
()
([]
byte
,
[]
int
)
{
return
fileDescriptor_paracross_
e0081cf2748ff01a
,
[]
int
{
5
}
return
fileDescriptor_paracross_
313193799a5638f5
,
[]
int
{
5
}
}
func
(
m
*
ParacrossConsensusStatus
)
XXX_Unmarshal
(
b
[]
byte
)
error
{
return
xxx_messageInfo_ParacrossConsensusStatus
.
Unmarshal
(
m
,
b
)
...
...
@@ -443,7 +443,7 @@ func (m *ParaNodeAddrConfig) Reset() { *m = ParaNodeAddrConfig{} }
func
(
m
*
ParaNodeAddrConfig
)
String
()
string
{
return
proto
.
CompactTextString
(
m
)
}
func
(
*
ParaNodeAddrConfig
)
ProtoMessage
()
{}
func
(
*
ParaNodeAddrConfig
)
Descriptor
()
([]
byte
,
[]
int
)
{
return
fileDescriptor_paracross_
e0081cf2748ff01a
,
[]
int
{
6
}
return
fileDescriptor_paracross_
313193799a5638f5
,
[]
int
{
6
}
}
func
(
m
*
ParaNodeAddrConfig
)
XXX_Unmarshal
(
b
[]
byte
)
error
{
return
xxx_messageInfo_ParaNodeAddrConfig
.
Unmarshal
(
m
,
b
)
...
...
@@ -517,7 +517,7 @@ func (m *ParaNodeVoteDetail) Reset() { *m = ParaNodeVoteDetail{} }
func
(
m
*
ParaNodeVoteDetail
)
String
()
string
{
return
proto
.
CompactTextString
(
m
)
}
func
(
*
ParaNodeVoteDetail
)
ProtoMessage
()
{}
func
(
*
ParaNodeVoteDetail
)
Descriptor
()
([]
byte
,
[]
int
)
{
return
fileDescriptor_paracross_
e0081cf2748ff01a
,
[]
int
{
7
}
return
fileDescriptor_paracross_
313193799a5638f5
,
[]
int
{
7
}
}
func
(
m
*
ParaNodeVoteDetail
)
XXX_Unmarshal
(
b
[]
byte
)
error
{
return
xxx_messageInfo_ParaNodeVoteDetail
.
Unmarshal
(
m
,
b
)
...
...
@@ -566,7 +566,7 @@ func (m *ParaNodeAddrIdStatus) Reset() { *m = ParaNodeAddrIdStatus{} }
func
(
m
*
ParaNodeAddrIdStatus
)
String
()
string
{
return
proto
.
CompactTextString
(
m
)
}
func
(
*
ParaNodeAddrIdStatus
)
ProtoMessage
()
{}
func
(
*
ParaNodeAddrIdStatus
)
Descriptor
()
([]
byte
,
[]
int
)
{
return
fileDescriptor_paracross_
e0081cf2748ff01a
,
[]
int
{
8
}
return
fileDescriptor_paracross_
313193799a5638f5
,
[]
int
{
8
}
}
func
(
m
*
ParaNodeAddrIdStatus
)
XXX_Unmarshal
(
b
[]
byte
)
error
{
return
xxx_messageInfo_ParaNodeAddrIdStatus
.
Unmarshal
(
m
,
b
)
...
...
@@ -639,7 +639,7 @@ func (m *ParaNodeIdStatus) Reset() { *m = ParaNodeIdStatus{} }
func
(
m
*
ParaNodeIdStatus
)
String
()
string
{
return
proto
.
CompactTextString
(
m
)
}
func
(
*
ParaNodeIdStatus
)
ProtoMessage
()
{}
func
(
*
ParaNodeIdStatus
)
Descriptor
()
([]
byte
,
[]
int
)
{
return
fileDescriptor_paracross_
e0081cf2748ff01a
,
[]
int
{
9
}
return
fileDescriptor_paracross_
313193799a5638f5
,
[]
int
{
9
}
}
func
(
m
*
ParaNodeIdStatus
)
XXX_Unmarshal
(
b
[]
byte
)
error
{
return
xxx_messageInfo_ParaNodeIdStatus
.
Unmarshal
(
m
,
b
)
...
...
@@ -729,7 +729,7 @@ func (m *ReceiptParaNodeConfig) Reset() { *m = ReceiptParaNodeConfig{} }
func
(
m
*
ReceiptParaNodeConfig
)
String
()
string
{
return
proto
.
CompactTextString
(
m
)
}
func
(
*
ReceiptParaNodeConfig
)
ProtoMessage
()
{}
func
(
*
ReceiptParaNodeConfig
)
Descriptor
()
([]
byte
,
[]
int
)
{
return
fileDescriptor_paracross_
e0081cf2748ff01a
,
[]
int
{
10
}
return
fileDescriptor_paracross_
313193799a5638f5
,
[]
int
{
10
}
}
func
(
m
*
ReceiptParaNodeConfig
)
XXX_Unmarshal
(
b
[]
byte
)
error
{
return
xxx_messageInfo_ReceiptParaNodeConfig
.
Unmarshal
(
m
,
b
)
...
...
@@ -790,7 +790,7 @@ func (m *ReceiptParaNodeAddrStatUpdate) Reset() { *m = ReceiptParaNodeAd
func
(
m
*
ReceiptParaNodeAddrStatUpdate
)
String
()
string
{
return
proto
.
CompactTextString
(
m
)
}
func
(
*
ReceiptParaNodeAddrStatUpdate
)
ProtoMessage
()
{}
func
(
*
ReceiptParaNodeAddrStatUpdate
)
Descriptor
()
([]
byte
,
[]
int
)
{
return
fileDescriptor_paracross_
e0081cf2748ff01a
,
[]
int
{
11
}
return
fileDescriptor_paracross_
313193799a5638f5
,
[]
int
{
11
}
}
func
(
m
*
ReceiptParaNodeAddrStatUpdate
)
XXX_Unmarshal
(
b
[]
byte
)
error
{
return
xxx_messageInfo_ReceiptParaNodeAddrStatUpdate
.
Unmarshal
(
m
,
b
)
...
...
@@ -849,7 +849,7 @@ func (m *ReceiptParaNodeVoteDone) Reset() { *m = ReceiptParaNodeVoteDone
func
(
m
*
ReceiptParaNodeVoteDone
)
String
()
string
{
return
proto
.
CompactTextString
(
m
)
}
func
(
*
ReceiptParaNodeVoteDone
)
ProtoMessage
()
{}
func
(
*
ReceiptParaNodeVoteDone
)
Descriptor
()
([]
byte
,
[]
int
)
{
return
fileDescriptor_paracross_
e0081cf2748ff01a
,
[]
int
{
12
}
return
fileDescriptor_paracross_
313193799a5638f5
,
[]
int
{
12
}
}
func
(
m
*
ReceiptParaNodeVoteDone
)
XXX_Unmarshal
(
b
[]
byte
)
error
{
return
xxx_messageInfo_ReceiptParaNodeVoteDone
.
Unmarshal
(
m
,
b
)
...
...
@@ -940,7 +940,7 @@ func (m *ParaNodeGroupConfig) Reset() { *m = ParaNodeGroupConfig{} }
func
(
m
*
ParaNodeGroupConfig
)
String
()
string
{
return
proto
.
CompactTextString
(
m
)
}
func
(
*
ParaNodeGroupConfig
)
ProtoMessage
()
{}
func
(
*
ParaNodeGroupConfig
)
Descriptor
()
([]
byte
,
[]
int
)
{
return
fileDescriptor_paracross_
e0081cf2748ff01a
,
[]
int
{
13
}
return
fileDescriptor_paracross_
313193799a5638f5
,
[]
int
{
13
}
}
func
(
m
*
ParaNodeGroupConfig
)
XXX_Unmarshal
(
b
[]
byte
)
error
{
return
xxx_messageInfo_ParaNodeGroupConfig
.
Unmarshal
(
m
,
b
)
...
...
@@ -1012,7 +1012,7 @@ func (m *ParaNodeGroupStatus) Reset() { *m = ParaNodeGroupStatus{} }
func
(
m
*
ParaNodeGroupStatus
)
String
()
string
{
return
proto
.
CompactTextString
(
m
)
}
func
(
*
ParaNodeGroupStatus
)
ProtoMessage
()
{}
func
(
*
ParaNodeGroupStatus
)
Descriptor
()
([]
byte
,
[]
int
)
{
return
fileDescriptor_paracross_
e0081cf2748ff01a
,
[]
int
{
14
}
return
fileDescriptor_paracross_
313193799a5638f5
,
[]
int
{
14
}
}
func
(
m
*
ParaNodeGroupStatus
)
XXX_Unmarshal
(
b
[]
byte
)
error
{
return
xxx_messageInfo_ParaNodeGroupStatus
.
Unmarshal
(
m
,
b
)
...
...
@@ -1095,7 +1095,7 @@ func (m *ReceiptParaNodeGroupConfig) Reset() { *m = ReceiptParaNodeGroup
func
(
m
*
ReceiptParaNodeGroupConfig
)
String
()
string
{
return
proto
.
CompactTextString
(
m
)
}
func
(
*
ReceiptParaNodeGroupConfig
)
ProtoMessage
()
{}
func
(
*
ReceiptParaNodeGroupConfig
)
Descriptor
()
([]
byte
,
[]
int
)
{
return
fileDescriptor_paracross_
e0081cf2748ff01a
,
[]
int
{
15
}
return
fileDescriptor_paracross_
313193799a5638f5
,
[]
int
{
15
}
}
func
(
m
*
ReceiptParaNodeGroupConfig
)
XXX_Unmarshal
(
b
[]
byte
)
error
{
return
xxx_messageInfo_ReceiptParaNodeGroupConfig
.
Unmarshal
(
m
,
b
)
...
...
@@ -1158,7 +1158,7 @@ func (m *ReqParacrossNodeInfo) Reset() { *m = ReqParacrossNodeInfo{} }
func
(
m
*
ReqParacrossNodeInfo
)
String
()
string
{
return
proto
.
CompactTextString
(
m
)
}
func
(
*
ReqParacrossNodeInfo
)
ProtoMessage
()
{}
func
(
*
ReqParacrossNodeInfo
)
Descriptor
()
([]
byte
,
[]
int
)
{
return
fileDescriptor_paracross_
e0081cf2748ff01a
,
[]
int
{
16
}
return
fileDescriptor_paracross_
313193799a5638f5
,
[]
int
{
16
}
}
func
(
m
*
ReqParacrossNodeInfo
)
XXX_Unmarshal
(
b
[]
byte
)
error
{
return
xxx_messageInfo_ReqParacrossNodeInfo
.
Unmarshal
(
m
,
b
)
...
...
@@ -1217,7 +1217,7 @@ func (m *RespParacrossNodeAddrs) Reset() { *m = RespParacrossNodeAddrs{}
func
(
m
*
RespParacrossNodeAddrs
)
String
()
string
{
return
proto
.
CompactTextString
(
m
)
}
func
(
*
RespParacrossNodeAddrs
)
ProtoMessage
()
{}
func
(
*
RespParacrossNodeAddrs
)
Descriptor
()
([]
byte
,
[]
int
)
{
return
fileDescriptor_paracross_
e0081cf2748ff01a
,
[]
int
{
17
}
return
fileDescriptor_paracross_
313193799a5638f5
,
[]
int
{
17
}
}
func
(
m
*
RespParacrossNodeAddrs
)
XXX_Unmarshal
(
b
[]
byte
)
error
{
return
xxx_messageInfo_RespParacrossNodeAddrs
.
Unmarshal
(
m
,
b
)
...
...
@@ -1255,7 +1255,7 @@ func (m *RespParacrossNodeGroups) Reset() { *m = RespParacrossNodeGroups
func
(
m
*
RespParacrossNodeGroups
)
String
()
string
{
return
proto
.
CompactTextString
(
m
)
}
func
(
*
RespParacrossNodeGroups
)
ProtoMessage
()
{}
func
(
*
RespParacrossNodeGroups
)
Descriptor
()
([]
byte
,
[]
int
)
{
return
fileDescriptor_paracross_
e0081cf2748ff01a
,
[]
int
{
18
}
return
fileDescriptor_paracross_
313193799a5638f5
,
[]
int
{
18
}
}
func
(
m
*
RespParacrossNodeGroups
)
XXX_Unmarshal
(
b
[]
byte
)
error
{
return
xxx_messageInfo_RespParacrossNodeGroups
.
Unmarshal
(
m
,
b
)
...
...
@@ -1296,7 +1296,7 @@ func (m *ParaBlock2MainMap) Reset() { *m = ParaBlock2MainMap{} }
func
(
m
*
ParaBlock2MainMap
)
String
()
string
{
return
proto
.
CompactTextString
(
m
)
}
func
(
*
ParaBlock2MainMap
)
ProtoMessage
()
{}
func
(
*
ParaBlock2MainMap
)
Descriptor
()
([]
byte
,
[]
int
)
{
return
fileDescriptor_paracross_
e0081cf2748ff01a
,
[]
int
{
19
}
return
fileDescriptor_paracross_
313193799a5638f5
,
[]
int
{
19
}
}
func
(
m
*
ParaBlock2MainMap
)
XXX_Unmarshal
(
b
[]
byte
)
error
{
return
xxx_messageInfo_ParaBlock2MainMap
.
Unmarshal
(
m
,
b
)
...
...
@@ -1355,7 +1355,7 @@ func (m *ParaBlock2MainInfo) Reset() { *m = ParaBlock2MainInfo{} }
func
(
m
*
ParaBlock2MainInfo
)
String
()
string
{
return
proto
.
CompactTextString
(
m
)
}
func
(
*
ParaBlock2MainInfo
)
ProtoMessage
()
{}
func
(
*
ParaBlock2MainInfo
)
Descriptor
()
([]
byte
,
[]
int
)
{
return
fileDescriptor_paracross_
e0081cf2748ff01a
,
[]
int
{
20
}
return
fileDescriptor_paracross_
313193799a5638f5
,
[]
int
{
20
}
}
func
(
m
*
ParaBlock2MainInfo
)
XXX_Unmarshal
(
b
[]
byte
)
error
{
return
xxx_messageInfo_ParaBlock2MainInfo
.
Unmarshal
(
m
,
b
)
...
...
@@ -1407,7 +1407,7 @@ func (m *ParacrossNodeStatus) Reset() { *m = ParacrossNodeStatus{} }
func
(
m
*
ParacrossNodeStatus
)
String
()
string
{
return
proto
.
CompactTextString
(
m
)
}
func
(
*
ParacrossNodeStatus
)
ProtoMessage
()
{}
func
(
*
ParacrossNodeStatus
)
Descriptor
()
([]
byte
,
[]
int
)
{
return
fileDescriptor_paracross_
e0081cf2748ff01a
,
[]
int
{
21
}
return
fileDescriptor_paracross_
313193799a5638f5
,
[]
int
{
21
}
}
func
(
m
*
ParacrossNodeStatus
)
XXX_Unmarshal
(
b
[]
byte
)
error
{
return
xxx_messageInfo_ParacrossNodeStatus
.
Unmarshal
(
m
,
b
)
...
...
@@ -1536,7 +1536,7 @@ func (m *SelfConsensStages) Reset() { *m = SelfConsensStages{} }
func
(
m
*
SelfConsensStages
)
String
()
string
{
return
proto
.
CompactTextString
(
m
)
}
func
(
*
SelfConsensStages
)
ProtoMessage
()
{}
func
(
*
SelfConsensStages
)
Descriptor
()
([]
byte
,
[]
int
)
{
return
fileDescriptor_paracross_
e0081cf2748ff01a
,
[]
int
{
22
}
return
fileDescriptor_paracross_
313193799a5638f5
,
[]
int
{
22
}
}
func
(
m
*
SelfConsensStages
)
XXX_Unmarshal
(
b
[]
byte
)
error
{
return
xxx_messageInfo_SelfConsensStages
.
Unmarshal
(
m
,
b
)
...
...
@@ -1575,7 +1575,7 @@ func (m *SelfConsensStage) Reset() { *m = SelfConsensStage{} }
func
(
m
*
SelfConsensStage
)
String
()
string
{
return
proto
.
CompactTextString
(
m
)
}
func
(
*
SelfConsensStage
)
ProtoMessage
()
{}
func
(
*
SelfConsensStage
)
Descriptor
()
([]
byte
,
[]
int
)
{
return
fileDescriptor_paracross_
e0081cf2748ff01a
,
[]
int
{
23
}
return
fileDescriptor_paracross_
313193799a5638f5
,
[]
int
{
23
}
}
func
(
m
*
SelfConsensStage
)
XXX_Unmarshal
(
b
[]
byte
)
error
{
return
xxx_messageInfo_SelfConsensStage
.
Unmarshal
(
m
,
b
)
...
...
@@ -1625,7 +1625,7 @@ func (m *SelfConsensStageInfo) Reset() { *m = SelfConsensStageInfo{} }
func
(
m
*
SelfConsensStageInfo
)
String
()
string
{
return
proto
.
CompactTextString
(
m
)
}
func
(
*
SelfConsensStageInfo
)
ProtoMessage
()
{}
func
(
*
SelfConsensStageInfo
)
Descriptor
()
([]
byte
,
[]
int
)
{
return
fileDescriptor_paracross_
e0081cf2748ff01a
,
[]
int
{
24
}
return
fileDescriptor_paracross_
313193799a5638f5
,
[]
int
{
24
}
}
func
(
m
*
SelfConsensStageInfo
)
XXX_Unmarshal
(
b
[]
byte
)
error
{
return
xxx_messageInfo_SelfConsensStageInfo
.
Unmarshal
(
m
,
b
)
...
...
@@ -1699,7 +1699,7 @@ func (m *LocalSelfConsStageInfo) Reset() { *m = LocalSelfConsStageInfo{}
func
(
m
*
LocalSelfConsStageInfo
)
String
()
string
{
return
proto
.
CompactTextString
(
m
)
}
func
(
*
LocalSelfConsStageInfo
)
ProtoMessage
()
{}
func
(
*
LocalSelfConsStageInfo
)
Descriptor
()
([]
byte
,
[]
int
)
{
return
fileDescriptor_paracross_
e0081cf2748ff01a
,
[]
int
{
25
}
return
fileDescriptor_paracross_
313193799a5638f5
,
[]
int
{
25
}
}
func
(
m
*
LocalSelfConsStageInfo
)
XXX_Unmarshal
(
b
[]
byte
)
error
{
return
xxx_messageInfo_LocalSelfConsStageInfo
.
Unmarshal
(
m
,
b
)
...
...
@@ -1746,7 +1746,7 @@ func (m *ConfigVoteInfo) Reset() { *m = ConfigVoteInfo{} }
func
(
m
*
ConfigVoteInfo
)
String
()
string
{
return
proto
.
CompactTextString
(
m
)
}
func
(
*
ConfigVoteInfo
)
ProtoMessage
()
{}
func
(
*
ConfigVoteInfo
)
Descriptor
()
([]
byte
,
[]
int
)
{
return
fileDescriptor_paracross_
e0081cf2748ff01a
,
[]
int
{
26
}
return
fileDescriptor_paracross_
313193799a5638f5
,
[]
int
{
26
}
}
func
(
m
*
ConfigVoteInfo
)
XXX_Unmarshal
(
b
[]
byte
)
error
{
return
xxx_messageInfo_ConfigVoteInfo
.
Unmarshal
(
m
,
b
)
...
...
@@ -1791,7 +1791,7 @@ func (m *ConfigCancelInfo) Reset() { *m = ConfigCancelInfo{} }
func
(
m
*
ConfigCancelInfo
)
String
()
string
{
return
proto
.
CompactTextString
(
m
)
}
func
(
*
ConfigCancelInfo
)
ProtoMessage
()
{}
func
(
*
ConfigCancelInfo
)
Descriptor
()
([]
byte
,
[]
int
)
{
return
fileDescriptor_paracross_
e0081cf2748ff01a
,
[]
int
{
27
}
return
fileDescriptor_paracross_
313193799a5638f5
,
[]
int
{
27
}
}
func
(
m
*
ConfigCancelInfo
)
XXX_Unmarshal
(
b
[]
byte
)
error
{
return
xxx_messageInfo_ConfigCancelInfo
.
Unmarshal
(
m
,
b
)
...
...
@@ -1837,7 +1837,7 @@ func (m *ParaStageConfig) Reset() { *m = ParaStageConfig{} }
func
(
m
*
ParaStageConfig
)
String
()
string
{
return
proto
.
CompactTextString
(
m
)
}
func
(
*
ParaStageConfig
)
ProtoMessage
()
{}
func
(
*
ParaStageConfig
)
Descriptor
()
([]
byte
,
[]
int
)
{
return
fileDescriptor_paracross_
e0081cf2748ff01a
,
[]
int
{
28
}
return
fileDescriptor_paracross_
313193799a5638f5
,
[]
int
{
28
}
}
func
(
m
*
ParaStageConfig
)
XXX_Unmarshal
(
b
[]
byte
)
error
{
return
xxx_messageInfo_ParaStageConfig
.
Unmarshal
(
m
,
b
)
...
...
@@ -2026,7 +2026,7 @@ func (m *ReceiptSelfConsStageConfig) Reset() { *m = ReceiptSelfConsStage
func
(
m
*
ReceiptSelfConsStageConfig
)
String
()
string
{
return
proto
.
CompactTextString
(
m
)
}
func
(
*
ReceiptSelfConsStageConfig
)
ProtoMessage
()
{}
func
(
*
ReceiptSelfConsStageConfig
)
Descriptor
()
([]
byte
,
[]
int
)
{
return
fileDescriptor_paracross_
e0081cf2748ff01a
,
[]
int
{
29
}
return
fileDescriptor_paracross_
313193799a5638f5
,
[]
int
{
29
}
}
func
(
m
*
ReceiptSelfConsStageConfig
)
XXX_Unmarshal
(
b
[]
byte
)
error
{
return
xxx_messageInfo_ReceiptSelfConsStageConfig
.
Unmarshal
(
m
,
b
)
...
...
@@ -2076,7 +2076,7 @@ func (m *ReceiptSelfConsStageVoteDone) Reset() { *m = ReceiptSelfConsSta
func
(
m
*
ReceiptSelfConsStageVoteDone
)
String
()
string
{
return
proto
.
CompactTextString
(
m
)
}
func
(
*
ReceiptSelfConsStageVoteDone
)
ProtoMessage
()
{}
func
(
*
ReceiptSelfConsStageVoteDone
)
Descriptor
()
([]
byte
,
[]
int
)
{
return
fileDescriptor_paracross_
e0081cf2748ff01a
,
[]
int
{
30
}
return
fileDescriptor_paracross_
313193799a5638f5
,
[]
int
{
30
}
}
func
(
m
*
ReceiptSelfConsStageVoteDone
)
XXX_Unmarshal
(
b
[]
byte
)
error
{
return
xxx_messageInfo_ReceiptSelfConsStageVoteDone
.
Unmarshal
(
m
,
b
)
...
...
@@ -2150,7 +2150,7 @@ func (m *ReceiptSelfConsStagesUpdate) Reset() { *m = ReceiptSelfConsStag
func
(
m
*
ReceiptSelfConsStagesUpdate
)
String
()
string
{
return
proto
.
CompactTextString
(
m
)
}
func
(
*
ReceiptSelfConsStagesUpdate
)
ProtoMessage
()
{}
func
(
*
ReceiptSelfConsStagesUpdate
)
Descriptor
()
([]
byte
,
[]
int
)
{
return
fileDescriptor_paracross_
e0081cf2748ff01a
,
[]
int
{
31
}
return
fileDescriptor_paracross_
313193799a5638f5
,
[]
int
{
31
}
}
func
(
m
*
ReceiptSelfConsStagesUpdate
)
XXX_Unmarshal
(
b
[]
byte
)
error
{
return
xxx_messageInfo_ReceiptSelfConsStagesUpdate
.
Unmarshal
(
m
,
b
)
...
...
@@ -2201,7 +2201,7 @@ func (m *ReqQuerySelfStages) Reset() { *m = ReqQuerySelfStages{} }
func
(
m
*
ReqQuerySelfStages
)
String
()
string
{
return
proto
.
CompactTextString
(
m
)
}
func
(
*
ReqQuerySelfStages
)
ProtoMessage
()
{}
func
(
*
ReqQuerySelfStages
)
Descriptor
()
([]
byte
,
[]
int
)
{
return
fileDescriptor_paracross_
e0081cf2748ff01a
,
[]
int
{
32
}
return
fileDescriptor_paracross_
313193799a5638f5
,
[]
int
{
32
}
}
func
(
m
*
ReqQuerySelfStages
)
XXX_Unmarshal
(
b
[]
byte
)
error
{
return
xxx_messageInfo_ReqQuerySelfStages
.
Unmarshal
(
m
,
b
)
...
...
@@ -2274,7 +2274,7 @@ func (m *ReplyQuerySelfStages) Reset() { *m = ReplyQuerySelfStages{} }
func
(
m
*
ReplyQuerySelfStages
)
String
()
string
{
return
proto
.
CompactTextString
(
m
)
}
func
(
*
ReplyQuerySelfStages
)
ProtoMessage
()
{}
func
(
*
ReplyQuerySelfStages
)
Descriptor
()
([]
byte
,
[]
int
)
{
return
fileDescriptor_paracross_
e0081cf2748ff01a
,
[]
int
{
33
}
return
fileDescriptor_paracross_
313193799a5638f5
,
[]
int
{
33
}
}
func
(
m
*
ReplyQuerySelfStages
)
XXX_Unmarshal
(
b
[]
byte
)
error
{
return
xxx_messageInfo_ReplyQuerySelfStages
.
Unmarshal
(
m
,
b
)
...
...
@@ -2312,7 +2312,7 @@ func (m *ParacrossCommitAction) Reset() { *m = ParacrossCommitAction{} }
func
(
m
*
ParacrossCommitAction
)
String
()
string
{
return
proto
.
CompactTextString
(
m
)
}
func
(
*
ParacrossCommitAction
)
ProtoMessage
()
{}
func
(
*
ParacrossCommitAction
)
Descriptor
()
([]
byte
,
[]
int
)
{
return
fileDescriptor_paracross_
e0081cf2748ff01a
,
[]
int
{
34
}
return
fileDescriptor_paracross_
313193799a5638f5
,
[]
int
{
34
}
}
func
(
m
*
ParacrossCommitAction
)
XXX_Unmarshal
(
b
[]
byte
)
error
{
return
xxx_messageInfo_ParacrossCommitAction
.
Unmarshal
(
m
,
b
)
...
...
@@ -2351,7 +2351,7 @@ func (m *ParacrossMinerAction) Reset() { *m = ParacrossMinerAction{} }
func
(
m
*
ParacrossMinerAction
)
String
()
string
{
return
proto
.
CompactTextString
(
m
)
}
func
(
*
ParacrossMinerAction
)
ProtoMessage
()
{}
func
(
*
ParacrossMinerAction
)
Descriptor
()
([]
byte
,
[]
int
)
{
return
fileDescriptor_paracross_
e0081cf2748ff01a
,
[]
int
{
35
}
return
fileDescriptor_paracross_
313193799a5638f5
,
[]
int
{
35
}
}
func
(
m
*
ParacrossMinerAction
)
XXX_Unmarshal
(
b
[]
byte
)
error
{
return
xxx_messageInfo_ParacrossMinerAction
.
Unmarshal
(
m
,
b
)
...
...
@@ -2408,7 +2408,7 @@ func (m *ParacrossAction) Reset() { *m = ParacrossAction{} }
func
(
m
*
ParacrossAction
)
String
()
string
{
return
proto
.
CompactTextString
(
m
)
}
func
(
*
ParacrossAction
)
ProtoMessage
()
{}
func
(
*
ParacrossAction
)
Descriptor
()
([]
byte
,
[]
int
)
{
return
fileDescriptor_paracross_
e0081cf2748ff01a
,
[]
int
{
36
}
return
fileDescriptor_paracross_
313193799a5638f5
,
[]
int
{
36
}
}
func
(
m
*
ParacrossAction
)
XXX_Unmarshal
(
b
[]
byte
)
error
{
return
xxx_messageInfo_ParacrossAction
.
Unmarshal
(
m
,
b
)
...
...
@@ -2817,7 +2817,7 @@ func (m *ReceiptParacrossCommit) Reset() { *m = ReceiptParacrossCommit{}
func
(
m
*
ReceiptParacrossCommit
)
String
()
string
{
return
proto
.
CompactTextString
(
m
)
}
func
(
*
ReceiptParacrossCommit
)
ProtoMessage
()
{}
func
(
*
ReceiptParacrossCommit
)
Descriptor
()
([]
byte
,
[]
int
)
{
return
fileDescriptor_paracross_
e0081cf2748ff01a
,
[]
int
{
37
}
return
fileDescriptor_paracross_
313193799a5638f5
,
[]
int
{
37
}
}
func
(
m
*
ReceiptParacrossCommit
)
XXX_Unmarshal
(
b
[]
byte
)
error
{
return
xxx_messageInfo_ReceiptParacrossCommit
.
Unmarshal
(
m
,
b
)
...
...
@@ -2876,7 +2876,7 @@ func (m *ReceiptParacrossMiner) Reset() { *m = ReceiptParacrossMiner{} }
func
(
m
*
ReceiptParacrossMiner
)
String
()
string
{
return
proto
.
CompactTextString
(
m
)
}
func
(
*
ReceiptParacrossMiner
)
ProtoMessage
()
{}
func
(
*
ReceiptParacrossMiner
)
Descriptor
()
([]
byte
,
[]
int
)
{
return
fileDescriptor_paracross_
e0081cf2748ff01a
,
[]
int
{
38
}
return
fileDescriptor_paracross_
313193799a5638f5
,
[]
int
{
38
}
}
func
(
m
*
ReceiptParacrossMiner
)
XXX_Unmarshal
(
b
[]
byte
)
error
{
return
xxx_messageInfo_ReceiptParacrossMiner
.
Unmarshal
(
m
,
b
)
...
...
@@ -2927,7 +2927,7 @@ func (m *ReceiptParacrossDone) Reset() { *m = ReceiptParacrossDone{} }
func
(
m
*
ReceiptParacrossDone
)
String
()
string
{
return
proto
.
CompactTextString
(
m
)
}
func
(
*
ReceiptParacrossDone
)
ProtoMessage
()
{}
func
(
*
ReceiptParacrossDone
)
Descriptor
()
([]
byte
,
[]
int
)
{
return
fileDescriptor_paracross_
e0081cf2748ff01a
,
[]
int
{
39
}
return
fileDescriptor_paracross_
313193799a5638f5
,
[]
int
{
39
}
}
func
(
m
*
ReceiptParacrossDone
)
XXX_Unmarshal
(
b
[]
byte
)
error
{
return
xxx_messageInfo_ReceiptParacrossDone
.
Unmarshal
(
m
,
b
)
...
...
@@ -3057,7 +3057,7 @@ func (m *ReceiptParacrossRecord) Reset() { *m = ReceiptParacrossRecord{}
func
(
m
*
ReceiptParacrossRecord
)
String
()
string
{
return
proto
.
CompactTextString
(
m
)
}
func
(
*
ReceiptParacrossRecord
)
ProtoMessage
()
{}
func
(
*
ReceiptParacrossRecord
)
Descriptor
()
([]
byte
,
[]
int
)
{
return
fileDescriptor_paracross_
e0081cf2748ff01a
,
[]
int
{
40
}
return
fileDescriptor_paracross_
313193799a5638f5
,
[]
int
{
40
}
}
func
(
m
*
ReceiptParacrossRecord
)
XXX_Unmarshal
(
b
[]
byte
)
error
{
return
xxx_messageInfo_ReceiptParacrossRecord
.
Unmarshal
(
m
,
b
)
...
...
@@ -3104,7 +3104,7 @@ func (m *ParacrossTx) Reset() { *m = ParacrossTx{} }
func
(
m
*
ParacrossTx
)
String
()
string
{
return
proto
.
CompactTextString
(
m
)
}
func
(
*
ParacrossTx
)
ProtoMessage
()
{}
func
(
*
ParacrossTx
)
Descriptor
()
([]
byte
,
[]
int
)
{
return
fileDescriptor_paracross_
e0081cf2748ff01a
,
[]
int
{
41
}
return
fileDescriptor_paracross_
313193799a5638f5
,
[]
int
{
41
}
}
func
(
m
*
ParacrossTx
)
XXX_Unmarshal
(
b
[]
byte
)
error
{
return
xxx_messageInfo_ParacrossTx
.
Unmarshal
(
m
,
b
)
...
...
@@ -3144,7 +3144,7 @@ func (m *ReqParacrossTitleHeight) Reset() { *m = ReqParacrossTitleHeight
func
(
m
*
ReqParacrossTitleHeight
)
String
()
string
{
return
proto
.
CompactTextString
(
m
)
}
func
(
*
ReqParacrossTitleHeight
)
ProtoMessage
()
{}
func
(
*
ReqParacrossTitleHeight
)
Descriptor
()
([]
byte
,
[]
int
)
{
return
fileDescriptor_paracross_
e0081cf2748ff01a
,
[]
int
{
42
}
return
fileDescriptor_paracross_
313193799a5638f5
,
[]
int
{
42
}
}
func
(
m
*
ReqParacrossTitleHeight
)
XXX_Unmarshal
(
b
[]
byte
)
error
{
return
xxx_messageInfo_ReqParacrossTitleHeight
.
Unmarshal
(
m
,
b
)
...
...
@@ -3196,7 +3196,7 @@ func (m *RespParacrossDone) Reset() { *m = RespParacrossDone{} }
func
(
m
*
RespParacrossDone
)
String
()
string
{
return
proto
.
CompactTextString
(
m
)
}
func
(
*
RespParacrossDone
)
ProtoMessage
()
{}
func
(
*
RespParacrossDone
)
Descriptor
()
([]
byte
,
[]
int
)
{
return
fileDescriptor_paracross_
e0081cf2748ff01a
,
[]
int
{
43
}
return
fileDescriptor_paracross_
313193799a5638f5
,
[]
int
{
43
}
}
func
(
m
*
RespParacrossDone
)
XXX_Unmarshal
(
b
[]
byte
)
error
{
return
xxx_messageInfo_RespParacrossDone
.
Unmarshal
(
m
,
b
)
...
...
@@ -3283,7 +3283,7 @@ func (m *RespParacrossTitles) Reset() { *m = RespParacrossTitles{} }
func
(
m
*
RespParacrossTitles
)
String
()
string
{
return
proto
.
CompactTextString
(
m
)
}
func
(
*
RespParacrossTitles
)
ProtoMessage
()
{}
func
(
*
RespParacrossTitles
)
Descriptor
()
([]
byte
,
[]
int
)
{
return
fileDescriptor_paracross_
e0081cf2748ff01a
,
[]
int
{
44
}
return
fileDescriptor_paracross_
313193799a5638f5
,
[]
int
{
44
}
}
func
(
m
*
RespParacrossTitles
)
XXX_Unmarshal
(
b
[]
byte
)
error
{
return
xxx_messageInfo_RespParacrossTitles
.
Unmarshal
(
m
,
b
)
...
...
@@ -3322,7 +3322,7 @@ func (m *ReqParacrossTitleHash) Reset() { *m = ReqParacrossTitleHash{} }
func
(
m
*
ReqParacrossTitleHash
)
String
()
string
{
return
proto
.
CompactTextString
(
m
)
}
func
(
*
ReqParacrossTitleHash
)
ProtoMessage
()
{}
func
(
*
ReqParacrossTitleHash
)
Descriptor
()
([]
byte
,
[]
int
)
{
return
fileDescriptor_paracross_
e0081cf2748ff01a
,
[]
int
{
45
}
return
fileDescriptor_paracross_
313193799a5638f5
,
[]
int
{
45
}
}
func
(
m
*
ReqParacrossTitleHash
)
XXX_Unmarshal
(
b
[]
byte
)
error
{
return
xxx_messageInfo_ReqParacrossTitleHash
.
Unmarshal
(
m
,
b
)
...
...
@@ -3381,7 +3381,7 @@ func (m *ParacrossAsset) Reset() { *m = ParacrossAsset{} }
func
(
m
*
ParacrossAsset
)
String
()
string
{
return
proto
.
CompactTextString
(
m
)
}
func
(
*
ParacrossAsset
)
ProtoMessage
()
{}
func
(
*
ParacrossAsset
)
Descriptor
()
([]
byte
,
[]
int
)
{
return
fileDescriptor_paracross_
e0081cf2748ff01a
,
[]
int
{
46
}
return
fileDescriptor_paracross_
313193799a5638f5
,
[]
int
{
46
}
}
func
(
m
*
ParacrossAsset
)
XXX_Unmarshal
(
b
[]
byte
)
error
{
return
xxx_messageInfo_ParacrossAsset
.
Unmarshal
(
m
,
b
)
...
...
@@ -3478,6 +3478,127 @@ func (m *ParacrossAsset) GetSuccess() bool {
return
false
}
type
ParacrossAssetRsp
struct
{
// input
From
string
`protobuf:"bytes,1,opt,name=from,proto3" json:"from,omitempty"`
To
string
`protobuf:"bytes,2,opt,name=to,proto3" json:"to,omitempty"`
IsWithdraw
string
`protobuf:"bytes,3,opt,name=isWithdraw,proto3" json:"isWithdraw,omitempty"`
TxHash
string
`protobuf:"bytes,4,opt,name=txHash,proto3" json:"txHash,omitempty"`
Amount
int64
`protobuf:"varint,5,opt,name=amount,proto3" json:"amount,omitempty"`
Exec
string
`protobuf:"bytes,6,opt,name=exec,proto3" json:"exec,omitempty"`
Symbol
string
`protobuf:"bytes,7,opt,name=symbol,proto3" json:"symbol,omitempty"`
// 主链部分
Height
int64
`protobuf:"varint,10,opt,name=height,proto3" json:"height,omitempty"`
// 平行链部分
CommitDoneHeight
int64
`protobuf:"varint,21,opt,name=commitDoneHeight,proto3" json:"commitDoneHeight,omitempty"`
ParaHeight
int64
`protobuf:"varint,22,opt,name=paraHeight,proto3" json:"paraHeight,omitempty"`
Success
string
`protobuf:"bytes,23,opt,name=success,proto3" json:"success,omitempty"`
XXX_NoUnkeyedLiteral
struct
{}
`json:"-"`
XXX_unrecognized
[]
byte
`json:"-"`
XXX_sizecache
int32
`json:"-"`
}
func
(
m
*
ParacrossAssetRsp
)
Reset
()
{
*
m
=
ParacrossAssetRsp
{}
}
func
(
m
*
ParacrossAssetRsp
)
String
()
string
{
return
proto
.
CompactTextString
(
m
)
}
func
(
*
ParacrossAssetRsp
)
ProtoMessage
()
{}
func
(
*
ParacrossAssetRsp
)
Descriptor
()
([]
byte
,
[]
int
)
{
return
fileDescriptor_paracross_313193799a5638f5
,
[]
int
{
47
}
}
func
(
m
*
ParacrossAssetRsp
)
XXX_Unmarshal
(
b
[]
byte
)
error
{
return
xxx_messageInfo_ParacrossAssetRsp
.
Unmarshal
(
m
,
b
)
}
func
(
m
*
ParacrossAssetRsp
)
XXX_Marshal
(
b
[]
byte
,
deterministic
bool
)
([]
byte
,
error
)
{
return
xxx_messageInfo_ParacrossAssetRsp
.
Marshal
(
b
,
m
,
deterministic
)
}
func
(
dst
*
ParacrossAssetRsp
)
XXX_Merge
(
src
proto
.
Message
)
{
xxx_messageInfo_ParacrossAssetRsp
.
Merge
(
dst
,
src
)
}
func
(
m
*
ParacrossAssetRsp
)
XXX_Size
()
int
{
return
xxx_messageInfo_ParacrossAssetRsp
.
Size
(
m
)
}
func
(
m
*
ParacrossAssetRsp
)
XXX_DiscardUnknown
()
{
xxx_messageInfo_ParacrossAssetRsp
.
DiscardUnknown
(
m
)
}
var
xxx_messageInfo_ParacrossAssetRsp
proto
.
InternalMessageInfo
func
(
m
*
ParacrossAssetRsp
)
GetFrom
()
string
{
if
m
!=
nil
{
return
m
.
From
}
return
""
}
func
(
m
*
ParacrossAssetRsp
)
GetTo
()
string
{
if
m
!=
nil
{
return
m
.
To
}
return
""
}
func
(
m
*
ParacrossAssetRsp
)
GetIsWithdraw
()
string
{
if
m
!=
nil
{
return
m
.
IsWithdraw
}
return
""
}
func
(
m
*
ParacrossAssetRsp
)
GetTxHash
()
string
{
if
m
!=
nil
{
return
m
.
TxHash
}
return
""
}
func
(
m
*
ParacrossAssetRsp
)
GetAmount
()
int64
{
if
m
!=
nil
{
return
m
.
Amount
}
return
0
}
func
(
m
*
ParacrossAssetRsp
)
GetExec
()
string
{
if
m
!=
nil
{
return
m
.
Exec
}
return
""
}
func
(
m
*
ParacrossAssetRsp
)
GetSymbol
()
string
{
if
m
!=
nil
{
return
m
.
Symbol
}
return
""
}
func
(
m
*
ParacrossAssetRsp
)
GetHeight
()
int64
{
if
m
!=
nil
{
return
m
.
Height
}
return
0
}
func
(
m
*
ParacrossAssetRsp
)
GetCommitDoneHeight
()
int64
{
if
m
!=
nil
{
return
m
.
CommitDoneHeight
}
return
0
}
func
(
m
*
ParacrossAssetRsp
)
GetParaHeight
()
int64
{
if
m
!=
nil
{
return
m
.
ParaHeight
}
return
0
}
func
(
m
*
ParacrossAssetRsp
)
GetSuccess
()
string
{
if
m
!=
nil
{
return
m
.
Success
}
return
""
}
type
ParaLocalDbBlock
struct
{
Height
int64
`protobuf:"varint,1,opt,name=height,proto3" json:"height,omitempty"`
MainHash
[]
byte
`protobuf:"bytes,2,opt,name=mainHash,proto3" json:"mainHash,omitempty"`
...
...
@@ -3494,7 +3615,7 @@ func (m *ParaLocalDbBlock) Reset() { *m = ParaLocalDbBlock{} }
func
(
m
*
ParaLocalDbBlock
)
String
()
string
{
return
proto
.
CompactTextString
(
m
)
}
func
(
*
ParaLocalDbBlock
)
ProtoMessage
()
{}
func
(
*
ParaLocalDbBlock
)
Descriptor
()
([]
byte
,
[]
int
)
{
return
fileDescriptor_paracross_
e0081cf2748ff01a
,
[]
int
{
47
}
return
fileDescriptor_paracross_
313193799a5638f5
,
[]
int
{
48
}
}
func
(
m
*
ParaLocalDbBlock
)
XXX_Unmarshal
(
b
[]
byte
)
error
{
return
xxx_messageInfo_ParaLocalDbBlock
.
Unmarshal
(
m
,
b
)
...
...
@@ -3572,7 +3693,7 @@ func (m *ParaLocalDbBlockInfo) Reset() { *m = ParaLocalDbBlockInfo{} }
func
(
m
*
ParaLocalDbBlockInfo
)
String
()
string
{
return
proto
.
CompactTextString
(
m
)
}
func
(
*
ParaLocalDbBlockInfo
)
ProtoMessage
()
{}
func
(
*
ParaLocalDbBlockInfo
)
Descriptor
()
([]
byte
,
[]
int
)
{
return
fileDescriptor_paracross_
e0081cf2748ff01a
,
[]
int
{
48
}
return
fileDescriptor_paracross_
313193799a5638f5
,
[]
int
{
49
}
}
func
(
m
*
ParaLocalDbBlockInfo
)
XXX_Unmarshal
(
b
[]
byte
)
error
{
return
xxx_messageInfo_ParaLocalDbBlockInfo
.
Unmarshal
(
m
,
b
)
...
...
@@ -3682,6 +3803,7 @@ func init() {
proto
.
RegisterType
((
*
RespParacrossTitles
)(
nil
),
"types.RespParacrossTitles"
)
proto
.
RegisterType
((
*
ReqParacrossTitleHash
)(
nil
),
"types.ReqParacrossTitleHash"
)
proto
.
RegisterType
((
*
ParacrossAsset
)(
nil
),
"types.ParacrossAsset"
)
proto
.
RegisterType
((
*
ParacrossAssetRsp
)(
nil
),
"types.ParacrossAssetRsp"
)
proto
.
RegisterType
((
*
ParaLocalDbBlock
)(
nil
),
"types.ParaLocalDbBlock"
)
proto
.
RegisterType
((
*
ParaLocalDbBlockInfo
)(
nil
),
"types.ParaLocalDbBlockInfo"
)
}
...
...
@@ -3702,7 +3824,7 @@ type ParacrossClient interface {
ListTitles
(
ctx
context
.
Context
,
in
*
types
.
ReqNil
,
opts
...
grpc
.
CallOption
)
(
*
RespParacrossTitles
,
error
)
GetDoneTitleHeight
(
ctx
context
.
Context
,
in
*
ReqParacrossTitleHeight
,
opts
...
grpc
.
CallOption
)
(
*
RespParacrossDone
,
error
)
GetTitleHeight
(
ctx
context
.
Context
,
in
*
ReqParacrossTitleHeight
,
opts
...
grpc
.
CallOption
)
(
*
ParacrossHeightStatusRsp
,
error
)
GetAssetTxResult
(
ctx
context
.
Context
,
in
*
types
.
Req
Hash
,
opts
...
grpc
.
CallOption
)
(
*
ParacrossAsset
,
error
)
GetAssetTxResult
(
ctx
context
.
Context
,
in
*
types
.
Req
String
,
opts
...
grpc
.
CallOption
)
(
*
ParacrossAssetRsp
,
error
)
IsSync
(
ctx
context
.
Context
,
in
*
types
.
ReqNil
,
opts
...
grpc
.
CallOption
)
(
*
types
.
IsCaughtUp
,
error
)
}
...
...
@@ -3750,8 +3872,8 @@ func (c *paracrossClient) GetTitleHeight(ctx context.Context, in *ReqParacrossTi
return
out
,
nil
}
func
(
c
*
paracrossClient
)
GetAssetTxResult
(
ctx
context
.
Context
,
in
*
types
.
Req
Hash
,
opts
...
grpc
.
CallOption
)
(
*
ParacrossAsset
,
error
)
{
out
:=
new
(
ParacrossAsset
)
func
(
c
*
paracrossClient
)
GetAssetTxResult
(
ctx
context
.
Context
,
in
*
types
.
Req
String
,
opts
...
grpc
.
CallOption
)
(
*
ParacrossAssetRsp
,
error
)
{
out
:=
new
(
ParacrossAsset
Rsp
)
err
:=
c
.
cc
.
Invoke
(
ctx
,
"/types.paracross/GetAssetTxResult"
,
in
,
out
,
opts
...
)
if
err
!=
nil
{
return
nil
,
err
...
...
@@ -3774,7 +3896,7 @@ type ParacrossServer interface {
ListTitles
(
context
.
Context
,
*
types
.
ReqNil
)
(
*
RespParacrossTitles
,
error
)
GetDoneTitleHeight
(
context
.
Context
,
*
ReqParacrossTitleHeight
)
(
*
RespParacrossDone
,
error
)
GetTitleHeight
(
context
.
Context
,
*
ReqParacrossTitleHeight
)
(
*
ParacrossHeightStatusRsp
,
error
)
GetAssetTxResult
(
context
.
Context
,
*
types
.
Req
Hash
)
(
*
ParacrossAsset
,
error
)
GetAssetTxResult
(
context
.
Context
,
*
types
.
Req
String
)
(
*
ParacrossAssetRsp
,
error
)
IsSync
(
context
.
Context
,
*
types
.
ReqNil
)
(
*
types
.
IsCaughtUp
,
error
)
}
...
...
@@ -3855,7 +3977,7 @@ func _Paracross_GetTitleHeight_Handler(srv interface{}, ctx context.Context, dec
}
func
_Paracross_GetAssetTxResult_Handler
(
srv
interface
{},
ctx
context
.
Context
,
dec
func
(
interface
{})
error
,
interceptor
grpc
.
UnaryServerInterceptor
)
(
interface
{},
error
)
{
in
:=
new
(
types
.
Req
Hash
)
in
:=
new
(
types
.
Req
String
)
if
err
:=
dec
(
in
);
err
!=
nil
{
return
nil
,
err
}
...
...
@@ -3867,7 +3989,7 @@ func _Paracross_GetAssetTxResult_Handler(srv interface{}, ctx context.Context, d
FullMethod
:
"/types.paracross/GetAssetTxResult"
,
}
handler
:=
func
(
ctx
context
.
Context
,
req
interface
{})
(
interface
{},
error
)
{
return
srv
.
(
ParacrossServer
)
.
GetAssetTxResult
(
ctx
,
req
.
(
*
types
.
Req
Hash
))
return
srv
.
(
ParacrossServer
)
.
GetAssetTxResult
(
ctx
,
req
.
(
*
types
.
Req
String
))
}
return
interceptor
(
ctx
,
in
,
info
,
handler
)
}
...
...
@@ -3923,157 +4045,158 @@ var _Paracross_serviceDesc = grpc.ServiceDesc{
Metadata
:
"paracross.proto"
,
}
func
init
()
{
proto
.
RegisterFile
(
"paracross.proto"
,
fileDescriptor_paracross_e0081cf2748ff01a
)
}
var
fileDescriptor_paracross_e0081cf2748ff01a
=
[]
byte
{
// 2376 bytes of a gzipped FileDescriptorProto
0x1f
,
0x8b
,
0x08
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0x02
,
0xff
,
0xd4
,
0x5a
,
0x4f
,
0x73
,
0x1c
,
0x47
,
0x15
,
0xdf
,
0xd9
,
0xbf
,
0xda
,
0x27
,
0xed
,
0x5a
,
0x9a
,
0xc8
,
0xca
,
0xb2
,
0x76
,
0x1c
,
0x55
,
0x97
,
0x49
,
0x09
,
0xe2
,
0xd8
,
0x58
,
0x06
,
0x53
,
0xa9
,
0x14
,
0x05
,
0xb6
,
0x1c
,
0x6b
,
0x55
,
0xb1
,
0x53
,
0xc9
,
0x48
,
0x81
,
0x03
,
0x17
,
0x46
,
0xbb
,
0x6d
,
0x69
,
0x8a
,
0xdd
,
0x99
,
0xf5
,
0x4c
,
0x6f
,
0x22
,
0x71
,
0xa1
,
0x28
,
0xe0
,
0x0c
,
0x27
,
0xaa
,
0xc2
,
0x81
,
0x0b
,
0x9c
,
0xf9
,
0x08
,
0x1c
,
0x38
,
0x86
,
0x53
,
0x38
,
0x70
,
0xe0
,
0xc6
,
0x8d
,
0x3b
,
0x07
,
0xae
,
0xd4
,
0x7b
,
0xdd
,
0x3d
,
0xd3
,
0xdd
,
0x3b
,
0xbb
,
0x92
,
0x1d
,
0x5f
,
0xb8
,
0x6d
,
0xbf
,
0x7e
,
0xfd
,
0xfa
,
0xbd
,
0x5f
,
0xbf
,
0xf7
,
0xfa
,
0xbd
,
0x9e
,
0x85
,
0x2b
,
0xd3
,
0x30
,
0x0d
,
0x87
,
0x69
,
0x92
,
0x65
,
0xb7
,
0xa7
,
0x69
,
0x22
,
0x12
,
0xbf
,
0x21
,
0xce
,
0xa7
,
0x3c
,
0xeb
,
0x6f
,
0x88
,
0x34
,
0x8c
,
0xb3
,
0x70
,
0x28
,
0xa2
,
0x24
,
0x96
,
0x33
,
0xfd
,
0xb5
,
0x61
,
0x32
,
0x99
,
0xe4
,
0xa3
,
0xf5
,
0xe3
,
0x71
,
0x32
,
0xfc
,
0xe9
,
0xf0
,
0x34
,
0x8c
,
0x14
,
0x85
,
0x3d
,
0x81
,
0xad
,
0x8f
,
0xb4
,
0xb0
,
0x43
,
0x11
,
0x8a
,
0x59
,
0xf6
,
0x88
,
0x8b
,
0x30
,
0x1a
,
0x67
,
0xfe
,
0x26
,
0x34
,
0xc2
,
0xd1
,
0x28
,
0xcd
,
0x7a
,
0xde
,
0x76
,
0x6d
,
0xa7
,
0x1d
,
0xc8
,
0x81
,
0x7f
,
0x1d
,
0xda
,
0x24
,
0x63
,
0x10
,
0x66
,
0xa7
,
0xbd
,
0xea
,
0x76
,
0x6d
,
0x67
,
0x2d
,
0x28
,
0x08
,
0xec
,
0xc7
,
0x70
,
0xcd
,
0x91
,
0xf6
,
0x10
,
0xe7
,
0xb4
,
0xc8
,
0x1b
,
0x00
,
0x39
,
0xaf
,
0x94
,
0xbb
,
0x16
,
0x18
,
0x14
,
0x14
,
0x2e
,
0xce
,
0x02
,
0x9e
,
0xcd
,
0xc6
,
0x22
,
0xd3
,
0xc2
,
0x73
,
0x02
,
0xfb
,
0x7d
,
0x15
,
0xae
,
0xe6
,
0xd2
,
0x07
,
0x3c
,
0x3a
,
0x39
,
0x15
,
0x72
,
0x0f
,
0x7f
,
0x0b
,
0x9a
,
0x19
,
0xfd
,
0xea
,
0x79
,
0xdb
,
0xde
,
0x4e
,
0x23
,
0x50
,
0x23
,
0x34
,
0x41
,
0x44
,
0x62
,
0xcc
,
0x7b
,
0xd5
,
0x6d
,
0x0f
,
0x4d
,
0xa0
,
0x01
,
0x72
,
0x9f
,
0xd2
,
0xea
,
0x5e
,
0x6d
,
0xdb
,
0xdb
,
0xa9
,
0x05
,
0x6a
,
0xe4
,
0x7f
,
0x17
,
0x5a
,
0x23
,
0xa9
,
0x68
,
0xaf
,
0xbe
,
0xed
,
0xed
,
0xac
,
0xee
,
0xbe
,
0x71
,
0x9b
,
0x60
,
0xbd
,
0x5d
,
0x0e
,
0x50
,
0xa0
,
0xb9
,
0xd1
,
0xac
,
0x49
,
0x18
,
0xc5
,
0x52
,
0xa5
,
0x5e
,
0x83
,
0x84
,
0x1a
,
0x14
,
0xbf
,
0x0f
,
0x2b
,
0x34
,
0x42
,
0xc8
,
0x9a
,
0xdb
,
0xde
,
0xce
,
0x5a
,
0x90
,
0x8f
,
0xfd
,
0xc7
,
0xb0
,
0x76
,
0x6c
,
0x40
,
0xd4
,
0x6b
,
0xd1
,
0xce
,
0xac
,
0x7c
,
0x67
,
0x13
,
0xcc
,
0xc0
,
0x5a
,
0xc7
,
0xfe
,
0xed
,
0x41
,
0xaf
,
0x14
,
0x9c
,
0x20
,
0x9b
,
0xbe
,
0x22
,
0x7c
,
0x6c
,
0x33
,
0xeb
,
0x4b
,
0xcd
,
0x6c
,
0x90
,
0xc0
,
0xc2
,
0xcc
,
0x6d
,
0x58
,
0x45
,
0x47
,
0x8c
,
0xc4
,
0x03
,
0x72
,
0xa9
,
0x26
,
0xb9
,
0x94
,
0x49
,
0xf2
,
0x77
,
0xe0
,
0x8a
,
0x1c
,
0x3e
,
0xcc
,
0xdd
,
0xab
,
0x45
,
0x5c
,
0x2e
,
0x99
,
0x7d
,
0xee
,
0xc1
,
0x15
,
0x07
,
0x98
,
0xc2
,
0x12
,
0xaf
,
0xdc
,
0x92
,
0xaa
,
0x65
,
0x89
,
0xe5
,
0xc4
,
0x35
,
0x3a
,
0x91
,
0x82
,
0xf0
,
0xc2
,
0x76
,
0x1a
,
0xc7
,
0xc9
,
0xfe
,
0x64
,
0x1e
,
0xc3
,
0x5e
,
0x12
,
0x67
,
0x3c
,
0xce
,
0x66
,
0xcb
,
0x95
,
0x44
,
0x68
,
0x4e
,
0x8b
,
0xfd
,
0xa4
,
0xa6
,
0x26
,
0xc9
,
0xbf
,
0x09
,
0x9d
,
0xa1
,
0x14
,
0x35
,
0x30
,
0xcf
,
0xc5
,
0x26
,
0xfa
,
0xdf
,
0x84
,
0x75
,
0x45
,
0x28
,
0x10
,
0xac
,
0xd3
,
0x46
,
0x73
,
0x74
,
0xf6
,
0x3b
,
0x0f
,
0x7c
,
0x54
,
0xf3
,
0xc3
,
0x64
,
0xc4
,
0x11
,
0xfe
,
0xbd
,
0x24
,
0x7e
,
0x16
,
0x9d
,
0x2c
,
0x50
,
0xb0
,
0x0b
,
0xd5
,
0x64
,
0x4a
,
0x7a
,
0x75
,
0x82
,
0x6a
,
0x32
,
0xc5
,
0x71
,
0x34
,
0x22
,
0x1d
,
0xda
,
0x41
,
0x35
,
0x1a
,
0xf9
,
0x3e
,
0xd4
,
0x31
,
0x37
,
0xa8
,
0xcd
,
0xe8
,
0x37
,
0x4a
,
0xfa
,
0x34
,
0x1c
,
0xcf
,
0x38
,
0x01
,
0xd4
,
0x09
,
0xe4
,
0x40
,
0x7a
,
0x41
,
0x14
,
0x67
,
0x8f
,
0xd3
,
0xe4
,
0x67
,
0x3c
,
0xa6
,
0x58
,
0x40
,
0x53
,
0x0b
,
0x12
,
0xfb
,
0x41
,
0xa1
,
0xd7
,
0x0f
,
0x13
,
0xc1
,
0xa5
,
0x77
,
0x2f
,
0x48
,
0x45
,
0xb8
,
0x47
,
0x22
,
0xb8
,
0xcc
,
0x14
,
0xed
,
0x40
,
0x0e
,
0xd8
,
0x6f
,
0x3d
,
0xd8
,
0x34
,
0x4d
,
0x3b
,
0x18
,
0x29
,
0xf4
,
0xb5
,
0x9a
,
0x9e
,
0xa1
,
0xe6
,
0x0d
,
0x80
,
0x69
,
0x9a
,
0x4c
,
0x93
,
0x2c
,
0x1c
,
0x1f
,
0x8c
,
0x54
,
0x14
,
0x18
,
0x14
,
0x74
,
0xa0
,
0xe7
,
0xb3
,
0x48
,
0x1c
,
0x68
,
0x73
,
0xd5
,
0xc8
,
0x08
,
0xa8
,
0x7a
,
0x79
,
0x40
,
0x35
,
0x0c
,
0x00
,
0xd9
,
0x7f
,
0x3d
,
0x58
,
0xd7
,
0x2a
,
0xe5
,
0xea
,
0x48
,
0x14
,
0xbd
,
0x1c
,
0xc5
,
0x42
,
0x64
,
0xb5
,
0x5c
,
0x64
,
0xcd
,
0x3c
,
0x93
,
0x1b
,
0x00
,
0x22
,
0x4c
,
0x4f
,
0x38
,
0x05
,
0x8f
,
0x42
,
0xde
,
0xa0
,
0xb8
,
0x48
,
0x37
,
0xe6
,
0x90
,
0xf6
,
0xef
,
0x68
,
0xf4
,
0x9a
,
0x94
,
0x71
,
0xbe
,
0x66
,
0x64
,
0x1c
,
0x1b
,
0x7d
,
0x05
,
0x2c
,
0xba
,
0xfd
,
0xb3
,
0x34
,
0x99
,
0xd0
,
0x86
,
0x2d
,
0x19
,
0xde
,
0x7a
,
0x6c
,
0x04
,
0xda
,
0x8a
,
0x19
,
0x68
,
0xec
,
0x2f
,
0x1e
,
0x5c
,
0x0d
,
0xf8
,
0x90
,
0x47
,
0x53
,
0xa1
,
0x05
,
0x2b
,
0x57
,
0x2b
,
0x3b
,
0x8d
,
0xbb
,
0xd0
,
0x1c
,
0xd2
,
0x2c
,
0x41
,
0x30
,
0xaf
,
0x53
,
0xe1
,
0xa9
,
0x81
,
0x62
,
0xf4
,
0xdf
,
0x86
,
0xfa
,
0x34
,
0xe5
,
0x9f
,
0x12
,
0x38
,
0xab
,
0xbb
,
0xaf
,
0x3b
,
0x0b
,
0x34
,
0xd8
,
0x01
,
0x31
,
0xf9
,
0x77
,
0xa1
,
0x35
,
0x9c
,
0xa5
,
0x29
,
0x8f
,
0x85
,
0x4a
,
0xf0
,
0x0b
,
0xf9
,
0x35
,
0x1f
,
0xfb
,
0xa3
,
0x07
,
0x6f
,
0x38
,
0x06
,
0xa0
,
0x16
,
0xc8
,
0xf6
,
0xc9
,
0x74
,
0x14
,
0x0a
,
0x6e
,
0xc1
,
0xe2
,
0x39
,
0xb0
,
0xdc
,
0x51
,
0xda
,
0x49
,
0x73
,
0xae
,
0x95
,
0x98
,
0xe3
,
0x68
,
0xf8
,
0x9d
,
0x42
,
0xc3
,
0xda
,
0xc5
,
0x6b
,
0x72
,
0x2d
,
0xff
,
0xe3
,
0xc1
,
0xeb
,
0x8e
,
0x96
,
0x74
,
0x7e
,
0x49
,
0xcc
,
0xe7
,
0xfc
,
0xac
,
0x3c
,
0xe7
,
0xdb
,
0xfe
,
0x54
,
0x9b
,
0xf3
,
0x27
,
0x9c
,
0x4f
,
0x44
,
0x38
,
0x46
,
0xd1
,
0xda
,
0xe9
,
0x0d
,
0x0a
,
0xdd
,
0xdc
,
0x38
,
0xc2
,
0x6d
,
0xc9
,
0xdb
,
0x1a
,
0x41
,
0x41
,
0xa0
,
0x8c
,
0x99
,
0x64
,
0x82
,
0x26
,
0x9b
,
0x34
,
0x99
,
0x8f
,
0xfd
,
0x1e
,
0xb4
,
0xd0
,
0xbf
,
0x82
,
0x4c
,
0x28
,
0xaf
,
0xd2
,
0x43
,
0xdc
,
0x73
,
0x94
,
0xc4
,
0x5c
,
0x1a
,
0x4b
,
0x8e
,
0xd5
,
0x08
,
0x0c
,
0x0a
,
0xfb
,
0xa5
,
0x07
,
0xaf
,
0x69
,
0x73
,
0xf7
,
0xd3
,
0x64
,
0x36
,
0xfd
,
0x4a
,
0x59
,
0x2c
,
0xcf
,
0x31
,
0x32
,
0x98
,
0x54
,
0x8e
,
0xb9
,
0x30
,
0x8e
,
0xd8
,
0xdf
,
0x5c
,
0x2d
,
0x5e
,
0x49
,
0x7c
,
0x6f
,
0xc3
,
0x6a
,
0x81
,
0xbe
,
0xd6
,
0xc9
,
0x24
,
0x5d
,
0x22
,
0xc2
,
0x4d
,
0xcf
,
0x6c
,
0x2e
,
0x0c
,
0xd8
,
0x96
,
0x15
,
0xb0
,
0x5f
,
0x78
,
0xd0
,
0x77
,
0x3c
,
0xc9
,
0x84
,
0xb6
,
0x2c
,
0x6a
,
0x77
,
0x9d
,
0xa8
,
0xed
,
0x3b
,
0x2e
,
0x6b
,
0xac
,
0xcf
,
0xc3
,
0xf6
,
0xb6
,
0x15
,
0xb6
,
0xa5
,
0x2b
,
0xac
,
0xb8
,
0xf8
,
0xb6
,
0x1b
,
0xb9
,
0xcb
,
0x96
,
0xe4
,
0x61
,
0x71
,
0x0a
,
0x9b
,
0x01
,
0x7f
,
0x9e
,
0x5f
,
0xc7
,
0x14
,
0xe1
,
0xf1
,
0xb3
,
0x64
,
0xb1
,
0x83
,
0x44
,
0xfa
,
0x0e
,
0x30
,
0xaf
,
0xb5
,
0x9a
,
0x61
,
0xeb
,
0x82
,
0xbc
,
0xcf
,
0xf6
,
0x60
,
0x2b
,
0xe0
,
0xd9
,
0xd4
,
0xda
,
0x4a
,
0x1e
,
0xd3
,
0x37
,
0xa0
,
0x16
,
0x8d
,
0xe4
,
0xc5
,
0xb5
,
0x24
,
0xdf
,
0x20
,
0x0f
,
0xdb
,
0xc7
,
0x20
,
0x76
,
0x84
,
0x90
,
0x5d
,
0x99
,
0x7f
,
0xcb
,
0x94
,
0xb2
,
0xcc
,
0x76
,
0x12
,
0xf4
,
0x6b
,
0x0f
,
0x36
,
0x70
,
0x92
,
0xee
,
0xfb
,
0xdd
,
0xa7
,
0x61
,
0x14
,
0x3f
,
0x0d
,
0xa7
,
0xc6
,
0x91
,
0x7b
,
0x8b
,
0x8b
,
0x21
,
0x69
,
0xfe
,
0xc2
,
0x62
,
0xa8
,
0xb6
,
0xb4
,
0x18
,
0xaa
,
0xdb
,
0x45
,
0x1f
,
0x7b
,
0x24
,
0x2f
,
0xf3
,
0x42
,
0x0d
,
0x42
,
0xff
,
0x36
,
0x34
,
0x22
,
0xc1
,
0x27
,
0xda
,
0x9a
,
0x9e
,
0x61
,
0x8d
,
0xa5
,
0x70
,
0x20
,
0xd9
,
0xd8
,
0xbf
,
0x6a
,
0x32
,
0xc0
,
0x72
,
0x4c
,
0x54
,
0x80
,
0xdd
,
0x84
,
0x0e
,
0xee
,
0x54
,
0x14
,
0x3b
,
0x1e
,
0xd5
,
0x62
,
0x36
,
0x11
,
0xcb
,
0xca
,
0x82
,
0x60
,
0x56
,
0x58
,
0x2e
,
0x79
,
0x41
,
0x20
,
0x16
,
0xa8
,
0xd5
,
0x2d
,
0xd4
,
0x18
,
0xac
,
0x4d
,
0x53
,
0x5e
,
0x6c
,
0x2e
,
0x0b
,
0x41
,
0x8b
,
0x66
,
0x23
,
0xdb
,
0x74
,
0xcb
,
0x4c
,
0x29
,
0x01
,
0x8d
,
0xe1
,
0xaa
,
0xda
,
0xd5
,
0x12
,
0x72
,
0x1a
,
0x4a
,
0xc8
,
0x72
,
0x86
,
0x15
,
0x29
,
0x21
,
0x27
,
0x20
,
0xf6
,
0xe2
,
0x6c
,
0x2f
,
0x99
,
0xc5
,
0x22
,
0xeb
,
0xb5
,
0x29
,
0xb1
,
0xe5
,
0x63
,
0x39
,
0x27
,
0x3b
,
0xa7
,
0x1e
,
0xc8
,
0x22
,
0x55
,
0x8f
,
0x31
,
0xe5
,
0x8a
,
0x33
,
0xd9
,
0x83
,
0xad
,
0x52
,
0x93
,
0xa5
,
0x87
,
0x54
,
0x69
,
0x22
,
0xcc
,
0x47
,
0x7a
,
0xe9
,
0x9a
,
0xc4
,
0xd4
,
0x22
,
0xa2
,
0xe6
,
0x8a
,
0x20
,
0x85
,
0x74
,
0x48
,
0x88
,
0x45
,
0xf3
,
0x6f
,
0xc1
,
0x46
,
0x9c
,
0xc4
,
0x7b
,
0x54
,
0xba
,
0x1f
,
0x69
,
0x25
,
0xbb
,
0xa4
,
0xe4
,
0xfc
,
0x04
,
0x7b
,
0x08
,
0x1b
,
0x87
,
0x7c
,
0xfc
,
0x4c
,
0x15
,
0xcc
,
0x87
,
0x22
,
0x3c
,
0xe1
,
0x99
,
0xff
,
0x8e
,
0xed
,
0x28
,
0x3a
,
0x78
,
0x5c
,
0x46
,
0xed
,
0x27
,
0x4f
,
0x60
,
0xdd
,
0x9d
,
0xc2
,
0x24
,
0x99
,
0x89
,
0x30
,
0x15
,
0x03
,
0xd3
,
0xf1
,
0x4d
,
0x12
,
0x9e
,
0x2f
,
0x8f
,
0xc3
,
0x63
,
0x75
,
0x1f
,
0x76
,
0x02
,
0x35
,
0x62
,
0xff
,
0xf4
,
0x60
,
0xd3
,
0x15
,
0x47
,
0xee
,
0xbb
,
0x3c
,
0xaf
,
0x77
,
0xf2
,
0xbc
,
0xfe
,
0x0e
,
0x34
,
0x32
,
0x5c
,
0xe4
,
0x94
,
0x26
,
0xf3
,
0xda
,
0x13
,
0x97
,
0x95
,
0xac
,
0xeb
,
0x4e
,
0xb2
,
0xbe
,
0x01
,
0xc0
,
0xcf
,
0xf8
,
0xd0
,
0xee
,
0x2f
,
0x0b
,
0xca
,
0x0b
,
0x97
,
0x72
,
0x8c
,
0xc3
,
0xd6
,
0x93
,
0x64
,
0x18
,
0x8e
,
0xb5
,
0x32
,
0x85
,
0x75
,
0x77
,
0xb5
,
0xd6
,
0x9e
,
0x55
,
0x7e
,
0x94
,
0x21
,
0xa1
,
0x35
,
0x27
,
0x6f
,
0x3a
,
0x88
,
0x47
,
0xfc
,
0x4c
,
0x65
,
0x0f
,
0x3d
,
0x64
,
0xf7
,
0xa1
,
0x2b
,
0xf3
,
0x3e
,
0x6a
,
0x50
,
0x0a
,
0x5e
,
0xde
,
0x26
,
0x54
,
0x8d
,
0x36
,
0x81
,
0x31
,
0x58
,
0x97
,
0xeb
,
0xf6
,
0xc2
,
0x78
,
0xc8
,
0xc7
,
0x65
,
0x2b
,
0xd9
,
0x97
,
0xaa
,
0x09
,
0x24
,
0x75
,
0x5e
,
0xe8
,
0xe2
,
0xbf
,
0xa3
,
0x4d
,
0x84
,
0xa5
,
0x07
,
0x33
,
0xa8
,
0x68
,
0x03
,
0xdf
,
0x86
,
0x3a
,
0xc2
,
0xd6
,
0x5b
,
0x25
,
0xfe
,
0xab
,
0x8a
,
0xdf
,
0xb6
,
0x6c
,
0x50
,
0x09
,
0x88
,
0x89
,
0x6a
,
0x58
,
0xd2
,
0x9a
,
0x42
,
0xa7
,
0x10
,
0xef
,
0x1a
,
0x34
,
0xa8
,
0x04
,
0x8a
,
0xf1
,
0x61
,
0x4b
,
0x81
,
0xc0
,
0x7e
,
0x55
,
0x5c
,
0xbe
,
0xd6
,
0xc9
,
0x28
,
0xf3
,
0x74
,
0x35
,
0x79
,
0x89
,
0xa3
,
0x99
,
0xab
,
0x26
,
0xab
,
0x17
,
0xaf
,
0xc9
,
0xaf
,
0xcd
,
0x2f
,
0x3d
,
0xb8
,
0x5e
,
0xa6
,
0xc6
,
0xc2
,
0x92
,
0x32
,
0x77
,
0xf5
,
0xea
,
0xa5
,
0x5c
,
0xdd
,
0xae
,
0x25
,
0x6b
,
0xcb
,
0x6b
,
0xc9
,
0xfa
,
0xb2
,
0x5a
,
0xb2
,
0xb1
,
0xb8
,
0x96
,
0x6c
,
0x5a
,
0xb5
,
0x24
,
0xfb
,
0x39
,
0x5c
,
0x2b
,
0x33
,
0x29
,
0x53
,
0x45
,
0xfc
,
0x2d
,
0x0b
,
0xda
,
0xde
,
0x02
,
0x03
,
0x74
,
0x35
,
0xb2
,
0xeb
,
0xe2
,
0xba
,
0x78
,
0x41
,
0x0e
,
0xea
,
0x1f
,
0x3c
,
0xf0
,
0x03
,
0xfe
,
0xfc
,
0xe3
,
0x19
,
0x4f
,
0xcf
,
0x91
,
0x4d
,
0xe5
,
0x38
,
0xfb
,
0x65
,
0xa6
,
0xc8
,
0x1e
,
0x6e
,
0x31
,
0xb2
,
0x09
,
0x8d
,
0x21
,
0xa6
,
0x4a
,
0x05
,
0x97
,
0x1c
,
0x20
,
0x52
,
0xa3
,
0x28
,
0xe5
,
0xf4
,
0xde
,
0xa7
,
0x91
,
0xca
,
0x09
,
0xc6
,
0xd5
,
0xd5
,
0xb0
,
0xae
,
0xae
,
0x4d
,
0x68
,
0x44
,
0x14
,
0xae
,
0xb2
,
0x14
,
0x97
,
0x03
,
0xf6
,
0x31
,
0x16
,
0x4b
,
0xd3
,
0xf1
,
0xb9
,
0xab
,
0xe1
,
0xbb
,
0x74
,
0x05
,
0x49
,
0x1f
,
0x51
,
0x99
,
0x78
,
0xa9
,
0x1b
,
0x15
,
0xdc
,
0xec
,
0x03
,
0xe3
,
0xbd
,
0x4e
,
0x26
,
0xfc
,
0x07
,
0x52
,
0xb3
,
0x5d
,
0xcb
,
0x6a
,
0xbb
,
0xa2
,
0x71
,
0xae
,
0xf9
,
0xbc
,
0xc4
,
0x12
,
0xb2
,
0xad
,
0xa7
,
0xe9
,
0xa7
,
0x51
,
0xcc
,
0xd3
,
0x97
,
0x97
,
0x85
,
0x45
,
0x41
,
0x94
,
0x19
,
0xda
,
0xab
,
0xe4
,
0xbd
,
0x12
,
0xb8
,
0x64
,
0xf6
,
0x9b
,
0x86
,
0xf1
,
0xd6
,
0xa4
,
0x76
,
0xbc
,
0x8f
,
0x05
,
0x2f
,
0x5a
,
0xa3
,
0x76
,
0xbc
,
0xee
,
0xee
,
0x68
,
0xda
,
0x4a
,
0x71
,
0x4e
,
0x63
,
0xff
,
0x1e
,
0x34
,
0x26
,
0xa8
,
0x78
,
0x49
,
0x6b
,
0xe7
,
0x5a
,
0x85
,
0xc9
,
0x87
,
0x78
,
0xfd
,
0xef
,
0x41
,
0x27
,
0xcc
,
0x32
,
0x2e
,
0x8e
,
0xd2
,
0x30
,
0xce
,
0x9e
,
0xf1
,
0x54
,
0xd5
,
0xbf
,
0x3a
,
0x0b
,
0x3d
,
0xc0
,
0xb9
,
0x4c
,
0x4f
,
0x0e
,
0x2a
,
0x81
,
0xcd
,
0x9d
,
0x2f
,
0xff
,
0x51
,
0x24
,
0x4e
,
0x47
,
0x69
,
0xf8
,
0x19
,
0xb9
,
0x82
,
0xbb
,
0x5c
,
0x4f
,
0xe6
,
0xcb
,
0x35
,
0xc1
,
0xbf
,
0x07
,
0x2b
,
0x42
,
0x6f
,
0xdc
,
0x5c
,
0xbe
,
0x71
,
0xce
,
0x88
,
0x8b
,
0x3e
,
0xd3
,
0xdb
,
0xb5
,
0x96
,
0x6f
,
0x97
,
0x33
,
0xfa
,
0xef
,
0x43
,
0x57
,
0x0b
,
0x38
,
0x4a
,
0xde
,
0x3f
,
0xe3
,
0x43
,
0x2a
,
0x77
,
0x0a
,
0x94
,
0xec
,
0xfd
,
0x24
,
0xcb
,
0xa0
,
0x12
,
0x38
,
0x8b
,
0xfc
,
0xf7
,
0x00
,
0xe2
,
0xfc
,
0x91
,
0x81
,
0x8a
,
0xa2
,
0x65
,
0xcf
,
0x08
,
0x83
,
0x4a
,
0x60
,
0xb0
,
0xfb
,
0x8f
,
0xe1
,
0x4a
,
0x6c
,
0x37
,
0x2c
,
0xea
,
0x8e
,
0x58
,
0xd2
,
0xd2
,
0x0c
,
0x2a
,
0x81
,
0xbb
,
0xc8
,
0x7f
,
0x08
,
0x57
,
0x32
,
0x1d
,
0x40
,
0x4a
,
0x8e
,
0xbc
,
0x3b
,
0xb6
,
0x0c
,
0x39
,
0xc6
,
0x2c
,
0xca
,
0x70
,
0x16
,
0x60
,
0x02
,
0x10
,
0xe7
,
0xaa
,
0x55
,
0xac
,
0x8a
,
0xf3
,
0xe2
,
0x92
,
0xf8
,
0xc2
,
0xc3
,
0x5e
,
0x23
,
0xef
,
0xd0
,
0x0c
,
0x87
,
0x5b
,
0xd4
,
0x9d
,
0x19
,
0xe5
,
0xc9
,
0xe5
,
0xc2
,
0xe3
,
0x5b
,
0x56
,
0x77
,
0x36
,
0xe7
,
0xde
,
0xd6
,
0xeb
,
0xb2
,
0xcc
,
0x88
,
0xf7
,
0xdd
,
0xfe
,
0x6c
,
0xf9
,
0xa2
,
0x3c
,
0x2b
,
0x7e
,
0x60
,
0x3d
,
0x0f
,
0x15
,
0x51
,
0xf0
,
0x52
,
0x19
,
0xe2
,
0x1f
,
0x35
,
0x4c
,
0x61
,
0xb6
,
0x34
,
0xba
,
0xaf
,
0xec
,
0x0b
,
0xc7
,
0x9b
,
0xbb
,
0x70
,
0xb0
,
0xd9
,
0xc6
,
0x91
,
0x84
,
0x51
,
0x81
,
0x6e
,
0x92
,
0xfc
,
0xb7
,
0xa0
,
0x8b
,
0x97
,
0xcc
,
0x61
,
0x38
,
0xe1
,
0x8a
,
0x49
,
0xe6
,
0x61
,
0x87
,
0x5a
,
0x54
,
0x20
,
0xf5
,
0xf2
,
0x1e
,
0xa2
,
0xe1
,
0x76
,
0x5e
,
0x45
,
0x75
,
0xdf
,
0x5c
,
0x56
,
0xdd
,
0xb7
,
0x96
,
0x54
,
0xf7
,
0x2b
,
0x4e
,
0x75
,
0x6f
,
0x75
,
0x1d
,
0x6d
,
0xb7
,
0xeb
,
0x30
,
0x6a
,
0x7f
,
0xb8
,
0xa0
,
0xf6
,
0x5f
,
0xbd
,
0x4c
,
0xed
,
0xbf
,
0x56
,
0x52
,
0xfb
,
0xcf
,
0x75
,
0x66
,
0x9d
,
0x4b
,
0x76
,
0x66
,
0xdd
,
0xd2
,
0xce
,
0x8c
,
0xfd
,
0x64
,
0xde
,
0xe3
,
0x03
,
0x3e
,
0x4c
,
0xd2
,
0xd1
,
0xab
,
0xf2
,
0x78
,
0xf6
,
0x75
,
0x58
,
0xcd
,
0xa7
,
0x8f
,
0xce
,
0xf0
,
0xc0
,
0x24
,
0x2a
,
0x4a
,
0xb0
,
0x1a
,
0xc9
,
0x0e
,
0xbd
,
0x78
,
0x50
,
0x38
,
0xc2
,
0xd3
,
0x75
,
0xbb
,
0xc7
,
0xcb
,
0x7c
,
0x80
,
0x60
,
0xbf
,
0xa8
,
0xc2
,
0x86
,
0xd5
,
0xeb
,
0xff
,
0x7f
,
0xf9
,
0x69
,
0xfb
,
0x65
,
0xfd
,
0xb4
,
0x5d
,
0xf8
,
0x29
,
0xdb
,
0x87
,
0xd7
,
0x2c
,
0x08
,
0x08
,
0x4d
,
0x4c
,
0x3e
,
0x4d
,
0xd2
,
0xc6
,
0x7d
,
0x1f
,
0x98
,
0x83
,
0x2b
,
0x50
,
0x7c
,
0x32
,
0x89
,
0xb8
,
0xa7
,
0x82
,
0x9a
,
0x95
,
0x9f
,
0xc9
,
0xdc
,
0x7b
,
0x87
,
0xf5
,
0x05
,
0xf3
,
0xcf
,
0x55
,
0xe8
,
0x16
,
0x17
,
0x3e
,
0x5e
,
0x3a
,
0xe8
,
0x64
,
0xd8
,
0x8a
,
0x69
,
0x27
,
0xc3
,
0xdf
,
0x94
,
0x9e
,
0x13
,
0x5d
,
0x9f
,
0x89
,
0x04
,
0x8f
,
0x2e
,
0xca
,
0x2f
,
0x36
,
0x02
,
0x7d
,
0x25
,
0x30
,
0x28
,
0x86
,
0x47
,
0xd5
,
0x69
,
0x47
,
0x35
,
0x42
,
0x7a
,
0x38
,
0xa1
,
0xc2
,
0x4e
,
0x41
,
0x2e
,
0x47
,
0xb8
,
0x27
,
0x36
,
0x78
,
0x0a
,
0x6d
,
0xfa
,
0x4d
,
0xb5
,
0xe2
,
0xf9
,
0xe4
,
0x38
,
0x19
,
0xab
,
0x87
,
0x52
,
0x35
,
0x32
,
0x8e
,
0x0d
,
0xac
,
0x63
,
0xa3
,
0x0f
,
0x42
,
0x78
,
0xdc
,
0x88
,
0x96
,
0x8a
,
0xb0
,
0xab
,
0xc4
,
0x31
,
0x47
,
0xa7
,
0x0f
,
0x21
,
0x61
,
0x1a
,
0x2a
,
0xae
,
0x2d
,
0xd9
,
0x62
,
0x16
,
0x14
,
0x4c
,
0x1b
,
0xd9
,
0x6c
,
0x38
,
0xe4
,
0x59
,
0xd6
,
0x7b
,
0x9d
,
0x8c
,
0xd3
,
0x43
,
0xf6
,
0x77
,
0xf5
,
0x71
,
0x83
,
0x1a
,
0xca
,
0x47
,
0xc7
,
0x14
,
0xb7
,
0x0b
,
0xdf
,
0x9a
,
0xcc
,
0xd7
,
0xa2
,
0xaa
,
0xf3
,
0x25
,
0xf4
,
0xa2
,
0x97
,
0xa6
,
0xb7
,
0xa0
,
0x3b
,
0x0d
,
0xf1
,
0xd6
,
0x78
,
0x6a
,
0xbe
,
0x37
,
0xad
,
0x05
,
0x0e
,
0x35
,
0x3f
,
0xdf
,
0xa3
,
0x68
,
0xc2
,
0x15
,
0xaa
,
0x05
,
0xc1
,
0xbf
,
0x09
,
0x35
,
0x71
,
0x26
,
0x3f
,
0x40
,
0xae
,
0xee
,
0xfa
,
0xca
,
0xb7
,
0x8e
,
0x8a
,
0xcf
,
0xe6
,
0x01
,
0x4e
,
0xb3
,
0xbf
,
0xaa
,
0x8f
,
0x48
,
0xa6
,
0x51
,
0xd4
,
0x86
,
0x5e
,
0xd6
,
0xb0
,
0xf6
,
0x57
,
0x36
,
0xac
,
0xfd
,
0x82
,
0x86
,
0xad
,
0x17
,
0x86
,
0xb5
,
0xc9
,
0x88
,
0xdd
,
0xcf
,
0x6b
,
0xd0
,
0xce
,
0xff
,
0x28
,
0xe0
,
0x7f
,
0x1f
,
0x56
,
0xf6
,
0xb9
,
0xa0
,
0xe0
,
0xf0
,
0xd7
,
0xf3
,
0x98
,
0x7a
,
0x7e
,
0x28
,
0xd2
,
0x28
,
0x3e
,
0xe9
,
0xbf
,
0x39
,
0x5f
,
0xc3
,
0x5a
,
0xdf
,
0x2e
,
0x59
,
0xc5
,
0x7f
,
0x17
,
0xe0
,
0x49
,
0x94
,
0x09
,
0x15
,
0xa6
,
0x9d
,
0x42
,
0xc4
,
0x87
,
0xd1
,
0xb8
,
0xdf
,
0x2f
,
0x8b
,
0x52
,
0xc9
,
0xca
,
0x2a
,
0xfe
,
0x47
,
0xe0
,
0xef
,
0x73
,
0x72
,
0x37
,
0x33
,
0x65
,
0xde
,
0x28
,
0x44
,
0x94
,
0xa5
,
0xd4
,
0xfe
,
0xc2
,
0xc8
,
0x67
,
0x15
,
0xff
,
0x10
,
0xba
,
0xda
,
0x9a
,
0x4b
,
0x4a
,
0x7b
,
0x73
,
0x69
,
0x45
,
0x92
,
0x4d
,
0x59
,
0xc5
,
0x7f
,
0x0f
,
0xd6
,
0xf7
,
0xb9
,
0xa0
,
0xa0
,
0xcf
,
0xef
,
0xbb
,
0x6e
,
0x21
,
0x16
,
0x0f
,
0xa1
,
0x7f
,
0xd5
,
0x15
,
0x43
,
0xec
,
0xac
,
0xe2
,
0xdf
,
0x82
,
0xe6
,
0x41
,
0x76
,
0x78
,
0x1e
,
0x0f
,
0x5d
,
0x68
,
0x36
,
0xd4
,
0xf0
,
0x20
,
0xdb
,
0x0b
,
0x67
,
0x27
,
0xa7
,
0xe2
,
0x93
,
0x29
,
0xab
,
0x1c
,
0x37
,
0xe9
,
0xdf
,
0x17
,
0xf7
,
0xfe
,
0x17
,
0x00
,
0x00
,
0xff
,
0xff
,
0x39
,
0x2e
,
0xe7
,
0xcd
,
0xca
,
0x21
,
0x00
,
0x00
,
func
init
()
{
proto
.
RegisterFile
(
"paracross.proto"
,
fileDescriptor_paracross_313193799a5638f5
)
}
var
fileDescriptor_paracross_313193799a5638f5
=
[]
byte
{
// 2397 bytes of a gzipped FileDescriptorProto
0x1f
,
0x8b
,
0x08
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0x02
,
0xff
,
0xd4
,
0x5a
,
0xcd
,
0x73
,
0x1c
,
0x47
,
0x15
,
0xdf
,
0xd9
,
0x2f
,
0x69
,
0x9f
,
0x3e
,
0x2c
,
0x4d
,
0x64
,
0x79
,
0x91
,
0x1d
,
0x47
,
0xd5
,
0x65
,
0x52
,
0x82
,
0x38
,
0x36
,
0x96
,
0xc1
,
0x54
,
0x8a
,
0xa2
,
0x88
,
0x2d
,
0xc7
,
0x5a
,
0x55
,
0xec
,
0x54
,
0x32
,
0x52
,
0xe0
,
0xc0
,
0x85
,
0xd1
,
0x6e
,
0x5b
,
0x9a
,
0x62
,
0x77
,
0x66
,
0x3c
,
0xdd
,
0x9b
,
0x48
,
0x5c
,
0x28
,
0x0a
,
0x38
,
0xc3
,
0x89
,
0x2a
,
0x38
,
0xe4
,
0x02
,
0x67
,
0xaa
,
0xf8
,
0x07
,
0x38
,
0x70
,
0x0c
,
0xa7
,
0x70
,
0xe0
,
0xc0
,
0x8d
,
0x1b
,
0x77
,
0x0e
,
0x5c
,
0xa9
,
0x7e
,
0xdd
,
0x3d
,
0xfd
,
0xb1
,
0xb3
,
0x63
,
0xd9
,
0xf1
,
0x25
,
0xb7
,
0xed
,
0xd7
,
0xaf
,
0x5f
,
0xbf
,
0xf7
,
0xeb
,
0xf7
,
0x5e
,
0xbf
,
0xd7
,
0xb3
,
0x70
,
0x29
,
0x8f
,
0x8b
,
0x78
,
0x58
,
0x64
,
0x8c
,
0xdd
,
0xca
,
0x8b
,
0x8c
,
0x67
,
0x61
,
0x87
,
0x9f
,
0xe7
,
0x94
,
0x6d
,
0xad
,
0xf3
,
0x22
,
0x4e
,
0x59
,
0x3c
,
0xe4
,
0x49
,
0x96
,
0xca
,
0x99
,
0xad
,
0xe5
,
0x61
,
0x36
,
0x99
,
0x94
,
0xa3
,
0xb5
,
0xe3
,
0x71
,
0x36
,
0xfc
,
0xe9
,
0xf0
,
0x34
,
0x4e
,
0x14
,
0x85
,
0x3c
,
0x86
,
0xcd
,
0x0f
,
0xb5
,
0xb0
,
0x43
,
0x1e
,
0xf3
,
0x29
,
0x7b
,
0x48
,
0x79
,
0x9c
,
0x8c
,
0x59
,
0xb8
,
0x01
,
0x9d
,
0x78
,
0x34
,
0x2a
,
0x58
,
0x3f
,
0xd8
,
0x6e
,
0xed
,
0xf4
,
0x22
,
0x39
,
0x08
,
0xaf
,
0x41
,
0x0f
,
0x65
,
0x0c
,
0x62
,
0x76
,
0xda
,
0x6f
,
0x6e
,
0xb7
,
0x76
,
0x96
,
0x23
,
0x43
,
0x20
,
0x3f
,
0x86
,
0xab
,
0x9e
,
0xb4
,
0x07
,
0x62
,
0x4e
,
0x8b
,
0xbc
,
0x0e
,
0x50
,
0xf2
,
0x4a
,
0xb9
,
0xcb
,
0x91
,
0x45
,
0x11
,
0xc2
,
0xf9
,
0x59
,
0x44
,
0xd9
,
0x74
,
0xcc
,
0x99
,
0x16
,
0x5e
,
0x12
,
0xc8
,
0x1f
,
0x9a
,
0x70
,
0xb9
,
0x94
,
0x3e
,
0xa0
,
0xc9
,
0xc9
,
0x29
,
0x97
,
0x7b
,
0x84
,
0x9b
,
0xd0
,
0x65
,
0xf8
,
0xab
,
0x1f
,
0x6c
,
0x07
,
0x3b
,
0x9d
,
0x48
,
0x8d
,
0x84
,
0x09
,
0x3c
,
0xe1
,
0x63
,
0xda
,
0x6f
,
0x6e
,
0x07
,
0xc2
,
0x04
,
0x1c
,
0x08
,
0xee
,
0x53
,
0x5c
,
0xdd
,
0x6f
,
0x6d
,
0x07
,
0x3b
,
0xad
,
0x48
,
0x8d
,
0xc2
,
0xef
,
0xc2
,
0xc2
,
0x48
,
0x2a
,
0xda
,
0x6f
,
0x6f
,
0x07
,
0x3b
,
0x4b
,
0xbb
,
0xaf
,
0xdf
,
0x42
,
0x58
,
0x6f
,
0x55
,
0x03
,
0x14
,
0x69
,
0x6e
,
0x61
,
0xd6
,
0x24
,
0x4e
,
0x52
,
0xa9
,
0x52
,
0xbf
,
0x83
,
0x42
,
0x2d
,
0x4a
,
0xb8
,
0x05
,
0x8b
,
0x38
,
0x12
,
0x90
,
0x75
,
0xb7
,
0x83
,
0x9d
,
0xe5
,
0xa8
,
0x1c
,
0x87
,
0x8f
,
0x60
,
0xf9
,
0xd8
,
0x82
,
0xa8
,
0xbf
,
0x80
,
0x3b
,
0x93
,
0xea
,
0x9d
,
0x6d
,
0x30
,
0x23
,
0x67
,
0x1d
,
0xf9
,
0x4f
,
0x00
,
0xfd
,
0x4a
,
0x70
,
0x22
,
0x96
,
0xbf
,
0x22
,
0x7c
,
0x5c
,
0x33
,
0xdb
,
0xb5
,
0x66
,
0x76
,
0x50
,
0xa0
,
0x31
,
0x73
,
0x1b
,
0x96
,
0x84
,
0x23
,
0x26
,
0xfc
,
0x3e
,
0xba
,
0x54
,
0x17
,
0x5d
,
0xca
,
0x26
,
0x85
,
0x3b
,
0x70
,
0x49
,
0x0e
,
0x1f
,
0x94
,
0xee
,
0xb5
,
0x80
,
0x5c
,
0x3e
,
0x99
,
0xfc
,
0x3e
,
0x80
,
0x4b
,
0x1e
,
0x30
,
0xc6
,
0x92
,
0xa0
,
0xda
,
0x92
,
0xa6
,
0x63
,
0x89
,
0xe3
,
0xc4
,
0x2d
,
0x3c
,
0x11
,
0x43
,
0x78
,
0x61
,
0x3b
,
0xad
,
0xe3
,
0x24
,
0x7f
,
0xb2
,
0x8f
,
0x61
,
0x2f
,
0x4b
,
0x19
,
0x4d
,
0xd9
,
0xb4
,
0x5e
,
0x49
,
0x01
,
0xcd
,
0xa9
,
0xd9
,
0x4f
,
0x6a
,
0x6a
,
0x93
,
0xc2
,
0x1b
,
0xb0
,
0x32
,
0x94
,
0xa2
,
0x06
,
0xf6
,
0xb9
,
0xb8
,
0xc4
,
0xf0
,
0x9b
,
0xb0
,
0xa6
,
0x08
,
0x06
,
0xc1
,
0x36
,
0x6e
,
0x34
,
0x43
,
0x27
,
0xbf
,
0x0b
,
0x20
,
0x14
,
0x6a
,
0x7e
,
0x90
,
0x8d
,
0xa8
,
0x80
,
0x7f
,
0x2f
,
0x4b
,
0x9f
,
0x26
,
0x27
,
0x73
,
0x14
,
0x5c
,
0x85
,
0x66
,
0x96
,
0xa3
,
0x5e
,
0x2b
,
0x51
,
0x33
,
0xcb
,
0xc5
,
0x38
,
0x19
,
0xa1
,
0x0e
,
0xbd
,
0xa8
,
0x99
,
0x8c
,
0xc2
,
0x10
,
0xda
,
0x22
,
0x37
,
0xa8
,
0xcd
,
0xf0
,
0xb7
,
0x90
,
0xf4
,
0x49
,
0x3c
,
0x9e
,
0x52
,
0x04
,
0x68
,
0x25
,
0x92
,
0x03
,
0xe9
,
0x05
,
0x49
,
0xca
,
0x1e
,
0x15
,
0xd9
,
0xcf
,
0x68
,
0x8a
,
0xb1
,
0x20
,
0x4c
,
0x35
,
0x24
,
0xf2
,
0xae
,
0xd1
,
0xeb
,
0x87
,
0x19
,
0xa7
,
0xd2
,
0xbb
,
0xe7
,
0xa4
,
0x22
,
0xb1
,
0x47
,
0xc6
,
0xa9
,
0xcc
,
0x14
,
0xbd
,
0x48
,
0x0e
,
0xc8
,
0x6f
,
0x03
,
0xd8
,
0xb0
,
0x4d
,
0x3b
,
0x18
,
0x29
,
0xf4
,
0xb5
,
0x9a
,
0x81
,
0xa5
,
0xe6
,
0x75
,
0x80
,
0xbc
,
0xc8
,
0xf2
,
0x8c
,
0xc5
,
0xe3
,
0x83
,
0x91
,
0x8a
,
0x02
,
0x8b
,
0x22
,
0x1c
,
0xe8
,
0xd9
,
0x34
,
0xe1
,
0x07
,
0xda
,
0x5c
,
0x35
,
0xb2
,
0x02
,
0xaa
,
0x5d
,
0x1d
,
0x50
,
0x1d
,
0x0b
,
0x40
,
0xf2
,
0xbf
,
0x00
,
0xd6
,
0xb4
,
0x4a
,
0xa5
,
0x3a
,
0x12
,
0xc5
,
0xa0
,
0x44
,
0xd1
,
0x88
,
0x6c
,
0x56
,
0x8b
,
0x6c
,
0xd9
,
0x67
,
0x72
,
0x1d
,
0x80
,
0xc7
,
0xc5
,
0x09
,
0xc5
,
0xe0
,
0x51
,
0xc8
,
0x5b
,
0x14
,
0x1f
,
0xe9
,
0xce
,
0x0c
,
0xd2
,
0xe1
,
0x6d
,
0x8d
,
0x5e
,
0x17
,
0x33
,
0xce
,
0xd7
,
0xac
,
0x8c
,
0xe3
,
0xa2
,
0xaf
,
0x80
,
0x15
,
0x6e
,
0xff
,
0xb4
,
0xc8
,
0x26
,
0xb8
,
0xe1
,
0x82
,
0x0c
,
0x6f
,
0x3d
,
0xb6
,
0x02
,
0x6d
,
0xd1
,
0x0e
,
0x34
,
0xf2
,
0xd7
,
0x00
,
0x2e
,
0x47
,
0x74
,
0x48
,
0x93
,
0x9c
,
0x6b
,
0xc1
,
0xca
,
0xd5
,
0xaa
,
0x4e
,
0xe3
,
0x0e
,
0x74
,
0x87
,
0x38
,
0x8b
,
0x10
,
0xcc
,
0xea
,
0x64
,
0x3c
,
0x35
,
0x52
,
0x8c
,
0xe1
,
0x5b
,
0xd0
,
0xce
,
0x0b
,
0xfa
,
0x09
,
0x82
,
0xb3
,
0xb4
,
0x7b
,
0xc5
,
0x5b
,
0xa0
,
0xc1
,
0x8e
,
0x90
,
0x29
,
0xbc
,
0x03
,
0x0b
,
0xc3
,
0x69
,
0x51
,
0xd0
,
0x94
,
0xab
,
0x04
,
0x3f
,
0x97
,
0x5f
,
0xf3
,
0x91
,
0x3f
,
0x06
,
0xf0
,
0xba
,
0x67
,
0x80
,
0xd0
,
0x42
,
0xb0
,
0x7d
,
0x9c
,
0x8f
,
0x62
,
0x4e
,
0x1d
,
0x58
,
0x02
,
0x0f
,
0x96
,
0xdb
,
0x4a
,
0x3b
,
0x69
,
0xce
,
0xd5
,
0x0a
,
0x73
,
0x3c
,
0x0d
,
0xbf
,
0x63
,
0x34
,
0x6c
,
0x3d
,
0x7f
,
0x4d
,
0xa9
,
0xe5
,
0x7f
,
0x03
,
0xb8
,
0xe2
,
0x69
,
0x89
,
0xe7
,
0x97
,
0xa5
,
0x74
,
0xc6
,
0xcf
,
0xaa
,
0x73
,
0xbe
,
0xeb
,
0x4f
,
0xad
,
0x19
,
0x7f
,
0x12
,
0xf3
,
0x19
,
0x8f
,
0xc7
,
0x42
,
0xb4
,
0x76
,
0x7a
,
0x8b
,
0x82
,
0x37
,
0xb7
,
0x18
,
0x89
,
0x6d
,
0xd1
,
0xdb
,
0x3a
,
0x91
,
0x21
,
0x60
,
0xc6
,
0xcc
,
0x18
,
0xc7
,
0xc9
,
0x2e
,
0x4e
,
0x96
,
0xe3
,
0xb0
,
0x0f
,
0x0b
,
0xc2
,
0xbf
,
0x22
,
0xc6
,
0x95
,
0x57
,
0xe9
,
0xa1
,
0xd8
,
0x73
,
0x94
,
0xa5
,
0x54
,
0x1a
,
0x8b
,
0x8e
,
0xd5
,
0x89
,
0x2c
,
0x0a
,
0xf9
,
0x65
,
0x00
,
0xaf
,
0x69
,
0x73
,
0xf7
,
0x8b
,
0x6c
,
0x9a
,
0x7f
,
0xa9
,
0x2c
,
0x56
,
0xe6
,
0x18
,
0x19
,
0x4c
,
0x2a
,
0xc7
,
0x3c
,
0x37
,
0x8e
,
0xc8
,
0xdf
,
0x7d
,
0x2d
,
0x5e
,
0x49
,
0x7c
,
0x6f
,
0xc3
,
0x92
,
0x41
,
0x5f
,
0xeb
,
0x64
,
0x93
,
0x2e
,
0x10
,
0xe1
,
0xb6
,
0x67
,
0x76
,
0xe7
,
0x06
,
0xec
,
0x82
,
0x13
,
0xb0
,
0x9f
,
0x07
,
0xb0
,
0xe5
,
0x79
,
0x92
,
0x0d
,
0x6d
,
0x55
,
0xd4
,
0xee
,
0x7a
,
0x51
,
0xbb
,
0xe5
,
0xb9
,
0xac
,
0xb5
,
0xbe
,
0x0c
,
0xdb
,
0x5b
,
0x4e
,
0xd8
,
0x56
,
0xae
,
0x70
,
0xe2
,
0xe2
,
0xdb
,
0x7e
,
0xe4
,
0xd6
,
0x2d
,
0x29
,
0xc3
,
0xe2
,
0x14
,
0x36
,
0x22
,
0xfa
,
0xac
,
0xbc
,
0x8e
,
0x31
,
0xc2
,
0xd3
,
0xa7
,
0xd9
,
0x7c
,
0x07
,
0x49
,
0xf4
,
0x1d
,
0x60
,
0x5f
,
0x6b
,
0x2d
,
0xcb
,
0xd6
,
0x39
,
0x79
,
0x9f
,
0xec
,
0xc1
,
0x66
,
0x44
,
0x59
,
0xee
,
0x6c
,
0x25
,
0x8f
,
0xe9
,
0x1b
,
0xd0
,
0x4a
,
0x46
,
0xf2
,
0xe2
,
0xaa
,
0xc9
,
0x37
,
0x82
,
0x87
,
0xec
,
0x8b
,
0x20
,
0xf6
,
0x84
,
0xa0
,
0x5d
,
0x2c
,
0xbc
,
0x69
,
0x4b
,
0xa9
,
0xb3
,
0x1d
,
0x05
,
0xfd
,
0x3a
,
0x80
,
0x75
,
0x31
,
0x89
,
0xf7
,
0xfd
,
0xee
,
0x93
,
0x38
,
0x49
,
0x9f
,
0xc4
,
0xb9
,
0x75
,
0xe4
,
0xc1
,
0xfc
,
0x62
,
0x48
,
0x9a
,
0x3f
,
0xb7
,
0x18
,
0x6a
,
0xd5
,
0x16
,
0x43
,
0x6d
,
0xb7
,
0xe8
,
0x23
,
0x0f
,
0xe5
,
0x65
,
0x6e
,
0xd4
,
0x40
,
0xf4
,
0x6f
,
0x41
,
0x27
,
0xe1
,
0x74
,
0xa2
,
0xad
,
0xe9
,
0x5b
,
0xd6
,
0x38
,
0x0a
,
0x47
,
0x92
,
0x8d
,
0xfc
,
0xbb
,
0x25
,
0x03
,
0xac
,
0xc4
,
0x44
,
0x05
,
0xd8
,
0x0d
,
0x58
,
0x11
,
0x3b
,
0x99
,
0x62
,
0x27
,
0xc0
,
0x5a
,
0xcc
,
0x25
,
0x8a
,
0xb2
,
0xd2
,
0x10
,
0xec
,
0x0a
,
0xcb
,
0x27
,
0xcf
,
0x09
,
0x44
,
0x83
,
0x5a
,
0xdb
,
0x41
,
0x8d
,
0xc0
,
0x72
,
0x5e
,
0x50
,
0xb3
,
0xb9
,
0x2c
,
0x04
,
0x1d
,
0x9a
,
0x8b
,
0x6c
,
0xd7
,
0x2f
,
0x33
,
0xa5
,
0x04
,
0x61
,
0x0c
,
0x55
,
0xd5
,
0xae
,
0x96
,
0x50
,
0xd2
,
0x84
,
0x04
,
0x56
,
0x32
,
0x2c
,
0x4a
,
0x09
,
0x25
,
0x41
,
0x60
,
0xcf
,
0xcf
,
0xf6
,
0xb2
,
0x69
,
0xca
,
0x59
,
0xbf
,
0x87
,
0x89
,
0xad
,
0x1c
,
0xcb
,
0x39
,
0xd9
,
0x39
,
0xf5
,
0x41
,
0x16
,
0xa9
,
0x7a
,
0x2c
,
0x52
,
0x2e
,
0x3f
,
0x93
,
0x3d
,
0xd8
,
0x12
,
0x36
,
0x59
,
0x7a
,
0x88
,
0x95
,
0xa6
,
0x80
,
0xf9
,
0x48
,
0x2f
,
0x5d
,
0x96
,
0x98
,
0x3a
,
0x44
,
0xa1
,
0xb9
,
0x22
,
0x48
,
0x21
,
0x2b
,
0x28
,
0xc4
,
0xa1
,
0x85
,
0x37
,
0x61
,
0x3d
,
0xcd
,
0xd2
,
0x3d
,
0x2c
,
0xdd
,
0x8f
,
0xb4
,
0x92
,
0xab
,
0xa8
,
0xe4
,
0xec
,
0x04
,
0x79
,
0x00
,
0xeb
,
0x87
,
0x74
,
0xfc
,
0x54
,
0x15
,
0xcc
,
0x87
,
0x3c
,
0x3e
,
0xa1
,
0x2c
,
0x7c
,
0xdb
,
0x75
,
0x14
,
0x1d
,
0x3c
,
0x3e
,
0xa3
,
0xf6
,
0x93
,
0xc7
,
0xb0
,
0xe6
,
0x4f
,
0x89
,
0x24
,
0xc9
,
0x78
,
0x5c
,
0xf0
,
0x81
,
0xed
,
0xf8
,
0x36
,
0x49
,
0x9c
,
0x2f
,
0x4d
,
0xe3
,
0x63
,
0x75
,
0x1f
,
0xae
,
0x44
,
0x6a
,
0x44
,
0xfe
,
0x15
,
0xc0
,
0x86
,
0x2f
,
0x0e
,
0xdd
,
0xb7
,
0x3e
,
0xaf
,
0xaf
,
0x94
,
0x79
,
0xfd
,
0x6d
,
0xe8
,
0x30
,
0xb1
,
0xc8
,
0x2b
,
0x4d
,
0x66
,
0xb5
,
0x47
,
0x2e
,
0x27
,
0x59
,
0xb7
,
0xbd
,
0x64
,
0x7d
,
0x1d
,
0x80
,
0x9e
,
0xd1
,
0xa1
,
0xdb
,
0x5f
,
0x1a
,
0xca
,
0x0b
,
0x97
,
0x72
,
0x84
,
0xc2
,
0xe6
,
0xe3
,
0x6c
,
0x18
,
0x8f
,
0xb5
,
0x32
,
0xc6
,
0xba
,
0x3b
,
0x5a
,
0xeb
,
0xc0
,
0x29
,
0x3f
,
0xaa
,
0x90
,
0xd0
,
0x9a
,
0xa3
,
0x37
,
0x1d
,
0xa4
,
0x23
,
0x7a
,
0xa6
,
0xb2
,
0x87
,
0x1e
,
0x92
,
0x7b
,
0xb0
,
0x2a
,
0xf3
,
0xbe
,
0xd0
,
0xa0
,
0x12
,
0xbc
,
0xb2
,
0x4d
,
0x68
,
0x5a
,
0x6d
,
0x02
,
0x21
,
0xb0
,
0x26
,
0xd7
,
0xed
,
0xc5
,
0xe9
,
0x90
,
0x8e
,
0xab
,
0x56
,
0x92
,
0x2f
,
0x54
,
0x13
,
0x88
,
0xea
,
0xbc
,
0xd0
,
0xc5
,
0x7f
,
0x5b
,
0x9b
,
0x08
,
0xb5
,
0x07
,
0x33
,
0x68
,
0x68
,
0x03
,
0xdf
,
0x82
,
0xb6
,
0x80
,
0xad
,
0xbf
,
0x84
,
0xfc
,
0x97
,
0x15
,
0xbf
,
0x6b
,
0xd9
,
0xa0
,
0x11
,
0x21
,
0x13
,
0xd6
,
0xb0
,
0xa8
,
0x35
,
0x86
,
0x8e
,
0x11
,
0xef
,
0x1b
,
0x34
,
0x68
,
0x44
,
0x8a
,
0xf1
,
0xc1
,
0x82
,
0x02
,
0x81
,
0xfc
,
0xca
,
0x5c
,
0xbe
,
0xce
,
0xc9
,
0x28
,
0xf3
,
0x74
,
0x35
,
0x79
,
0x81
,
0xa3
,
0x99
,
0xa9
,
0x26
,
0x9b
,
0xcf
,
0x5f
,
0x53
,
0x5e
,
0x9b
,
0x5f
,
0x04
,
0x70
,
0xad
,
0x4a
,
0x8d
,
0xb9
,
0x25
,
0x65
,
0xe9
,
0xea
,
0xcd
,
0x0b
,
0xb9
,
0xba
,
0x5b
,
0x4b
,
0xb6
,
0xea
,
0x6b
,
0xc9
,
0x76
,
0x5d
,
0x2d
,
0xd9
,
0x99
,
0x5f
,
0x4b
,
0x76
,
0x9d
,
0x5a
,
0x92
,
0xfc
,
0x1c
,
0xae
,
0x56
,
0x99
,
0xc4
,
0x54
,
0x11
,
0x7f
,
0xd3
,
0x81
,
0xb6
,
0x3f
,
0xc7
,
0x00
,
0x5d
,
0x8d
,
0xec
,
0xfa
,
0xb8
,
0xce
,
0x5f
,
0x50
,
0x82
,
0xfa
,
0x59
,
0x00
,
0x61
,
0x44
,
0x9f
,
0x7d
,
0x34
,
0xa5
,
0xc5
,
0xb9
,
0x60
,
0x53
,
0x39
,
0xce
,
0x7d
,
0x99
,
0x31
,
0xd9
,
0xc3
,
0x2f
,
0x46
,
0x36
,
0xa0
,
0x33
,
0x14
,
0xa9
,
0x52
,
0xc1
,
0x25
,
0x07
,
0x02
,
0xa9
,
0x51
,
0x52
,
0x50
,
0x7c
,
0xef
,
0xd3
,
0x48
,
0x95
,
0x04
,
0xeb
,
0xea
,
0xea
,
0x38
,
0x57
,
0xd7
,
0x06
,
0x74
,
0x12
,
0x0c
,
0x57
,
0x59
,
0x8a
,
0xcb
,
0x01
,
0xf9
,
0x48
,
0x14
,
0x4b
,
0xf9
,
0xf8
,
0xdc
,
0xd7
,
0xf0
,
0x1d
,
0xbc
,
0x82
,
0xa4
,
0x8f
,
0xa8
,
0x4c
,
0x5c
,
0xeb
,
0x46
,
0x86
,
0x9b
,
0xbc
,
0x6f
,
0xbd
,
0xd7
,
0xc9
,
0x84
,
0x7f
,
0x5f
,
0x6a
,
0xb6
,
0xeb
,
0x58
,
0xed
,
0x56
,
0x34
,
0xde
,
0x35
,
0x5f
,
0x96
,
0x58
,
0x5c
,
0xb6
,
0xf5
,
0x38
,
0xfd
,
0x24
,
0x49
,
0x69
,
0xf1
,
0xf2
,
0xb2
,
0x44
,
0x51
,
0x90
,
0x30
,
0x4b
,
0x7b
,
0x95
,
0xbc
,
0x17
,
0x23
,
0x9f
,
0x4c
,
0x7e
,
0xd3
,
0xb1
,
0xde
,
0x9a
,
0xd4
,
0x8e
,
0xf7
,
0x44
,
0xc1
,
0x2b
,
0xac
,
0x51
,
0x3b
,
0x5e
,
0xf3
,
0x77
,
0xb4
,
0x6d
,
0xc5
,
0x38
,
0xc7
,
0x71
,
0x78
,
0x17
,
0x3a
,
0x13
,
0xa1
,
0x78
,
0x45
,
0x6b
,
0xe7
,
0x5b
,
0x25
,
0x92
,
0x0f
,
0xf2
,
0x86
,
0xdf
,
0x87
,
0x95
,
0x98
,
0x31
,
0xca
,
0x8f
,
0x8a
,
0x38
,
0x65
,
0x4f
,
0x69
,
0xa1
,
0xea
,
0x5f
,
0x9d
,
0x85
,
0xee
,
0x8b
,
0x39
,
0xa6
,
0x27
,
0x07
,
0x8d
,
0xc8
,
0xe5
,
0x2e
,
0x97
,
0xff
,
0x28
,
0xe1
,
0xa7
,
0xa3
,
0x22
,
0xfe
,
0x14
,
0x5d
,
0xc1
,
0x5f
,
0xae
,
0x27
,
0xcb
,
0xe5
,
0x9a
,
0x10
,
0xde
,
0x85
,
0x45
,
0xae
,
0x37
,
0xee
,
0xd6
,
0x6f
,
0x5c
,
0x32
,
0x8a
,
0x45
,
0x9f
,
0xea
,
0xed
,
0x16
,
0xea
,
0xb7
,
0x2b
,
0x19
,
0xc3
,
0xf7
,
0x60
,
0x55
,
0x0b
,
0x38
,
0xca
,
0xde
,
0x3b
,
0xa3
,
0x43
,
0x2c
,
0x77
,
0x0c
,
0x4a
,
0xee
,
0x7e
,
0x92
,
0x65
,
0xd0
,
0x88
,
0xbc
,
0x45
,
0xe1
,
0xf7
,
0x00
,
0xd2
,
0xf2
,
0x91
,
0x01
,
0x8b
,
0xa2
,
0xba
,
0x67
,
0x84
,
0x41
,
0x23
,
0xb2
,
0xd8
,
0xc3
,
0x47
,
0x70
,
0x29
,
0x75
,
0x1b
,
0x16
,
0x75
,
0x47
,
0xd4
,
0xb4
,
0x34
,
0x83
,
0x46
,
0xe4
,
0x2f
,
0x0a
,
0x1f
,
0xc0
,
0x25
,
0xa6
,
0x03
,
0x48
,
0xc9
,
0x91
,
0x77
,
0xc7
,
0xa6
,
0x25
,
0xc7
,
0x9a
,
0x15
,
0x32
,
0xbc
,
0x05
,
0x22
,
0x01
,
0xf0
,
0x73
,
0xd5
,
0x2a
,
0x36
,
0xf9
,
0xb9
,
0xb9
,
0x24
,
0x3e
,
0x0f
,
0x44
,
0xaf
,
0x51
,
0x76
,
0x68
,
0x96
,
0xc3
,
0xcd
,
0xeb
,
0xce
,
0xac
,
0xf2
,
0xe4
,
0x62
,
0xe1
,
0xf1
,
0x2d
,
0xa7
,
0x3b
,
0x9b
,
0x71
,
0x6f
,
0xe7
,
0x75
,
0x59
,
0x66
,
0xc4
,
0x7b
,
0x7e
,
0x7f
,
0x56
,
0xbf
,
0xa8
,
0xcc
,
0x8a
,
0xef
,
0x3b
,
0xcf
,
0x43
,
0x26
,
0x0a
,
0x5e
,
0x2a
,
0x43
,
0xfc
,
0xb3
,
0x25
,
0x52
,
0x98
,
0x2b
,
0x0d
,
0xef
,
0x2b
,
0xf7
,
0xc2
,
0x09
,
0x66
,
0x2e
,
0x1c
,
0xd1
,
0x6c
,
0x8b
,
0x91
,
0x84
,
0x51
,
0x81
,
0x6e
,
0x93
,
0xc2
,
0x37
,
0x61
,
0x55
,
0x5c
,
0x32
,
0x87
,
0xf1
,
0x84
,
0x2a
,
0x26
,
0x99
,
0x87
,
0x3d
,
0xaa
,
0xa9
,
0x40
,
0xda
,
0xd5
,
0x3d
,
0x44
,
0xc7
,
0xef
,
0xbc
,
0x4c
,
0x75
,
0xdf
,
0xad
,
0xab
,
0xee
,
0x17
,
0x6a
,
0xaa
,
0xfb
,
0x45
,
0xaf
,
0xba
,
0x77
,
0xba
,
0x8e
,
0x9e
,
0xdf
,
0x75
,
0x58
,
0xb5
,
0x3f
,
0x3c
,
0xa7
,
0xf6
,
0x5f
,
0xba
,
0x48
,
0xed
,
0xbf
,
0x5c
,
0x51
,
0xfb
,
0xcf
,
0x74
,
0x66
,
0x2b
,
0x17
,
0xec
,
0xcc
,
0x56
,
0x2b
,
0x3b
,
0x33
,
0xf2
,
0x93
,
0x59
,
0x8f
,
0x8f
,
0xe8
,
0x30
,
0x2b
,
0x46
,
0xaf
,
0xca
,
0xe3
,
0xc9
,
0xd7
,
0x61
,
0xa9
,
0x9c
,
0x3e
,
0x3a
,
0x13
,
0x07
,
0x26
,
0x51
,
0x51
,
0x82
,
0xd5
,
0x48
,
0x76
,
0xe8
,
0xe6
,
0x41
,
0xe1
,
0x48
,
0x9c
,
0xae
,
0xdf
,
0x3d
,
0x5e
,
0xe4
,
0x03
,
0x04
,
0xf9
,
0x45
,
0x13
,
0xd6
,
0x9d
,
0x5e
,
0xff
,
0xab
,
0xe5
,
0xa7
,
0xbd
,
0x97
,
0xf5
,
0xd3
,
0x9e
,
0xf1
,
0x53
,
0xb2
,
0x0f
,
0xaf
,
0x39
,
0x10
,
0x20
,
0x9a
,
0x22
,
0xf9
,
0x74
,
0x51
,
0x1b
,
0xff
,
0x7d
,
0x60
,
0x06
,
0xae
,
0x48
,
0xf1
,
0xc9
,
0x24
,
0xe2
,
0x9f
,
0x8a
,
0xd0
,
0xac
,
0xfa
,
0x4c
,
0x66
,
0xde
,
0x3b
,
0x9c
,
0x2f
,
0x98
,
0x7f
,
0x6e
,
0xc2
,
0xaa
,
0xb9
,
0xf0
,
0xc5
,
0xa5
,
0x23
,
0x9c
,
0x4c
,
0xb4
,
0x62
,
0xda
,
0xc9
,
0xc4
,
0x6f
,
0x4c
,
0xcf
,
0x99
,
0xae
,
0xcf
,
0x78
,
0x26
,
0x8e
,
0x2e
,
0x29
,
0x2f
,
0x36
,
0x04
,
0x7d
,
0x31
,
0xb2
,
0x28
,
0x96
,
0x47
,
0xb5
,
0x71
,
0x47
,
0x35
,
0x12
,
0xf4
,
0x78
,
0x82
,
0x85
,
0x9d
,
0x82
,
0x5c
,
0x8e
,
0xc4
,
0x9e
,
0xa2
,
0xc1
,
0x53
,
0x68
,
0xe3
,
0x6f
,
0xac
,
0x15
,
0xcf
,
0x27
,
0xc7
,
0xd9
,
0x58
,
0x3d
,
0x94
,
0xaa
,
0x91
,
0x75
,
0x6c
,
0xe0
,
0x1c
,
0x1b
,
0x7e
,
0x10
,
0x12
,
0xc7
,
0x2d
,
0xd0
,
0x52
,
0x11
,
0x76
,
0x19
,
0x39
,
0x66
,
0xe8
,
0xf8
,
0x21
,
0x24
,
0x2e
,
0x62
,
0xc5
,
0xb5
,
0x29
,
0x5b
,
0x4c
,
0x43
,
0x11
,
0x69
,
0x83
,
0x4d
,
0x87
,
0x43
,
0xca
,
0x58
,
0xff
,
0x0a
,
0x1a
,
0xa7
,
0x87
,
0xe4
,
0x2f
,
0x4d
,
0xf9
,
0xd8
,
0x64
,
0x00
,
0x8b
,
0x58
,
0xfe
,
0x92
,
0x98
,
0xf5
,
0x6a
,
0x30
,
0xeb
,
0x7d
,
0xd5
,
0x31
,
0xeb
,
0x19
,
0xcc
,
0xfe
,
0xa1
,
0x3e
,
0x08
,
0x61
,
0x13
,
0xfe
,
0xf0
,
0x18
,
0x73
,
0xdd
,
0xdc
,
0xf7
,
0x39
,
0xfb
,
0x85
,
0xad
,
0xe9
,
0x7d
,
0x3d
,
0x7e
,
0xde
,
0xeb
,
0xdc
,
0x9b
,
0xb0
,
0x9a
,
0xc7
,
0xe2
,
0xa6
,
0x7d
,
0x62
,
0xbf
,
0xd1
,
0x2d
,
0x47
,
0x1e
,
0xb5
,
0x8c
,
0x89
,
0xa3
,
0x64
,
0x42
,
0x15
,
0xaa
,
0x86
,
0x10
,
0xde
,
0x80
,
0x16
,
0x3f
,
0x93
,
0x1f
,
0x6d
,
0x97
,
0x76
,
0x43
,
0x15
,
0x8f
,
0x47
,
0xe6
,
0xaf
,
0x06
,
0x91
,
0x98
,
0x26
,
0x7f
,
0x53
,
0x1f
,
0xde
,
0x6c
,
0xa3
,
0xb0
,
0x75
,
0xbf
,
0xa8
,
0x61
,
0xbd
,
0x2f
,
0x6d
,
0x58
,
0xef
,
0x05
,
0x0d
,
0x5b
,
0x33
,
0x86
,
0xf5
,
0xd0
,
0x88
,
0xdd
,
0xcf
,
0x5a
,
0xd0
,
0x2b
,
0xff
,
0x5c
,
0x11
,
0xfe
,
0x00
,
0x16
,
0xf7
,
0x29
,
0xc7
,
0x84
,
0x12
,
0xae
,
0x95
,
0x79
,
0xe8
,
0xd9
,
0x21
,
0x2f
,
0x92
,
0xf4
,
0x64
,
0xeb
,
0x8d
,
0xd9
,
0xba
,
0xdf
,
0xf9
,
0xde
,
0x4b
,
0x1a
,
0xe1
,
0x3b
,
0x00
,
0x8f
,
0x13
,
0xc6
,
0x55
,
0x6a
,
0x5b
,
0x31
,
0x22
,
0x3e
,
0x48
,
0xc6
,
0x5b
,
0x5b
,
0x55
,
0x99
,
0x4d
,
0xb2
,
0x92
,
0x46
,
0xf8
,
0x21
,
0x84
,
0xfb
,
0x14
,
0xdd
,
0xcd
,
0xbe
,
0x66
,
0xae
,
0x1b
,
0x11
,
0x55
,
0xd7
,
0xd0
,
0xd6
,
0xdc
,
0x6c
,
0x49
,
0x1a
,
0xe1
,
0x21
,
0xac
,
0x6a
,
0x6b
,
0x2e
,
0x28
,
0xed
,
0x8d
,
0xda
,
0x2a
,
0x8e
,
0xe5
,
0xa4
,
0x11
,
0xbe
,
0x0b
,
0x6b
,
0xfb
,
0x94
,
0x63
,
0xdc
,
0x97
,
0x35
,
0xc2
,
0x2c
,
0x54
,
0x7d
,
0x5f
,
0x90
,
0x4e
,
0x14
,
0xa4
,
0x11
,
0xde
,
0x84
,
0xee
,
0x01
,
0x3b
,
0x3c
,
0x4f
,
0x87
,
0x3e
,
0x3e
,
0xeb
,
0x6a
,
0x78
,
0xc0
,
0xf6
,
0xe2
,
0xe9
,
0xc9
,
0x29
,
0xff
,
0x38
,
0x27
,
0x8d
,
0xe3
,
0x2e
,
0xfe
,
0x6d
,
0xe5
,
0xee
,
0xff
,
0x03
,
0x00
,
0x00
,
0xff
,
0xff
,
0x3c
,
0x35
,
0x92
,
0x17
,
0x03
,
0x23
,
0x00
,
0x00
,
}
plugin/dapp/paracross/types/type.go
View file @
17b6b5f4
...
...
@@ -26,6 +26,8 @@ var (
MainLoopCheckCommitTxDoneForkHeight
=
"mainLoopCheckCommitTxDoneForkHeight"
// ForkParaSelfConsStages 平行链自共识分阶段共识
ForkParaSelfConsStages
=
"ForkParaSelfConsStages"
// ForkParaAssetTransferRbk 平行链资产转移平行链失败主链回滚
ForkParaAssetTransferRbk
=
"ForkParaAssetTransferRbk"
// ParaConsSubConf sub
ParaConsSubConf
=
"consensus.sub.para"
...
...
@@ -52,6 +54,8 @@ func InitFork(cfg *types.Chain33Config) {
cfg
.
RegisterDappFork
(
ParaX
,
"ForkParacrossWithdrawFromParachain"
,
1298600
)
cfg
.
RegisterDappFork
(
ParaX
,
ForkCommitTx
,
1850000
)
cfg
.
RegisterDappFork
(
ParaX
,
ForkLoopCheckCommitTxDone
,
3230000
)
cfg
.
RegisterDappFork
(
ParaX
,
ForkParaAssetTransferRbk
,
4500000
)
//只在平行链启用
cfg
.
RegisterDappFork
(
ParaX
,
ForkParaSelfConsStages
,
types
.
MaxHeight
)
}
...
...
plugin/dapp/storage/cmd/Makefile
0 → 100644
View file @
17b6b5f4
all
:
chmod
+x ./build.sh
./build.sh
$(OUT)
$(FLAG)
plugin/dapp/storage/cmd/build.sh
0 → 100755
View file @
17b6b5f4
#!/bin/sh
# 官方ci集成脚本
strpwd
=
$(
pwd
)
strcmd
=
${
strpwd
##*dapp/
}
strapp
=
${
strcmd
%/cmd*
}
OUT_DIR
=
"
${
1
}
/
$strapp
"
#FLAG=$2
mkdir
-p
"
${
OUT_DIR
}
"
cp
./build/
*
"
${
OUT_DIR
}
"
plugin/dapp/storage/commands/commands.go
0 → 100644
View file @
17b6b5f4
/*Package commands implement dapp client commands*/
package
commands
import
(
"github.com/spf13/cobra"
)
/*
* 实现合约对应客户端
*/
// Cmd storage client command
func
Cmd
()
*
cobra
.
Command
{
cmd
:=
&
cobra
.
Command
{
Use
:
"storage"
,
Short
:
"storage command"
,
Args
:
cobra
.
MinimumNArgs
(
1
),
}
cmd
.
AddCommand
(
//add sub command
)
return
cmd
}
plugin/dapp/storage/crypto/aes.go
0 → 100644
View file @
17b6b5f4
package
crypto
import
(
"crypto/aes"
"crypto/cipher"
)
type
AES
struct
{
key
[]
byte
//iv的长度必须等于block块的大小,这里是16字节,固定
iv
[]
byte
}
//AES 密钥长度为 16,24,32 字节,三种
func
NewAES
(
key
,
iv
[]
byte
)
*
AES
{
return
&
AES
{
key
:
key
,
iv
:
iv
}
}
func
(
a
*
AES
)
Encrypt
(
origData
[]
byte
)
([]
byte
,
error
)
{
block
,
err
:=
aes
.
NewCipher
(
a
.
key
)
if
err
!=
nil
{
return
nil
,
err
}
blockSize
:=
block
.
BlockSize
()
origData
=
PKCS5Padding
(
origData
,
blockSize
)
// origData = ZeroPadding(origData, block.BlockSize())
blockMode
:=
cipher
.
NewCBCEncrypter
(
block
,
a
.
iv
[
:
blockSize
])
crypted
:=
make
([]
byte
,
len
(
origData
))
// 根据CryptBlocks方法的说明,如下方式初始化crypted也可以
// crypted := origData
blockMode
.
CryptBlocks
(
crypted
,
origData
)
return
crypted
,
nil
}
func
(
a
*
AES
)
Decrypt
(
crypted
[]
byte
)
([]
byte
,
error
)
{
block
,
err
:=
aes
.
NewCipher
(
a
.
key
)
if
err
!=
nil
{
return
nil
,
err
}
blockSize
:=
block
.
BlockSize
()
blockMode
:=
cipher
.
NewCBCDecrypter
(
block
,
a
.
iv
[
:
blockSize
])
origData
:=
make
([]
byte
,
len
(
crypted
))
// origData := crypted
blockMode
.
CryptBlocks
(
origData
,
crypted
)
origData
=
PKCS5UnPadding
(
origData
)
// origData = ZeroUnPadding(origData)
return
origData
,
nil
}
plugin/dapp/storage/crypto/aes_test.go
0 → 100644
View file @
17b6b5f4
package
crypto
import
(
"encoding/base64"
"testing"
"github.com/stretchr/testify/assert"
)
//DES 加解密测试
func
TestAes
(
t
*
testing
.
T
)
{
aes
:=
NewAES
(
keys
[
2
],
ivs
[
0
])
result
,
err
:=
aes
.
Encrypt
(
contents
[
1
])
if
err
!=
nil
{
t
.
Error
(
err
)
}
t
.
Log
(
base64
.
StdEncoding
.
EncodeToString
(
result
))
origData
,
err
:=
aes
.
Decrypt
(
result
)
if
err
!=
nil
{
t
.
Error
(
err
)
}
assert
.
Equal
(
t
,
contents
[
1
],
origData
)
}
plugin/dapp/storage/crypto/crypto.go
0 → 100644
View file @
17b6b5f4
package
crypto
import
"bytes"
type
Crypto
interface
{
Encrypt
(
origData
[]
byte
)
([]
byte
,
error
)
Decrypt
(
crypted
[]
byte
)
([]
byte
,
error
)
}
func
ZeroPadding
(
ciphertext
[]
byte
,
blockSize
int
)
[]
byte
{
padding
:=
blockSize
-
len
(
ciphertext
)
%
blockSize
padtext
:=
bytes
.
Repeat
([]
byte
{
0
},
padding
)
return
append
(
ciphertext
,
padtext
...
)
}
func
ZeroUnPadding
(
origData
[]
byte
)
[]
byte
{
return
bytes
.
TrimRightFunc
(
origData
,
func
(
r
rune
)
bool
{
return
r
==
rune
(
0
)
})
}
func
PKCS5Padding
(
ciphertext
[]
byte
,
blockSize
int
)
[]
byte
{
padding
:=
blockSize
-
len
(
ciphertext
)
%
blockSize
padtext
:=
bytes
.
Repeat
([]
byte
{
byte
(
padding
)},
padding
)
return
append
(
ciphertext
,
padtext
...
)
}
func
PKCS5UnPadding
(
origData
[]
byte
)
[]
byte
{
length
:=
len
(
origData
)
// 去掉最后一个字节 unpadding 次
unpadding
:=
int
(
origData
[
length
-
1
])
return
origData
[
:
(
length
-
unpadding
)]
}
plugin/dapp/storage/crypto/des.go
0 → 100644
View file @
17b6b5f4
package
crypto
import
(
"crypto/cipher"
"crypto/des"
)
type
DES
struct
{
key
[]
byte
//iv的长度必须等于block块的大小
iv
[]
byte
}
func
NewDES
(
key
,
iv
[]
byte
)
*
DES
{
return
&
DES
{
key
:
key
,
iv
:
iv
}
}
func
(
d
*
DES
)
Encrypt
(
origData
[]
byte
)
([]
byte
,
error
)
{
block
,
err
:=
des
.
NewCipher
(
d
.
key
)
if
err
!=
nil
{
return
nil
,
err
}
origData
=
PKCS5Padding
(
origData
,
block
.
BlockSize
())
// origData = ZeroPadding(origData, block.BlockSize())
blockMode
:=
cipher
.
NewCBCEncrypter
(
block
,
d
.
iv
[
:
block
.
BlockSize
()])
crypted
:=
make
([]
byte
,
len
(
origData
))
// 根据CryptBlocks方法的说明,如下方式初始化crypted也可以
// crypted := origData
blockMode
.
CryptBlocks
(
crypted
,
origData
)
return
crypted
,
nil
}
// 密钥key长度固定8字节
func
(
d
*
DES
)
Decrypt
(
crypted
[]
byte
)
([]
byte
,
error
)
{
block
,
err
:=
des
.
NewCipher
(
d
.
key
)
if
err
!=
nil
{
return
nil
,
err
}
blockMode
:=
cipher
.
NewCBCDecrypter
(
block
,
d
.
iv
[
:
block
.
BlockSize
()])
origData
:=
make
([]
byte
,
len
(
crypted
))
// origData := crypted
blockMode
.
CryptBlocks
(
origData
,
crypted
)
origData
=
PKCS5UnPadding
(
origData
)
// origData = ZeroUnPadding(origData)
return
origData
,
nil
}
type
TripleDES
struct
{
key
[]
byte
//iv的长度必须等于block块的大小
iv
[]
byte
}
func
NewTripleDES
(
key
,
iv
[]
byte
)
*
TripleDES
{
return
&
TripleDES
{
key
:
key
,
iv
:
iv
}
}
// 3DES加密 24字节
func
(
d
*
TripleDES
)
Encrypt
(
origData
[]
byte
)
([]
byte
,
error
)
{
block
,
err
:=
des
.
NewTripleDESCipher
(
d
.
key
)
if
err
!=
nil
{
return
nil
,
err
}
origData
=
PKCS5Padding
(
origData
,
block
.
BlockSize
())
// origData = ZeroPadding(origData, block.BlockSize())
blockMode
:=
cipher
.
NewCBCEncrypter
(
block
,
d
.
iv
[
:
block
.
BlockSize
()])
crypted
:=
make
([]
byte
,
len
(
origData
))
blockMode
.
CryptBlocks
(
crypted
,
origData
)
return
crypted
,
nil
}
// 3DES解密
func
(
d
*
TripleDES
)
Decrypt
(
crypted
[]
byte
)
([]
byte
,
error
)
{
block
,
err
:=
des
.
NewTripleDESCipher
(
d
.
key
)
if
err
!=
nil
{
return
nil
,
err
}
blockMode
:=
cipher
.
NewCBCDecrypter
(
block
,
d
.
iv
[
:
block
.
BlockSize
()])
origData
:=
make
([]
byte
,
len
(
crypted
))
// origData := crypted
blockMode
.
CryptBlocks
(
origData
,
crypted
)
origData
=
PKCS5UnPadding
(
origData
)
// origData = ZeroUnPadding(origData)
return
origData
,
nil
}
plugin/dapp/storage/crypto/des_test.go
0 → 100644
View file @
17b6b5f4
package
crypto
import
(
"encoding/base64"
"testing"
"github.com/stretchr/testify/assert"
)
var
(
contents
=
[][]
byte
{
[]
byte
(
"1KSBd17H7ZK8iT37aJztFB22XGwsPTdwE4"
),
[]
byte
(
"1JRNjdEqp4LJ5fqycUBm9ayCKSeeskgMKR"
),
[]
byte
(
"1NLHPEcbTWWxxU3dGUZBhayjrCHD3psX7k"
),
[]
byte
(
"1MCftFynyvG2F4ED5mdHYgziDxx6vDrScs"
),
}
keys
=
[][]
byte
{
[]
byte
(
"123456ab"
),
[]
byte
(
"G2F4ED5m123456abx6vDrScs"
),
[]
byte
(
"G2F4ED5m123456abx6vDrScsHD3psX7k"
),
}
ivs
=
[][]
byte
{
[]
byte
(
"1KSBd17H7ZK8iT37aJztFB22XGwsPTdwE4"
),
[]
byte
(
"1JRNjdEqp4LJ5fqycUBm9ayCKSeeskgMKR"
),
[]
byte
(
"1NLHPEcbTWWxxU3dGUZBhayjrCHD3psX7k"
),
[]
byte
(
"1MCftFynyvG2F4ED5mdHYgziDxx6vDrScs"
),
}
)
//DES 加解密测试
func
TestDes
(
t
*
testing
.
T
)
{
des
:=
NewDES
(
keys
[
0
],
ivs
[
0
])
result
,
err
:=
des
.
Encrypt
(
contents
[
0
])
if
err
!=
nil
{
t
.
Error
(
err
)
}
t
.
Log
(
base64
.
StdEncoding
.
EncodeToString
(
result
))
origData
,
err
:=
des
.
Decrypt
(
result
)
if
err
!=
nil
{
t
.
Error
(
err
)
}
assert
.
Equal
(
t
,
contents
[
0
],
origData
)
}
//3DES 加解密测试
func
Test3Des
(
t
*
testing
.
T
)
{
des
:=
NewTripleDES
(
keys
[
1
],
ivs
[
1
])
result
,
err
:=
des
.
Encrypt
(
contents
[
0
])
if
err
!=
nil
{
t
.
Error
(
err
)
}
t
.
Log
(
base64
.
StdEncoding
.
EncodeToString
(
result
))
origData
,
err
:=
des
.
Decrypt
(
result
)
if
err
!=
nil
{
t
.
Error
(
err
)
}
assert
.
Equal
(
t
,
contents
[
0
],
origData
)
}
plugin/dapp/storage/executor/exec.go
0 → 100644
View file @
17b6b5f4
package
executor
import
(
"github.com/33cn/chain33/types"
storagetypes
"github.com/33cn/plugin/plugin/dapp/storage/types"
)
/*
* 实现交易的链上执行接口
* 关键数据上链(statedb)并生成交易回执(log)
*/
func
(
s
*
storage
)
Exec_ContentStorage
(
payload
*
storagetypes
.
ContentOnlyNotaryStorage
,
tx
*
types
.
Transaction
,
index
int
)
(
*
types
.
Receipt
,
error
)
{
action
:=
newStorageAction
(
s
,
tx
,
index
)
return
action
.
ContentStorage
(
&
storagetypes
.
Storage
{
Value
:
&
storagetypes
.
Storage_ContentStorage
{
ContentStorage
:
payload
}})
}
func
(
s
*
storage
)
Exec_HashStorage
(
payload
*
storagetypes
.
HashOnlyNotaryStorage
,
tx
*
types
.
Transaction
,
index
int
)
(
*
types
.
Receipt
,
error
)
{
action
:=
newStorageAction
(
s
,
tx
,
index
)
return
action
.
HashStorage
(
&
storagetypes
.
Storage
{
Value
:
&
storagetypes
.
Storage_HashStorage
{
HashStorage
:
payload
}})
}
func
(
s
*
storage
)
Exec_LinkStorage
(
payload
*
storagetypes
.
LinkNotaryStorage
,
tx
*
types
.
Transaction
,
index
int
)
(
*
types
.
Receipt
,
error
)
{
action
:=
newStorageAction
(
s
,
tx
,
index
)
return
action
.
LinkStorage
(
&
storagetypes
.
Storage
{
Value
:
&
storagetypes
.
Storage_LinkStorage
{
LinkStorage
:
payload
}})
}
func
(
s
*
storage
)
Exec_EncryptStorage
(
payload
*
storagetypes
.
EncryptNotaryStorage
,
tx
*
types
.
Transaction
,
index
int
)
(
*
types
.
Receipt
,
error
)
{
action
:=
newStorageAction
(
s
,
tx
,
index
)
return
action
.
EncryptStorage
(
&
storagetypes
.
Storage
{
Value
:
&
storagetypes
.
Storage_EncryptStorage
{
EncryptStorage
:
payload
}})
}
func
(
s
*
storage
)
Exec_EncryptShareStorage
(
payload
*
storagetypes
.
EncryptShareNotaryStorage
,
tx
*
types
.
Transaction
,
index
int
)
(
*
types
.
Receipt
,
error
)
{
action
:=
newStorageAction
(
s
,
tx
,
index
)
return
action
.
EncryptShareStorage
(
&
storagetypes
.
Storage
{
Value
:
&
storagetypes
.
Storage_EncryptShareStorage
{
EncryptShareStorage
:
payload
}})
}
plugin/dapp/storage/executor/exec_del_local.go
0 → 100644
View file @
17b6b5f4
package
executor
import
(
"github.com/33cn/chain33/types"
)
/*
* 实现区块回退时本地执行的数据清除
*/
// ExecDelLocal 回退自动删除,重写基类
func
(
s
*
storage
)
ExecDelLocal
(
tx
*
types
.
Transaction
,
receipt
*
types
.
ReceiptData
,
index
int
)
(
*
types
.
LocalDBSet
,
error
)
{
kvs
,
err
:=
s
.
DelRollbackKV
(
tx
,
tx
.
Execer
)
if
err
!=
nil
{
return
nil
,
err
}
dbSet
:=
&
types
.
LocalDBSet
{}
dbSet
.
KV
=
append
(
dbSet
.
KV
,
kvs
...
)
return
dbSet
,
nil
}
plugin/dapp/storage/executor/exec_local.go
0 → 100644
View file @
17b6b5f4
package
executor
import
(
"github.com/33cn/chain33/types"
storagetypes
"github.com/33cn/plugin/plugin/dapp/storage/types"
)
/*
* 实现交易相关数据本地执行,数据不上链
* 非关键数据,本地存储(localDB), 用于辅助查询,效率高
*/
func
(
s
*
storage
)
ExecLocal_ContentStorage
(
payload
*
storagetypes
.
ContentOnlyNotaryStorage
,
tx
*
types
.
Transaction
,
receiptData
*
types
.
ReceiptData
,
index
int
)
(
*
types
.
LocalDBSet
,
error
)
{
dbSet
:=
&
types
.
LocalDBSet
{}
//implement code
return
s
.
addAutoRollBack
(
tx
,
dbSet
.
KV
),
nil
}
func
(
s
*
storage
)
ExecLocal_HashStorage
(
payload
*
storagetypes
.
HashOnlyNotaryStorage
,
tx
*
types
.
Transaction
,
receiptData
*
types
.
ReceiptData
,
index
int
)
(
*
types
.
LocalDBSet
,
error
)
{
dbSet
:=
&
types
.
LocalDBSet
{}
//implement code
return
s
.
addAutoRollBack
(
tx
,
dbSet
.
KV
),
nil
}
func
(
s
*
storage
)
ExecLocal_LinkStorage
(
payload
*
storagetypes
.
LinkNotaryStorage
,
tx
*
types
.
Transaction
,
receiptData
*
types
.
ReceiptData
,
index
int
)
(
*
types
.
LocalDBSet
,
error
)
{
dbSet
:=
&
types
.
LocalDBSet
{}
//implement code
return
s
.
addAutoRollBack
(
tx
,
dbSet
.
KV
),
nil
}
func
(
s
*
storage
)
ExecLocal_EncryptStorage
(
payload
*
storagetypes
.
EncryptNotaryStorage
,
tx
*
types
.
Transaction
,
receiptData
*
types
.
ReceiptData
,
index
int
)
(
*
types
.
LocalDBSet
,
error
)
{
dbSet
:=
&
types
.
LocalDBSet
{}
//implement code
return
s
.
addAutoRollBack
(
tx
,
dbSet
.
KV
),
nil
}
func
(
s
*
storage
)
ExecLocal_EncryptShareStorage
(
payload
*
storagetypes
.
EncryptShareNotaryStorage
,
tx
*
types
.
Transaction
,
receiptData
*
types
.
ReceiptData
,
index
int
)
(
*
types
.
LocalDBSet
,
error
)
{
dbSet
:=
&
types
.
LocalDBSet
{}
//implement code
return
s
.
addAutoRollBack
(
tx
,
dbSet
.
KV
),
nil
}
//设置自动回滚
func
(
s
*
storage
)
addAutoRollBack
(
tx
*
types
.
Transaction
,
kv
[]
*
types
.
KeyValue
)
*
types
.
LocalDBSet
{
dbSet
:=
&
types
.
LocalDBSet
{}
dbSet
.
KV
=
s
.
AddRollbackKV
(
tx
,
tx
.
Execer
,
kv
)
return
dbSet
}
plugin/dapp/storage/executor/kv.go
0 → 100644
View file @
17b6b5f4
package
executor
/*
* 用户合约存取kv数据时,key值前缀需要满足一定规范
* 即key = keyPrefix + userKey
* 需要字段前缀查询时,使用’-‘作为分割符号
*/
var
(
//KeyPrefixStateDB state db key必须前缀
KeyPrefixStateDB
=
"mavl-storage-"
//KeyPrefixLocalDB local db的key必须前缀
KeyPrefixLocalDB
=
"LODB-storage-"
)
// Key Storage to save key
func
Key
(
txHash
string
)
(
key
[]
byte
)
{
key
=
append
(
key
,
[]
byte
(
KeyPrefixStateDB
)
...
)
key
=
append
(
key
,
[]
byte
(
txHash
)
...
)
return
key
}
plugin/dapp/storage/executor/query.go
0 → 100644
View file @
17b6b5f4
package
executor
import
(
"github.com/33cn/chain33/types"
storagetypes
"github.com/33cn/plugin/plugin/dapp/storage/types"
)
//从statedb 读取原始数据
func
(
s
*
storage
)
Query_QueryStorage
(
in
*
storagetypes
.
QueryStorage
)
(
types
.
Message
,
error
)
{
return
QueryStorage
(
s
.
GetStateDB
(),
in
)
}
//通过状态查询ids
func
(
s
*
storage
)
Query_BatchQueryStorage
(
in
*
storagetypes
.
BatchQueryStorage
)
(
types
.
Message
,
error
)
{
return
BatchQueryStorage
(
s
.
GetStateDB
(),
in
)
}
plugin/dapp/storage/executor/storage.go
0 → 100644
View file @
17b6b5f4
package
executor
import
(
log
"github.com/33cn/chain33/common/log/log15"
drivers
"github.com/33cn/chain33/system/dapp"
"github.com/33cn/chain33/types"
storagetypes
"github.com/33cn/plugin/plugin/dapp/storage/types"
)
/*
* 执行器相关定义
* 重载基类相关接口
*/
var
(
//日志
elog
=
log
.
New
(
"module"
,
"storage.executor"
)
)
var
driverName
=
storagetypes
.
StorageX
// Init register dapp
func
Init
(
name
string
,
cfg
*
types
.
Chain33Config
,
sub
[]
byte
)
{
drivers
.
Register
(
cfg
,
GetName
(),
newStorage
,
cfg
.
GetDappFork
(
driverName
,
"Enable"
))
InitExecType
()
}
// InitExecType Init Exec Type
func
InitExecType
()
{
ety
:=
types
.
LoadExecutorType
(
driverName
)
ety
.
InitFuncList
(
types
.
ListMethod
(
&
storage
{}))
}
type
storage
struct
{
drivers
.
DriverBase
}
func
newStorage
()
drivers
.
Driver
{
t
:=
&
storage
{}
t
.
SetChild
(
t
)
t
.
SetExecutorType
(
types
.
LoadExecutorType
(
driverName
))
return
t
}
// GetName get driver name
func
GetName
()
string
{
return
newStorage
()
.
GetName
()
}
func
(
s
*
storage
)
GetDriverName
()
string
{
return
driverName
}
// CheckTx 实现自定义检验交易接口,供框架调用
func
(
s
*
storage
)
CheckTx
(
tx
*
types
.
Transaction
,
index
int
)
error
{
// implement code
return
nil
}
plugin/dapp/storage/executor/storage_test.go
0 → 100644
View file @
17b6b5f4
package
executor
import
(
"math/rand"
"testing"
"github.com/33cn/chain33/account"
"github.com/33cn/chain33/client"
"github.com/33cn/chain33/common/address"
"github.com/33cn/chain33/types"
"github.com/33cn/chain33/util"
"github.com/33cn/chain33/common"
"github.com/33cn/chain33/common/crypto"
dbm
"github.com/33cn/chain33/common/db"
"github.com/33cn/chain33/queue"
des
"github.com/33cn/plugin/plugin/dapp/storage/crypto"
oty
"github.com/33cn/plugin/plugin/dapp/storage/types"
"github.com/stretchr/testify/assert"
"strings"
)
type
execEnv
struct
{
blockTime
int64
blockHeight
int64
difficulty
uint64
}
var
(
PrivKeyA
=
"0x6da92a632ab7deb67d38c0f6560bcfed28167998f6496db64c258d5e8393a81b"
// 1KSBd17H7ZK8iT37aJztFB22XGwsPTdwE4
Nodes
=
[][]
byte
{
[]
byte
(
"1KSBd17H7ZK8iT37aJztFB22XGwsPTdwE4"
),
[]
byte
(
"1JRNjdEqp4LJ5fqycUBm9ayCKSeeskgMKR"
),
[]
byte
(
"1NLHPEcbTWWxxU3dGUZBhayjrCHD3psX7k"
),
[]
byte
(
"1MCftFynyvG2F4ED5mdHYgziDxx6vDrScs"
),
}
contents
=
[][]
byte
{
[]
byte
(
"1KSBd17H7ZK8iT37aJztFB22XGwsPTdwE4"
),
[]
byte
(
"1JRNjdEqp4LJ5fqycUBm9ayCKSeeskgMKR"
),
[]
byte
(
"1NLHPEcbTWWxxU3dGUZBhayjrCHD3psX7k"
),
[]
byte
(
"1MCftFynyvG2F4ED5mdHYgziDxx6vDrScs"
),
}
keys
=
[][]
byte
{
[]
byte
(
"123456ab"
),
[]
byte
(
"G2F4ED5m123456abx6vDrScs"
),
[]
byte
(
"G2F4ED5m123456abx6vDrScsHD3psX7k"
),
}
ivs
=
[][]
byte
{
[]
byte
(
"1KSBd17H7ZK8iT37aJztFB22XGwsPTdwE4"
),
[]
byte
(
"1JRNjdEqp4LJ5fqycUBm9ayCKSeeskgMKR"
),
[]
byte
(
"1NLHPEcbTWWxxU3dGUZBhayjrCHD3psX7k"
),
[]
byte
(
"1MCftFynyvG2F4ED5mdHYgziDxx6vDrScs"
),
}
)
var
(
r
*
rand
.
Rand
)
func
init
()
{
r
=
rand
.
New
(
rand
.
NewSource
(
types
.
Now
()
.
UnixNano
()))
}
func
TestOrace
(
t
*
testing
.
T
)
{
cfg
:=
types
.
NewChain33Config
(
strings
.
Replace
(
types
.
GetDefaultCfgstring
(),
"Title=
\"
local
\"
"
,
"Title=
\"
chain33
\"
"
,
1
))
Init
(
oty
.
StorageX
,
cfg
,
nil
)
total
:=
100
*
types
.
Coin
accountA
:=
types
.
Account
{
Balance
:
total
,
Frozen
:
0
,
Addr
:
string
(
Nodes
[
0
]),
}
accountB
:=
types
.
Account
{
Balance
:
total
,
Frozen
:
0
,
Addr
:
string
(
Nodes
[
1
]),
}
accountC
:=
types
.
Account
{
Balance
:
total
,
Frozen
:
0
,
Addr
:
string
(
Nodes
[
2
]),
}
accountD
:=
types
.
Account
{
Balance
:
total
,
Frozen
:
0
,
Addr
:
string
(
Nodes
[
3
]),
}
execAddr
:=
address
.
ExecAddress
(
oty
.
StorageX
)
stateDB
,
_
:=
dbm
.
NewGoMemDB
(
"1"
,
"2"
,
1000
)
_
,
_
,
kvdb
:=
util
.
CreateTestDB
()
accA
,
_
:=
account
.
NewAccountDB
(
cfg
,
"coins"
,
"bty"
,
stateDB
)
accA
.
SaveExecAccount
(
execAddr
,
&
accountA
)
accB
,
_
:=
account
.
NewAccountDB
(
cfg
,
"coins"
,
"bty"
,
stateDB
)
accB
.
SaveExecAccount
(
execAddr
,
&
accountB
)
accC
,
_
:=
account
.
NewAccountDB
(
cfg
,
"coins"
,
"bty"
,
stateDB
)
accC
.
SaveExecAccount
(
execAddr
,
&
accountC
)
accD
,
_
:=
account
.
NewAccountDB
(
cfg
,
"coins"
,
"bty"
,
stateDB
)
accD
.
SaveExecAccount
(
execAddr
,
&
accountD
)
env
:=
execEnv
{
10
,
cfg
.
GetDappFork
(
oty
.
StorageX
,
"Enable"
),
1539918074
,
}
// publish event
ety
:=
types
.
LoadExecutorType
(
oty
.
StorageX
)
tx
,
err
:=
ety
.
Create
(
"ContentStorage"
,
&
oty
.
ContentOnlyNotaryStorage
{
Content
:
contents
[
0
]})
assert
.
Nil
(
t
,
err
)
tx
,
err
=
types
.
FormatTx
(
cfg
,
oty
.
StorageX
,
tx
)
assert
.
Nil
(
t
,
err
)
tx
,
err
=
signTx
(
tx
,
PrivKeyA
)
assert
.
Nil
(
t
,
err
)
t
.
Log
(
"tx"
,
tx
)
exec
:=
newStorage
()
q
:=
queue
.
New
(
"channel"
)
q
.
SetConfig
(
cfg
)
api
,
_
:=
client
.
New
(
q
.
Client
(),
nil
)
exec
.
SetAPI
(
api
)
exec
.
SetStateDB
(
stateDB
)
exec
.
SetLocalDB
(
kvdb
)
exec
.
SetEnv
(
1
,
env
.
blockTime
,
env
.
difficulty
)
receipt
,
err
:=
exec
.
Exec
(
tx
,
int
(
1
))
if
err
!=
nil
{
t
.
Error
(
err
)
}
for
_
,
kv
:=
range
receipt
.
KV
{
stateDB
.
Set
(
kv
.
Key
,
kv
.
Value
)
}
receiptDate
:=
&
types
.
ReceiptData
{
Ty
:
receipt
.
Ty
,
Logs
:
receipt
.
Logs
}
set
,
err
:=
exec
.
ExecLocal
(
tx
,
receiptDate
,
int
(
1
))
if
err
!=
nil
{
t
.
Error
(
err
)
}
for
_
,
kv
:=
range
set
.
KV
{
kvdb
.
Set
(
kv
.
Key
,
kv
.
Value
)
}
txhash
:=
common
.
ToHex
(
tx
.
Hash
())
t
.
Log
(
"txhash:"
,
txhash
)
//根据hash查询存储得明文内容
msg
,
err
:=
exec
.
Query
(
oty
.
FuncNameQueryStorage
,
types
.
Encode
(
&
oty
.
QueryStorage
{
TxHash
:
txhash
}))
if
err
!=
nil
{
t
.
Error
(
err
)
}
t
.
Log
(
msg
)
reply
:=
msg
.
(
*
oty
.
Storage
)
assert
.
Equal
(
t
,
contents
[
0
],
reply
.
GetContentStorage
()
.
Content
)
//根据hash批量查询存储数据
msg
,
err
=
exec
.
Query
(
oty
.
FuncNameBatchQueryStorage
,
types
.
Encode
(
&
oty
.
BatchQueryStorage
{
TxHashs
:
[]
string
{
txhash
}}))
if
err
!=
nil
{
t
.
Error
(
err
)
}
t
.
Log
(
msg
)
reply2
:=
msg
.
(
*
oty
.
BatchReplyStorage
)
assert
.
Equal
(
t
,
contents
[
0
],
reply2
.
Storages
[
0
]
.
GetContentStorage
()
.
Content
)
tx
,
err
=
ety
.
Create
(
"HashStorage"
,
&
oty
.
HashOnlyNotaryStorage
{
Hash
:
common
.
Sha256
(
contents
[
0
])})
assert
.
Nil
(
t
,
err
)
tx
,
err
=
types
.
FormatTx
(
cfg
,
oty
.
StorageX
,
tx
)
assert
.
Nil
(
t
,
err
)
tx
,
err
=
signTx
(
tx
,
PrivKeyA
)
assert
.
Nil
(
t
,
err
)
t
.
Log
(
"tx"
,
tx
)
exec
.
SetEnv
(
env
.
blockHeight
+
1
,
env
.
blockTime
+
20
,
env
.
difficulty
+
1
)
receipt
,
err
=
exec
.
Exec
(
tx
,
int
(
1
))
if
err
!=
nil
{
t
.
Error
(
err
)
}
for
_
,
kv
:=
range
receipt
.
KV
{
stateDB
.
Set
(
kv
.
Key
,
kv
.
Value
)
}
receiptDate
=
&
types
.
ReceiptData
{
Ty
:
receipt
.
Ty
,
Logs
:
receipt
.
Logs
}
set
,
err
=
exec
.
ExecLocal
(
tx
,
receiptDate
,
int
(
1
))
if
err
!=
nil
{
t
.
Error
(
err
)
}
for
_
,
kv
:=
range
set
.
KV
{
kvdb
.
Set
(
kv
.
Key
,
kv
.
Value
)
}
txhash
=
common
.
ToHex
(
tx
.
Hash
())
t
.
Log
(
"txhash:"
,
txhash
)
//根据hash查询存储得明文内容
msg
,
err
=
exec
.
Query
(
oty
.
FuncNameQueryStorage
,
types
.
Encode
(
&
oty
.
QueryStorage
{
TxHash
:
txhash
}))
if
err
!=
nil
{
t
.
Error
(
err
)
}
t
.
Log
(
msg
)
reply
=
msg
.
(
*
oty
.
Storage
)
assert
.
Equal
(
t
,
common
.
Sha256
(
contents
[
0
]),
reply
.
GetHashStorage
()
.
Hash
)
//根据hash批量查询存储数据
msg
,
err
=
exec
.
Query
(
oty
.
FuncNameBatchQueryStorage
,
types
.
Encode
(
&
oty
.
BatchQueryStorage
{
TxHashs
:
[]
string
{
txhash
}}))
if
err
!=
nil
{
t
.
Error
(
err
)
}
t
.
Log
(
msg
)
reply2
=
msg
.
(
*
oty
.
BatchReplyStorage
)
assert
.
Equal
(
t
,
common
.
Sha256
(
contents
[
0
]),
reply2
.
Storages
[
0
]
.
GetHashStorage
()
.
Hash
)
//存储链接地址
tx
,
err
=
ety
.
Create
(
"LinkStorage"
,
&
oty
.
LinkNotaryStorage
{
Hash
:
common
.
Sha256
(
contents
[
0
]),
Link
:
contents
[
0
]})
assert
.
Nil
(
t
,
err
)
tx
,
err
=
types
.
FormatTx
(
cfg
,
oty
.
StorageX
,
tx
)
assert
.
Nil
(
t
,
err
)
tx
,
err
=
signTx
(
tx
,
PrivKeyA
)
assert
.
Nil
(
t
,
err
)
t
.
Log
(
"tx"
,
tx
)
exec
.
SetEnv
(
env
.
blockHeight
+
1
,
env
.
blockTime
+
20
,
env
.
difficulty
+
1
)
receipt
,
err
=
exec
.
Exec
(
tx
,
int
(
1
))
if
err
!=
nil
{
t
.
Error
(
err
)
}
for
_
,
kv
:=
range
receipt
.
KV
{
stateDB
.
Set
(
kv
.
Key
,
kv
.
Value
)
}
receiptDate
=
&
types
.
ReceiptData
{
Ty
:
receipt
.
Ty
,
Logs
:
receipt
.
Logs
}
set
,
err
=
exec
.
ExecLocal
(
tx
,
receiptDate
,
int
(
1
))
if
err
!=
nil
{
t
.
Error
(
err
)
}
for
_
,
kv
:=
range
set
.
KV
{
kvdb
.
Set
(
kv
.
Key
,
kv
.
Value
)
}
txhash
=
common
.
ToHex
(
tx
.
Hash
())
t
.
Log
(
"txhash:"
,
txhash
)
//根据hash查询存储得明文内容
msg
,
err
=
exec
.
Query
(
oty
.
FuncNameQueryStorage
,
types
.
Encode
(
&
oty
.
QueryStorage
{
TxHash
:
txhash
}))
if
err
!=
nil
{
t
.
Error
(
err
)
}
t
.
Log
(
msg
)
reply
=
msg
.
(
*
oty
.
Storage
)
assert
.
Equal
(
t
,
common
.
Sha256
(
contents
[
0
]),
reply
.
GetLinkStorage
()
.
Hash
)
//根据hash批量查询存储数据
msg
,
err
=
exec
.
Query
(
oty
.
FuncNameBatchQueryStorage
,
types
.
Encode
(
&
oty
.
BatchQueryStorage
{
TxHashs
:
[]
string
{
txhash
}}))
if
err
!=
nil
{
t
.
Error
(
err
)
}
t
.
Log
(
msg
)
reply2
=
msg
.
(
*
oty
.
BatchReplyStorage
)
assert
.
Equal
(
t
,
common
.
Sha256
(
contents
[
0
]),
reply2
.
Storages
[
0
]
.
GetLinkStorage
()
.
Hash
)
//加密存储
aes
:=
des
.
NewAES
(
keys
[
2
],
ivs
[
0
])
crypted
,
err
:=
aes
.
Encrypt
(
contents
[
0
])
if
err
!=
nil
{
t
.
Error
(
err
)
}
tx
,
err
=
ety
.
Create
(
"EncryptStorage"
,
&
oty
.
EncryptNotaryStorage
{
ContentHash
:
common
.
Sha256
(
contents
[
0
]),
EncryptContent
:
crypted
,
Nonce
:
ivs
[
0
]})
assert
.
Nil
(
t
,
err
)
tx
,
err
=
types
.
FormatTx
(
cfg
,
oty
.
StorageX
,
tx
)
assert
.
Nil
(
t
,
err
)
tx
,
err
=
signTx
(
tx
,
PrivKeyA
)
assert
.
Nil
(
t
,
err
)
t
.
Log
(
"tx"
,
tx
)
exec
.
SetEnv
(
env
.
blockHeight
+
1
,
env
.
blockTime
+
20
,
env
.
difficulty
+
1
)
receipt
,
err
=
exec
.
Exec
(
tx
,
int
(
1
))
if
err
!=
nil
{
t
.
Error
(
err
)
}
for
_
,
kv
:=
range
receipt
.
KV
{
stateDB
.
Set
(
kv
.
Key
,
kv
.
Value
)
}
receiptDate
=
&
types
.
ReceiptData
{
Ty
:
receipt
.
Ty
,
Logs
:
receipt
.
Logs
}
set
,
err
=
exec
.
ExecLocal
(
tx
,
receiptDate
,
int
(
1
))
if
err
!=
nil
{
t
.
Error
(
err
)
}
for
_
,
kv
:=
range
set
.
KV
{
kvdb
.
Set
(
kv
.
Key
,
kv
.
Value
)
}
txhash
=
common
.
ToHex
(
tx
.
Hash
())
t
.
Log
(
"txhash:"
,
txhash
)
//根据hash查询存储得明文内容
msg
,
err
=
exec
.
Query
(
oty
.
FuncNameQueryStorage
,
types
.
Encode
(
&
oty
.
QueryStorage
{
TxHash
:
txhash
}))
if
err
!=
nil
{
t
.
Error
(
err
)
}
t
.
Log
(
msg
)
reply
=
msg
.
(
*
oty
.
Storage
)
assert
.
Equal
(
t
,
common
.
Sha256
(
contents
[
0
]),
reply
.
GetEncryptStorage
()
.
ContentHash
)
assert
.
Equal
(
t
,
crypted
,
reply
.
GetEncryptStorage
()
.
EncryptContent
)
assert
.
Equal
(
t
,
ivs
[
0
],
reply
.
GetEncryptStorage
()
.
Nonce
)
}
func
signTx
(
tx
*
types
.
Transaction
,
hexPrivKey
string
)
(
*
types
.
Transaction
,
error
)
{
signType
:=
types
.
SECP256K1
c
,
err
:=
crypto
.
New
(
types
.
GetSignName
(
oty
.
StorageX
,
signType
))
if
err
!=
nil
{
return
tx
,
err
}
bytes
,
err
:=
common
.
FromHex
(
hexPrivKey
[
:
])
if
err
!=
nil
{
return
tx
,
err
}
privKey
,
err
:=
c
.
PrivKeyFromBytes
(
bytes
)
if
err
!=
nil
{
return
tx
,
err
}
tx
.
Sign
(
int32
(
signType
),
privKey
)
return
tx
,
nil
}
plugin/dapp/storage/executor/storagedb.go
0 → 100644
View file @
17b6b5f4
package
executor
import
(
"fmt"
"github.com/33cn/chain33/common"
dbm
"github.com/33cn/chain33/common/db"
"github.com/33cn/chain33/types"
storagetypes
"github.com/33cn/plugin/plugin/dapp/storage/types"
"github.com/gogo/protobuf/proto"
)
type
StorageAction
struct
{
db
dbm
.
KV
txhash
[]
byte
fromaddr
string
blocktime
int64
height
int64
index
int
}
func
newStorageAction
(
s
*
storage
,
tx
*
types
.
Transaction
,
index
int
)
*
StorageAction
{
hash
:=
tx
.
Hash
()
fromaddr
:=
tx
.
From
()
return
&
StorageAction
{
s
.
GetStateDB
(),
hash
,
fromaddr
,
s
.
GetBlockTime
(),
s
.
GetHeight
(),
index
}
}
func
(
s
*
StorageAction
)
GetKVSet
(
payload
proto
.
Message
)
(
kvset
[]
*
types
.
KeyValue
)
{
kvset
=
append
(
kvset
,
&
types
.
KeyValue
{
Key
:
Key
(
common
.
ToHex
(
s
.
txhash
)),
Value
:
types
.
Encode
(
payload
)})
return
kvset
}
func
(
s
*
StorageAction
)
ContentStorage
(
payload
proto
.
Message
)
(
*
types
.
Receipt
,
error
)
{
//TODO 这里可以加具体得文本内容限制,超过指定大小的数据不容许写到状态数据库中
var
logs
[]
*
types
.
ReceiptLog
log
:=
&
types
.
ReceiptLog
{
Ty
:
storagetypes
.
TyContentStorageLog
}
logs
=
append
(
logs
,
log
)
kv
:=
s
.
GetKVSet
(
payload
)
receipt
:=
&
types
.
Receipt
{
Ty
:
types
.
ExecOk
,
KV
:
kv
,
Logs
:
logs
}
return
receipt
,
nil
}
func
(
s
*
StorageAction
)
HashStorage
(
payload
proto
.
Message
)
(
*
types
.
Receipt
,
error
)
{
var
logs
[]
*
types
.
ReceiptLog
log
:=
&
types
.
ReceiptLog
{
Ty
:
storagetypes
.
TyHashStorageLog
}
logs
=
append
(
logs
,
log
)
kv
:=
s
.
GetKVSet
(
payload
)
receipt
:=
&
types
.
Receipt
{
Ty
:
types
.
ExecOk
,
KV
:
kv
,
Logs
:
logs
}
return
receipt
,
nil
}
func
(
s
*
StorageAction
)
LinkStorage
(
payload
proto
.
Message
)
(
*
types
.
Receipt
,
error
)
{
var
logs
[]
*
types
.
ReceiptLog
log
:=
&
types
.
ReceiptLog
{
Ty
:
storagetypes
.
TyLinkStorageLog
}
logs
=
append
(
logs
,
log
)
kv
:=
s
.
GetKVSet
(
payload
)
receipt
:=
&
types
.
Receipt
{
Ty
:
types
.
ExecOk
,
KV
:
kv
,
Logs
:
logs
}
return
receipt
,
nil
}
func
(
s
*
StorageAction
)
EncryptStorage
(
payload
proto
.
Message
)
(
*
types
.
Receipt
,
error
)
{
var
logs
[]
*
types
.
ReceiptLog
log
:=
&
types
.
ReceiptLog
{
Ty
:
storagetypes
.
TyEncryptStorageLog
}
logs
=
append
(
logs
,
log
)
kv
:=
s
.
GetKVSet
(
payload
)
receipt
:=
&
types
.
Receipt
{
Ty
:
types
.
ExecOk
,
KV
:
kv
,
Logs
:
logs
}
return
receipt
,
nil
}
func
(
s
*
StorageAction
)
EncryptShareStorage
(
payload
proto
.
Message
)
(
*
types
.
Receipt
,
error
)
{
var
logs
[]
*
types
.
ReceiptLog
log
:=
&
types
.
ReceiptLog
{
Ty
:
storagetypes
.
TyEncryptShareStorageLog
}
logs
=
append
(
logs
,
log
)
kv
:=
s
.
GetKVSet
(
payload
)
receipt
:=
&
types
.
Receipt
{
Ty
:
types
.
ExecOk
,
KV
:
kv
,
Logs
:
logs
}
return
receipt
,
nil
}
func
QueryStorageByTxHash
(
db
dbm
.
KV
,
txhash
string
)
(
*
storagetypes
.
Storage
,
error
)
{
data
,
err
:=
db
.
Get
(
Key
(
txhash
))
if
err
!=
nil
{
elog
.
Debug
(
"QueryStorage"
,
"get"
,
err
)
return
nil
,
err
}
var
storage
storagetypes
.
Storage
//decode
err
=
types
.
Decode
(
data
,
&
storage
)
if
err
!=
nil
{
elog
.
Debug
(
"QueryStorage"
,
"decode"
,
err
)
return
nil
,
err
}
return
&
storage
,
nil
}
func
QueryStorage
(
db
dbm
.
KV
,
in
*
storagetypes
.
QueryStorage
)
(
types
.
Message
,
error
)
{
if
in
.
TxHash
==
""
{
return
nil
,
fmt
.
Errorf
(
"txhash can't equail nil"
)
}
return
QueryStorageByTxHash
(
db
,
in
.
TxHash
)
}
func
BatchQueryStorage
(
db
dbm
.
KV
,
in
*
storagetypes
.
BatchQueryStorage
)
(
types
.
Message
,
error
)
{
if
len
(
in
.
TxHashs
)
>
10
{
return
nil
,
fmt
.
Errorf
(
"The number of batch queries is too large! the maximux is %d,but current num %d"
,
10
,
len
(
in
.
TxHashs
))
}
var
storage
storagetypes
.
BatchReplyStorage
for
_
,
txhash
:=
range
in
.
TxHashs
{
msg
,
err
:=
QueryStorageByTxHash
(
db
,
txhash
)
if
err
!=
nil
{
return
msg
,
err
}
storage
.
Storages
=
append
(
storage
.
Storages
,
msg
)
}
return
&
storage
,
nil
}
plugin/dapp/storage/plugin.go
0 → 100644
View file @
17b6b5f4
package
types
import
(
"github.com/33cn/chain33/pluginmgr"
"github.com/33cn/plugin/plugin/dapp/storage/commands"
"github.com/33cn/plugin/plugin/dapp/storage/executor"
"github.com/33cn/plugin/plugin/dapp/storage/rpc"
storagetypes
"github.com/33cn/plugin/plugin/dapp/storage/types"
)
/*
* 初始化dapp相关的组件
*/
func
init
()
{
pluginmgr
.
Register
(
&
pluginmgr
.
PluginBase
{
Name
:
storagetypes
.
StorageX
,
ExecName
:
executor
.
GetName
(),
Exec
:
executor
.
Init
,
Cmd
:
commands
.
Cmd
,
RPC
:
rpc
.
Init
,
})
}
plugin/dapp/storage/proto/Makefile
0 → 100644
View file @
17b6b5f4
all
:
./create_protobuf.sh
plugin/dapp/storage/proto/create_protobuf.sh
0 → 100644
View file @
17b6b5f4
#!/bin/sh
# proto生成命令,将pb.go文件生成到types/目录下, chain33_path支持引用chain33框架的proto文件
chain33_path
=
$(
go list
-f
'{{.Dir}}'
"github.com/33cn/chain33"
)
protoc
--go_out
=
plugins
=
grpc:../types ./
*
.proto
--proto_path
=
.
--proto_path
=
"
${
chain33_path
}
/types/proto/"
plugin/dapp/storage/proto/storage.proto
0 → 100644
View file @
17b6b5f4
syntax
=
"proto3"
;
package
types
;
//后面如果有其他数据模型可继续往上面添加
message
Storage
{
oneof
value
{
ContentOnlyNotaryStorage
contentStorage
=
1
;
HashOnlyNotaryStorage
hashStorage
=
2
;
LinkNotaryStorage
linkStorage
=
3
;
EncryptNotaryStorage
encryptStorage
=
4
;
EncryptShareNotaryStorage
encryptShareStorage
=
5
;
}
}
message
StorageAction
{
oneof
value
{
ContentOnlyNotaryStorage
contentStorage
=
1
;
HashOnlyNotaryStorage
hashStorage
=
2
;
LinkNotaryStorage
linkStorage
=
3
;
EncryptNotaryStorage
encryptStorage
=
4
;
EncryptShareNotaryStorage
encryptShareStorage
=
5
;
}
int32
ty
=
6
;
}
// 内容存证模型
message
ContentOnlyNotaryStorage
{
//长度需要小于512k
bytes
content
=
1
;
}
//哈希存证模型,推荐使用sha256哈希,限制256位得摘要值
message
HashOnlyNotaryStorage
{
//长度固定为32字节
bytes
hash
=
1
;
}
// 链接存证模型
message
LinkNotaryStorage
{
//存证内容的链接,可以写入URL,或者其他可用于定位源文件得线索.
bytes
link
=
1
;
//源文件得hash值,推荐使用sha256哈希,限制256位得摘要值
bytes
hash
=
2
;
}
// 隐私存证模型,如果一个文件需要存证,且不公开内容,可以选择将源文件通过对称加密算法加密后上链
message
EncryptNotaryStorage
{
//存证明文内容的hash值,推荐使用sha256哈希,限制256位得摘要值
bytes
contentHash
=
1
;
//源文件得密文,由加密key及nonce对明文加密得到该值。
bytes
encryptContent
=
2
;
//加密iv,通过AES进行加密时制定随机生成的iv,解密时需要使用该值
bytes
nonce
=
3
;
}
// 隐私存证模型
message
EncryptContentOnlyNotaryStorage
{
//存证内容的hash值,推荐使用sha256哈希,限制256位得摘要值
// bytes contentHash = 1;
//源文件得密文。
bytes
encryptContent
=
1
;
//加密iv,通过AES进行加密时制定随机生成的iv,解密时需要使用该值
bytes
nonce
=
2
;
}
// 分享隐私存证模型,需要完备的sdk或者相应的密钥库支持
message
EncryptShareNotaryStorage
{
//存证明文内容的hash值,推荐使用sha256哈希,限制256位得摘要值
bytes
contentHash
=
1
;
//源文件得密文。
bytes
encryptContent
=
2
;
//密钥的kdf推导路径。密钥tree父节点根据该路径可以推导出私钥key
bytes
keyName
=
3
;
//加密key的wrap key。加密key随机生成,对明文进行加密,该key有私密key进行key wrap后公开。
//使用时,通过私密key对wrap key解密得到加密key对密文进行解密。
bytes
keyWrap
=
4
;
//加密iv,通过AES进行加密时制定随机生成的iv,解密时需要使用该值
bytes
nonce
=
5
;
}
service
storage
{
}
//根据txhash去状态数据库中查询存储内容
message
QueryStorage
{
string
txHash
=
1
;
}
//批量查询有可能导致数据库崩溃
message
BatchQueryStorage
{
repeated
string
txHashs
=
1
;
}
message
BatchReplyStorage
{
repeated
Storage
storages
=
1
;
}
\ No newline at end of file
plugin/dapp/storage/rpc/rpc.go
0 → 100644
View file @
17b6b5f4
package
rpc
/*
* 实现json rpc和grpc service接口
* json rpc用Jrpc结构作为接收实例
* grpc使用channelClient结构作为接收实例
*/
plugin/dapp/storage/rpc/types.go
0 → 100644
View file @
17b6b5f4
package
rpc
import
(
rpctypes
"github.com/33cn/chain33/rpc/types"
storagetypes
"github.com/33cn/plugin/plugin/dapp/storage/types"
)
/*
* rpc相关结构定义和初始化
*/
// 实现grpc的service接口
type
channelClient
struct
{
rpctypes
.
ChannelClient
}
// Jrpc 实现json rpc调用实例
type
Jrpc
struct
{
cli
*
channelClient
}
// Grpc grpc
type
Grpc
struct
{
*
channelClient
}
// Init init rpc
func
Init
(
name
string
,
s
rpctypes
.
RPCServer
)
{
cli
:=
&
channelClient
{}
grpc
:=
&
Grpc
{
channelClient
:
cli
}
cli
.
Init
(
name
,
s
,
&
Jrpc
{
cli
:
cli
},
grpc
)
//存在grpc service时注册grpc server,需要生成对应的pb.go文件
storagetypes
.
RegisterStorageServer
(
s
.
GRPC
(),
grpc
)
}
plugin/dapp/storage/types/storage.go
0 → 100644
View file @
17b6b5f4
package
types
import
(
"github.com/33cn/chain33/types"
)
/*
* 交易相关类型定义
* 交易action通常有对应的log结构,用于交易回执日志记录
* 每一种action和log需要用id数值和name名称加以区分
*/
// action类型id和name,这些常量可以自定义修改
const
(
TyUnknowAction
=
iota
TyContentStorageAction
TyHashStorageAction
TyLinkStorageAction
TyEncryptStorageAction
TyEncryptShareStorageAction
NameContentStorageAction
=
"ContentStorage"
NameHashStorageAction
=
"HashStorage"
NameLinkStorageAction
=
"LinkStorage"
NameEncryptStorageAction
=
"EncryptStorage"
NameEncryptShareStorageAction
=
"EncryptShareStorage"
FuncNameQueryStorage
=
"QueryStorage"
FuncNameBatchQueryStorage
=
"BatchQueryStorage"
)
// log类型id值
const
(
TyUnknownLog
=
iota
TyContentStorageLog
TyHashStorageLog
TyLinkStorageLog
TyEncryptStorageLog
TyEncryptShareStorageLog
)
var
(
//StorageX 执行器名称定义
StorageX
=
"storage"
//定义actionMap
actionMap
=
map
[
string
]
int32
{
NameContentStorageAction
:
TyContentStorageAction
,
NameHashStorageAction
:
TyHashStorageAction
,
NameLinkStorageAction
:
TyLinkStorageAction
,
NameEncryptStorageAction
:
TyEncryptStorageAction
,
NameEncryptShareStorageAction
:
TyEncryptShareStorageAction
,
}
//定义log的id和具体log类型及名称,填入具体自定义log类型
logMap
=
map
[
int64
]
*
types
.
LogInfo
{
//LogID: {Ty: reflect.TypeOf(LogStruct), Name: LogName},
}
//tlog = log.New("module", "storage.types")
)
// init defines a register function
func
init
()
{
types
.
AllowUserExec
=
append
(
types
.
AllowUserExec
,
[]
byte
(
StorageX
))
//注册合约启用高度
types
.
RegFork
(
StorageX
,
InitFork
)
types
.
RegExec
(
StorageX
,
InitExecutor
)
}
// InitFork defines register fork
func
InitFork
(
cfg
*
types
.
Chain33Config
)
{
cfg
.
RegisterDappFork
(
StorageX
,
"Enable"
,
0
)
}
// InitExecutor defines register executor
func
InitExecutor
(
cfg
*
types
.
Chain33Config
)
{
types
.
RegistorExecutor
(
StorageX
,
NewType
(
cfg
))
}
type
StorageType
struct
{
types
.
ExecTypeBase
}
func
NewType
(
cfg
*
types
.
Chain33Config
)
*
StorageType
{
c
:=
&
StorageType
{}
c
.
SetChild
(
c
)
c
.
SetConfig
(
cfg
)
return
c
}
// GetPayload 获取合约action结构
func
(
s
*
StorageType
)
GetPayload
()
types
.
Message
{
return
&
StorageAction
{}
}
// GeTypeMap 获取合约action的id和name信息
func
(
s
*
StorageType
)
GetTypeMap
()
map
[
string
]
int32
{
return
actionMap
}
// GetLogMap 获取合约log相关信息
func
(
s
*
StorageType
)
GetLogMap
()
map
[
int64
]
*
types
.
LogInfo
{
return
logMap
}
plugin/dapp/storage/types/storage.pb.go
0 → 100644
View file @
17b6b5f4
// Code generated by protoc-gen-go. DO NOT EDIT.
// source: storage.proto
/*
Package types is a generated protocol buffer package.
It is generated from these files:
storage.proto
It has these top-level messages:
Storage
StorageAction
ContentOnlyNotaryStorage
HashOnlyNotaryStorage
LinkNotaryStorage
EncryptNotaryStorage
EncryptContentOnlyNotaryStorage
EncryptShareNotaryStorage
QueryStorage
BatchQueryStorage
BatchReplyStorage
*/
package
types
import
(
fmt
"fmt"
proto
"github.com/golang/protobuf/proto"
math
"math"
context
"golang.org/x/net/context"
grpc
"google.golang.org/grpc"
)
// Reference imports to suppress errors if they are not otherwise used.
var
_
=
proto
.
Marshal
var
_
=
fmt
.
Errorf
var
_
=
math
.
Inf
// This is a compile-time assertion to ensure that this generated file
// is compatible with the proto package it is being compiled against.
// A compilation error at this line likely means your copy of the
// proto package needs to be updated.
const
_
=
proto
.
ProtoPackageIsVersion2
// please upgrade the proto package
type
Storage
struct
{
// Types that are valid to be assigned to Value:
// *Storage_ContentStorage
// *Storage_HashStorage
// *Storage_LinkStorage
// *Storage_EncryptStorage
// *Storage_EncryptShareStorage
Value
isStorage_Value
`protobuf_oneof:"value"`
}
func
(
m
*
Storage
)
Reset
()
{
*
m
=
Storage
{}
}
func
(
m
*
Storage
)
String
()
string
{
return
proto
.
CompactTextString
(
m
)
}
func
(
*
Storage
)
ProtoMessage
()
{}
func
(
*
Storage
)
Descriptor
()
([]
byte
,
[]
int
)
{
return
fileDescriptor0
,
[]
int
{
0
}
}
type
isStorage_Value
interface
{
isStorage_Value
()
}
type
Storage_ContentStorage
struct
{
ContentStorage
*
ContentOnlyNotaryStorage
`protobuf:"bytes,1,opt,name=contentStorage,oneof"`
}
type
Storage_HashStorage
struct
{
HashStorage
*
HashOnlyNotaryStorage
`protobuf:"bytes,2,opt,name=hashStorage,oneof"`
}
type
Storage_LinkStorage
struct
{
LinkStorage
*
LinkNotaryStorage
`protobuf:"bytes,3,opt,name=linkStorage,oneof"`
}
type
Storage_EncryptStorage
struct
{
EncryptStorage
*
EncryptNotaryStorage
`protobuf:"bytes,4,opt,name=encryptStorage,oneof"`
}
type
Storage_EncryptShareStorage
struct
{
EncryptShareStorage
*
EncryptShareNotaryStorage
`protobuf:"bytes,5,opt,name=encryptShareStorage,oneof"`
}
func
(
*
Storage_ContentStorage
)
isStorage_Value
()
{}
func
(
*
Storage_HashStorage
)
isStorage_Value
()
{}
func
(
*
Storage_LinkStorage
)
isStorage_Value
()
{}
func
(
*
Storage_EncryptStorage
)
isStorage_Value
()
{}
func
(
*
Storage_EncryptShareStorage
)
isStorage_Value
()
{}
func
(
m
*
Storage
)
GetValue
()
isStorage_Value
{
if
m
!=
nil
{
return
m
.
Value
}
return
nil
}
func
(
m
*
Storage
)
GetContentStorage
()
*
ContentOnlyNotaryStorage
{
if
x
,
ok
:=
m
.
GetValue
()
.
(
*
Storage_ContentStorage
);
ok
{
return
x
.
ContentStorage
}
return
nil
}
func
(
m
*
Storage
)
GetHashStorage
()
*
HashOnlyNotaryStorage
{
if
x
,
ok
:=
m
.
GetValue
()
.
(
*
Storage_HashStorage
);
ok
{
return
x
.
HashStorage
}
return
nil
}
func
(
m
*
Storage
)
GetLinkStorage
()
*
LinkNotaryStorage
{
if
x
,
ok
:=
m
.
GetValue
()
.
(
*
Storage_LinkStorage
);
ok
{
return
x
.
LinkStorage
}
return
nil
}
func
(
m
*
Storage
)
GetEncryptStorage
()
*
EncryptNotaryStorage
{
if
x
,
ok
:=
m
.
GetValue
()
.
(
*
Storage_EncryptStorage
);
ok
{
return
x
.
EncryptStorage
}
return
nil
}
func
(
m
*
Storage
)
GetEncryptShareStorage
()
*
EncryptShareNotaryStorage
{
if
x
,
ok
:=
m
.
GetValue
()
.
(
*
Storage_EncryptShareStorage
);
ok
{
return
x
.
EncryptShareStorage
}
return
nil
}
// XXX_OneofFuncs is for the internal use of the proto package.
func
(
*
Storage
)
XXX_OneofFuncs
()
(
func
(
msg
proto
.
Message
,
b
*
proto
.
Buffer
)
error
,
func
(
msg
proto
.
Message
,
tag
,
wire
int
,
b
*
proto
.
Buffer
)
(
bool
,
error
),
func
(
msg
proto
.
Message
)
(
n
int
),
[]
interface
{})
{
return
_Storage_OneofMarshaler
,
_Storage_OneofUnmarshaler
,
_Storage_OneofSizer
,
[]
interface
{}{
(
*
Storage_ContentStorage
)(
nil
),
(
*
Storage_HashStorage
)(
nil
),
(
*
Storage_LinkStorage
)(
nil
),
(
*
Storage_EncryptStorage
)(
nil
),
(
*
Storage_EncryptShareStorage
)(
nil
),
}
}
func
_Storage_OneofMarshaler
(
msg
proto
.
Message
,
b
*
proto
.
Buffer
)
error
{
m
:=
msg
.
(
*
Storage
)
// value
switch
x
:=
m
.
Value
.
(
type
)
{
case
*
Storage_ContentStorage
:
b
.
EncodeVarint
(
1
<<
3
|
proto
.
WireBytes
)
if
err
:=
b
.
EncodeMessage
(
x
.
ContentStorage
);
err
!=
nil
{
return
err
}
case
*
Storage_HashStorage
:
b
.
EncodeVarint
(
2
<<
3
|
proto
.
WireBytes
)
if
err
:=
b
.
EncodeMessage
(
x
.
HashStorage
);
err
!=
nil
{
return
err
}
case
*
Storage_LinkStorage
:
b
.
EncodeVarint
(
3
<<
3
|
proto
.
WireBytes
)
if
err
:=
b
.
EncodeMessage
(
x
.
LinkStorage
);
err
!=
nil
{
return
err
}
case
*
Storage_EncryptStorage
:
b
.
EncodeVarint
(
4
<<
3
|
proto
.
WireBytes
)
if
err
:=
b
.
EncodeMessage
(
x
.
EncryptStorage
);
err
!=
nil
{
return
err
}
case
*
Storage_EncryptShareStorage
:
b
.
EncodeVarint
(
5
<<
3
|
proto
.
WireBytes
)
if
err
:=
b
.
EncodeMessage
(
x
.
EncryptShareStorage
);
err
!=
nil
{
return
err
}
case
nil
:
default
:
return
fmt
.
Errorf
(
"Storage.Value has unexpected type %T"
,
x
)
}
return
nil
}
func
_Storage_OneofUnmarshaler
(
msg
proto
.
Message
,
tag
,
wire
int
,
b
*
proto
.
Buffer
)
(
bool
,
error
)
{
m
:=
msg
.
(
*
Storage
)
switch
tag
{
case
1
:
// value.contentStorage
if
wire
!=
proto
.
WireBytes
{
return
true
,
proto
.
ErrInternalBadWireType
}
msg
:=
new
(
ContentOnlyNotaryStorage
)
err
:=
b
.
DecodeMessage
(
msg
)
m
.
Value
=
&
Storage_ContentStorage
{
msg
}
return
true
,
err
case
2
:
// value.hashStorage
if
wire
!=
proto
.
WireBytes
{
return
true
,
proto
.
ErrInternalBadWireType
}
msg
:=
new
(
HashOnlyNotaryStorage
)
err
:=
b
.
DecodeMessage
(
msg
)
m
.
Value
=
&
Storage_HashStorage
{
msg
}
return
true
,
err
case
3
:
// value.linkStorage
if
wire
!=
proto
.
WireBytes
{
return
true
,
proto
.
ErrInternalBadWireType
}
msg
:=
new
(
LinkNotaryStorage
)
err
:=
b
.
DecodeMessage
(
msg
)
m
.
Value
=
&
Storage_LinkStorage
{
msg
}
return
true
,
err
case
4
:
// value.encryptStorage
if
wire
!=
proto
.
WireBytes
{
return
true
,
proto
.
ErrInternalBadWireType
}
msg
:=
new
(
EncryptNotaryStorage
)
err
:=
b
.
DecodeMessage
(
msg
)
m
.
Value
=
&
Storage_EncryptStorage
{
msg
}
return
true
,
err
case
5
:
// value.encryptShareStorage
if
wire
!=
proto
.
WireBytes
{
return
true
,
proto
.
ErrInternalBadWireType
}
msg
:=
new
(
EncryptShareNotaryStorage
)
err
:=
b
.
DecodeMessage
(
msg
)
m
.
Value
=
&
Storage_EncryptShareStorage
{
msg
}
return
true
,
err
default
:
return
false
,
nil
}
}
func
_Storage_OneofSizer
(
msg
proto
.
Message
)
(
n
int
)
{
m
:=
msg
.
(
*
Storage
)
// value
switch
x
:=
m
.
Value
.
(
type
)
{
case
*
Storage_ContentStorage
:
s
:=
proto
.
Size
(
x
.
ContentStorage
)
n
+=
proto
.
SizeVarint
(
1
<<
3
|
proto
.
WireBytes
)
n
+=
proto
.
SizeVarint
(
uint64
(
s
))
n
+=
s
case
*
Storage_HashStorage
:
s
:=
proto
.
Size
(
x
.
HashStorage
)
n
+=
proto
.
SizeVarint
(
2
<<
3
|
proto
.
WireBytes
)
n
+=
proto
.
SizeVarint
(
uint64
(
s
))
n
+=
s
case
*
Storage_LinkStorage
:
s
:=
proto
.
Size
(
x
.
LinkStorage
)
n
+=
proto
.
SizeVarint
(
3
<<
3
|
proto
.
WireBytes
)
n
+=
proto
.
SizeVarint
(
uint64
(
s
))
n
+=
s
case
*
Storage_EncryptStorage
:
s
:=
proto
.
Size
(
x
.
EncryptStorage
)
n
+=
proto
.
SizeVarint
(
4
<<
3
|
proto
.
WireBytes
)
n
+=
proto
.
SizeVarint
(
uint64
(
s
))
n
+=
s
case
*
Storage_EncryptShareStorage
:
s
:=
proto
.
Size
(
x
.
EncryptShareStorage
)
n
+=
proto
.
SizeVarint
(
5
<<
3
|
proto
.
WireBytes
)
n
+=
proto
.
SizeVarint
(
uint64
(
s
))
n
+=
s
case
nil
:
default
:
panic
(
fmt
.
Sprintf
(
"proto: unexpected type %T in oneof"
,
x
))
}
return
n
}
type
StorageAction
struct
{
// Types that are valid to be assigned to Value:
// *StorageAction_ContentStorage
// *StorageAction_HashStorage
// *StorageAction_LinkStorage
// *StorageAction_EncryptStorage
// *StorageAction_EncryptShareStorage
Value
isStorageAction_Value
`protobuf_oneof:"value"`
Ty
int32
`protobuf:"varint,6,opt,name=ty" json:"ty,omitempty"`
}
func
(
m
*
StorageAction
)
Reset
()
{
*
m
=
StorageAction
{}
}
func
(
m
*
StorageAction
)
String
()
string
{
return
proto
.
CompactTextString
(
m
)
}
func
(
*
StorageAction
)
ProtoMessage
()
{}
func
(
*
StorageAction
)
Descriptor
()
([]
byte
,
[]
int
)
{
return
fileDescriptor0
,
[]
int
{
1
}
}
type
isStorageAction_Value
interface
{
isStorageAction_Value
()
}
type
StorageAction_ContentStorage
struct
{
ContentStorage
*
ContentOnlyNotaryStorage
`protobuf:"bytes,1,opt,name=contentStorage,oneof"`
}
type
StorageAction_HashStorage
struct
{
HashStorage
*
HashOnlyNotaryStorage
`protobuf:"bytes,2,opt,name=hashStorage,oneof"`
}
type
StorageAction_LinkStorage
struct
{
LinkStorage
*
LinkNotaryStorage
`protobuf:"bytes,3,opt,name=linkStorage,oneof"`
}
type
StorageAction_EncryptStorage
struct
{
EncryptStorage
*
EncryptNotaryStorage
`protobuf:"bytes,4,opt,name=encryptStorage,oneof"`
}
type
StorageAction_EncryptShareStorage
struct
{
EncryptShareStorage
*
EncryptShareNotaryStorage
`protobuf:"bytes,5,opt,name=encryptShareStorage,oneof"`
}
func
(
*
StorageAction_ContentStorage
)
isStorageAction_Value
()
{}
func
(
*
StorageAction_HashStorage
)
isStorageAction_Value
()
{}
func
(
*
StorageAction_LinkStorage
)
isStorageAction_Value
()
{}
func
(
*
StorageAction_EncryptStorage
)
isStorageAction_Value
()
{}
func
(
*
StorageAction_EncryptShareStorage
)
isStorageAction_Value
()
{}
func
(
m
*
StorageAction
)
GetValue
()
isStorageAction_Value
{
if
m
!=
nil
{
return
m
.
Value
}
return
nil
}
func
(
m
*
StorageAction
)
GetContentStorage
()
*
ContentOnlyNotaryStorage
{
if
x
,
ok
:=
m
.
GetValue
()
.
(
*
StorageAction_ContentStorage
);
ok
{
return
x
.
ContentStorage
}
return
nil
}
func
(
m
*
StorageAction
)
GetHashStorage
()
*
HashOnlyNotaryStorage
{
if
x
,
ok
:=
m
.
GetValue
()
.
(
*
StorageAction_HashStorage
);
ok
{
return
x
.
HashStorage
}
return
nil
}
func
(
m
*
StorageAction
)
GetLinkStorage
()
*
LinkNotaryStorage
{
if
x
,
ok
:=
m
.
GetValue
()
.
(
*
StorageAction_LinkStorage
);
ok
{
return
x
.
LinkStorage
}
return
nil
}
func
(
m
*
StorageAction
)
GetEncryptStorage
()
*
EncryptNotaryStorage
{
if
x
,
ok
:=
m
.
GetValue
()
.
(
*
StorageAction_EncryptStorage
);
ok
{
return
x
.
EncryptStorage
}
return
nil
}
func
(
m
*
StorageAction
)
GetEncryptShareStorage
()
*
EncryptShareNotaryStorage
{
if
x
,
ok
:=
m
.
GetValue
()
.
(
*
StorageAction_EncryptShareStorage
);
ok
{
return
x
.
EncryptShareStorage
}
return
nil
}
func
(
m
*
StorageAction
)
GetTy
()
int32
{
if
m
!=
nil
{
return
m
.
Ty
}
return
0
}
// XXX_OneofFuncs is for the internal use of the proto package.
func
(
*
StorageAction
)
XXX_OneofFuncs
()
(
func
(
msg
proto
.
Message
,
b
*
proto
.
Buffer
)
error
,
func
(
msg
proto
.
Message
,
tag
,
wire
int
,
b
*
proto
.
Buffer
)
(
bool
,
error
),
func
(
msg
proto
.
Message
)
(
n
int
),
[]
interface
{})
{
return
_StorageAction_OneofMarshaler
,
_StorageAction_OneofUnmarshaler
,
_StorageAction_OneofSizer
,
[]
interface
{}{
(
*
StorageAction_ContentStorage
)(
nil
),
(
*
StorageAction_HashStorage
)(
nil
),
(
*
StorageAction_LinkStorage
)(
nil
),
(
*
StorageAction_EncryptStorage
)(
nil
),
(
*
StorageAction_EncryptShareStorage
)(
nil
),
}
}
func
_StorageAction_OneofMarshaler
(
msg
proto
.
Message
,
b
*
proto
.
Buffer
)
error
{
m
:=
msg
.
(
*
StorageAction
)
// value
switch
x
:=
m
.
Value
.
(
type
)
{
case
*
StorageAction_ContentStorage
:
b
.
EncodeVarint
(
1
<<
3
|
proto
.
WireBytes
)
if
err
:=
b
.
EncodeMessage
(
x
.
ContentStorage
);
err
!=
nil
{
return
err
}
case
*
StorageAction_HashStorage
:
b
.
EncodeVarint
(
2
<<
3
|
proto
.
WireBytes
)
if
err
:=
b
.
EncodeMessage
(
x
.
HashStorage
);
err
!=
nil
{
return
err
}
case
*
StorageAction_LinkStorage
:
b
.
EncodeVarint
(
3
<<
3
|
proto
.
WireBytes
)
if
err
:=
b
.
EncodeMessage
(
x
.
LinkStorage
);
err
!=
nil
{
return
err
}
case
*
StorageAction_EncryptStorage
:
b
.
EncodeVarint
(
4
<<
3
|
proto
.
WireBytes
)
if
err
:=
b
.
EncodeMessage
(
x
.
EncryptStorage
);
err
!=
nil
{
return
err
}
case
*
StorageAction_EncryptShareStorage
:
b
.
EncodeVarint
(
5
<<
3
|
proto
.
WireBytes
)
if
err
:=
b
.
EncodeMessage
(
x
.
EncryptShareStorage
);
err
!=
nil
{
return
err
}
case
nil
:
default
:
return
fmt
.
Errorf
(
"StorageAction.Value has unexpected type %T"
,
x
)
}
return
nil
}
func
_StorageAction_OneofUnmarshaler
(
msg
proto
.
Message
,
tag
,
wire
int
,
b
*
proto
.
Buffer
)
(
bool
,
error
)
{
m
:=
msg
.
(
*
StorageAction
)
switch
tag
{
case
1
:
// value.contentStorage
if
wire
!=
proto
.
WireBytes
{
return
true
,
proto
.
ErrInternalBadWireType
}
msg
:=
new
(
ContentOnlyNotaryStorage
)
err
:=
b
.
DecodeMessage
(
msg
)
m
.
Value
=
&
StorageAction_ContentStorage
{
msg
}
return
true
,
err
case
2
:
// value.hashStorage
if
wire
!=
proto
.
WireBytes
{
return
true
,
proto
.
ErrInternalBadWireType
}
msg
:=
new
(
HashOnlyNotaryStorage
)
err
:=
b
.
DecodeMessage
(
msg
)
m
.
Value
=
&
StorageAction_HashStorage
{
msg
}
return
true
,
err
case
3
:
// value.linkStorage
if
wire
!=
proto
.
WireBytes
{
return
true
,
proto
.
ErrInternalBadWireType
}
msg
:=
new
(
LinkNotaryStorage
)
err
:=
b
.
DecodeMessage
(
msg
)
m
.
Value
=
&
StorageAction_LinkStorage
{
msg
}
return
true
,
err
case
4
:
// value.encryptStorage
if
wire
!=
proto
.
WireBytes
{
return
true
,
proto
.
ErrInternalBadWireType
}
msg
:=
new
(
EncryptNotaryStorage
)
err
:=
b
.
DecodeMessage
(
msg
)
m
.
Value
=
&
StorageAction_EncryptStorage
{
msg
}
return
true
,
err
case
5
:
// value.encryptShareStorage
if
wire
!=
proto
.
WireBytes
{
return
true
,
proto
.
ErrInternalBadWireType
}
msg
:=
new
(
EncryptShareNotaryStorage
)
err
:=
b
.
DecodeMessage
(
msg
)
m
.
Value
=
&
StorageAction_EncryptShareStorage
{
msg
}
return
true
,
err
default
:
return
false
,
nil
}
}
func
_StorageAction_OneofSizer
(
msg
proto
.
Message
)
(
n
int
)
{
m
:=
msg
.
(
*
StorageAction
)
// value
switch
x
:=
m
.
Value
.
(
type
)
{
case
*
StorageAction_ContentStorage
:
s
:=
proto
.
Size
(
x
.
ContentStorage
)
n
+=
proto
.
SizeVarint
(
1
<<
3
|
proto
.
WireBytes
)
n
+=
proto
.
SizeVarint
(
uint64
(
s
))
n
+=
s
case
*
StorageAction_HashStorage
:
s
:=
proto
.
Size
(
x
.
HashStorage
)
n
+=
proto
.
SizeVarint
(
2
<<
3
|
proto
.
WireBytes
)
n
+=
proto
.
SizeVarint
(
uint64
(
s
))
n
+=
s
case
*
StorageAction_LinkStorage
:
s
:=
proto
.
Size
(
x
.
LinkStorage
)
n
+=
proto
.
SizeVarint
(
3
<<
3
|
proto
.
WireBytes
)
n
+=
proto
.
SizeVarint
(
uint64
(
s
))
n
+=
s
case
*
StorageAction_EncryptStorage
:
s
:=
proto
.
Size
(
x
.
EncryptStorage
)
n
+=
proto
.
SizeVarint
(
4
<<
3
|
proto
.
WireBytes
)
n
+=
proto
.
SizeVarint
(
uint64
(
s
))
n
+=
s
case
*
StorageAction_EncryptShareStorage
:
s
:=
proto
.
Size
(
x
.
EncryptShareStorage
)
n
+=
proto
.
SizeVarint
(
5
<<
3
|
proto
.
WireBytes
)
n
+=
proto
.
SizeVarint
(
uint64
(
s
))
n
+=
s
case
nil
:
default
:
panic
(
fmt
.
Sprintf
(
"proto: unexpected type %T in oneof"
,
x
))
}
return
n
}
// 内容存证模型
type
ContentOnlyNotaryStorage
struct
{
// 长度需要小于512k
Content
[]
byte
`protobuf:"bytes,1,opt,name=content,proto3" json:"content,omitempty"`
}
func
(
m
*
ContentOnlyNotaryStorage
)
Reset
()
{
*
m
=
ContentOnlyNotaryStorage
{}
}
func
(
m
*
ContentOnlyNotaryStorage
)
String
()
string
{
return
proto
.
CompactTextString
(
m
)
}
func
(
*
ContentOnlyNotaryStorage
)
ProtoMessage
()
{}
func
(
*
ContentOnlyNotaryStorage
)
Descriptor
()
([]
byte
,
[]
int
)
{
return
fileDescriptor0
,
[]
int
{
2
}
}
func
(
m
*
ContentOnlyNotaryStorage
)
GetContent
()
[]
byte
{
if
m
!=
nil
{
return
m
.
Content
}
return
nil
}
// 哈希存证模型,推荐使用sha256哈希,限制256位得摘要值
type
HashOnlyNotaryStorage
struct
{
// 长度固定为32字节
Hash
[]
byte
`protobuf:"bytes,1,opt,name=hash,proto3" json:"hash,omitempty"`
}
func
(
m
*
HashOnlyNotaryStorage
)
Reset
()
{
*
m
=
HashOnlyNotaryStorage
{}
}
func
(
m
*
HashOnlyNotaryStorage
)
String
()
string
{
return
proto
.
CompactTextString
(
m
)
}
func
(
*
HashOnlyNotaryStorage
)
ProtoMessage
()
{}
func
(
*
HashOnlyNotaryStorage
)
Descriptor
()
([]
byte
,
[]
int
)
{
return
fileDescriptor0
,
[]
int
{
3
}
}
func
(
m
*
HashOnlyNotaryStorage
)
GetHash
()
[]
byte
{
if
m
!=
nil
{
return
m
.
Hash
}
return
nil
}
// 链接存证模型
type
LinkNotaryStorage
struct
{
// 存证内容的链接,可以写入URL,或者其他可用于定位源文件得线索.
Link
[]
byte
`protobuf:"bytes,1,opt,name=link,proto3" json:"link,omitempty"`
// 源文件得hash值,推荐使用sha256哈希,限制256位得摘要值
Hash
[]
byte
`protobuf:"bytes,2,opt,name=hash,proto3" json:"hash,omitempty"`
}
func
(
m
*
LinkNotaryStorage
)
Reset
()
{
*
m
=
LinkNotaryStorage
{}
}
func
(
m
*
LinkNotaryStorage
)
String
()
string
{
return
proto
.
CompactTextString
(
m
)
}
func
(
*
LinkNotaryStorage
)
ProtoMessage
()
{}
func
(
*
LinkNotaryStorage
)
Descriptor
()
([]
byte
,
[]
int
)
{
return
fileDescriptor0
,
[]
int
{
4
}
}
func
(
m
*
LinkNotaryStorage
)
GetLink
()
[]
byte
{
if
m
!=
nil
{
return
m
.
Link
}
return
nil
}
func
(
m
*
LinkNotaryStorage
)
GetHash
()
[]
byte
{
if
m
!=
nil
{
return
m
.
Hash
}
return
nil
}
// 隐私存证模型,如果一个文件需要存证,且不公开内容,可以选择将源文件通过对称加密算法加密后上链
type
EncryptNotaryStorage
struct
{
// 存证明文内容的hash值,推荐使用sha256哈希,限制256位得摘要值
ContentHash
[]
byte
`protobuf:"bytes,1,opt,name=contentHash,proto3" json:"contentHash,omitempty"`
// 源文件得密文,由加密key及nonce对明文加密得到该值。
EncryptContent
[]
byte
`protobuf:"bytes,2,opt,name=encryptContent,proto3" json:"encryptContent,omitempty"`
// 加密iv,通过AES进行加密时制定随机生成的iv,解密时需要使用该值
Nonce
[]
byte
`protobuf:"bytes,3,opt,name=nonce,proto3" json:"nonce,omitempty"`
}
func
(
m
*
EncryptNotaryStorage
)
Reset
()
{
*
m
=
EncryptNotaryStorage
{}
}
func
(
m
*
EncryptNotaryStorage
)
String
()
string
{
return
proto
.
CompactTextString
(
m
)
}
func
(
*
EncryptNotaryStorage
)
ProtoMessage
()
{}
func
(
*
EncryptNotaryStorage
)
Descriptor
()
([]
byte
,
[]
int
)
{
return
fileDescriptor0
,
[]
int
{
5
}
}
func
(
m
*
EncryptNotaryStorage
)
GetContentHash
()
[]
byte
{
if
m
!=
nil
{
return
m
.
ContentHash
}
return
nil
}
func
(
m
*
EncryptNotaryStorage
)
GetEncryptContent
()
[]
byte
{
if
m
!=
nil
{
return
m
.
EncryptContent
}
return
nil
}
func
(
m
*
EncryptNotaryStorage
)
GetNonce
()
[]
byte
{
if
m
!=
nil
{
return
m
.
Nonce
}
return
nil
}
// 隐私存证模型
type
EncryptContentOnlyNotaryStorage
struct
{
// 存证内容的hash值,推荐使用sha256哈希,限制256位得摘要值
// bytes contentHash = 1;
// 源文件得密文。
EncryptContent
[]
byte
`protobuf:"bytes,1,opt,name=encryptContent,proto3" json:"encryptContent,omitempty"`
// 加密iv,通过AES进行加密时制定随机生成的iv,解密时需要使用该值
Nonce
[]
byte
`protobuf:"bytes,2,opt,name=nonce,proto3" json:"nonce,omitempty"`
}
func
(
m
*
EncryptContentOnlyNotaryStorage
)
Reset
()
{
*
m
=
EncryptContentOnlyNotaryStorage
{}
}
func
(
m
*
EncryptContentOnlyNotaryStorage
)
String
()
string
{
return
proto
.
CompactTextString
(
m
)
}
func
(
*
EncryptContentOnlyNotaryStorage
)
ProtoMessage
()
{}
func
(
*
EncryptContentOnlyNotaryStorage
)
Descriptor
()
([]
byte
,
[]
int
)
{
return
fileDescriptor0
,
[]
int
{
6
}
}
func
(
m
*
EncryptContentOnlyNotaryStorage
)
GetEncryptContent
()
[]
byte
{
if
m
!=
nil
{
return
m
.
EncryptContent
}
return
nil
}
func
(
m
*
EncryptContentOnlyNotaryStorage
)
GetNonce
()
[]
byte
{
if
m
!=
nil
{
return
m
.
Nonce
}
return
nil
}
// 分享隐私存证模型
type
EncryptShareNotaryStorage
struct
{
// 存证明文内容的hash值,推荐使用sha256哈希,限制256位得摘要值
ContentHash
[]
byte
`protobuf:"bytes,1,opt,name=contentHash,proto3" json:"contentHash,omitempty"`
// 源文件得密文。
EncryptContent
[]
byte
`protobuf:"bytes,2,opt,name=encryptContent,proto3" json:"encryptContent,omitempty"`
// 密钥的kdf推导路径。密钥tree父节点根据该路径可以推导出私钥key
KeyName
[]
byte
`protobuf:"bytes,3,opt,name=keyName,proto3" json:"keyName,omitempty"`
// 加密key的wrap key。加密key随机生成,对明文进行加密,该key有私密key进行key wrap后公开。
// 使用时,通过私密key对wrap key解密得到加密key对密文进行解密。
KeyWrap
[]
byte
`protobuf:"bytes,4,opt,name=keyWrap,proto3" json:"keyWrap,omitempty"`
// 加密iv,通过AES进行加密时制定随机生成的iv,解密时需要使用该值
Nonce
[]
byte
`protobuf:"bytes,5,opt,name=nonce,proto3" json:"nonce,omitempty"`
}
func
(
m
*
EncryptShareNotaryStorage
)
Reset
()
{
*
m
=
EncryptShareNotaryStorage
{}
}
func
(
m
*
EncryptShareNotaryStorage
)
String
()
string
{
return
proto
.
CompactTextString
(
m
)
}
func
(
*
EncryptShareNotaryStorage
)
ProtoMessage
()
{}
func
(
*
EncryptShareNotaryStorage
)
Descriptor
()
([]
byte
,
[]
int
)
{
return
fileDescriptor0
,
[]
int
{
7
}
}
func
(
m
*
EncryptShareNotaryStorage
)
GetContentHash
()
[]
byte
{
if
m
!=
nil
{
return
m
.
ContentHash
}
return
nil
}
func
(
m
*
EncryptShareNotaryStorage
)
GetEncryptContent
()
[]
byte
{
if
m
!=
nil
{
return
m
.
EncryptContent
}
return
nil
}
func
(
m
*
EncryptShareNotaryStorage
)
GetKeyName
()
[]
byte
{
if
m
!=
nil
{
return
m
.
KeyName
}
return
nil
}
func
(
m
*
EncryptShareNotaryStorage
)
GetKeyWrap
()
[]
byte
{
if
m
!=
nil
{
return
m
.
KeyWrap
}
return
nil
}
func
(
m
*
EncryptShareNotaryStorage
)
GetNonce
()
[]
byte
{
if
m
!=
nil
{
return
m
.
Nonce
}
return
nil
}
// 根据txhash去状态数据中查询存储内容
type
QueryStorage
struct
{
TxHash
string
`protobuf:"bytes,1,opt,name=txHash" json:"txHash,omitempty"`
}
func
(
m
*
QueryStorage
)
Reset
()
{
*
m
=
QueryStorage
{}
}
func
(
m
*
QueryStorage
)
String
()
string
{
return
proto
.
CompactTextString
(
m
)
}
func
(
*
QueryStorage
)
ProtoMessage
()
{}
func
(
*
QueryStorage
)
Descriptor
()
([]
byte
,
[]
int
)
{
return
fileDescriptor0
,
[]
int
{
8
}
}
func
(
m
*
QueryStorage
)
GetTxHash
()
string
{
if
m
!=
nil
{
return
m
.
TxHash
}
return
""
}
// 批量查询有可能导致数据库崩溃
type
BatchQueryStorage
struct
{
TxHashs
[]
string
`protobuf:"bytes,1,rep,name=txHashs" json:"txHashs,omitempty"`
}
func
(
m
*
BatchQueryStorage
)
Reset
()
{
*
m
=
BatchQueryStorage
{}
}
func
(
m
*
BatchQueryStorage
)
String
()
string
{
return
proto
.
CompactTextString
(
m
)
}
func
(
*
BatchQueryStorage
)
ProtoMessage
()
{}
func
(
*
BatchQueryStorage
)
Descriptor
()
([]
byte
,
[]
int
)
{
return
fileDescriptor0
,
[]
int
{
9
}
}
func
(
m
*
BatchQueryStorage
)
GetTxHashs
()
[]
string
{
if
m
!=
nil
{
return
m
.
TxHashs
}
return
nil
}
type
BatchReplyStorage
struct
{
Storages
[]
*
Storage
`protobuf:"bytes,1,rep,name=storages" json:"storages,omitempty"`
}
func
(
m
*
BatchReplyStorage
)
Reset
()
{
*
m
=
BatchReplyStorage
{}
}
func
(
m
*
BatchReplyStorage
)
String
()
string
{
return
proto
.
CompactTextString
(
m
)
}
func
(
*
BatchReplyStorage
)
ProtoMessage
()
{}
func
(
*
BatchReplyStorage
)
Descriptor
()
([]
byte
,
[]
int
)
{
return
fileDescriptor0
,
[]
int
{
10
}
}
func
(
m
*
BatchReplyStorage
)
GetStorages
()
[]
*
Storage
{
if
m
!=
nil
{
return
m
.
Storages
}
return
nil
}
func
init
()
{
proto
.
RegisterType
((
*
Storage
)(
nil
),
"types.Storage"
)
proto
.
RegisterType
((
*
StorageAction
)(
nil
),
"types.StorageAction"
)
proto
.
RegisterType
((
*
ContentOnlyNotaryStorage
)(
nil
),
"types.ContentOnlyNotaryStorage"
)
proto
.
RegisterType
((
*
HashOnlyNotaryStorage
)(
nil
),
"types.HashOnlyNotaryStorage"
)
proto
.
RegisterType
((
*
LinkNotaryStorage
)(
nil
),
"types.LinkNotaryStorage"
)
proto
.
RegisterType
((
*
EncryptNotaryStorage
)(
nil
),
"types.EncryptNotaryStorage"
)
proto
.
RegisterType
((
*
EncryptContentOnlyNotaryStorage
)(
nil
),
"types.EncryptContentOnlyNotaryStorage"
)
proto
.
RegisterType
((
*
EncryptShareNotaryStorage
)(
nil
),
"types.EncryptShareNotaryStorage"
)
proto
.
RegisterType
((
*
QueryStorage
)(
nil
),
"types.QueryStorage"
)
proto
.
RegisterType
((
*
BatchQueryStorage
)(
nil
),
"types.BatchQueryStorage"
)
proto
.
RegisterType
((
*
BatchReplyStorage
)(
nil
),
"types.BatchReplyStorage"
)
}
// Reference imports to suppress errors if they are not otherwise used.
var
_
context
.
Context
var
_
grpc
.
ClientConn
// This is a compile-time assertion to ensure that this generated file
// is compatible with the grpc package it is being compiled against.
const
_
=
grpc
.
SupportPackageIsVersion4
// Client API for Storage service
type
StorageClient
interface
{
}
type
storageClient
struct
{
cc
*
grpc
.
ClientConn
}
func
NewStorageClient
(
cc
*
grpc
.
ClientConn
)
StorageClient
{
return
&
storageClient
{
cc
}
}
// Server API for Storage service
type
StorageServer
interface
{
}
func
RegisterStorageServer
(
s
*
grpc
.
Server
,
srv
StorageServer
)
{
s
.
RegisterService
(
&
_Storage_serviceDesc
,
srv
)
}
var
_Storage_serviceDesc
=
grpc
.
ServiceDesc
{
ServiceName
:
"types.storage"
,
HandlerType
:
(
*
StorageServer
)(
nil
),
Methods
:
[]
grpc
.
MethodDesc
{},
Streams
:
[]
grpc
.
StreamDesc
{},
Metadata
:
"storage.proto"
,
}
func
init
()
{
proto
.
RegisterFile
(
"storage.proto"
,
fileDescriptor0
)
}
var
fileDescriptor0
=
[]
byte
{
// 462 bytes of a gzipped FileDescriptorProto
0x1f
,
0x8b
,
0x08
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0x02
,
0xff
,
0xec
,
0x94
,
0xcf
,
0x8b
,
0xd3
,
0x40
,
0x14
,
0xc7
,
0x4d
,
0xba
,
0x69
,
0xec
,
0x4b
,
0xb7
,
0xb0
,
0xe3
,
0x2a
,
0x23
,
0x0a
,
0x1b
,
0x72
,
0x58
,
0x8a
,
0x62
,
0x0f
,
0xd5
,
0x9b
,
0x82
,
0xba
,
0x52
,
0xa8
,
0x20
,
0x2b
,
0x8e
,
0x82
,
0x47
,
0x19
,
0xc3
,
0x60
,
0x4a
,
0xeb
,
0x24
,
0x24
,
0xb3
,
0x8b
,
0xf9
,
0x2f
,
0xfc
,
0x4f
,
0xfc
,
0xff
,
0x3c
,
0x49
,
0x66
,
0xde
,
0xe4
,
0x47
,
0x93
,
0x7a
,
0x12
,
0x4f
,
0x7b
,
0x9b
,
0xf7
,
0xde
,
0xf7
,
0x7d
,
0xde
,
0xaf
,
0x10
,
0x38
,
0x2e
,
0x54
,
0x9a
,
0xf3
,
0x6f
,
0x62
,
0x91
,
0xe5
,
0xa9
,
0x4a
,
0x89
,
0xa7
,
0xca
,
0x4c
,
0x14
,
0xd1
,
0x6f
,
0x17
,
0xfc
,
0x8f
,
0x26
,
0x40
,
0xde
,
0xc2
,
0x2c
,
0x4e
,
0xa5
,
0x12
,
0x52
,
0xa1
,
0x87
,
0x3a
,
0xa1
,
0x33
,
0x0f
,
0x96
,
0x67
,
0x0b
,
0xad
,
0x5d
,
0xbc
,
0x31
,
0xc1
,
0xf7
,
0x72
,
0x57
,
0x5e
,
0xa6
,
0x8a
,
0xe7
,
0x25
,
0xca
,
0xd6
,
0xb7
,
0xd8
,
0x5e
,
0x22
,
0x79
,
0x05
,
0x41
,
0xc2
,
0x8b
,
0xc4
,
0x72
,
0x5c
,
0xcd
,
0x79
,
0x88
,
0x9c
,
0x35
,
0x2f
,
0x92
,
0x21
,
0x48
,
0x3b
,
0x85
,
0xbc
,
0x80
,
0x60
,
0xb7
,
0x91
,
0x5b
,
0x4b
,
0x18
,
0x69
,
0x02
,
0x45
,
0xc2
,
0xbb
,
0x8d
,
0xdc
,
0xf6
,
0xb2
,
0x5b
,
0x72
,
0xb2
,
0x82
,
0x99
,
0x90
,
0x71
,
0x5e
,
0x66
,
0xf5
,
0x28
,
0x47
,
0x1a
,
0xf0
,
0x00
,
0x01
,
0x2b
,
0x13
,
0xec
,
0x8d
,
0xd1
,
0x4d
,
0x22
,
0x9f
,
0xe0
,
0x8e
,
0xf5
,
0x24
,
0x3c
,
0x17
,
0x96
,
0xe5
,
0x69
,
0x56
,
0xd8
,
0x65
,
0x69
,
0xc5
,
0x3e
,
0x70
,
0x28
,
0xfd
,
0xc2
,
0x07
,
0xef
,
0x9a
,
0xef
,
0xae
,
0x44
,
0xf4
,
0x73
,
0x04
,
0xc7
,
0xe8
,
0x7c
,
0x1d
,
0xab
,
0x4d
,
0x2a
,
0x6f
,
0x4e
,
0xf0
,
0x7f
,
0x4e
,
0x40
,
0x66
,
0xe0
,
0xaa
,
0x92
,
0x8e
,
0x43
,
0x67
,
0xee
,
0x31
,
0x57
,
0x95
,
0xcd
,
0x49
,
0x9e
,
0x01
,
0x3d
,
0xb4
,
0x63
,
0x42
,
0xc1
,
0xc7
,
0x1d
,
0xeb
,
0xab
,
0x4c
,
0x99
,
0x35
,
0xa3
,
0xc7
,
0x70
,
0x77
,
0x70
,
0xa3
,
0x84
,
0xc0
,
0x51
,
0xb5
,
0x51
,
0xd4
,
0xeb
,
0x77
,
0xf4
,
0x1c
,
0x4e
,
0x7a
,
0xcb
,
0xab
,
0x84
,
0xd5
,
0xf2
,
0xac
,
0xb0
,
0x7a
,
0xd7
,
0xc9
,
0x6e
,
0x2b
,
0xf9
,
0x1a
,
0x4e
,
0x87
,
0x16
,
0x47
,
0x42
,
0x08
,
0xb0
,
0x99
,
0x75
,
0x53
,
0xaf
,
0xed
,
0x22
,
0xe7
,
0xf5
,
0x3d
,
0x70
,
0x40
,
0xe4
,
0xee
,
0x79
,
0xc9
,
0x29
,
0x78
,
0x32
,
0x95
,
0xb1
,
0xb9
,
0xf7
,
0x94
,
0x19
,
0x23
,
0xfa
,
0x02
,
0x67
,
0xab
,
0x8e
,
0xae
,
0x3f
,
0x6b
,
0xbf
,
0x80
,
0xf3
,
0xf7
,
0x02
,
0x6e
,
0xbb
,
0xc0
,
0x2f
,
0x07
,
0xee
,
0x1f
,
0x3c
,
0xe3
,
0x3f
,
0x1c
,
0x8f
,
0x82
,
0xbf
,
0x15
,
0xe5
,
0x25
,
0xff
,
0x6e
,
0x07
,
0xb4
,
0x26
,
0x46
,
0x3e
,
0xe7
,
0x3c
,
0xd3
,
0x5f
,
0xaa
,
0x89
,
0x54
,
0x66
,
0xd3
,
0xb1
,
0xd7
,
0xee
,
0xf8
,
0x1c
,
0xa6
,
0x1f
,
0xae
,
0x44
,
0xd3
,
0xe3
,
0x3d
,
0x18
,
0xab
,
0x1f
,
0x75
,
0x7b
,
0x13
,
0x86
,
0x56
,
0xf4
,
0x04
,
0x4e
,
0x2e
,
0xb8
,
0x8a
,
0x93
,
0x8e
,
0x98
,
0x82
,
0x6f
,
0xc2
,
0x05
,
0x75
,
0xc2
,
0xd1
,
0x7c
,
0xc2
,
0xac
,
0x19
,
0xbd
,
0x44
,
0x39
,
0x13
,
0xd9
,
0xae
,
0x96
,
0x3f
,
0x82
,
0xdb
,
0xf8
,
0xfb
,
0x36
,
0xfa
,
0x60
,
0x39
,
0xc3
,
0x4f
,
0x1f
,
0x15
,
0xac
,
0x8e
,
0x2f
,
0x27
,
0xe0
,
0xe3
,
0xfb
,
0xeb
,
0x58
,
0xff
,
0xeb
,
0x9f
,
0xfe
,
0x09
,
0x00
,
0x00
,
0xff
,
0xff
,
0x93
,
0x02
,
0x76
,
0xfb
,
0xfc
,
0x05
,
0x00
,
0x00
,
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment