Commit af694733 authored by liuyuhang's avatar liuyuhang Committed by 33cn

add proposal board

parent aa055772
all:
chmod +x ./build.sh
./build.sh $(OUT) $(FLAG)
\ No newline at end of file
#!/usr/bin/env bash
output_dir=${1}
strpwd=$(pwd)
strcmd=${strpwd##*dapp/}
strapp=${strcmd%/cmd*}
OUT_DIR="${output_dir}/$strapp"
[ ! -e "${OUT_DIR}" ] && mkdir -p "${OUT_DIR}"
# shellcheck disable=SC2086
cp ./build/* "${OUT_DIR}"
OUT_TESTDIR="${1}/dapptest/$strapp"
mkdir -p "${OUT_TESTDIR}"
cp ./build/test-rpc.sh "${OUT_TESTDIR}"
#!/usr/bin/env bash
# shellcheck disable=SC2128
# shellcheck source=/dev/null
source ../dapp-test-common.sh
MAIN_HTTP=""
txhash=""
function query_unfreezeID() {
chain33_BlockWait 1 "$MAIN_HTTP"
# echo "req=$req"
local times=10
while true; do
req='{"method":"Chain33.QueryTransaction","params":[{"hash":"'"$txhash"'"}]}'
ret=$(curl -ksd "$req" ${MAIN_HTTP})
tx=$(jq -r ".result.tx.hash" <<<"$ret")
echo "====query tx= ${txhash}, return=$ret "
if [ "${tx}" != "${txhash}" ]; then
block_wait 1
times=$((times - 1))
if [ $times -le 0 ]; then
echo "====query tx=$txhash failed"
echo "req=$req"
curl -ksd "$req" ${MAIN_HTTP}
exit 1
fi
else
unfreeze_id=$(jq '(.result.receipt.logs['"$uid_index"'].log.current.unfreezeID)' <<<"$ret")
#echo "${unfreeze_id}"
unfreeze_id2=${unfreeze_id#\"mavl-unfreeze-}
uid=${unfreeze_id2%\"}
echo "====query tx=$txhash success"
break
fi
done
}
function init() {
ispara=$(echo '"'"${MAIN_HTTP}"'"' | jq '.|contains("8901")')
echo "ipara=$ispara"
exec_name="unfreeze"
uid_index=2
if [ "$ispara" == true ]; then
exec_name="user.p.para."${exec_name}
uid_index=1
fi
exec_addr=$(curl -ksd '{"method":"Chain33.ConvertExectoAddr","params":[{"execname":"'${exec_name}'"}]}' ${MAIN_HTTP} | jq -r ".result")
echo "exec_addr=${exec_addr}"
beneficiary=12qyocayNF7Lv6C9qW4avxs2E7U41fKSfv
beneficiary_key=0x4257d8692ef7fe13c68b65d6a52f03933db2fa5ce8faf210b5b8b80c721ced01
owner=14KEKbYtKKQm4wMthSK9J4La4nAiidGozt
owner_key=CC38546E9E659D15E6B4893F0AB32A06D103931A8230B0BDE71459D2B27D6944
#unfreeze_exec_addr=15YsqAuXeEXVHgm6RVx4oJaAAnhtwqnu3H
Chain33_SendToAddress "$owner" "$exec_addr" 500000000 "${MAIN_HTTP}"
Chain33_SendToAddress "$beneficiary" "$exec_addr" 500000000 "${MAIN_HTTP}"
block_wait 1
}
function CreateRawUnfreezeCreate() {
req='{"jsonrpc": "2.0", "method" : "unfreeze.CreateRawUnfreezeCreate" , "params":[{"startTime":10000,"assetExec":"coins","assetSymbol":"bty","totalCount":400000000,"beneficiary":"'$beneficiary'","means":"FixAmount","fixAmount": {"period":10,"amount":1000000}}]}'
# echo "#request: $req"
resp=$(curl -ksd "$req" "${MAIN_HTTP}")
# echo "#resp: $resp"
ok=$(jq '(.error|not) and (.result != "")' <<<"$resp")
[ "$ok" == true ]
echo_rst "$FUNCNAME" "$?"
rawtx=$(jq -r ".result" <<<"$resp")
chain33_SignRawTx "$rawtx" "$owner_key" "${MAIN_HTTP}"
query_unfreezeID
}
function CreateRawUnfreezeWithdraw() {
sleep 10
req='{"method":"unfreeze.CreateRawUnfreezeWithdraw","params":[{"unfreezeID":"'${uid}'"}]}'
# echo "#request: $req"
resp=$(curl -ksd "$req" "${MAIN_HTTP}")
# echo "#resp: $resp"
ok=$(jq '(.error|not) and (.result != "")' <<<"$resp")
[ "$ok" == true ]
echo_rst "$FUNCNAME" "$?"
rawtx=$(jq -r ".result" <<<"$resp")
chain33_SignRawTx "$rawtx" "${beneficiary_key}" "${MAIN_HTTP}"
}
function CreateRawUnfreezeTerminate() {
req='{"method":"unfreeze.CreateRawUnfreezeTerminate","params":[{"unfreezeID":"'${uid}'"}]}'
# echo "#request: $req"
resp=$(curl -ksd "$req" "${MAIN_HTTP}")
# echo "#resp: $resp"
ok=$(jq '(.error|not) and (.result != "")' <<<"$resp")
[ "$ok" == true ]
echo_rst "$FUNCNAME" "$?"
rawtx=$(jq -r ".result" <<<"$resp")
chain33_SignRawTx "$rawtx" "$owner_key" "${MAIN_HTTP}"
block_wait 2
}
function GetUnfreeze() {
req='{"method":"unfreeze.GetUnfreeze","params":[{"data":"'${uid}'"}]}'
# echo "#request: $req"
resp=$(curl -ksd "$req" "${MAIN_HTTP}")
# echo "#resp: $resp"
ok=$(jq '(.error|not) and (.result != "")' <<<"$resp")
[ "$ok" == true ]
echo_rst "$FUNCNAME" "$?"
}
function GetUnfreezeWithdraw() {
req='{"method":"unfreeze.GetUnfreezeWithdraw","params":[{"data":"'${uid}'"}]}'
# echo "#request: $req"
resp=$(curl -ksd "$req" "${MAIN_HTTP}")
# echo "#resp: $resp"
ok=$(jq '(.error|not) and (.result != "")' <<<"$resp")
[ "$ok" == true ]
echo_rst "$FUNCNAME" "$?"
}
function run_testcases() {
CreateRawUnfreezeCreate
CreateRawUnfreezeWithdraw
GetUnfreeze
GetUnfreezeWithdraw
CreateRawUnfreezeTerminate
}
function debug_function() {
set -x
eval "$@"
set +x
}
function rpc_test() {
MAIN_HTTP="$1"
echo "main_ip=$MAIN_HTTP"
init
run_testcases
if [ -n "$CASE_ERR" ]; then
echo "=======unfreeze rpc test error ==========="
exit 1
else
echo "====== unfreeze rpc test pass ==========="
fi
}
debug_function rpc_test "$1"
#!/usr/bin/env bash
CLI="docker exec ${NODE3} /root/chain33-cli"
beneficiary=12qyocayNF7Lv6C9qW4avxs2E7U41fKSfv
beneficiary_key=0x4257d8692ef7fe13c68b65d6a52f03933db2fa5ce8faf210b5b8b80c721ced01
#owner=14KEKbYtKKQm4wMthSK9J4La4nAiidGozt
owner_key=CC38546E9E659D15E6B4893F0AB32A06D103931A8230B0BDE71459D2B27D6944
unfreeze_exec_addr=15YsqAuXeEXVHgm6RVx4oJaAAnhtwqnu3H
function unfreeze_test() {
echo "=========== # unfreeze test ============="
echo "=== 1 check exec addr"
result=$($CLI exec addr -e unfreeze)
if [ "${result}" != "${unfreeze_exec_addr}" ]; then
echo "unfreeze exec addr is not right, expect ${unfreeze_exec_addr} result ${result}"
exit 1
fi
block_wait "${CLI}" 2
echo "=== 2 prepare: transfer bty to unfreeze "
result=$($CLI send coins transfer -a 5 -n test -t ${unfreeze_exec_addr} -k ${owner_key})
echo "${result}"
block_wait "${CLI}" 2
echo "=== 3 create unfreeze tx"
tx_hash=$(${CLI} send unfreeze create fix_amount -a 0.01 -e coins -s bty -b ${beneficiary} -p 20 -t 2 -k ${owner_key})
block_wait "${CLI}" 2
unfreeze_id=$(${CLI} tx query -s "${tx_hash}" | jq ".receipt.logs[2].log.current.unfreezeID")
echo "${unfreeze_id}"
unfreeze_id2=${unfreeze_id#\"mavl-unfreeze-}
uid=${unfreeze_id2%\"}
echo "==== 4 check some message "
sleep 20
withdraw=$(${CLI} unfreeze show_withdraw --id "${uid}" | jq ".availableAmount")
if [ "${withdraw}" = "0" ]; then
echo "create unfreeze failed, expect withdraw shoult >0 "
exit 1
fi
echo "==== 5 withdraw"
${CLI} send unfreeze withdraw --id "${uid}" -k "${beneficiary_key}"
block_wait "${CLI}" 2
remaining=$(${CLI} unfreeze show --id "${uid}" | jq ".remaining")
if [ "${remaining}" = '"200000000"' ]; then
echo "withdraw failed, expect remaining < 200000000, result ${remaining}"
exit 1
fi
echo "==== 6 termenate"
${CLI} send unfreeze terminate --id "${uid}" -k "${owner_key}"
block_wait "${CLI}" 2
remaining=$(${CLI} unfreeze show --id "${uid}" | jq ".remaining")
remainingNum=$(echo "$remaining" | awk '{print int($0)}')
if [ "100000000" -lt "${remainingNum}" ]; then
echo "terminate failed, expect remaining < 100000000, result ${remaining}"
exit 1
fi
echo "==================== unfreeze test end"
}
function unfreeze() {
if [ "${2}" == "init" ]; then
return
elif [ "${2}" == "config" ]; then
return
elif [ "${2}" == "test" ]; then
unfreeze_test "${1}"
fi
}
This diff is collapsed.
// 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 commands
// 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 commands
// 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.
//Chain33投票治理系统旨在为chain33链提供一种社区发展自治的系统,可以由利益相关者制定规则。
//Chain33投票治理系统中参与投票治理主要由董事会以及全体持票人。
//董事会主要参与日常项目的执行决策;董事会的产生由提案人提案董事会成员(暂定30),由全体持票人投票,超过50%的持票进行投票,其中得票率超过50%
//即可认为该提案的董事会成员合法;董事会行使投票权利:针对某一提案,需要全体董事会成员三分之二以上成员参与,且需要参与成员中三分之二以上投赞成票,说明该提案通过董事会投票。
//根据提案示项目大小(金额,这个金额可以由全体持票人投票来定)来决定是否需要公示期:
//(1)对于小项目,则不需要进入公示期,董事会通过之后即可以进行项目开发。
//(2)对于大项目,则董事会成员通过之后,进入公示期,公示期期间(大约一周的区块高度),全体持票人可以对该项目投否决票,超过三分之一的全体持票人投否决票,则该提案视为不通过(后台服务提供消息注册提醒功能)
//全体持票人指全体持有比特元票的人。全体持票人主要负责:
//(1)选举董事会成员,对于提案的董事会成员进行投票
//(2)对于重大项目的否决权利,即对通过董事会成员投票进入公示期的重大项目有否决权利。
//(3)可以重新对董事会成员进行提案投票,一旦通过,则原有董事会成员权利自动失效。
//(4)可以重新对提案投票自治系统某些参数进行修改,一旦通过,则投票的判断以新参数为准。
//
//
//任何人可以消耗一定数量的费用(如1000)进行提案,提案的费用转入到发展基金中,提案的种类包括三种:
//(1)提案董事会成员,即提案董事会成员后投票形成董事会;
//1)提案董事会成员数目在[3 30]范围
//2)提案需要指定参与有效投票的区块高度区间。
//3)需全体持票50%进行投票且得票率超过50%即可认为该提案的董事会成员合法。
//
//(2)提案项目方案,提案后投票确定是否执行该项目;
//1)提案人跟具体线下承包方具有一定的绑定关系:
//a 承包商可以将营业执照、收款地址、身份证信息等注册到钱包或者其它的服务器上面;
//b 在某个承包商提交一个提案后,客户端获得(钱包或者服务器可以主动将该提案推送给董事会成员)该提案,并且与保存在钱包服务器中的承包商信息想匹配,给出参与投票人相关的提示;
//2)提案需要指定参与有效投票的区块高度区间
//3)需要按照要求在填入项目相关信息,包括项目地址、第一阶段提案hash(针对项目多阶段提案)、上一阶段提案hash(针对项目多阶段提案)、项目阶段性简述(md格式)、承包人、项目经费、经费细则(md格式)、收款地址。
//4)提案通过董事会之后,根据项目金额大小来决定是否进入公示期,公示期周期固定为1周的区块高度,从董事会实际投票结束的高度向后推算一周区块高度。有超过30%的否决票,则该提案不通过。
//5)根据每个不同阶段,完成的情况,追缴上一阶段的金额,开始阶段预付一定金额,最后一个阶段支付尾款,尾款的控制由董事会进行把控。
//6)董事会成员可以对提案进行评论,评论将以交易的形式提出并且与提案相关联,显示到提案区,参与评论的截止时间以实际提案结束投票高度为准。
//
//(3)提案投票自治系统参数修改,如达成董事会投票的参与率/通过率,全体持票人重大项目的否决率,提案费用,重大项目金额阈值的修改。
package autonomy
// 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 executor
import (
log "github.com/33cn/chain33/common/log/log15"
drivers "github.com/33cn/chain33/system/dapp"
"github.com/33cn/chain33/types"
auty "github.com/33cn/plugin/plugin/dapp/autonomy/types"
)
var alog = log.New("module", "execs.autonomy")
var driverName = auty.AutonomyX
func init() {
ety := types.LoadExecutorType(driverName)
ety.InitFuncList(types.ListMethod(&Autonomy{}))
}
// Init 重命名执行器名称
func Init(name string, sub []byte) {
drivers.Register(GetName(), newAutonomy, types.GetDappFork(driverName, "Enable"))
}
// Autonomy 执行器结构体
type Autonomy struct {
drivers.DriverBase
}
func newAutonomy() drivers.Driver {
t := &Autonomy{}
t.SetChild(t)
t.SetExecutorType(types.LoadExecutorType(driverName))
return t
}
// GetName 获得执行器名字
func GetName() string {
return newAutonomy().GetName()
}
// GetDriverName 获得驱动名字
func (u *Autonomy) GetDriverName() string {
return driverName
}
// 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 executor
import (
"github.com/33cn/chain33/system/dapp"
"github.com/33cn/chain33/types"
auty "github.com/33cn/plugin/plugin/dapp/autonomy/types"
)
func (a *Autonomy) execLocalBoard(receiptData *types.ReceiptData) (*types.LocalDBSet, error) {
dbSet := &types.LocalDBSet{}
var set []*types.KeyValue
for _, log := range receiptData.Logs {
switch log.Ty {
case auty.TyLogPropBoard,
auty.TyLogRvkPropBoard,
auty.TyLogVotePropBoard,
auty.TyLogTmintPropBoard:
{
var receipt auty.ReceiptProposalBoard
err := types.Decode(log.Log, &receipt)
if err != nil {
return nil, err
}
kv := a.saveHeightIndex(&receipt)
set = append(set, kv...)
}
default:
break
}
}
dbSet.KV = append(dbSet.KV, set...)
return dbSet, nil
}
func (c *Autonomy) saveHeightIndex(res *auty.ReceiptProposalBoard) (kvs []*types.KeyValue) {
// 先将之前的状态删除掉,再做更新
if res.Current.Status > 1 {
kv := &types.KeyValue{}
kv.Key = calcBoardKey4StatusHeight(res.Prev.Status, dapp.HeightIndexStr(res.Prev.Height, int64(res.Prev.Index)))
kv.Value = nil
kvs = append(kvs, kv)
}
kv := &types.KeyValue{}
kv.Key = calcBoardKey4StatusHeight(res.Current.Status, dapp.HeightIndexStr(res.Current.Height, int64(res.Current.Index)))
kv.Value = types.Encode(res.Current)
kvs = append(kvs, kv)
return kvs
}
func (a *Autonomy) execDelLocalBoard(receiptData *types.ReceiptData) (*types.LocalDBSet, error) {
dbSet := &types.LocalDBSet{}
var set []*types.KeyValue
for _, log := range receiptData.Logs {
switch log.Ty {
case auty.TyLogPropBoard,
auty.TyLogRvkPropBoard,
auty.TyLogVotePropBoard,
auty.TyLogTmintPropBoard:
{
var receipt auty.ReceiptProposalBoard
err := types.Decode(log.Log, &receipt)
if err != nil {
return nil, err
}
kv := a.delHeightIndex(&receipt)
set = append(set, kv...)
}
default:
break
}
}
dbSet.KV = append(dbSet.KV, set...)
return dbSet, nil
}
func (c *Autonomy) delHeightIndex(res *auty.ReceiptProposalBoard) (kvs []*types.KeyValue) {
kv := &types.KeyValue{}
kv.Key = calcBoardKey4StatusHeight(res.Current.Status, dapp.HeightIndexStr(res.Current.Height, int64(res.Current.Index)))
kv.Value = nil
kvs = append(kvs, kv)
if res.Current.Status > 1 {
kv := &types.KeyValue{}
kv.Key = calcBoardKey4StatusHeight(res.Prev.Status, dapp.HeightIndexStr(res.Prev.Height, int64(res.Prev.Index)))
kv.Value = types.Encode(res.Prev)
kvs = append(kvs, kv)
}
return kvs
}
\ No newline at end of file
This diff is collapsed.
// 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 executor
import (
"github.com/33cn/chain33/types"
auty "github.com/33cn/plugin/plugin/dapp/autonomy/types"
)
// Exec_PropBoard 创建提案
func (a *Autonomy) Exec_PropBoard(payload *auty.ProposalBoard, tx *types.Transaction, index int) (*types.Receipt, error) {
action := newAction(a, tx, int32(index))
return action.propBoard(payload)
}
// Exec_RvkPropBoard 撤销提案
func (a *Autonomy) Exec_RvkPropBoard(payload *auty.RevokeProposalBoard, tx *types.Transaction, index int) (*types.Receipt, error) {
action := newAction(a, tx, int32(index))
return action.rvkPropBoard(payload)
}
// Exec_VotePropBoard 投票提案
func (a *Autonomy) Exec_VotePropBoard(payload *auty.VoteProposalBoard, tx *types.Transaction, index int) (*types.Receipt, error) {
action := newAction(a, tx, int32(index))
return action.votePropBoard(payload)
}
// Exec_TmintPropBoard 终止提案
func (a *Autonomy) Exec_TmintPropBoard(payload *auty.TerminateProposalBoard, tx *types.Transaction, index int) (*types.Receipt, error) {
action := newAction(a, tx, int32(index))
return action.tmintPropBoard(payload)
}
\ 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 executor
import (
"github.com/33cn/chain33/types"
auty "github.com/33cn/plugin/plugin/dapp/autonomy/types"
)
// ExecDelLocal_PropBoard 创建提案
func (a *Autonomy) ExecDelLocal_PropBoard(payload *auty.ProposalBoard, tx *types.Transaction, receiptData *types.ReceiptData, index int) (*types.LocalDBSet, error) {
return a.execDelLocalBoard(receiptData)
}
// ExecDelLocal_RvkPropBoard 撤销提案
func (a *Autonomy) ExecDelLocal_RvkPropBoard(payload *auty.RevokeProposalBoard, tx *types.Transaction, receiptData *types.ReceiptData, index int) (*types.LocalDBSet, error){
return a.execDelLocalBoard(receiptData)
}
// ExecDelLocal_VotePropBoard 投票提案
func (a *Autonomy) ExecDelLocal_VotePropBoard(payload *auty.VoteProposalBoard, tx *types.Transaction, receiptData *types.ReceiptData, index int) (*types.LocalDBSet, error) {
return a.execDelLocalBoard(receiptData)
}
// ExecDelLocal_TmintPropBoard 终止提案
func (a *Autonomy) ExecDelLocal_TmintPropBoard(payload *auty.TerminateProposalBoard, tx *types.Transaction, receiptData *types.ReceiptData, index int) (*types.LocalDBSet, error) {
return a.execDelLocalBoard(receiptData)
}
// 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 executor
import (
"github.com/33cn/chain33/types"
auty "github.com/33cn/plugin/plugin/dapp/autonomy/types"
)
// ExecLocal_PropBoard 创建提案
func (a *Autonomy) ExecLocal_PropBoard(payload *auty.ProposalBoard, tx *types.Transaction, receiptData *types.ReceiptData, index int) (*types.LocalDBSet, error) {
return a.execLocalBoard(receiptData)
}
// ExecLocal_RvkPropBoard 撤销提案
func (a *Autonomy) ExecLocal_RvkPropBoard(payload *auty.RevokeProposalBoard, tx *types.Transaction, receiptData *types.ReceiptData, index int) (*types.LocalDBSet, error){
return a.execLocalBoard(receiptData)
}
// ExecLocal_VotePropBoard 投票提案
func (a *Autonomy) ExecLocal_VotePropBoard(payload *auty.VoteProposalBoard, tx *types.Transaction, receiptData *types.ReceiptData, index int) (*types.LocalDBSet, error) {
return a.execLocalBoard(receiptData)
}
// ExecLocal_TmintPropBoard 终止提案
func (a *Autonomy) ExecLocal_TmintPropBoard(payload *auty.TerminateProposalBoard, tx *types.Transaction, receiptData *types.ReceiptData, index int) (*types.LocalDBSet, error) {
return a.execLocalBoard(receiptData)
}
// 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 executor
import (
"testing"
"github.com/stretchr/testify/assert"
"encoding/hex"
"github.com/33cn/chain33/account"
"github.com/33cn/chain33/common"
"github.com/33cn/chain33/common/address"
"github.com/33cn/chain33/common/crypto"
dbm "github.com/33cn/chain33/common/db"
"github.com/33cn/chain33/types"
"github.com/33cn/chain33/util"
pty "github.com/33cn/plugin/plugin/dapp/unfreeze/types"
)
type execEnv struct {
blockTime int64
blockHeight int64
difficulty uint64
}
var (
Symbol = "TEST"
AssetExecToken = "token"
AssetExecPara = "paracross"
PrivKeyA = "0x6da92a632ab7deb67d38c0f6560bcfed28167998f6496db64c258d5e8393a81b" // 1KSBd17H7ZK8iT37aJztFB22XGwsPTdwE4
PrivKeyB = "0x19c069234f9d3e61135fefbeb7791b149cdf6af536f26bebb310d4cd22c3fee4" // 1JRNjdEqp4LJ5fqycUBm9ayCKSeeskgMKR
PrivKeyC = "0x7a80a1f75d7360c6123c32a78ecf978c1ac55636f87892df38d8b85a9aeff115" // 1NLHPEcbTWWxxU3dGUZBhayjrCHD3psX7k
PrivKeyD = "0xcacb1f5d51700aea07fca2246ab43b0917d70405c65edea9b5063d72eb5c6b71" // 1MCftFynyvG2F4ED5mdHYgziDxx6vDrScs
Nodes = [][]byte{
[]byte("1KSBd17H7ZK8iT37aJztFB22XGwsPTdwE4"),
[]byte("1JRNjdEqp4LJ5fqycUBm9ayCKSeeskgMKR"),
[]byte("1NLHPEcbTWWxxU3dGUZBhayjrCHD3psX7k"),
[]byte("1MCftFynyvG2F4ED5mdHYgziDxx6vDrScs"),
}
)
func TestUnfreeze(t *testing.T) {
types.SetTitleOnlyForTest("chain33")
total := int64(100000)
accountA := types.Account{
Balance: total,
Frozen: 0,
Addr: string(Nodes[0]),
}
accountB := types.Account{
Balance: total,
Frozen: 0,
Addr: string(Nodes[1]),
}
execAddr := address.ExecAddress(pty.UnfreezeX)
stateDB, _ := dbm.NewGoMemDB("1", "2", 100)
_, ldb, kvdb := util.CreateTestDB()
accA, _ := account.NewAccountDB(AssetExecPara, Symbol, stateDB)
accA.SaveExecAccount(execAddr, &accountA)
accB, _ := account.NewAccountDB(AssetExecPara, Symbol, stateDB)
accB.SaveExecAccount(execAddr, &accountB)
env := execEnv{
10,
types.GetDappFork(pty.UnfreezeX, pty.ForkUnfreezeIDX),
1539918074,
}
ty := pty.UnfreezeType{}
// 创建
opt := &pty.FixAmount{Period: 10, Amount: 2}
p1 := &pty.UnfreezeCreate{
StartTime: 10,
AssetExec: AssetExecPara,
AssetSymbol: Symbol,
TotalCount: 10000,
Beneficiary: string(Nodes[1]),
Means: "FixAmount",
MeansOpt: &pty.UnfreezeCreate_FixAmount{FixAmount: opt},
}
createTx, err := ty.RPC_UnfreezeCreateTx(p1)
if err != nil {
t.Error("RPC_UnfreezeCreateTx", "err", err)
}
createTx, err = signTx(createTx, PrivKeyA)
if err != nil {
t.Error("RPC_UnfreezeCreateTx sign", "err", err)
}
exec := newUnfreeze()
exec.SetStateDB(stateDB)
exec.SetLocalDB(kvdb)
exec.SetEnv(env.blockHeight, env.blockTime, env.difficulty)
receipt, err := exec.Exec(createTx, int(1))
assert.Nil(t, err)
assert.NotNil(t, receipt)
//t.Log(receipt)
accTmp := accA.LoadExecAccount(accountA.Addr, execAddr)
assert.Equal(t, total-p1.TotalCount, accTmp.Balance)
assert.Equal(t, p1.TotalCount, accTmp.Frozen)
receiptDate := &types.ReceiptData{Ty: receipt.Ty, Logs: receipt.Logs}
set, err := exec.ExecLocal(createTx, receiptDate, int(1))
assert.Nil(t, err)
assert.NotNil(t, set)
req1 := &pty.ReqUnfreezes{
Beneficiary: p1.Beneficiary,
}
reply, err := exec.Query("ListUnfreezeByBeneficiary", types.Encode(req1))
assert.Nil(t, err)
assert.NotNil(t, reply)
resp, ok := reply.(*pty.ReplyUnfreezes)
assert.True(t, ok)
assert.Equal(t, 1, len(resp.Unfreeze))
assert.Equal(t, string(unfreezeID(createTx.Hash())), resp.Unfreeze[0].UnfreezeID)
// 提币
p2 := &pty.UnfreezeWithdraw{
UnfreezeID: hex.EncodeToString(createTx.Hash()),
}
withdrawTx, err := ty.RPC_UnfreezeWithdrawTx(p2)
if err != nil {
t.Error("RPC_UnfreezeWithdrawTx", "err", err)
}
withdrawTx, err = signTx(withdrawTx, PrivKeyB)
if err != nil {
t.Error("RPC_UnfreezeWithdrawTx sign", "err", err)
}
blockTime := int64(10)
exec.SetEnv(env.blockHeight+1, env.blockTime+blockTime, env.difficulty)
receipt, err = exec.Exec(withdrawTx, 1)
assert.Nil(t, err)
assert.NotNil(t, receipt)
//t.Log(receipt)
accATmp := accA.LoadExecAccount(accountA.Addr, execAddr)
accBTmp := accB.LoadExecAccount(accountB.Addr, execAddr)
assert.Equal(t, total-p1.TotalCount, accATmp.Balance)
u := pty.Unfreeze{}
e := types.Decode(receipt.KV[2].Value, &u)
assert.Nil(t, e)
assert.Equal(t, u.Remaining, accATmp.Frozen)
assert.Equal(t, accountB.Balance+p1.TotalCount-u.Remaining, accBTmp.Balance)
receiptDate2 := &types.ReceiptData{Ty: receipt.Ty, Logs: receipt.Logs}
set, err = exec.ExecLocal(withdrawTx, receiptDate2, int(1))
assert.Nil(t, err)
assert.NotNil(t, set)
// 不是受益人提币
{
p2 := &pty.UnfreezeWithdraw{
UnfreezeID: hex.EncodeToString(createTx.Hash()),
}
withdrawTx, err := ty.RPC_UnfreezeWithdrawTx(p2)
if err != nil {
t.Error("RPC_UnfreezeWithdrawTx", "err", err)
}
withdrawTx, err = signTx(withdrawTx, PrivKeyC)
if err != nil {
t.Error("RPC_UnfreezeWithdrawTx sign", "err", err)
}
blockTime := int64(10)
exec.SetEnv(env.blockHeight+1, env.blockTime+blockTime, env.difficulty)
receipt, err = exec.Exec(withdrawTx, 1)
assert.Equal(t, pty.ErrNoPrivilege, err)
assert.Nil(t, receipt)
}
// 不是创建者终止
{
p3 := &pty.UnfreezeTerminate{
UnfreezeID: hex.EncodeToString(createTx.Hash()),
}
terminateTx, err := ty.RPC_UnfreezeTerminateTx(p3)
if err != nil {
t.Error("RPC_UnfreezeTerminateTx", "err", err)
}
terminateTx, err = signTx(terminateTx, PrivKeyC)
if err != nil {
t.Error("RPC_UnfreezeTerminateTx sign", "err", err)
}
receipt, err = exec.Exec(terminateTx, 1)
assert.Equal(t, pty.ErrNoPrivilege, err)
assert.Nil(t, receipt)
}
// 终止
p3 := &pty.UnfreezeTerminate{
UnfreezeID: hex.EncodeToString(createTx.Hash()),
}
terminateTx, err := ty.RPC_UnfreezeTerminateTx(p3)
if err != nil {
t.Error("RPC_UnfreezeTerminateTx", "err", err)
}
terminateTx, err = signTx(terminateTx, PrivKeyA)
if err != nil {
t.Error("RPC_UnfreezeTerminateTx sign", "err", err)
}
exec.SetEnv(env.blockHeight+2, env.blockTime+blockTime, env.difficulty)
receipt, err = exec.Exec(terminateTx, 1)
assert.Nil(t, err)
assert.NotNil(t, receipt)
//t.Log(receipt)
accATmp = accA.LoadExecAccount(accountA.Addr, execAddr)
assert.Equal(t, total+total, accATmp.Balance+accBTmp.Balance)
assert.Equal(t, int64(0), accATmp.Frozen)
receiptDate3 := &types.ReceiptData{Ty: receipt.Ty, Logs: receipt.Logs}
set, err = exec.ExecLocal(terminateTx, receiptDate3, int(1))
assert.Nil(t, err)
assert.NotNil(t, set)
// 终止后不能继续提币
{
p2 := &pty.UnfreezeWithdraw{
UnfreezeID: hex.EncodeToString(createTx.Hash()),
}
withdrawTx, err := ty.RPC_UnfreezeWithdrawTx(p2)
if err != nil {
t.Error("RPC_UnfreezeWithdrawTx", "err", err)
}
withdrawTx, err = signTx(withdrawTx, PrivKeyB)
if err != nil {
t.Error("RPC_UnfreezeWithdrawTx sign", "err", err)
}
blockTime := int64(10)
exec.SetEnv(env.blockHeight+1, env.blockTime+blockTime+blockTime, env.difficulty)
receipt, err = exec.Exec(withdrawTx, 1)
assert.Equal(t, pty.ErrUnfreezeEmptied, err)
assert.Nil(t, receipt)
}
req := types.ReqString{Data: hex.EncodeToString(createTx.Hash())}
_, err = exec.Query("GetUnfreeze", types.Encode(&req))
assert.Nil(t, err)
_, err = exec.Query("GetUnfreezeWithdraw", types.Encode(&req))
assert.Nil(t, err)
_, err = exec.ExecDelLocal(terminateTx, receiptDate3, int(1))
assert.Nil(t, err)
exec.SetEnv(env.blockHeight+1, env.blockTime+blockTime, env.difficulty)
_, err = exec.ExecDelLocal(withdrawTx, receiptDate2, int(1))
assert.Nil(t, err)
exec.SetEnv(env.blockHeight, env.blockTime+blockTime, env.difficulty)
_, err = exec.ExecDelLocal(createTx, receiptDate, int(1))
assert.Nil(t, err)
ldb.Close()
}
func signTx(tx *types.Transaction, hexPrivKey string) (*types.Transaction, error) {
signType := types.SECP256K1
c, err := crypto.New(types.GetSignName(pty.UnfreezeX, 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
}
// 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 executor
import (
"fmt"
auty "github.com/33cn/plugin/plugin/dapp/autonomy/types"
)
var (
idPrefix = "mavl-" + auty.AutonomyX + "-"
votesRecordPrefix = idPrefix + "vote" + "-"
localPrefix = "LOCDB" + auty.AutonomyX + "-"
)
var (
// board
boardPrefix = idPrefix + "board" + "-"
)
func propBoardID(txHash string) []byte {
return []byte(fmt.Sprintf("%s%s", boardPrefix, txHash))
}
func VotesRecord(txHash string) []byte {
return []byte(fmt.Sprintf("%s%s", votesRecordPrefix, txHash))
}
func calcBoardKey4StatusHeight(status int32, heightindex string) []byte {
key := fmt.Sprintf(localPrefix + "%d-" +"%s", status, heightindex)
return []byte(key)
}
// 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 executor
import (
"time"
dbm "github.com/33cn/chain33/common/db"
"github.com/33cn/chain33/types"
auty "github.com/33cn/plugin/plugin/dapp/autonomy/types"
)
// Query_GetUnfreezeWithdraw 查询合约可提币量
func (u *Unfreeze) Query_GetUnfreezeWithdraw(in *types.ReqString) (types.Message, error) {
return QueryWithdraw(u.GetStateDB(), in.GetData())
}
\ 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 autonomy
import (
"github.com/33cn/chain33/pluginmgr"
"github.com/33cn/plugin/plugin/dapp/autonomy/commands"
"github.com/33cn/plugin/plugin/dapp/autonomy/executor"
"github.com/33cn/plugin/plugin/dapp/autonomy/rpc"
ptypes "github.com/33cn/plugin/plugin/dapp/autonomy/types"
)
func init() {
pluginmgr.Register(&pluginmgr.PluginBase{
Name: ptypes.PackageName,
ExecName: executor.GetName(),
Exec: executor.Init,
Cmd: commands.Cmd,
RPC: rpc.Init,
})
}
all:
./create_protobuf.sh
// 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.
syntax = "proto3";
//import "common.proto";
import "board.proto";
import "project.proto";
import "rule.proto";
package types;
// message for execs.Autonomy
message AutonomyAction {
oneof value {
// 提案董事会相关
ProposalBoard propBoard = 1;
RevokeProposalBoard rvkPropBoard = 2;
VoteProposalBoard votePropBoard = 3;
TerminateProposalBoard tmintPropBoard = 4;
// 提案项目相关
ProposalProject propProject = 5;
RevokeProposalProject rvkPropProject = 6;
VoteProposalBoard votePropProject = 7;
TerminateProposalProject tmintPropProject = 8;
// 提案规则修改相关
ProposalRule propRule = 9;
RevokeProposalRule rvkPropRule = 10;
VoteProposalBoard votePropRule = 11;
TerminateProposalRule tmintPropRule = 12;
}
int32 ty = 13;
}
service autonomy {
rpc QueryProposalBoard(ReplyQueryProposalBoard) returns (ReplyProposalBoard) {}
rpc QueryProposalProject(ReplyQueryProposalProject) returns (ReplyProposalProject) {}
rpc QueryProposalRule(ReplyQueryProposalRule) returns (ReplyProposalRule) {}
}
\ 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.
syntax = "proto3";
import "lcommon.proto";
package types;
message AutonomyProposalBoard {
ProposalBoard propBoard = 1;
// 全体持票人投票结果
VotesResult res = 2;
// 状态
int32 status = 3;
string address = 4;
int64 height = 5;
int32 index = 6;
}
// action
message ProposalBoard {
// 提案时间
int32 year = 1;
int32 month = 2;
int32 day = 3;
// 提案董事会成员
repeated string boards = 4;
// 投票相关
int64 startBlockHeight = 5; // 提案开始投票高度
int64 endBlockHeight = 6; // 提案结束投票高度
int64 realEndBlockHeight = 7; // 实际提案结束投票高度
}
message RevokeProposalBoard {
string proposalID = 1;
}
message VoteProposalBoard {
string proposalID = 1;
bool approve = 2;
}
message TerminateProposalBoard {
string proposalID = 1;
}
// receipt
message ReceiptProposalBoard {
AutonomyProposalBoard prev = 1;
AutonomyProposalBoard current = 2;
}
message LocalProposalBoard {
AutonomyProposalBoard propBd = 1;
repeated string comments = 2;
}
// query
message ReplyQueryProposalBoard {
string proposalID = 1;
}
message ReplyProposalBoard {
repeated LocalProposalBoard propBoards = 1;
}
\ No newline at end of file
#!/bin/sh
protoc --go_out=plugins=grpc:../types ./*.proto --proto_path=. --proto_path="$GOPATH/src/github.com/33cn/chain33/types/proto/"
// 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.
syntax = "proto3";
package types;
message VotesResult {
// 总票数
int32 totalVotes = 1;
// 赞成票
int32 approveVotes = 2;
// 反对票
int32 opposeVotes = 3;
// 是否通过
bool pass = 4;
}
message VotesRecord {
repeated string address = 1;
}
\ 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.
syntax = "proto3";
import "lcommon.proto";
package types;
message AutonomyProposalProject {
ProposalProject propProject = 1;
// 董事会投票结果
VotesResult boardResult = 2;
// 是否需要公示
bool publicity = 3;
// 全体持票人反对票
int32 opposeVotes = 4;
// 是否通过
bool pubPass = 5;
// 状态
int32 status = 6;
}
message ProposalProject {
// 提案时间
int32 year = 1;
int32 month = 2;
int32 day = 3;
// 项目相关
string firstStage = 4; // 第一阶段提案项目hash
string lastStage = 5; // 上一阶段提案项目hash
string production = 6; // 项目地址
string description = 7; // 项目阶段性简述
string contractor = 8; // 承包人
int32 amount = 9; // 项目经费
string amountDetail = 10; // 经费细则
// 支付相关
string toAddr = 11; // 收款地址
// 投票相关
int64 startBlockHeight = 12; // 提案开始投票高度
int64 endBlockHeight = 13; // 提案结束投票高度
int64 realEndBlockHeight = 14; // 实际提案结束投票高度
int32 projectNeedBlockNum = 15; // 以提案结束投票高度为准,需要项目需要消耗的区块数目所对应的时间
}
message RevokeProposalProject {
string proposalID = 1;
}
message TerminateProposalProject {
string proposalID = 1;
}
// receipt
message ReceiptProposalProject {
AutonomyProposalProject prev = 1;
AutonomyProposalProject current = 2;
}
message LocalProposalProject {
AutonomyProposalProject propPrj = 1;
repeated string comments = 2;
}
// query
message ReplyQueryProposalProject {
string proposalID = 1;
}
message ReplyProposalProject {
repeated LocalProposalProject propProjects = 1;
}
\ 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.
syntax = "proto3";
import "lcommon.proto";
package types;
message AutonomyProposalRule {
ProposalRule propRule = 1;
// 全体持票人投票结果
VotesResult res = 2;
// 状态
int32 status = 3;
}
message ProposalRule {
// 提案时间
int32 year = 1;
int32 month = 2;
int32 day = 3;
// 可修改项
int32 boardAttendProb = 4; //参与率,以%为单位,只保留整数部分
int32 boardPassProb = 5; //通过率
int32 opposeProb = 6; //否决率
int32 proposalAmount = 7; //提案金额
int32 pubAmountThreshold = 8; //公示金额阈值
// 投票相关
int64 startBlockHeight = 9; // 提案开始投票高度
int64 endBlockHeight = 10; // 提案结束投票高度
int64 realEndBlockHeight = 11; // 实际提案结束投票高度
}
message RevokeProposalRule {
string proposalID = 1;
}
message TerminateProposalRule {
string proposalID = 1;
}
// receipt
message ReceiptProposalRule {
AutonomyProposalRule prev = 1;
AutonomyProposalRule current = 2;
}
message LocalProposalRule {
AutonomyProposalRule propRule = 1;
repeated string comments = 2;
}
// query
message ReplyQueryProposalRule {
string proposalID = 1;
}
message ReplyProposalRule {
repeated LocalProposalRule propRules = 1;
}
\ 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"
auty "github.com/33cn/plugin/plugin/dapp/autonomy/types"
)
// PropBoardTx 提案董事会成员RPC接口
func (c *Jrpc) PropBoardTx(parm *auty.ProposalBoard, result *interface{}) error {
if parm == nil {
return types.ErrInvalidParam
}
reply, err := c.cli.propBoard(context.Background(), parm)
if err != nil {
return err
}
*result = hex.EncodeToString(reply.Data)
return nil
}
// RevokeProposalBoardTx 撤销提案董事会成员的RPC接口
func (c *Jrpc) RevokeProposalBoardTx(parm *auty.RevokeProposalBoard, result *interface{}) error {
if parm == nil {
return types.ErrInvalidParam
}
reply, err := c.cli.revokeProposalBoard(context.Background(), parm)
if err != nil {
return err
}
*result = hex.EncodeToString(reply.Data)
return nil
}
// TerminateProposalBoardTx 终止提案董事会成员的RPC接口
func (c *Jrpc) TerminateProposalBoardTx(parm *auty.TerminateProposalBoard, result *interface{}) error {
if parm == nil {
return types.ErrInvalidParam
}
reply, err := c.cli.terminateProposalBoard(context.Background(), parm)
if err != nil {
return err
}
*result = hex.EncodeToString(reply.Data)
return nil
}
\ 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_test
import (
"strings"
"testing"
commonlog "github.com/33cn/chain33/common/log"
"github.com/33cn/chain33/rpc/jsonclient"
rpctypes "github.com/33cn/chain33/rpc/types"
"github.com/33cn/chain33/types"
"github.com/33cn/chain33/util/testnode"
pty "github.com/33cn/plugin/plugin/dapp/blackwhite/types"
"github.com/stretchr/testify/assert"
_ "github.com/33cn/chain33/system"
_ "github.com/33cn/plugin/plugin"
)
func init() {
commonlog.SetLogLevel("error")
}
func TestJRPCChannel(t *testing.T) {
// 启动RPCmocker
mocker := testnode.New("--notset--", nil)
defer func() {
mocker.Close()
}()
mocker.Listen()
jrpcClient := mocker.GetJSONC()
assert.NotNil(t, jrpcClient)
testCases := []struct {
fn func(*testing.T, *jsonclient.JSONClient) error
}{
{fn: testCreateRawTxCmd},
{fn: testPlayRawTxCmd},
{fn: testShowRawTxCmd},
{fn: testTimeoutDoneTxCmd},
{fn: testRoundInfoCmd},
{fn: testRoundListCmd},
{fn: testLoopResultCmd},
}
for index, testCase := range testCases {
err := testCase.fn(t, jrpcClient)
if err == nil {
continue
}
assert.NotEqualf(t, err, types.ErrActionNotSupport, "test index %d", index)
if strings.Contains(err.Error(), "rpc: can't find") {
assert.FailNowf(t, err.Error(), "test index %d", index)
}
}
}
func testCreateRawTxCmd(t *testing.T, jrpc *jsonclient.JSONClient) error {
params := &pty.BlackwhiteCreateTxReq{}
var res string
return jrpc.Call("blackwhite.BlackwhiteCreateTx", params, &res)
}
func testPlayRawTxCmd(t *testing.T, jrpc *jsonclient.JSONClient) error {
params := &pty.BlackwhitePlayTxReq{}
var res string
return jrpc.Call("blackwhite.BlackwhitePlayTx", params, &res)
}
func testShowRawTxCmd(t *testing.T, jrpc *jsonclient.JSONClient) error {
params := &pty.BlackwhiteShowTxReq{}
var res string
return jrpc.Call("blackwhite.BlackwhiteShowTx", params, &res)
}
func testTimeoutDoneTxCmd(t *testing.T, jrpc *jsonclient.JSONClient) error {
params := &pty.BlackwhiteTimeoutDoneTxReq{}
var res string
return jrpc.Call("blackwhite.BlackwhiteTimeoutDoneTx", params, &res)
}
func testRoundInfoCmd(t *testing.T, jrpc *jsonclient.JSONClient) error {
var rep interface{}
var params rpctypes.Query4Jrpc
req := &pty.ReqBlackwhiteRoundInfo{}
params.FuncName = pty.GetBlackwhiteRoundInfo
params.Payload = types.MustPBToJSON(req)
rep = &pty.ReplyBlackwhiteRoundInfo{}
return jrpc.Call("Chain33.Query", params, rep)
}
func testRoundListCmd(t *testing.T, jrpc *jsonclient.JSONClient) error {
var rep interface{}
var params rpctypes.Query4Jrpc
req := &pty.ReqBlackwhiteRoundList{}
params.FuncName = pty.GetBlackwhiteByStatusAndAddr
params.Payload = types.MustPBToJSON(req)
rep = &pty.ReplyBlackwhiteRoundList{}
return jrpc.Call("Chain33.Query", params, rep)
}
func testLoopResultCmd(t *testing.T, jrpc *jsonclient.JSONClient) error {
var rep interface{}
var params rpctypes.Query4Jrpc
req := &pty.ReqLoopResult{}
params.FuncName = pty.GetBlackwhiteloopResult
params.Payload = types.MustPBToJSON(req)
rep = &pty.ReplyLoopResults{}
return jrpc.Call("Chain33.Query", params, rep)
}
// 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 (
"golang.org/x/net/context"
"github.com/33cn/chain33/types"
auty "github.com/33cn/plugin/plugin/dapp/autonomy/types"
)
// Proposal Board 相关的接口
func (c *channelClient) propBoard(ctx context.Context, head *auty.ProposalBoard) (*types.UnsignTx, error) {
val := &auty.AutonomyAction{
Ty: auty.AutonomyActionPropBoard,
Value: &auty.AutonomyAction_PropBoard{PropBoard: head},
}
tx := &types.Transaction{
Payload: types.Encode(val),
}
data, err := types.FormatTxEncode(types.ExecName(auty.AutonomyX), tx)
if err != nil {
return nil, err
}
return &types.UnsignTx{Data: data}, nil
}
func (c *channelClient) revokeProposalBoard(ctx context.Context, head *auty.RevokeProposalBoard) (*types.UnsignTx, error) {
val := &auty.AutonomyAction{
Ty: auty.AutonomyActionRvkPropBoard,
Value: &auty.AutonomyAction_RvkPropBoard{RvkPropBoard: head},
}
tx := &types.Transaction{
Payload: types.Encode(val),
}
data, err := types.FormatTxEncode(types.ExecName(auty.AutonomyX), tx)
if err != nil {
return nil, err
}
return &types.UnsignTx{Data: data}, nil
}
func (c *channelClient) terminateProposalBoard(ctx context.Context, head *auty.TerminateProposalBoard) (*types.UnsignTx, error) {
val := &auty.AutonomyAction{
Ty: auty.AutonomyActionTmintPropBoard,
Value: &auty.AutonomyAction_TmintPropBoard{TmintPropBoard: head},
}
tx := &types.Transaction{
Payload: types.Encode(val),
}
data, err := types.FormatTxEncode(types.ExecName(auty.AutonomyX), tx)
if err != nil {
return nil, err
}
return &types.UnsignTx{Data: data}, 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)
}
This diff is collapsed.
This diff is collapsed.
// 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 types
// autonomy action ty
const (
AutonomyActionPropBoard = iota + 1
AutonomyActionRvkPropBoard
AutonomyActionVotePropBoard
AutonomyActionTmintPropBoard
AutonomyActionPropProject
AutonomyActionRvkPropProject
AutonomyActionVotePropProject
AutonomyActionTmintPropProject
AutonomyActionPropRule
AutonomyActionRvkPropRule
AutonomyActionVotePropRule
AutonomyActionTmintPropRule
//log for autonomy
TyLogPropBoard = 2101
TyLogRvkPropBoard = 2102
TyLogVotePropBoard = 2103
TyLogTmintPropBoard = 2104
TyLogPropProject = 2111
TyLogRvkPropProject = 2112
TyLogVotePropProject = 2113
TyLogTmintPropProject = 2114
TyLogPropRule = 2121
TyLogRvkPropRule = 2122
TyLogVotePropRule = 2123
TyLogTmintPropRule = 2124
)
const (
// Action_PropBoard Action 名字
Action_PropBoard = "propBoard"
// Action_RvkPropBoard Action 名字
Action_RvkPropBoard = "rvkPropBoard"
// Action_TmintPropBoard Action 名字
Action_TmintPropBoard = "tmintPropBoard"
// Action_PropProject Action 名字
Action_PropProject = "propProject"
// Action_RvkPropProject Action 名字
Action_RvkPropProject = "rvkPropProject"
// Action_TmintPropProject Action 名字
Action_TmintPropProject = "tmintPropProject"
// Action_PropRule Action 名字
Action_PropRule= "propRule"
// Action_RvkPropRule Action 名字
Action_RvkPropRule = "rvkPropRule"
// Action_TmintPropRule Action 名字
Action_TmintPropRule = "tmintPropRule"
)
// status
const (
AutonomyStatusProposalBoard = iota + 1
AutonomyStatusRvkPropBoard
AutonomyStatusVotePropBoard
AutonomyStatusTmintPropBoard
)
const (
// FuncNameQueryProposalBoard 查询方法名
FuncNameQueryProposalBoard = "QueryProposalBoard"
FuncNameQueryProposalProject = "QueryProposalProject"
FuncNameQueryProposalRule = "QueryProposalRule"
)
//包的名字可以通过配置文件来配置
//建议用github的组织名称,或者用户名字开头, 再加上自己的插件的名字
//如果发生重名,可以通过配置文件修改这些名字
var (
PackageName = "chain33.autonomy"
RPCName = "Chain33.Autonomy"
AutonomyX = "autonomy"
ExecerAutonomy = []byte(AutonomyX)
)
// 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 types
import "errors"
var (
// ErrVotePeriod 非投票期间
ErrVotePeriod = errors.New("ErrVotePeriod")
// ErrProposalStatus 状态错误
ErrProposalStatus = errors.New("ErrProposalStatus")
// ErrRepeatVoteAddr 重复投票地址
ErrRepeatVoteAddr = errors.New("ErrRepeatVoteAddr")
// ErrRevokePeriod 非取消提案期间
ErrRevokeProposalPeriod = errors.New("ErrRevokeProposalPeriod")
// ErrRevokeProposalPower 不能取消
ErrRevokeProposalPower = errors.New("ErrRevokeProposalPower")
// ErrRevokeProposal 不能取消
//ErrRevokeProposal = errors.New("ErrRevokeProposal")
)
// Code generated by protoc-gen-go. DO NOT EDIT.
// source: lcommon.proto
package types
import proto "github.com/golang/protobuf/proto"
import fmt "fmt"
import math "math"
// Reference imports to suppress errors if they are not otherwise used.
var _ = proto.Marshal
var _ = fmt.Errorf
var _ = math.Inf
type VotesResult struct {
// 总票数
TotalVotes int32 `protobuf:"varint,1,opt,name=totalVotes" json:"totalVotes,omitempty"`
// 赞成票
ApproveVotes int32 `protobuf:"varint,2,opt,name=approveVotes" json:"approveVotes,omitempty"`
// 反对票
OpposeVotes int32 `protobuf:"varint,3,opt,name=opposeVotes" json:"opposeVotes,omitempty"`
// 是否通过
Pass bool `protobuf:"varint,4,opt,name=pass" json:"pass,omitempty"`
}
func (m *VotesResult) Reset() { *m = VotesResult{} }
func (m *VotesResult) String() string { return proto.CompactTextString(m) }
func (*VotesResult) ProtoMessage() {}
func (*VotesResult) Descriptor() ([]byte, []int) { return fileDescriptor2, []int{0} }
func (m *VotesResult) GetTotalVotes() int32 {
if m != nil {
return m.TotalVotes
}
return 0
}
func (m *VotesResult) GetApproveVotes() int32 {
if m != nil {
return m.ApproveVotes
}
return 0
}
func (m *VotesResult) GetOpposeVotes() int32 {
if m != nil {
return m.OpposeVotes
}
return 0
}
func (m *VotesResult) GetPass() bool {
if m != nil {
return m.Pass
}
return false
}
type VotesRecord struct {
Address []string `protobuf:"bytes,1,rep,name=address" json:"address,omitempty"`
}
func (m *VotesRecord) Reset() { *m = VotesRecord{} }
func (m *VotesRecord) String() string { return proto.CompactTextString(m) }
func (*VotesRecord) ProtoMessage() {}
func (*VotesRecord) Descriptor() ([]byte, []int) { return fileDescriptor2, []int{1} }
func (m *VotesRecord) GetAddress() []string {
if m != nil {
return m.Address
}
return nil
}
func init() {
proto.RegisterType((*VotesResult)(nil), "types.VotesResult")
proto.RegisterType((*VotesRecord)(nil), "types.VotesRecord")
}
func init() { proto.RegisterFile("lcommon.proto", fileDescriptor2) }
var fileDescriptor2 = []byte{
// 161 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x54, 0x8f, 0xbd, 0xae, 0xc2, 0x30,
0x0c, 0x46, 0x95, 0xdb, 0xf6, 0x02, 0x2e, 0x2c, 0x9e, 0x3a, 0xa1, 0xaa, 0x0b, 0x99, 0x58, 0x78,
0x93, 0x0c, 0xec, 0xa1, 0xc9, 0x96, 0x62, 0x2b, 0x36, 0x48, 0x3c, 0x01, 0xaf, 0x8d, 0x08, 0x3f,
0x2a, 0x9b, 0x7d, 0x74, 0x86, 0xf3, 0xc1, 0x26, 0x8d, 0x34, 0x4d, 0x74, 0xde, 0x73, 0x26, 0x25,
0x6c, 0xf4, 0xc6, 0x51, 0x86, 0xbb, 0x81, 0xf6, 0x48, 0x1a, 0xc5, 0x45, 0xb9, 0x24, 0xc5, 0x2d,
0x80, 0x92, 0xfa, 0x54, 0x58, 0x67, 0x7a, 0x63, 0x1b, 0x37, 0x23, 0x38, 0xc0, 0xda, 0x33, 0x67,
0xba, 0xc6, 0x97, 0xf1, 0x57, 0x8c, 0x1f, 0x86, 0x3d, 0xb4, 0xc4, 0x4c, 0xf2, 0x56, 0xaa, 0xa2,
0xcc, 0x11, 0x22, 0xd4, 0xec, 0x45, 0xba, 0xba, 0x37, 0x76, 0xe9, 0xca, 0x3d, 0xec, 0xbe, 0x21,
0x23, 0xe5, 0x80, 0x1d, 0x2c, 0x7c, 0x08, 0x39, 0xca, 0xb3, 0xa2, 0xb2, 0x2b, 0xf7, 0x79, 0x4f,
0xff, 0x65, 0xc0, 0xe1, 0x11, 0x00, 0x00, 0xff, 0xff, 0x6b, 0x42, 0x8d, 0xc4, 0xd1, 0x00, 0x00,
0x00,
}
This diff is collapsed.
This diff is collapsed.
// 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 types
import (
"reflect"
log "github.com/33cn/chain33/common/log/log15"
"github.com/33cn/chain33/types"
)
var name string
var tlog = log.New("module", name)
func init() {
name = AutonomyX
types.AllowUserExec = append(types.AllowUserExec, []byte(AutonomyX))
// init executor type
types.RegistorExecutor(name, NewType())
}
//getRealExecName
func getRealExecName(paraName string) string {
return types.ExecName(paraName + AutonomyX)
}
// NewType 生成新的基础类型
func NewType() *AutonomyType {
c := &AutonomyType{}
c.SetChild(c)
return c
}
// AutonomyType 基础类型结构体
type AutonomyType struct {
types.ExecTypeBase
}
// GetName 获取执行器名称
func (a *AutonomyType) GetName() string {
return AutonomyX
}
// GetLogMap 获得日志类型列表
func (a *AutonomyType) GetLogMap() map[int64]*types.LogInfo {
return map[int64]*types.LogInfo{
TyLogPropBoard: {Ty: reflect.TypeOf(ReceiptProposalBoard{}), Name: "LogPropBoard"},
TyLogRvkPropBoard: {Ty: reflect.TypeOf(ReceiptProposalBoard{}), Name: "LogRvkPropBoard"},
TyLogVotePropBoard: {Ty: reflect.TypeOf(ReceiptProposalBoard{}), Name: "LogVotePropBoard"},
TyLogTmintPropBoard: {Ty: reflect.TypeOf(ReceiptProposalBoard{}), Name: "LogTmintPropBoard"},
TyLogPropProject: {Ty: reflect.TypeOf(ReceiptProposalProject{}), Name: "LogPropProject"},
TyLogRvkPropProject: {Ty: reflect.TypeOf(ReceiptProposalProject{}), Name: "LogRvkPropProject"},
TyLogVotePropProject: {Ty: reflect.TypeOf(ReceiptProposalProject{}), Name: "LogVotePropProject"},
TyLogTmintPropProject: {Ty: reflect.TypeOf(ReceiptProposalProject{}), Name: "LogTmintPropProject"},
TyLogPropRule: {Ty: reflect.TypeOf(ReceiptProposalRule{}), Name: "LogPropRule"},
TyLogRvkPropRule: {Ty: reflect.TypeOf(ReceiptProposalRule{}), Name: "LogRvkPropRule"},
TyLogVotePropRule: {Ty: reflect.TypeOf(ReceiptProposalRule{}), Name: "LogVotePropRule"},
TyLogTmintPropRule: {Ty: reflect.TypeOf(ReceiptProposalRule{}), Name: "LogTmintPropRule"},
}
}
// GetPayload 获得空的Unfreeze 的 Payload
func (a *AutonomyType) GetPayload() types.Message {
return &AutonomyAction{}
}
// GetTypeMap 获得Action 方法列表
func (a *AutonomyType) GetTypeMap() map[string]int32 {
return map[string]int32{
"PropBoard": AutonomyActionPropBoard,
"RvkPropBoard": AutonomyActionRvkPropBoard,
"VotePropBoard": AutonomyActionVotePropBoard,
"TmintPropBoard": AutonomyActionTmintPropBoard,
"PropProject": AutonomyActionPropProject,
"RvkPropProject": AutonomyActionRvkPropProject,
"VotePropProject": AutonomyActionVotePropProject,
"TmintPropProject": AutonomyActionTmintPropProject,
"PropRule": AutonomyActionPropRule,
"RvkPropRule": AutonomyActionRvkPropRule,
"VotePropRule": AutonomyActionVotePropRule,
"TmintPropRule": AutonomyActionTmintPropRule,
}
}
\ No newline at end of file
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