Commit 59a23feb authored by lynAzrael's avatar lynAzrael Committed by 33cn

add evm rpc test

parent 156dc659
all:
chmod +x ./build.sh
./build.sh $(OUT) $(FLAG)
\ No newline at end of file
#!/usr/bin/env bash
strpwd=$(pwd)
strcmd=${strpwd##*dapp/}
strapp=${strcmd%/cmd*}
OUT_DIR="${1}/$strapp"
#FLAG=$2
mkdir -p "${OUT_DIR}"
cp ./build/* "${OUT_DIR}"
OUT_TESTDIR="${1}/dapptest/$strapp"
mkdir -p "${OUT_TESTDIR}"
chmod +x ./build/test-rpc.sh
cp ./build/test-rpc.sh "${OUT_TESTDIR}"
#!/usr/bin/env bash
# shellcheck disable=SC2128
MAIN_HTTP=""
CASE_ERR=""
evm_createContract_unsignedTx="0a0365766d129407228405608060405234801561001057600080fd5b50610264806100206000396000f3fe608060405234801561001057600080fd5b50600436106100365760003560e01c8063b8e010de1461003b578063cc80f6f314610045575b600080fd5b6100436100c2565b005b61004d610109565b6040805160208082528351818301528351919283929083019185019080838360005b8381101561008757818101518382015260200161006f565b50505050905090810190601f1680156100b45780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b60408051808201909152600d8082527f5468697320697320746573742e000000000000000000000000000000000000006020909201918252610106916000916101a0565b50565b60008054604080516020601f60026000196101006001881615020190951694909404938401819004810282018101909252828152606093909290918301828280156101955780601f1061016a57610100808354040283529160200191610195565b820191906000526020600020905b81548152906001019060200180831161017857829003601f168201915b505050505090505b90565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106101e157805160ff191683800117855561020e565b8280016001018555821561020e579182015b8281111561020e5782518255916020019190600101906101f3565b5061021a92915061021e565b5090565b61019d91905b8082111561021a576000815560010161022456fea165627a7a72305820fec5dd5ca2cb47523ba08c04749bc5c14c435afee039f3047c2b7ea2faca737800293a8a025b7b22636f6e7374616e74223a66616c73652c22696e70757473223a5b5d2c226e616d65223a22736574222c226f757470757473223a5b5d2c2270617961626c65223a66616c73652c2273746174654d75746162696c697479223a226e6f6e70617961626c65222c2274797065223a2266756e6374696f6e227d2c7b22636f6e7374616e74223a747275652c22696e70757473223a5b5d2c226e616d65223a2273686f77222c226f757470757473223a5b7b226e616d65223a22222c2274797065223a22737472696e67227d5d2c2270617961626c65223a66616c73652c2273746174654d75746162696c697479223a2276696577222c2274797065223a2266756e6374696f6e227d5d20c0c7ee04309aedc4bcfba5beca5f3a223139746a5335316b6a7772436f535153313355336f7765376759424c6653666f466d"
evm_createContract_para_unsignedTx="0a0f757365722e702e706172612e65766d129407228405608060405234801561001057600080fd5b50610264806100206000396000f3fe608060405234801561001057600080fd5b50600436106100365760003560e01c8063b8e010de1461003b578063cc80f6f314610045575b600080fd5b6100436100c2565b005b61004d610109565b6040805160208082528351818301528351919283929083019185019080838360005b8381101561008757818101518382015260200161006f565b50505050905090810190601f1680156100b45780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b60408051808201909152600d8082527f5468697320697320746573742e000000000000000000000000000000000000006020909201918252610106916000916101a0565b50565b60008054604080516020601f60026000196101006001881615020190951694909404938401819004810282018101909252828152606093909290918301828280156101955780601f1061016a57610100808354040283529160200191610195565b820191906000526020600020905b81548152906001019060200180831161017857829003601f168201915b505050505090505b90565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106101e157805160ff191683800117855561020e565b8280016001018555821561020e579182015b8281111561020e5782518255916020019190600101906101f3565b5061021a92915061021e565b5090565b61019d91905b8082111561021a576000815560010161022456fea165627a7a7230582080ff1004de2195e6c08d0d0a65484b3d393c99c280e305cb383dbc89343cdd6a00293a8a025b7b22636f6e7374616e74223a66616c73652c22696e70757473223a5b5d2c226e616d65223a22736574222c226f757470757473223a5b5d2c2270617961626c65223a66616c73652c2273746174654d75746162696c697479223a226e6f6e70617961626c65222c2274797065223a2266756e6374696f6e227d2c7b22636f6e7374616e74223a747275652c22696e70757473223a5b5d2c226e616d65223a2273686f77222c226f757470757473223a5b7b226e616d65223a22222c2274797065223a22737472696e67227d5d2c2270617961626c65223a66616c73652c2273746174654d75746162696c697479223a2276696577222c2274797065223a2266756e6374696f6e227d5d20c0c7ee0430e1c7facdc1f199956c3a2231483969326a67464a594e5167573350695468694337796b7a5663653570764b7478"
evm_creatorAddr="14KEKbYtKKQm4wMthSK9J4La4nAiidGozt"
evm_contractAddr=""
evm_addr=""
#color
RED='\033[1;31m'
GRE='\033[1;32m'
NOC='\033[0m'
# $2=0 means true, other false
function echo_rst() {
if [ "$2" -eq 0 ]; then
echo -e "${GRE}$1 ok${NOC}"
else
echo -e "${RED}$1 fail${NOC}"
CASE_ERR="FAIL"
fi
}
function chain33_ImportPrivkey() {
local pri=$2
local acc=$3
local req='"method":"Chain33.ImportPrivkey", "params":[{"privkey":"'"$pri"'", "label":"admin"}]'
echo "#request: $req"
resp=$(curl -ksd "{$req}" "$1")
echo "#response: $resp"
ok=$(jq '(.error|not) and (.result.label=="admin") and (.result.acc.addr == "'"$acc"'")' <<<"$resp")
[ "$ok" == true ]
echo_rst "$FUNCNAME" "$?"
}
function Chain33_SendToAddress() {
local from="$1"
local to="$2"
local amount=$3
local req='"method":"Chain33.SendToAddress", "params":[{"from":"'"$from"'","to":"'"$to"'", "amount":'"$amount"', "note":"test\n"}]'
# echo "#request: $req"
resp=$(curl -ksd "{$req}" "${MAIN_HTTP}")
# echo "#response: $resp"
ok=$(jq '(.error|not) and (.result.hash|length==66)' <<<"$resp")
[ "$ok" == true ]
echo_rst "$FUNCNAME" "$?"
hash=$(jq '(.result.hash)' <<<"$resp")
echo "hash=$hash"
# query_tx "$hash"
}
function chain33_unlock() {
ok=$(curl -k -s --data-binary '{"jsonrpc":"2.0","id":2,"method":"Chain33.UnLock","params":[{"passwd":"1314fuzamei","timeout":0}]}' -H 'content-type:text/plain;' ${MAIN_HTTP} | jq -r ".result.isOK")
[ "$ok" == true ]
rst=$?
echo_rst "$FUNCNAME" "$rst"
}
function block_wait() {
local req='"method":"Chain33.GetLastHeader","params":[]'
cur_height=$(curl -ksd "{$req}" ${MAIN_HTTP} | jq ".result.height")
expect=$((cur_height + ${1}))
local count=0
while true; do
new_height=$(curl -ksd "{$req}" ${MAIN_HTTP} | jq ".result.height")
if [ "${new_height}" -ge "${expect}" ]; then
break
fi
count=$((count + 1))
sleep 1
done
echo "wait new block $count s, cur height=$expect,old=$cur_height"
}
function evm_createContract() {
validator=$1
expectRes=$2
if [ "$ispara" == "true" ]; then
paraName="user.p.para."
signRawTx "${evm_createContract_para_unsignedTx}" "${evm_creatorAddr}"
else
signRawTx "${evm_createContract_unsignedTx}" "${evm_creatorAddr}"
fi
echo_rst "CreateContract signRawTx" "$?"
sendSignedTx
echo_rst "CreateContract sendSignedTx" "$?"
block_wait 2
queryTransaction "${validator}" "${expectRes}"
echo_rst "CreateContract queryExecRes" "$?"
}
function evm_addressCheck() {
res=$(curl -s --data-binary '{"jsonrpc":"2.0","id":2,"method":"Chain33.Query","params":[{"execer":"evm","funcName":"CheckAddrExists","payload":{"addr":"'${evm_contractAddr}'"}}]}' -H 'content-type:text/plain;' ${MAIN_HTTP})
bContract=$(echo "${res}" | jq -r ".result.contract")
contractAddr=$(echo "${res}" | jq -r ".result.contractAddr")
if [ "${bContract}" == "true" ] && [ "${contractAddr}" == "${evm_contractAddr}" ]; then
echo_rst "evm address check" 0
else
echo_rst "evm address check" 1
fi
return
}
function evm_callContract() {
op=$1
validator=$2
expectRes=$3
if [ "${op}" == "preExec" ]; then
unsignedTx=$(curl -s --data-binary '{"jsonrpc":"2.0","id":2,"method":"evm.EvmCallTx","params":[{"fee":1,"caller":"'${evm_creatorAddr}'", "expire":"120s", "exec":"'${evm_addr}'", "abi": "set()"}]}' -H 'content-type:text/plain;' ${MAIN_HTTP} | jq -r ".result")
elif [ "${op}" == "Exec" ]; then
unsignedTx=$(curl -s --data-binary '{"jsonrpc":"2.0","id":2,"method":"evm.EvmCallTx","params":[{"fee":1,"caller":"'${evm_creatorAddr}'", "expire":"120s", "exec":"'${evm_addr}'", "abi": "show()"}]}' -H 'content-type:text/plain;' ${MAIN_HTTP} | jq -r ".result")
else
rst=1
echo_rst "CallContract invalid param" "$rst"
return
fi
signRawTx "${unsignedTx}" "${evm_creatorAddr}"
rst=$?
echo_rst "CallContract signRawTx" "$rst"
if [ ${rst} == 1 ]; then
return
fi
sendSignedTx
echo_rst "CallContract sendSignedTx" "$?"
block_wait 2
queryTransaction "${validator}" "${expectRes}"
echo_rst "CallContract queryExecRes" "$?"
}
function evm_abiGet() {
abiInfo=$(curl -s --data-binary '{"jsonrpc":"2.0","id":2,"method":"Chain33.Query","params":[{"execer":"evm","funcName":"QueryABI","payload":{"address":"'${evm_contractAddr}'"}}]}' -H 'content-type:text/plain;' ${MAIN_HTTP})
res=$(echo "${abiInfo}" | jq -r ".result" | jq -r 'has("abi")')
if [ "${res}" == "true" ]; then
echo_rst "CallContract queryExecRes" 0
else
echo_rst "CallContract queryExecRes" 1
fi
return
}
function evm_transfer() {
validator=$1
expectRes=$2
unsignedTx=$(curl -s --data-binary '{"jsonrpc":"2.0","id":2,"method":"evm.EvmTransferTx","params":[{"amount":1,"caller":"'${evm_creatorAddr}'","expire":"", "exec":"'${evm_addr}'", "paraName": "'${paraName}'"}]}' -H 'content-type:text/plain;' ${MAIN_HTTP} | jq -r ".result")
if [ "${unsignedTx}" == "" ]; then
rst=1
echo_rst "evm transfer create tx" "$rst"
return
fi
signRawTx "${unsignedTx}" "${evm_creatorAddr}"
echo_rst "evm transfer signRawTx" "$?"
sendSignedTx
echo_rst "evm transfer sendSignedTx" "$?"
block_wait 2
queryTransaction "${validator}" "${expectRes}"
echo_rst "evm transfer queryExecRes" "$?"
}
function evm_getBalance() {
expectBalance=$1
echo "This is evm get balance test."
res=$(curl -s --data-binary '{"jsonrpc":"2.0","id":2,"method":"Chain33.GetBalance","params":[{"addresses":["'${evm_creatorAddr}'"],"execer":"'${evm_addr}'", "paraName": "'${paraName}'"}]}' -H 'content-type:text/plain;' ${MAIN_HTTP})
balance=$(echo "${res}" | jq -r ".result[0].balance")
addr=$(echo "${res}" | jq -r ".result[0].addr")
if [ "${balance}" == "${expectBalance}" ] && [ "${addr}" == "${evm_creatorAddr}" ]; then
echo_rst "evm getBalance" 0
else
echo_rst "evm getBalance" 1
fi
}
function evm_withDraw() {
echo "In evm withDraw test."
validator=$1
expectRes=$2
unsignedTx=$(curl -s --data-binary '{"jsonrpc":"2.0","id":2,"method":"evm.EvmWithdrawTx","params":[{"amount":1,"caller":"'${evm_creatorAddr}'","expire":"", "exec":"'${evm_addr}'", "paraName":"'${paraName}'"}]}' -H 'content-type:text/plain;' ${MAIN_HTTP} | jq -r ".result")
if [ "${unsignedTx}" == "" ]; then
rst=1
echo_rst "evm withdraw create tx" "$rst"
return
fi
signRawTx "${unsignedTx}" "${evm_creatorAddr}"
echo_rst "evm withdraw signRawTx" "$?"
sendSignedTx
echo_rst "evm withdraw sendSignedTx" "$?"
block_wait 2
queryTransaction "${validator}" "${expectRes}"
echo_rst "evm withdraw queryExecRes" "$?"
}
function signRawTx() {
unsignedTx=$1
addr=$2
signedTx=$(curl -s --data-binary '{"jsonrpc":"2.0","id":2,"method":"Chain33.SignRawTx","params":[{"addr":"'"${addr}"'","txHex":"'"${unsignedTx}"'","expire":"120s"}]}' -H 'content-type:text/plain;' ${MAIN_HTTP} | jq -r ".result")
if [ "$signedTx" == "null" ]; then
return 1
else
return 0
fi
}
function sendSignedTx() {
txHash=$(curl -s --data-binary '{"jsonrpc":"2.0","id":2,"method":"Chain33.SendTransaction","params":[{"token":"","data":"'"${signedTx}"'"}]}' -H 'content-type:text/plain;' ${MAIN_HTTP} | jq -r ".result")
if [ "$txHash" == "null" ]; then
return 1
else
return 0
fi
}
# 查询交易的执行结果
# 根据传入的规则,校验查询的结果 (参数1: 校验规则 参数2: 预期匹配结果)
function queryTransaction() {
validators=$1
expectRes=$2
res=$(curl -s --data-binary '{"jsonrpc":"2.0","id":2,"method":"Chain33.QueryTransaction","params":[{"hash":"'"${txHash}"'"}]}' -H 'content-type:text/plain;' ${MAIN_HTTP})
times=$(echo "${validators}" | awk -F '|' '{print NF}')
for ((i = 1; i <= times; i++)); do
validator=$(echo "${validators}" | awk -F '|' '{print $'$i'}')
res=$(echo "${res}" | ${validator})
done
if [ "${res}" != "${expectRes}" ]; then
return 1
else
res=$(curl -s --data-binary '{"jsonrpc":"2.0","id":2,"method":"Chain33.QueryTransaction","params":[{"hash":"'"${txHash}"'"}]}' -H 'content-type:text/plain;' ${MAIN_HTTP})
if [ "${evm_addr}" == "" ]; then
if [ "$ispara" == "true" ]; then
evm_addr=$(echo "${res}" | jq -r ".result.receipt.logs[0].log.contractName")
else
evm_addr=$(echo "${res}" | jq -r ".result.receipt.logs[1].log.contractName")
fi
fi
if [ "${evm_contractAddr}" == "" ]; then
if [ "$ispara" == "true" ]; then
evm_contractAddr=$(echo "${res}" | jq -r ".result.receipt.logs[0].log.contractAddr")
else
evm_contractAddr=$(echo "${res}" | jq -r ".result.receipt.logs[1].log.contractAddr")
fi
fi
return 0
fi
}
function init() {
ispara=$(echo '"'"${MAIN_HTTP}"'"' | jq '.|contains("8901")')
echo "ipara=$ispara"
from="14KEKbYtKKQm4wMthSK9J4La4nAiidGozt"
local evm_addr=""
if [ "$ispara" == "true" ]; then
evm_addr=$(curl -ksd '{"method":"Chain33.ConvertExectoAddr","params":[{"execname":"user.p.para.evm"}]}' ${MAIN_HTTP} | jq -r ".result")
Chain33_SendToAddress "$from" "$evm_addr" 10000000000
else
evm_addr=$(curl -ksd '{"method":"Chain33.ConvertExectoAddr","params":[{"execname":"evm"}]}' ${MAIN_HTTP} | jq -r ".result")
fi
echo "evm=$evm_addr"
Chain33_SendToAddress "$from" "$evm_addr" 10000000000
block_wait 2
}
function run_test() {
local ip=$1
evm_createContract "jq -r .result.receipt.tyName" "ExecOk"
evm_addressCheck
if [ "$ispara" == "true" ]; then
evm_callContract preExec "jq -r .result.receipt.logs[0].tyName" "LogEVMStateChangeItem"
evm_callContract Exec "jq -r .result.receipt.logs[0].log.jsonRet | jq -r .[0].value" "This is test."
else
evm_callContract preExec "jq -r .result.receipt.logs[1].tyName" "LogEVMStateChangeItem"
evm_callContract Exec "jq -r .result.receipt.logs[1].log.jsonRet | jq -r .[0].value" "This is test."
fi
evm_abiGet
evm_transfer "jq -r .result.receipt.tyName" "ExecOk"
evm_getBalance 100000000
evm_withDraw "jq -r .result.receipt.tyName" "ExecOk"
evm_getBalance 0
}
function main() {
local ip=$1
MAIN_HTTP=$ip
echo "=========== # evm rpc test ============="
echo "main_ip=$MAIN_HTTP"
init
run_test "$MAIN_HTTP"
if [ -n "$CASE_ERR" ]; then
echo -e "${RED}=============Evm Rpc Test Fail=============${NOC}"
exit 1
else
echo -e "${GRE}=============Evm Rpc Test Pass==============${NOC}"
fi
}
main "$1"
...@@ -8,6 +8,7 @@ import ( ...@@ -8,6 +8,7 @@ import (
"github.com/33cn/chain33/pluginmgr" "github.com/33cn/chain33/pluginmgr"
"github.com/33cn/plugin/plugin/dapp/evm/commands" "github.com/33cn/plugin/plugin/dapp/evm/commands"
"github.com/33cn/plugin/plugin/dapp/evm/executor" "github.com/33cn/plugin/plugin/dapp/evm/executor"
"github.com/33cn/plugin/plugin/dapp/evm/rpc"
"github.com/33cn/plugin/plugin/dapp/evm/types" "github.com/33cn/plugin/plugin/dapp/evm/types"
) )
...@@ -17,6 +18,6 @@ func init() { ...@@ -17,6 +18,6 @@ func init() {
ExecName: executor.GetName(), ExecName: executor.GetName(),
Exec: executor.Init, Exec: executor.Init,
Cmd: commands.EvmCmd, Cmd: commands.EvmCmd,
RPC: nil, RPC: rpc.Init,
}) })
} }
...@@ -146,4 +146,36 @@ message EvmQueryResp { ...@@ -146,4 +146,36 @@ message EvmQueryResp {
string caller = 3; string caller = 3;
string rawData = 4; string rawData = 4;
string jsonData = 5; string jsonData = 5;
}
message EvmContractCreateReq {
string code = 1;
int64 fee = 2;
string note = 3;
string alias = 4;
string caller = 5;
string abi = 6;
string expire = 7;
string paraName = 8;
}
message EvmContractCallReq {
uint64 amount = 1;
string code = 2;
int64 fee = 3;
string note = 4;
string caller = 5;
string abi = 6;
string exec = 7;
string expire = 8;
string paraName = 9;
}
message EvmContractTransferReq {
string caller = 1;
float amount = 2;
string exec = 3;
string expire = 4;
bool isWithdraw = 5;
string paraName = 6;
} }
\ No newline at end of file
// Copyright Fuzamei Corp. 2018 All Rights Reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package rpc
import (
"context"
"encoding/hex"
"github.com/33cn/chain33/types"
evm "github.com/33cn/plugin/plugin/dapp/evm/types"
)
// EvmCreateTx 创建Evm合约接口
func (c *Jrpc) EvmCreateTx(parm *evm.EvmContractCreateReq, result *interface{}) error {
if parm == nil {
return types.ErrInvalidParam
}
reply, err := c.cli.Create(context.Background(), *parm)
if err != nil {
return err
}
*result = hex.EncodeToString(reply.Data)
return nil
}
// EvmCallTx 调用Evm合约接口
func (c *Jrpc) EvmCallTx(parm *evm.EvmContractCallReq, result *interface{}) error {
if parm == nil {
return types.ErrInvalidParam
}
reply, err := c.cli.Call(context.Background(), *parm)
if err != nil {
return err
}
*result = hex.EncodeToString(reply.Data)
return nil
}
// EvmTransferTx Evm转账接口
func (c *Jrpc) EvmTransferTx(parm *evm.EvmContractTransferReq, result *interface{}) error {
if parm == nil {
return types.ErrInvalidParam
}
reply, err := c.cli.Transfer(context.Background(), *parm, false)
if err != nil {
return err
}
*result = hex.EncodeToString(reply.Data)
return nil
}
// EvmWithdrawTx Evm转账接口
func (c *Jrpc) EvmWithdrawTx(parm *evm.EvmContractTransferReq, result *interface{}) error {
if parm == nil {
return types.ErrInvalidParam
}
reply, err := c.cli.Transfer(context.Background(), *parm, true)
if err != nil {
return err
}
*result = hex.EncodeToString(reply.Data)
return nil
}
// Copyright Fuzamei Corp. 2018 All Rights Reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package rpc
import (
"context"
"fmt"
"math/rand"
"os"
"time"
"github.com/33cn/chain33/common"
"github.com/33cn/chain33/common/address"
cty "github.com/33cn/chain33/system/dapp/coins/types"
"github.com/33cn/chain33/types"
evmtypes "github.com/33cn/plugin/plugin/dapp/evm/types"
)
// CreateEvmCallTx 创建未签名的调用evm交易
func (c *channelClient) Create(ctx context.Context, in evmtypes.EvmContractCreateReq) (*types.UnsignTx, error) {
bCode, err := common.FromHex(in.Code)
if err != nil {
fmt.Fprintln(os.Stderr, "parse evm code error", err)
return nil, err
}
action := evmtypes.EVMContractAction{Amount: 0, Code: bCode, GasLimit: 0, GasPrice: 0, Note: in.Note, Abi: in.Abi}
execer := types.ExecName(in.ParaName + "evm")
addr := address.ExecAddress(types.ExecName(in.ParaName + "evm"))
tx := &types.Transaction{Execer: []byte(execer), Payload: types.Encode(&action), Fee: 0, To: addr}
tx.Fee, _ = tx.GetRealFee(types.GInt("MinFee"))
if tx.Fee < in.Fee {
tx.Fee += in.Fee
}
random := rand.New(rand.NewSource(time.Now().UnixNano()))
tx.Nonce = random.Int63()
txHex := types.Encode(tx)
return &types.UnsignTx{Data: txHex}, nil
}
func (c *channelClient) Call(ctx context.Context, in evmtypes.EvmContractCallReq) (*types.UnsignTx, error) {
amountInt64 := in.Amount * 1e4 * 1e4
feeInt64 := in.Fee * 1e4 * 1e4
toAddr := address.ExecAddress(in.Exec)
bCode, err := common.FromHex(in.Code)
if err != nil {
fmt.Fprintln(os.Stderr, "parse evm code error", err)
return nil, err
}
action := evmtypes.EVMContractAction{Amount: amountInt64, Code: bCode, GasLimit: 0, GasPrice: 0, Note: in.Note, Abi: in.Abi}
tx := &types.Transaction{Execer: []byte(in.Exec), Payload: types.Encode(&action), Fee: 0, To: toAddr}
tx.Fee, _ = tx.GetRealFee(types.GInt("MinFee"))
if tx.Fee < feeInt64 {
tx.Fee += feeInt64
}
random := rand.New(rand.NewSource(time.Now().UnixNano()))
tx.Nonce = random.Int63()
txHex := types.Encode(tx)
return &types.UnsignTx{Data: txHex}, nil
}
func (c *channelClient) Transfer(ctx context.Context, in evmtypes.EvmContractTransferReq, isWithdraw bool) (*types.UnsignTx, error) {
var tx *types.Transaction
transfer := &cty.CoinsAction{}
amountInt64 := int64(in.Amount*1e4) * 1e4
execName := in.Exec
if isWithdraw {
transfer.Value = &cty.CoinsAction_Withdraw{Withdraw: &types.AssetsWithdraw{Amount: amountInt64, ExecName: execName, To: address.ExecAddress(execName)}}
transfer.Ty = cty.CoinsActionWithdraw
} else {
transfer.Value = &cty.CoinsAction_TransferToExec{TransferToExec: &types.AssetsTransferToExec{Amount: amountInt64, ExecName: execName, To: address.ExecAddress(execName)}}
transfer.Ty = cty.CoinsActionTransferToExec
}
if in.ParaName == "" {
tx = &types.Transaction{Execer: []byte(types.ExecName(in.ParaName + "coins")), Payload: types.Encode(transfer), To: address.ExecAddress(execName)}
} else {
tx = &types.Transaction{Execer: []byte(types.ExecName(in.ParaName + "coins")), Payload: types.Encode(transfer), To: address.ExecAddress(types.ExecName(in.ParaName + "coins"))}
}
var err error
tx.Fee, err = tx.GetRealFee(types.GInt("MinFee"))
if err != nil {
return nil, err
}
random := rand.New(rand.NewSource(time.Now().UnixNano()))
tx.Nonce = random.Int63()
txHex := types.Encode(tx)
return &types.UnsignTx{Data: txHex}, nil
}
// Copyright Fuzamei Corp. 2018 All Rights Reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package rpc
import (
"github.com/33cn/chain33/rpc/types"
)
// Jrpc json rpc struct
type Jrpc struct {
cli *channelClient
}
// Grpc grpc struct
type Grpc struct {
*channelClient
}
type channelClient struct {
types.ChannelClient
}
// Init init grpc param
func Init(name string, s types.RPCServer) {
cli := &channelClient{}
grpc := &Grpc{channelClient: cli}
cli.Init(name, s, &Jrpc{cli: cli}, grpc)
}
...@@ -1184,6 +1184,283 @@ func (m *EvmQueryResp) GetJsonData() string { ...@@ -1184,6 +1184,283 @@ func (m *EvmQueryResp) GetJsonData() string {
return "" return ""
} }
type EvmContractCreateReq struct {
Code string `protobuf:"bytes,1,opt,name=code,proto3" json:"code,omitempty"`
Fee int64 `protobuf:"varint,2,opt,name=fee,proto3" json:"fee,omitempty"`
Note string `protobuf:"bytes,3,opt,name=note,proto3" json:"note,omitempty"`
Alias string `protobuf:"bytes,4,opt,name=alias,proto3" json:"alias,omitempty"`
Caller string `protobuf:"bytes,5,opt,name=caller,proto3" json:"caller,omitempty"`
Abi string `protobuf:"bytes,6,opt,name=abi,proto3" json:"abi,omitempty"`
Expire string `protobuf:"bytes,7,opt,name=expire,proto3" json:"expire,omitempty"`
ParaName string `protobuf:"bytes,8,opt,name=paraName,proto3" json:"paraName,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *EvmContractCreateReq) Reset() { *m = EvmContractCreateReq{} }
func (m *EvmContractCreateReq) String() string { return proto.CompactTextString(m) }
func (*EvmContractCreateReq) ProtoMessage() {}
func (*EvmContractCreateReq) Descriptor() ([]byte, []int) {
return fileDescriptor_74353de561acd7c6, []int{19}
}
func (m *EvmContractCreateReq) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_EvmContractCreateReq.Unmarshal(m, b)
}
func (m *EvmContractCreateReq) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_EvmContractCreateReq.Marshal(b, m, deterministic)
}
func (m *EvmContractCreateReq) XXX_Merge(src proto.Message) {
xxx_messageInfo_EvmContractCreateReq.Merge(m, src)
}
func (m *EvmContractCreateReq) XXX_Size() int {
return xxx_messageInfo_EvmContractCreateReq.Size(m)
}
func (m *EvmContractCreateReq) XXX_DiscardUnknown() {
xxx_messageInfo_EvmContractCreateReq.DiscardUnknown(m)
}
var xxx_messageInfo_EvmContractCreateReq proto.InternalMessageInfo
func (m *EvmContractCreateReq) GetCode() string {
if m != nil {
return m.Code
}
return ""
}
func (m *EvmContractCreateReq) GetFee() int64 {
if m != nil {
return m.Fee
}
return 0
}
func (m *EvmContractCreateReq) GetNote() string {
if m != nil {
return m.Note
}
return ""
}
func (m *EvmContractCreateReq) GetAlias() string {
if m != nil {
return m.Alias
}
return ""
}
func (m *EvmContractCreateReq) GetCaller() string {
if m != nil {
return m.Caller
}
return ""
}
func (m *EvmContractCreateReq) GetAbi() string {
if m != nil {
return m.Abi
}
return ""
}
func (m *EvmContractCreateReq) GetExpire() string {
if m != nil {
return m.Expire
}
return ""
}
func (m *EvmContractCreateReq) GetParaName() string {
if m != nil {
return m.ParaName
}
return ""
}
type EvmContractCallReq struct {
Amount uint64 `protobuf:"varint,1,opt,name=amount,proto3" json:"amount,omitempty"`
Code string `protobuf:"bytes,2,opt,name=code,proto3" json:"code,omitempty"`
Fee int64 `protobuf:"varint,3,opt,name=fee,proto3" json:"fee,omitempty"`
Note string `protobuf:"bytes,4,opt,name=note,proto3" json:"note,omitempty"`
Caller string `protobuf:"bytes,5,opt,name=caller,proto3" json:"caller,omitempty"`
Abi string `protobuf:"bytes,6,opt,name=abi,proto3" json:"abi,omitempty"`
Exec string `protobuf:"bytes,7,opt,name=exec,proto3" json:"exec,omitempty"`
Expire string `protobuf:"bytes,8,opt,name=expire,proto3" json:"expire,omitempty"`
ParaName string `protobuf:"bytes,9,opt,name=paraName,proto3" json:"paraName,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *EvmContractCallReq) Reset() { *m = EvmContractCallReq{} }
func (m *EvmContractCallReq) String() string { return proto.CompactTextString(m) }
func (*EvmContractCallReq) ProtoMessage() {}
func (*EvmContractCallReq) Descriptor() ([]byte, []int) {
return fileDescriptor_74353de561acd7c6, []int{20}
}
func (m *EvmContractCallReq) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_EvmContractCallReq.Unmarshal(m, b)
}
func (m *EvmContractCallReq) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_EvmContractCallReq.Marshal(b, m, deterministic)
}
func (m *EvmContractCallReq) XXX_Merge(src proto.Message) {
xxx_messageInfo_EvmContractCallReq.Merge(m, src)
}
func (m *EvmContractCallReq) XXX_Size() int {
return xxx_messageInfo_EvmContractCallReq.Size(m)
}
func (m *EvmContractCallReq) XXX_DiscardUnknown() {
xxx_messageInfo_EvmContractCallReq.DiscardUnknown(m)
}
var xxx_messageInfo_EvmContractCallReq proto.InternalMessageInfo
func (m *EvmContractCallReq) GetAmount() uint64 {
if m != nil {
return m.Amount
}
return 0
}
func (m *EvmContractCallReq) GetCode() string {
if m != nil {
return m.Code
}
return ""
}
func (m *EvmContractCallReq) GetFee() int64 {
if m != nil {
return m.Fee
}
return 0
}
func (m *EvmContractCallReq) GetNote() string {
if m != nil {
return m.Note
}
return ""
}
func (m *EvmContractCallReq) GetCaller() string {
if m != nil {
return m.Caller
}
return ""
}
func (m *EvmContractCallReq) GetAbi() string {
if m != nil {
return m.Abi
}
return ""
}
func (m *EvmContractCallReq) GetExec() string {
if m != nil {
return m.Exec
}
return ""
}
func (m *EvmContractCallReq) GetExpire() string {
if m != nil {
return m.Expire
}
return ""
}
func (m *EvmContractCallReq) GetParaName() string {
if m != nil {
return m.ParaName
}
return ""
}
type EvmContractTransferReq struct {
Caller string `protobuf:"bytes,1,opt,name=caller,proto3" json:"caller,omitempty"`
Amount float32 `protobuf:"fixed32,2,opt,name=amount,proto3" json:"amount,omitempty"`
Exec string `protobuf:"bytes,3,opt,name=exec,proto3" json:"exec,omitempty"`
Expire string `protobuf:"bytes,4,opt,name=expire,proto3" json:"expire,omitempty"`
IsWithdraw bool `protobuf:"varint,5,opt,name=isWithdraw,proto3" json:"isWithdraw,omitempty"`
ParaName string `protobuf:"bytes,6,opt,name=paraName,proto3" json:"paraName,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *EvmContractTransferReq) Reset() { *m = EvmContractTransferReq{} }
func (m *EvmContractTransferReq) String() string { return proto.CompactTextString(m) }
func (*EvmContractTransferReq) ProtoMessage() {}
func (*EvmContractTransferReq) Descriptor() ([]byte, []int) {
return fileDescriptor_74353de561acd7c6, []int{21}
}
func (m *EvmContractTransferReq) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_EvmContractTransferReq.Unmarshal(m, b)
}
func (m *EvmContractTransferReq) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_EvmContractTransferReq.Marshal(b, m, deterministic)
}
func (m *EvmContractTransferReq) XXX_Merge(src proto.Message) {
xxx_messageInfo_EvmContractTransferReq.Merge(m, src)
}
func (m *EvmContractTransferReq) XXX_Size() int {
return xxx_messageInfo_EvmContractTransferReq.Size(m)
}
func (m *EvmContractTransferReq) XXX_DiscardUnknown() {
xxx_messageInfo_EvmContractTransferReq.DiscardUnknown(m)
}
var xxx_messageInfo_EvmContractTransferReq proto.InternalMessageInfo
func (m *EvmContractTransferReq) GetCaller() string {
if m != nil {
return m.Caller
}
return ""
}
func (m *EvmContractTransferReq) GetAmount() float32 {
if m != nil {
return m.Amount
}
return 0
}
func (m *EvmContractTransferReq) GetExec() string {
if m != nil {
return m.Exec
}
return ""
}
func (m *EvmContractTransferReq) GetExpire() string {
if m != nil {
return m.Expire
}
return ""
}
func (m *EvmContractTransferReq) GetIsWithdraw() bool {
if m != nil {
return m.IsWithdraw
}
return false
}
func (m *EvmContractTransferReq) GetParaName() string {
if m != nil {
return m.ParaName
}
return ""
}
func init() { func init() {
proto.RegisterType((*EVMContractObject)(nil), "types.EVMContractObject") proto.RegisterType((*EVMContractObject)(nil), "types.EVMContractObject")
proto.RegisterType((*EVMContractData)(nil), "types.EVMContractData") proto.RegisterType((*EVMContractData)(nil), "types.EVMContractData")
...@@ -1206,63 +1483,76 @@ func init() { ...@@ -1206,63 +1483,76 @@ func init() {
proto.RegisterType((*EvmQueryAbiResp)(nil), "types.EvmQueryAbiResp") proto.RegisterType((*EvmQueryAbiResp)(nil), "types.EvmQueryAbiResp")
proto.RegisterType((*EvmQueryReq)(nil), "types.EvmQueryReq") proto.RegisterType((*EvmQueryReq)(nil), "types.EvmQueryReq")
proto.RegisterType((*EvmQueryResp)(nil), "types.EvmQueryResp") proto.RegisterType((*EvmQueryResp)(nil), "types.EvmQueryResp")
proto.RegisterType((*EvmContractCreateReq)(nil), "types.EvmContractCreateReq")
proto.RegisterType((*EvmContractCallReq)(nil), "types.EvmContractCallReq")
proto.RegisterType((*EvmContractTransferReq)(nil), "types.EvmContractTransferReq")
} }
func init() { proto.RegisterFile("evmcontract.proto", fileDescriptor_74353de561acd7c6) } func init() { proto.RegisterFile("evmcontract.proto", fileDescriptor_74353de561acd7c6) }
var fileDescriptor_74353de561acd7c6 = []byte{ var fileDescriptor_74353de561acd7c6 = []byte{
// 833 bytes of a gzipped FileDescriptorProto // 1004 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xcc, 0x56, 0x4b, 0x6f, 0x2b, 0x35, 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xcc, 0x56, 0xcf, 0x8f, 0xdb, 0x44,
0x18, 0xd5, 0x24, 0x93, 0xc7, 0x7c, 0x09, 0xb7, 0xad, 0x81, 0x32, 0xaa, 0x58, 0x44, 0x16, 0x17, 0x14, 0x96, 0x63, 0x27, 0x1b, 0xbf, 0x0d, 0xed, 0xae, 0x29, 0x4b, 0xb4, 0x42, 0x28, 0xb2, 0x28,
0xa2, 0x2b, 0x11, 0xa1, 0xcb, 0x06, 0x5d, 0x09, 0xa4, 0x28, 0x77, 0x54, 0x90, 0x08, 0x0f, 0x57, 0xac, 0x2a, 0xb1, 0x42, 0xe5, 0x82, 0x2a, 0x81, 0xb4, 0x4a, 0xa3, 0x82, 0xc4, 0xf2, 0x63, 0x0a,
0x64, 0xef, 0xcc, 0x98, 0x74, 0xda, 0xcc, 0x83, 0xb1, 0x27, 0x28, 0x5b, 0xd6, 0x2c, 0x59, 0xb2, 0xe1, 0x3c, 0xb1, 0x67, 0xb3, 0x6e, 0xe3, 0x1f, 0xcc, 0x4c, 0xd2, 0xe6, 0xca, 0x99, 0x23, 0x47,
0x63, 0xc9, 0x92, 0x1d, 0x3f, 0x87, 0x15, 0x3f, 0x03, 0x7d, 0x1e, 0xcf, 0x2b, 0x4d, 0x2a, 0x21, 0x6e, 0x1c, 0xb9, 0x20, 0x71, 0xe3, 0xcc, 0x1f, 0xc1, 0x99, 0x13, 0x7f, 0x06, 0x7a, 0xcf, 0x63,
0x55, 0x88, 0x55, 0x7d, 0xec, 0x63, 0xfb, 0x9c, 0xf9, 0xce, 0xe7, 0x06, 0x2e, 0xc4, 0x2e, 0xf2, 0x7b, 0xec, 0x4d, 0x2a, 0x90, 0x2a, 0xc4, 0x29, 0xf3, 0xcd, 0x3c, 0xcf, 0x7c, 0xdf, 0xbc, 0xef,
0x93, 0x58, 0x65, 0xdc, 0x57, 0xb3, 0x34, 0x4b, 0x54, 0x42, 0x7a, 0x6a, 0x9f, 0x0a, 0x49, 0x7f, 0xbd, 0x09, 0x1c, 0x8b, 0x4d, 0x1a, 0xe5, 0x99, 0x96, 0x3c, 0xd2, 0xe7, 0x85, 0xcc, 0x75, 0x1e,
0xb2, 0xe0, 0xc2, 0x5b, 0x2d, 0x17, 0x66, 0xf1, 0xeb, 0xf5, 0x9d, 0xf0, 0x15, 0x21, 0x60, 0xf3, 0xf4, 0xf5, 0xb6, 0x10, 0x2a, 0xfc, 0xce, 0x81, 0xe3, 0xd9, 0xfc, 0x72, 0x6a, 0x16, 0x3f, 0x5f,
0x20, 0xc8, 0x5c, 0x6b, 0x62, 0x4d, 0x1d, 0xa6, 0xc7, 0xe4, 0x05, 0xd8, 0x01, 0x57, 0xdc, 0xed, 0x3c, 0x11, 0x91, 0x0e, 0x02, 0xf0, 0x78, 0x1c, 0xcb, 0xb1, 0x33, 0x71, 0xce, 0x7c, 0x46, 0xe3,
0x4c, 0xac, 0xe9, 0xe8, 0xe5, 0xe5, 0x4c, 0xef, 0x9f, 0x35, 0xf6, 0xbe, 0xe6, 0x8a, 0x33, 0xcd, 0xe0, 0x1e, 0x78, 0x31, 0xd7, 0x7c, 0xdc, 0x9b, 0x38, 0x67, 0x87, 0xf7, 0x4f, 0xce, 0xe9, 0xfb,
0x21, 0x1f, 0x42, 0x4f, 0x2a, 0xae, 0x84, 0xdb, 0xd5, 0xe4, 0x77, 0x1e, 0x92, 0x6f, 0x70, 0x99, 0x73, 0xeb, 0xdb, 0x87, 0x5c, 0x73, 0x46, 0x31, 0xc1, 0xbb, 0xd0, 0x57, 0x9a, 0x6b, 0x31, 0x76,
0x15, 0x2c, 0xfa, 0xbb, 0x05, 0x67, 0x07, 0x07, 0x11, 0x17, 0x06, 0x7e, 0x26, 0xb8, 0x4a, 0x4a, 0x29, 0xf8, 0xf5, 0x9b, 0xc1, 0x8f, 0x71, 0x99, 0x95, 0x51, 0xe1, 0xcf, 0x0e, 0xdc, 0xee, 0x6c,
0x15, 0x25, 0x44, 0x71, 0x31, 0x8f, 0x84, 0x16, 0xe2, 0x30, 0x3d, 0x26, 0x6f, 0x41, 0x8f, 0x6f, 0x14, 0x8c, 0xe1, 0x20, 0x92, 0x82, 0xeb, 0xbc, 0x62, 0x51, 0x41, 0x24, 0x97, 0xf1, 0x54, 0x10,
0x43, 0x2e, 0xf5, 0x85, 0x0e, 0x2b, 0x40, 0x65, 0xc3, 0x6e, 0xd8, 0x20, 0x60, 0xfb, 0x49, 0x20, 0x11, 0x9f, 0xd1, 0x38, 0xb8, 0x03, 0x7d, 0xbe, 0x4a, 0xb8, 0xa2, 0x03, 0x7d, 0x56, 0x82, 0x5a,
0xdc, 0xde, 0xc4, 0x9a, 0x8e, 0x99, 0x1e, 0x93, 0x2b, 0x18, 0xe2, 0xdf, 0xcf, 0xb9, 0xbc, 0x75, 0x86, 0x67, 0xc9, 0x08, 0xc0, 0x8b, 0xf2, 0x58, 0x8c, 0xfb, 0x13, 0xe7, 0x6c, 0xc4, 0x68, 0x1c,
0xfb, 0x7a, 0xbe, 0xc2, 0xe4, 0x1c, 0xba, 0x7c, 0x1d, 0xba, 0x03, 0x7d, 0x04, 0x0e, 0xe9, 0x5f, 0x9c, 0xc2, 0x10, 0x7f, 0x3f, 0xe6, 0xea, 0x7a, 0x3c, 0xa0, 0xf9, 0x1a, 0x07, 0x47, 0xe0, 0xf2,
0x16, 0x9c, 0x1f, 0x3a, 0x41, 0x01, 0x71, 0x12, 0xfb, 0x42, 0x8b, 0xb5, 0x59, 0x01, 0xf0, 0x60, 0x45, 0x32, 0x3e, 0xa0, 0x2d, 0x70, 0x18, 0xfe, 0xe9, 0xc0, 0x51, 0x57, 0x09, 0x12, 0xc8, 0xf2,
0x99, 0x87, 0x7e, 0x18, 0x88, 0x40, 0xcb, 0x1d, 0xb2, 0x0a, 0x93, 0x09, 0x8c, 0xa4, 0x4a, 0x32, 0x2c, 0x12, 0x44, 0xd6, 0x63, 0x25, 0xc0, 0x8d, 0xd5, 0x3a, 0x89, 0x92, 0x58, 0xc4, 0x44, 0x77,
0xbe, 0x29, 0xee, 0xed, 0xea, 0x7b, 0x9b, 0x53, 0xe4, 0x33, 0x18, 0x18, 0xe8, 0xda, 0x93, 0xee, 0xc8, 0x6a, 0x1c, 0x4c, 0xe0, 0x50, 0xe9, 0x5c, 0xf2, 0x65, 0x79, 0xae, 0x4b, 0xe7, 0xda, 0x53,
0x74, 0xf4, 0xf2, 0xbd, 0x13, 0xdf, 0x71, 0x76, 0x53, 0xd0, 0xbc, 0x58, 0x65, 0x7b, 0x56, 0x6e, 0xc1, 0x47, 0x70, 0x60, 0xe0, 0xd8, 0x9b, 0xb8, 0x67, 0x87, 0xf7, 0xdf, 0xda, 0x73, 0x8f, 0xe7,
0xba, 0x7a, 0x05, 0xe3, 0xe6, 0x02, 0x5a, 0xb9, 0x17, 0x7b, 0xf3, 0x39, 0x71, 0x88, 0xaa, 0x77, 0x8f, 0xcb, 0xb0, 0x59, 0xa6, 0xe5, 0x96, 0x55, 0x1f, 0x9d, 0x3e, 0x80, 0x91, 0xbd, 0x80, 0x52,
0x7c, 0x9b, 0x17, 0xdf, 0x72, 0xcc, 0x0a, 0xf0, 0xaa, 0xf3, 0x89, 0x45, 0xff, 0x68, 0xe7, 0x62, 0x9e, 0x8a, 0xad, 0xb9, 0x4e, 0x1c, 0x22, 0xeb, 0x0d, 0x5f, 0xad, 0xcb, 0xbb, 0x1c, 0xb1, 0x12,
0xee, 0xab, 0x30, 0x89, 0xc9, 0x25, 0xf4, 0x79, 0x94, 0xe4, 0xb1, 0x32, 0x36, 0x0d, 0x42, 0x9f, 0x3c, 0xe8, 0x7d, 0xe0, 0x84, 0xbf, 0xb6, 0x7d, 0x71, 0x11, 0xe9, 0x24, 0xcf, 0x82, 0x13, 0x18,
0x1b, 0x2e, 0xbf, 0x0c, 0xa3, 0x50, 0xe9, 0xa3, 0x6c, 0x56, 0x61, 0xb3, 0xf6, 0x4d, 0x16, 0xfa, 0xf0, 0x34, 0x5f, 0x67, 0xda, 0xc8, 0x34, 0x08, 0x75, 0x2e, 0xb9, 0xfa, 0x34, 0x49, 0x13, 0x4d,
0x45, 0x1c, 0xde, 0x60, 0x15, 0xae, 0x8a, 0x61, 0x37, 0x8a, 0x51, 0x95, 0xb2, 0x77, 0x50, 0xca, 0x5b, 0x79, 0xac, 0xc6, 0x66, 0xed, 0x0b, 0x99, 0x44, 0xa5, 0x1d, 0x5e, 0x61, 0x35, 0xae, 0x93,
0x38, 0x51, 0x42, 0x97, 0x07, 0x8b, 0x9e, 0x28, 0x71, 0xa4, 0x34, 0x7f, 0x5a, 0x40, 0x98, 0xf0, 0xe1, 0x59, 0xc9, 0xa8, 0x53, 0xd9, 0xef, 0xa4, 0x32, 0xcb, 0xb5, 0xa0, 0xf4, 0x60, 0xd2, 0x73,
0x45, 0x98, 0xaa, 0x86, 0x78, 0x94, 0xed, 0xf3, 0xed, 0x56, 0x94, 0x51, 0x32, 0x88, 0x50, 0x18, 0x2d, 0x76, 0xa4, 0xe6, 0x37, 0x07, 0x02, 0x26, 0x22, 0x91, 0x14, 0xda, 0x22, 0x8f, 0xb4, 0x23,
0x97, 0x5d, 0xf1, 0x55, 0x9d, 0xa8, 0xd6, 0x5c, 0x93, 0x33, 0xc7, 0x2c, 0x75, 0xdb, 0x1c, 0x9c, 0xbe, 0x5a, 0x89, 0xca, 0x4a, 0x06, 0x05, 0x21, 0x8c, 0xaa, 0xaa, 0xf8, 0xac, 0x71, 0x54, 0x6b,
0xc3, 0xac, 0xe6, 0x52, 0x04, 0xd7, 0x5c, 0x6a, 0x27, 0x36, 0x2b, 0x21, 0x4a, 0xcc, 0x84, 0x32, 0xce, 0x8e, 0xb9, 0x40, 0x2f, 0xb9, 0xed, 0x18, 0x9c, 0x43, 0xaf, 0xae, 0x95, 0x88, 0x1f, 0x71,
0x61, 0xc3, 0x21, 0x72, 0xef, 0x64, 0x12, 0x33, 0xa1, 0x8c, 0x97, 0x12, 0xd2, 0xef, 0x81, 0x78, 0x45, 0x4a, 0x3c, 0x56, 0x41, 0xa4, 0x28, 0x85, 0x36, 0x66, 0xc3, 0x21, 0xc6, 0x3e, 0x51, 0x79,
0xab, 0xa5, 0x2e, 0xe8, 0xe2, 0x96, 0xc7, 0x1b, 0xf1, 0x85, 0x12, 0xd1, 0x91, 0xa2, 0x5d, 0xc1, 0xc6, 0x84, 0x36, 0x5a, 0x2a, 0x18, 0x5e, 0x41, 0x30, 0x9b, 0x5f, 0x52, 0x42, 0xa7, 0xd7, 0x3c,
0x30, 0xcd, 0xc4, 0xaa, 0x51, 0xb7, 0x0a, 0x6b, 0xb5, 0x79, 0x96, 0x89, 0x58, 0x15, 0xeb, 0x45, 0x5b, 0x8a, 0x4f, 0xb4, 0x48, 0x77, 0x24, 0xed, 0x14, 0x86, 0x85, 0x14, 0x73, 0x2b, 0x6f, 0x35,
0xaa, 0x5a, 0x73, 0xf4, 0x57, 0x4b, 0x5f, 0xd4, 0xec, 0xb6, 0x45, 0x14, 0xfc, 0x27, 0x0d, 0xe7, 0x26, 0xb6, 0x6b, 0x29, 0x45, 0xa6, 0xcb, 0xf5, 0xd2, 0x55, 0xad, 0xb9, 0xf0, 0x47, 0x87, 0x0e,
0x9c, 0x68, 0x38, 0xa7, 0x6e, 0x38, 0xfa, 0xb7, 0x05, 0x6f, 0x1e, 0x06, 0x1c, 0xf5, 0x3d, 0x49, 0xb2, 0xab, 0x6d, 0x9a, 0xc6, 0xff, 0x49, 0xc1, 0xf9, 0x7b, 0x0a, 0xce, 0x6f, 0x0a, 0x2e, 0xfc,
0x87, 0x39, 0xed, 0x0e, 0x9b, 0x1f, 0x76, 0xd8, 0x07, 0x27, 0x3a, 0x6c, 0x11, 0x05, 0x4f, 0xd3, 0xcb, 0x81, 0x57, 0xbb, 0x06, 0x47, 0x7e, 0x2f, 0xa5, 0xc2, 0xfc, 0x76, 0x85, 0x5d, 0x74, 0x2b,
0x64, 0x4e, 0xb3, 0xc9, 0x7e, 0xb3, 0xe0, 0xed, 0x87, 0x71, 0x45, 0xb3, 0xff, 0x8b, 0xc4, 0x3a, 0xec, 0x9d, 0x3d, 0x15, 0x36, 0x4d, 0xe3, 0x97, 0x53, 0x64, 0xbe, 0x5d, 0x64, 0x3f, 0x39, 0xf0,
0x3a, 0xb1, 0xf4, 0x39, 0x9c, 0x2d, 0x6e, 0x85, 0x7f, 0xef, 0xad, 0x96, 0xb8, 0x97, 0x89, 0x1f, 0xda, 0x4d, 0xbb, 0xa2, 0xd8, 0xff, 0x85, 0x63, 0x7d, 0x72, 0x6c, 0x78, 0x17, 0x6e, 0x4f, 0xaf,
0x8e, 0xfd, 0x7f, 0xa0, 0xbf, 0x58, 0x70, 0xde, 0xe6, 0xc9, 0xb4, 0x28, 0x74, 0x71, 0xaf, 0x26, 0x45, 0xf4, 0x74, 0x36, 0xbf, 0xc4, 0x6f, 0x99, 0xf8, 0x76, 0xd7, 0xfb, 0x10, 0xfe, 0xe0, 0xc0,
0x0f, 0x59, 0x85, 0x1f, 0xe8, 0xec, 0x1c, 0xd1, 0x79, 0xe8, 0xb7, 0x7b, 0xc4, 0xef, 0xbb, 0xe0, 0x51, 0x3b, 0x4e, 0x15, 0x65, 0xa2, 0xcb, 0x73, 0x29, 0x78, 0xc8, 0x6a, 0x7c, 0x83, 0x67, 0x6f,
0xe8, 0xf4, 0x69, 0x42, 0x91, 0xbc, 0x7a, 0x82, 0xee, 0xe1, 0xc2, 0x93, 0x2a, 0x8c, 0xb8, 0x12, 0x07, 0xcf, 0xae, 0x5e, 0x77, 0x87, 0xde, 0x37, 0xc0, 0x27, 0xf7, 0x51, 0x40, 0xe9, 0xbc, 0x66,
0xde, 0x6a, 0x79, 0xcd, 0x25, 0xea, 0x7f, 0x06, 0x1d, 0x95, 0x18, 0xf5, 0x1d, 0x95, 0x54, 0x19, 0x22, 0xdc, 0xc2, 0xf1, 0x4c, 0xe9, 0x24, 0xe5, 0x5a, 0xcc, 0xe6, 0x97, 0x8f, 0xb8, 0x42, 0xfe,
0xed, 0x34, 0xde, 0xa1, 0xba, 0x04, 0xdd, 0x56, 0x09, 0xea, 0x37, 0xd0, 0x6e, 0xbd, 0x81, 0xe6, 0xb7, 0xa0, 0xa7, 0x73, 0xc3, 0xbe, 0xa7, 0xf3, 0xda, 0xa3, 0x3d, 0xab, 0x0f, 0x35, 0x29, 0x70,
0x35, 0xea, 0xd5, 0xaf, 0xd1, 0xfb, 0x40, 0x0e, 0xaf, 0x96, 0x29, 0xf2, 0x36, 0x5c, 0x9a, 0x14, 0x5b, 0x29, 0x68, 0x7a, 0xa0, 0xd7, 0xea, 0x81, 0xa6, 0x1b, 0xf5, 0x9b, 0x6e, 0xf4, 0x36, 0x04,
0xe3, 0x90, 0x3e, 0x87, 0x91, 0xb7, 0x8b, 0x5e, 0x8b, 0x75, 0xbe, 0x41, 0x71, 0x97, 0xd0, 0x4f, 0xdd, 0xa3, 0x55, 0x81, 0x71, 0x4b, 0xae, 0x8c, 0x8b, 0x71, 0x18, 0xde, 0x85, 0xc3, 0xd9, 0x26,
0x52, 0x8c, 0xa1, 0xe6, 0xf4, 0x98, 0x41, 0xf4, 0x23, 0x18, 0xd7, 0x34, 0x99, 0x62, 0xbc, 0x03, 0x7d, 0x28, 0x16, 0xeb, 0x25, 0x92, 0x3b, 0x81, 0x41, 0x5e, 0xa0, 0x0d, 0x29, 0xa6, 0xcf, 0x0c,
0x04, 0x18, 0xd0, 0x5c, 0x1a, 0x37, 0xcd, 0x29, 0xfa, 0x02, 0x9e, 0x79, 0xbb, 0xe8, 0xdb, 0x5c, 0x0a, 0xdf, 0x83, 0x51, 0x13, 0xa6, 0x0a, 0xb4, 0x77, 0x8c, 0x00, 0x0d, 0xba, 0x56, 0x46, 0x8d,
0x64, 0xfb, 0xf9, 0x3a, 0xc4, 0xb3, 0x5d, 0x18, 0x60, 0xb1, 0x84, 0x2c, 0xf9, 0x25, 0xa4, 0x9f, 0x3d, 0x15, 0xde, 0x83, 0x5b, 0xb3, 0x4d, 0xfa, 0xe5, 0x5a, 0xc8, 0xed, 0xc5, 0x22, 0xc1, 0xbd,
0xc2, 0x59, 0x8b, 0x2b, 0xd3, 0xd3, 0xe4, 0xd2, 0x6b, 0xa7, 0xf6, 0xfa, 0x9d, 0xf6, 0xa0, 0xb7, 0xc7, 0x70, 0x80, 0xc9, 0x12, 0xaa, 0x8a, 0xaf, 0x60, 0xf8, 0x21, 0xdc, 0x6e, 0xc5, 0xaa, 0x62,
0x3f, 0x7a, 0x0f, 0x76, 0x43, 0x18, 0xa7, 0xb9, 0x2a, 0xbb, 0x41, 0x83, 0x53, 0x1f, 0x9b, 0xfe, 0x7f, 0x70, 0xa5, 0xb5, 0xd7, 0x68, 0xfd, 0x9a, 0x34, 0xd0, 0xe7, 0x2f, 0x3c, 0x07, 0xab, 0x21,
0x6c, 0x69, 0xd3, 0xe6, 0xdc, 0x47, 0x35, 0xfd, 0xab, 0x83, 0xf1, 0x9c, 0x8c, 0xff, 0x88, 0x6f, 0xc9, 0x8a, 0xb5, 0xae, 0xaa, 0x81, 0xc0, 0xbe, 0xcb, 0x0e, 0xbf, 0x77, 0x48, 0xb4, 0xd9, 0xf7,
0x9f, 0x89, 0x4c, 0x09, 0x31, 0xb2, 0xf8, 0x22, 0xeb, 0xa5, 0xa2, 0x98, 0x15, 0x5e, 0xf7, 0xf5, 0x85, 0x9c, 0xfe, 0xd5, 0xc6, 0xb8, 0x8f, 0xe4, 0xcf, 0xb0, 0xf7, 0x19, 0xcb, 0x54, 0x10, 0x2d,
0x6f, 0xa7, 0x8f, 0xff, 0x09, 0x00, 0x00, 0xff, 0xff, 0x22, 0x7b, 0xc5, 0xdf, 0x50, 0x09, 0x00, 0x8b, 0x1d, 0x99, 0x96, 0xca, 0x64, 0xd6, 0x38, 0xfc, 0xdd, 0x81, 0x3b, 0xb3, 0x4d, 0x5a, 0x57,
0x00, 0x2a, 0x36, 0x48, 0x61, 0x0a, 0x82, 0x0c, 0xe4, 0x58, 0x4d, 0xee, 0x08, 0xdc, 0x2b, 0x51, 0x7a,
0xca, 0x65, 0x38, 0xac, 0x1f, 0x31, 0xd7, 0x7a, 0xc4, 0xea, 0x46, 0xea, 0xd9, 0x8d, 0xb4, 0xa1,
0xdd, 0x6f, 0xd1, 0x36, 0x17, 0x3f, 0xa8, 0x2f, 0x1e, 0x23, 0xc5, 0xf3, 0x22, 0x91, 0xc2, 0xbc,
0x83, 0x06, 0xd1, 0x2b, 0xc1, 0x25, 0xa7, 0xa2, 0x18, 0x96, 0x32, 0x2a, 0x1c, 0xfe, 0x81, 0x2f,
0x80, 0x25, 0x83, 0xaf, 0x56, 0xc6, 0x78, 0x3b, 0x5f, 0x77, 0xbb, 0x3a, 0x3a, 0xe2, 0xdc, 0x9b,
0xe2, 0x3c, 0x4b, 0xdc, 0x3f, 0x97, 0x11, 0x80, 0x27, 0x9e, 0x8b, 0xc8, 0x88, 0xa0, 0xb1, 0x25,
0x6d, 0xb8, 0x57, 0x9a, 0xdf, 0x91, 0xf6, 0x8b, 0x03, 0x27, 0x96, 0xb4, 0xaf, 0x24, 0xcf, 0xd4,
0x95, 0x90, 0x46, 0xde, 0xce, 0x9e, 0xda, 0xc8, 0x46, 0x81, 0x3d, 0x5b, 0x36, 0x51, 0x72, 0x77,
0x52, 0xf2, 0x5a, 0x94, 0xde, 0x04, 0x48, 0xd4, 0x37, 0x89, 0xbe, 0x8e, 0x25, 0x7f, 0x46, 0x62,
0x87, 0xcc, 0x9a, 0x69, 0x51, 0x1e, 0xb4, 0x29, 0x2f, 0x06, 0xf4, 0x87, 0xfc, 0xfd, 0xbf, 0x03,
0x00, 0x00, 0xff, 0xff, 0x77, 0x17, 0xf5, 0x15, 0xa5, 0x0b, 0x00, 0x00,
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment