Commit 1ea44029 authored by madengji's avatar madengji Committed by vipwzw

add query

parent 6a0752f6
Title="user.p.para."
TestNet=false
CoinSymbol="para"
#symbol需要大小
CoinSymbol="PARA"
EnableParaFork=true
[crypto]
......
package main
import (
util "github.com/33cn/plugin/plugin/dapp/mix/cmd/gnark/circuit"
"github.com/consensys/gnark/encoding/gob"
"github.com/consensys/gnark/frontend"
"github.com/consensys/gnark/gadgets/hash/mimc"
......@@ -68,7 +69,7 @@ func NewAuth() *frontend.R1CS {
//通过merkle tree保证noteHash存在,即便return,auth都是null也是存在的,则可以不经过授权即可消费
// specify note hash constraint
preImage := mimc.Hash(&circuit, spendPubKey, returnPubKey, authPubKey, spendAmount, noteRandom)
merkelPathPart(&circuit, mimc, preImage)
util.MerkelPathPart(&circuit, mimc, preImage)
r1cs := circuit.ToR1CS()
......
package main
import (
util "github.com/33cn/plugin/plugin/dapp/mix/cmd/gnark/circuit"
"github.com/consensys/gnark/encoding/gob"
"github.com/consensys/gnark/frontend"
"github.com/consensys/gnark/gadgets/hash/mimc"
......@@ -86,8 +87,8 @@ func NewTransferInput() *frontend.R1CS {
preImage := mimc.Hash(&circuit, spendPubkey, calcReturnPubkey, calcAuthPubkey, spendValue, noteRandom)
circuit.MUSTBE_EQ(noteHash, preImage)
commitValuePart(&circuit, spendValue)
merkelPathPart(&circuit, mimc, preImage)
util.CommitValuePart(&circuit, spendValue)
util.MerkelPathPart(&circuit, mimc, preImage)
r1cs := circuit.ToR1CS()
......
package main
import (
util "github.com/33cn/plugin/plugin/dapp/mix/cmd/gnark/circuit"
"github.com/consensys/gnark/encoding/gob"
"github.com/consensys/gnark/frontend"
"github.com/consensys/gnark/gadgets/hash/mimc"
......@@ -53,7 +54,7 @@ func NewTransferOutput() *frontend.R1CS {
preImage := mimc.Hash(&circuit, spendPubkey, returnPubkey, authPubkey, spendValue, noteRandom)
circuit.MUSTBE_EQ(noteHash, preImage)
commitValuePart(&circuit, spendValue)
util.CommitValuePart(&circuit, spendValue)
r1cs := circuit.ToR1CS()
......
package main
package circuit
import (
"strconv"
......@@ -10,7 +10,7 @@ import (
fr_bn256 "github.com/consensys/gurvy/bn256/fr"
)
func merkelPathPart(circuit *frontend.CS, mimc mimc.MiMCGadget, noteHash *frontend.Constraint) {
func MerkelPathPart(circuit *frontend.CS, mimc mimc.MiMCGadget, noteHash *frontend.Constraint) {
var proofSet, helper, valid []*frontend.Constraint
merkleRoot := circuit.PUBLIC_INPUT("treeRootHash")
proofSet = append(proofSet, noteHash)
......@@ -25,10 +25,10 @@ func merkelPathPart(circuit *frontend.CS, mimc mimc.MiMCGadget, noteHash *fronte
valid = append(valid, circuit.SECRET_INPUT("valid"+strconv.Itoa(i)))
}
verifyMerkleProof(circuit, mimc, merkleRoot, proofSet, helper, valid)
VerifyMerkleProof(circuit, mimc, merkleRoot, proofSet, helper, valid)
}
func verifyMerkleProof(circuit *frontend.CS, h mimc.MiMCGadget, merkleRoot *frontend.Constraint, proofSet, helper, valid []*frontend.Constraint) {
func VerifyMerkleProof(circuit *frontend.CS, h mimc.MiMCGadget, merkleRoot *frontend.Constraint, proofSet, helper, valid []*frontend.Constraint) {
sum := leafSum(circuit, h, proofSet[0])
......@@ -63,7 +63,7 @@ func leafSum(circuit *frontend.CS, h mimc.MiMCGadget, data *frontend.Constraint)
return res
}
func commitValuePart(circuit *frontend.CS, spendValue *frontend.Constraint) {
func CommitValuePart(circuit *frontend.CS, spendValue *frontend.Constraint) {
//cmt=transfer_value*G + random_value*H
cmtvalueX := circuit.PUBLIC_INPUT("commitValueX")
cmtvalueY := circuit.PUBLIC_INPUT("commitValueY")
......
package main
import (
util "github.com/33cn/plugin/plugin/dapp/mix/cmd/gnark/circuit"
"github.com/consensys/gnark/encoding/gob"
"github.com/consensys/gnark/frontend"
"github.com/consensys/gnark/gadgets/hash/mimc"
......@@ -79,7 +80,7 @@ func NewWithdraw() *frontend.R1CS {
preImage := mimc.Hash(&circuit, spendPubkey, calcReturnPubkey, calcAuthPubkey, spendValue, noteRandom)
circuit.MUSTBE_EQ(noteHash, preImage)
merkelPathPart(&circuit, mimc, preImage)
util.MerkelPathPart(&circuit, mimc, preImage)
r1cs := circuit.ToR1CS()
......
This diff is collapsed.
......@@ -94,11 +94,14 @@ func (a *action) Authorize(authorize *mixTy.MixAuthorizeAction) (*types.Receipt,
}
receipt := &types.Receipt{Ty: types.ExecOk}
var auths, authSpends []string
for _, in := range inputs {
r := makeReceipt(calcAuthorizeHashKey(in.AuthorizeHash), mixTy.TyLogAuthorizeSet, &mixTy.ExistValue{Data: true})
mergeReceipt(receipt, r)
r = makeReceipt(calcAuthorizeSpendHashKey(in.AuthorizeSpendHash), mixTy.TyLogAuthorizeSpendSet, &mixTy.ExistValue{Data: true})
mergeReceipt(receipt, r)
auths = append(auths, in.AuthorizeHash)
authSpends = append(authSpends, in.AuthorizeSpendHash)
}
return receipt, nil
......
......@@ -245,6 +245,8 @@ func getProveData(targetLeaf []byte, leaves [][]byte) (*mixTy.CommitTreeProve, e
}
//1. 首先在当前tree查找
//2. 如果提供了rootHash,则根据roothash+leaf查找,否则全局遍历查找
func CalcTreeProve(db dbm.KV, rootHash, leaf string) (*mixTy.CommitTreeProve, error) {
if len(leaf) <= 0 {
return nil, errors.Wrap(types.ErrInvalidParam, "leaf is null")
......
......@@ -37,9 +37,9 @@ func (a *action) Config(config *mixTy.MixConfigAction) (*types.Receipt, error) {
}
case mixTy.MixConfigType_AuthPubKey:
if config.Action == mixTy.MixConfigAct_Add {
return a.ConfigAddAuthPubKey(config.GetAuthKey())
return a.ConfigAddAuthPubKey(config.GetAuthPk())
} else {
return a.ConfigDeleteAuthPubKey(config.GetAuthKey())
return a.ConfigDeleteAuthPubKey(config.GetAuthPk())
}
}
return nil, types.ErrNotFound
......@@ -137,22 +137,22 @@ func (a *action) getAuthKeys() (*mixTy.AuthPubKeys, error) {
return &keys, nil
}
func (a *action) ConfigAddAuthPubKey(config *mixTy.AuthorizePubKey) (*types.Receipt, error) {
func (a *action) ConfigAddAuthPubKey(key string) (*types.Receipt, error) {
keys, err := a.getAuthKeys()
if isNotFound(errors.Cause(err)) {
keys := &mixTy.AuthPubKeys{}
keys.Data = append(keys.Data, config.Value)
keys.Data = append(keys.Data, key)
return makeConfigAuthKeyReceipt(keys), nil
}
if err != nil {
return nil, err
}
keys.Data = append(keys.Data, config.Value)
keys.Data = append(keys.Data, key)
return makeConfigAuthKeyReceipt(keys), nil
}
func (a *action) ConfigDeleteAuthPubKey(config *mixTy.AuthorizePubKey) (*types.Receipt, error) {
func (a *action) ConfigDeleteAuthPubKey(key string) (*types.Receipt, error) {
keys, err := a.getAuthKeys()
if err != nil {
return nil, err
......@@ -160,7 +160,7 @@ func (a *action) ConfigDeleteAuthPubKey(config *mixTy.AuthorizePubKey) (*types.R
var newKeys mixTy.AuthPubKeys
for _, v := range keys.Data {
if config.Value == v {
if key == v {
continue
}
newKeys.Data = append(newKeys.Data, v)
......
......@@ -50,27 +50,27 @@ func (a *action) zkProofVerify(proof *mixTy.ZkProofInfo, verifyTy mixTy.VerifyTy
return nil
}
func (a *action) depositVerify(proof *mixTy.ZkProofInfo) ([]byte, uint64, error) {
func (a *action) depositVerify(proof *mixTy.ZkProofInfo) (string, uint64, error) {
var input mixTy.DepositPublicInput
data, err := hex.DecodeString(proof.PublicInput)
if err != nil {
return nil, 0, errors.Wrapf(err, "decode string=%s", proof.PublicInput)
return "", 0, errors.Wrapf(err, "decode string=%s", proof.PublicInput)
}
err = json.Unmarshal(data, &input)
if err != nil {
return nil, 0, errors.Wrapf(err, "unmarshal string=%s", proof.PublicInput)
return "", 0, errors.Wrapf(err, "unmarshal string=%s", proof.PublicInput)
}
val, err := strconv.ParseUint(input.Amount, 10, 64)
if err != nil {
return nil, 0, errors.Wrapf(err, "parseUint=%s", input.Amount)
return "", 0, errors.Wrapf(err, "parseUint=%s", input.Amount)
}
err = a.zkProofVerify(proof, mixTy.VerifyType_DEPOSIT)
if err != nil {
return nil, 0, err
return "", 0, err
}
return transferFr2Bytes(input.NoteHash), val, nil
return input.NoteHash, val, nil
}
......@@ -83,7 +83,7 @@ func (a *action) depositVerify(proof *mixTy.ZkProofInfo) ([]byte, uint64, error)
func (a *action) Deposit(deposit *mixTy.MixDepositAction) (*types.Receipt, error) {
//1. zk-proof校验
var sum uint64
var commitHashs [][]byte
var commitHashs []string
for _, v := range deposit.NewCommits {
hash, val, err := a.depositVerify(v)
if err != nil {
......@@ -112,7 +112,7 @@ func (a *action) Deposit(deposit *mixTy.MixDepositAction) (*types.Receipt, error
//push new commit to merkle tree
var leaves [][]byte
for _, h := range commitHashs {
leaves = append(leaves, h)
leaves = append(leaves, transferFr2Bytes(h))
}
rpt, err := pushTree(a.db, leaves)
if err != nil {
......
......@@ -6,29 +6,30 @@ package executor
import (
"github.com/33cn/chain33/types"
mixTy "github.com/33cn/plugin/plugin/dapp/mix/types"
)
//ExecLocal_Config asset withdraw local db process
func (m *Mix) ExecDelLocal_Config(payload *types.AssetsWithdraw, tx *types.Transaction, receiptData *types.ReceiptData, index int) (*types.LocalDBSet, error) {
func (m *Mix) ExecDelLocal_Config(payload *mixTy.MixConfigAction, tx *types.Transaction, receiptData *types.ReceiptData, index int) (*types.LocalDBSet, error) {
return nil, nil
}
//ExecLocal_Deposit asset withdraw local db process
func (m *Mix) ExecDelLocal_Deposit(payload *types.AssetsWithdraw, tx *types.Transaction, receiptData *types.ReceiptData, index int) (*types.LocalDBSet, error) {
return nil, nil
func (m *Mix) ExecDelLocal_Deposit(payload *mixTy.MixDepositAction, tx *types.Transaction, receiptData *types.ReceiptData, index int) (*types.LocalDBSet, error) {
return m.execAutoDelLocal(tx, receiptData)
}
//ExecLocal_Withdraw asset withdraw local db process
func (m *Mix) ExecDelLocal_Withdraw(payload *types.AssetsWithdraw, tx *types.Transaction, receiptData *types.ReceiptData, index int) (*types.LocalDBSet, error) {
return nil, nil
func (m *Mix) ExecDelLocal_Withdraw(payload *mixTy.MixWithdrawAction, tx *types.Transaction, receiptData *types.ReceiptData, index int) (*types.LocalDBSet, error) {
return m.execAutoDelLocal(tx, receiptData)
}
// ExecLocal_Transfer asset transfer local db process
func (m *Mix) ExecDelLocal_Transfer(payload *types.AssetsTransfer, tx *types.Transaction, receiptData *types.ReceiptData, index int) (*types.LocalDBSet, error) {
return nil, nil
func (m *Mix) ExecDelLocal_Transfer(payload *mixTy.MixTransferAction, tx *types.Transaction, receiptData *types.ReceiptData, index int) (*types.LocalDBSet, error) {
return m.execAutoDelLocal(tx, receiptData)
}
//ExecLocal_Authorize asset withdraw local db process
func (m *Mix) ExecDelLocal_Authorize(payload *types.AssetsWithdraw, tx *types.Transaction, receiptData *types.ReceiptData, index int) (*types.LocalDBSet, error) {
return nil, nil
func (m *Mix) ExecDelLocal_Authorize(payload *mixTy.MixAuthorizeAction, tx *types.Transaction, receiptData *types.ReceiptData, index int) (*types.LocalDBSet, error) {
return m.execAutoDelLocal(tx, receiptData)
}
......@@ -6,29 +6,31 @@ package executor
import (
"github.com/33cn/chain33/types"
mixTy "github.com/33cn/plugin/plugin/dapp/mix/types"
)
//ExecLocal_Config asset withdraw local db process
func (m *Mix) ExecLocal_Config(payload *types.AssetsWithdraw, tx *types.Transaction, receiptData *types.ReceiptData, index int) (*types.LocalDBSet, error) {
func (m *Mix) ExecLocal_Config(payload *mixTy.MixConfigAction, tx *types.Transaction, receiptData *types.ReceiptData, index int) (*types.LocalDBSet, error) {
return nil, nil
}
//ExecLocal_Deposit asset withdraw local db process
func (m *Mix) ExecLocal_Deposit(payload *types.AssetsWithdraw, tx *types.Transaction, receiptData *types.ReceiptData, index int) (*types.LocalDBSet, error) {
return nil, nil
func (m *Mix) ExecLocal_Deposit(payload *mixTy.MixDepositAction, tx *types.Transaction, receiptData *types.ReceiptData, index int) (*types.LocalDBSet, error) {
return m.execAutoLocalMix(tx, receiptData, index)
}
//ExecLocal_Withdraw asset withdraw local db process
func (m *Mix) ExecLocal_Withdraw(payload *types.AssetsWithdraw, tx *types.Transaction, receiptData *types.ReceiptData, index int) (*types.LocalDBSet, error) {
return nil, nil
func (m *Mix) ExecLocal_Withdraw(payload *mixTy.MixWithdrawAction, tx *types.Transaction, receiptData *types.ReceiptData, index int) (*types.LocalDBSet, error) {
return m.execAutoLocalMix(tx, receiptData, index)
}
// ExecLocal_Transfer asset transfer local db process
func (m *Mix) ExecLocal_Transfer(payload *types.AssetsTransfer, tx *types.Transaction, receiptData *types.ReceiptData, index int) (*types.LocalDBSet, error) {
return nil, nil
func (m *Mix) ExecLocal_Transfer(payload *mixTy.MixTransferAction, tx *types.Transaction, receiptData *types.ReceiptData, index int) (*types.LocalDBSet, error) {
return m.execAutoLocalMix(tx, receiptData, index)
}
//ExecLocal_Authorize asset withdraw local db process
func (m *Mix) ExecLocal_Authorize(payload *types.AssetsWithdraw, tx *types.Transaction, receiptData *types.ReceiptData, index int) (*types.LocalDBSet, error) {
return nil, nil
func (m *Mix) ExecLocal_Authorize(payload *mixTy.MixAuthorizeAction, tx *types.Transaction, receiptData *types.ReceiptData, index int) (*types.LocalDBSet, error) {
return m.execAutoLocalMix(tx, receiptData, index)
}
......@@ -18,9 +18,6 @@ var (
authorizeHash string
authorizeSpendHash string
nullifierHash string
localTx string
localTitle string
)
func setPrefix() {
......
// 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/common"
"github.com/33cn/chain33/types"
mixTy "github.com/33cn/plugin/plugin/dapp/mix/types"
)
func (e *Mix) execAutoLocalMix(tx *types.Transaction, receiptData *types.ReceiptData, index int) (*types.LocalDBSet, error) {
if receiptData.Ty != types.ExecOk {
return nil, types.ErrInvalidParam
}
set, err := e.execLocalMix(tx, receiptData, index)
if err != nil {
return set, err
}
dbSet := &types.LocalDBSet{}
dbSet.KV = e.AddRollbackKV(tx, tx.Execer, set.KV)
return dbSet, nil
}
func (e *Mix) execLocalMix(tx *types.Transaction, receiptData *types.ReceiptData, index int) (*types.LocalDBSet, error) {
table := NewMixTxTable(e.GetLocalDB())
r := &mixTy.LocalMixTx{
Hash: tx.Hash(),
Height: e.GetHeight(),
Index: int64(index),
}
err := table.Add(r)
if err != nil {
return nil, err
}
kvs, err := table.Save()
if err != nil {
return nil, err
}
dbSet := &types.LocalDBSet{}
dbSet.KV = append(dbSet.KV, kvs...)
return dbSet, nil
}
func (e *Mix) execAutoDelLocal(tx *types.Transaction, receiptData *types.ReceiptData) (*types.LocalDBSet, error) {
kvs, err := e.DelRollbackKV(tx, tx.Execer)
if err != nil {
return nil, err
}
dbSet := &types.LocalDBSet{}
dbSet.KV = append(dbSet.KV, kvs...)
return dbSet, nil
}
func (e *Mix) listMixInfos(req *mixTy.MixTxListReq) (types.Message, error) {
if req == nil {
return nil, types.ErrInvalidParam
}
localDb := e.GetLocalDB()
query := NewMixTxTable(localDb).GetQuery(localDb)
var primary []byte
if len(req.TxIndex) > 0 {
primary = []byte(req.TxIndex)
}
indexName := "height"
info := &mixTy.LocalMixTx{Height: req.Height, Index: req.Index}
if len(req.Hash) > 0 {
hash, err := common.FromHex(req.Hash)
if err != nil {
mlog.Error("listMixInfos fromHex", "hash", req.Hash, "err", err)
return nil, err
}
info.Hash = hash
indexName = "hash"
}
cur := &MixTxRow{}
cur.SetPayload(info)
prefix, err := cur.Get(indexName)
if err != nil {
mlog.Error("listMixInfos Get", "indexName", indexName, "err", err)
return nil, err
}
rows, err := query.ListIndex(indexName, prefix, primary, req.Count, req.Direction)
if err != nil {
mlog.Error("listMixInfos query failed", "indexName", indexName, "prefix", prefix, "key", string(primary), "err", err)
return nil, err
}
if len(rows) == 0 {
return nil, types.ErrNotFound
}
var rep mixTy.MixTxListResp
for _, row := range rows {
r, ok := row.Data.(*mixTy.LocalMixTx)
if !ok {
mlog.Error("listMixInfos", "err", "bad row type")
return nil, types.ErrDecode
}
rep.Txs = append(rep.Txs, r)
}
return &rep, nil
}
package executor
import (
"fmt"
"github.com/33cn/chain33/system/dapp"
"github.com/33cn/chain33/common/db"
"github.com/33cn/chain33/common/db/table"
"github.com/33cn/chain33/types"
mix "github.com/33cn/plugin/plugin/dapp/mix/types"
)
/*
table struct
data: self consens stage
index: status
*/
var txBoardOpt = &table.Option{
Prefix: "LODB-mixcoin",
Name: "tx",
Primary: "txIndex",
Index: []string{"height", "hash"},
}
//NewStageTable 新建表
func NewMixTxTable(kvdb db.KV) *table.Table {
rowmeta := NewMixTxRow()
table, err := table.NewTable(rowmeta, kvdb, txBoardOpt)
if err != nil {
panic(err)
}
return table
}
//MixRow table meta 结构
type MixTxRow struct {
*mix.LocalMixTx
}
//NewMixTxRow 新建一个meta 结构
func NewMixTxRow() *MixTxRow {
return &MixTxRow{LocalMixTx: &mix.LocalMixTx{}}
}
//CreateRow 新建数据行(注意index 数据一定也要保存到数据中,不能就保存heightindex)
func (r *MixTxRow) CreateRow() *table.Row {
return &table.Row{Data: &mix.LocalMixTx{}}
}
//SetPayload 设置数据
func (r *MixTxRow) SetPayload(data types.Message) error {
if d, ok := data.(*mix.LocalMixTx); ok {
r.LocalMixTx = d
return nil
}
return types.ErrTypeAsset
}
//Get 按照indexName 查询 indexValue
func (r *MixTxRow) Get(key string) ([]byte, error) {
switch key {
case "txIndex":
return []byte(dapp.HeightIndexStr(r.Height, r.Index)), nil
case "height":
return []byte(fmt.Sprintf("%022d", r.Height)), nil
case "hash":
return r.Hash, nil
default:
return nil, types.ErrNotFound
}
}
......@@ -11,9 +11,52 @@ import (
)
// Query_GetTitle query paracross title
func (m *Mix) Query_GetTreePath(in *mixTy.TreePathReq) (types.Message, error) {
func (m *Mix) Query_GetTreePath(in *mixTy.TreeInfoReq) (types.Message, error) {
if in == nil {
return nil, types.ErrInvalidParam
}
return CalcTreeProve(m.GetStateDB(), in.RootHash, in.LeafHash)
}
// Query_GetTreeList query paracross title
func (m *Mix) Query_GetLeavesList(in *mixTy.TreeInfoReq) (types.Message, error) {
if in == nil {
return nil, types.ErrInvalidParam
}
var leaves *mixTy.CommitTreeLeaves
var err error
if len(in.RootHash) > 0 {
leaves, err = getCommitLeaves(m.GetStateDB(), calcCommitTreeRootLeaves(in.RootHash))
} else {
leaves, err = getCommitLeaves(m.GetStateDB(), calcCurrentCommitLeavesKey())
}
if err != nil {
return nil, err
}
var resp mixTy.TreeListResp
for _, k := range leaves.Data {
resp.Datas = append(resp.Datas, transferFr2String(k))
}
return &resp, nil
}
// Query_GetRootList query title
func (m *Mix) Query_GetRootList(in *types.ReqNil) (types.Message, error) {
roots, err := getArchiveCommitRoots(m.GetStateDB())
if err != nil {
return nil, err
}
var resp mixTy.TreeListResp
for _, k := range roots.Data {
resp.Datas = append(resp.Datas, transferFr2String(k))
}
return &resp, nil
}
// Query_ListMixTxs 批量查询
func (m *Mix) Query_ListMixTxs(in *mixTy.MixTxListReq) (types.Message, error) {
return m.listMixInfos(in)
}
......@@ -74,15 +74,15 @@ func verifyCommitValues(inputs []*mixTy.TransferInputPublicInput, outputs []*mix
var inputPoints, outputPoints []*twistededwards.Point
for _, in := range inputs {
var p twistededwards.Point
p.X.SetString(in.CommitValueX)
p.Y.SetString(in.CommitValueY)
p.X.SetString(in.AmountX)
p.Y.SetString(in.AmountY)
inputPoints = append(inputPoints, &p)
}
for _, out := range outputs {
var p twistededwards.Point
p.X.SetString(out.CommitValueX)
p.Y.SetString(out.CommitValueY)
p.X.SetString(out.AmountX)
p.Y.SetString(out.AmountY)
outputPoints = append(outputPoints, &p)
}
......@@ -130,7 +130,6 @@ func (a *action) Transfer(transfer *mixTy.MixTransferAction) (*types.Receipt, er
}
receipt := &types.Receipt{Ty: types.ExecOk}
//set nullifier
for _, k := range inputs {
r := makeNullifierSetReceipt(k.NullifierHash, &mixTy.ExistValue{Data: true})
mergeReceipt(receipt, r)
......
......@@ -113,6 +113,5 @@ func (a *action) Withdraw(withdraw *mixTy.MixWithdrawAction) (*types.Receipt, er
r := makeNullifierSetReceipt(k, &mixTy.ExistValue{Data: true})
mergeReceipt(receipt, r)
}
return receipt, nil
}
......@@ -6,11 +6,11 @@ package paracross
import (
"github.com/33cn/chain33/pluginmgr"
"github.com/33cn/plugin/plugin/dapp/mix/commands"
"github.com/33cn/plugin/plugin/dapp/mix/executor"
"github.com/33cn/plugin/plugin/dapp/mix/rpc"
"github.com/33cn/plugin/plugin/dapp/mix/types"
_ "github.com/33cn/plugin/plugin/dapp/paracross/wallet" // register wallet package
_ "github.com/33cn/plugin/plugin/dapp/mix/wallet" // register wallet package
)
func init() {
......@@ -18,6 +18,7 @@ func init() {
Name: types.MixX,
ExecName: executor.GetName(),
Exec: executor.Init,
Cmd: commands.ParcCmd,
Cmd: commands.MixCmd,
RPC: rpc.Init,
})
}
......@@ -3,6 +3,9 @@ syntax = "proto3";
package types;
import "common.proto";
import "transaction.proto";
//区分不同的验证电路
enum VerifyType{
DEPOSIT = 0;
......@@ -36,7 +39,10 @@ message AuthPubKeys{
enum MixConfigType{
VerifyKey = 0;
//register unify authorize pubkey
AuthPubKey = 1;
//for spender's pay pubkey register,DH secret
PaymentPubKey = 2;
}
enum MixConfigAct{
......@@ -45,23 +51,36 @@ enum MixConfigAct{
}
message AuthorizePubKey {
string value = 3;
}
//config verify parameter for proof
//当前authPk=mimc_hash(prikey),没有X,Y值
message MixConfigAction {
MixConfigType Ty = 1;
MixConfigAct Action = 2;
oneof value {
ZkVerifyKey verifyKey = 3;
AuthorizePubKey authKey = 4;
ZkVerifyKey verifyKey = 3;
string authPk = 4;
PubKey paymentPk = 5;
}
}
//DH one time pubkey with secret
message DHSecret{
PubKey epk = 1;
string secret = 3;
}
//Diff-Helman 加密group, for spender, returner, authorizer to decrypt
message DHSecretGroup{
DHSecret spender = 1;
DHSecret returner = 2;
DHSecret authorize = 3;
}
message ZkProofInfo {
string proof = 1;
string publicInput = 2;
DHSecretGroup group = 3;
}
message MixDepositAction {
......@@ -101,6 +120,7 @@ message MixAction {
}
message DepositPublicInput {
string noteHash = 1;
string amount = 2;
......@@ -115,19 +135,26 @@ message WithdrawPublicInput {
}
//加密了的input/output amount
message commitAmount{
string X = 1;
string Y = 2;
}
message TransferInputPublicInput {
string treeRootHash = 1;
string commitValueX = 2;
string commitValueY = 3;
string amountX = 2;
string amountY = 3;
string authorizeSpendHash = 4;
string nullifierHash = 5;
}
message TransferOutputPublicInput {
string noteHash = 1;
string commitValueX = 2;
string commitValueY = 3;
string amountX = 2;
string amountY = 3;
DHSecretGroup dhSecrets = 4;
}
message AuthorizePublicInput {
......@@ -138,6 +165,7 @@ message AuthorizePublicInput {
}
//nullifer 存在value
message ExistValue {
bool data = 1;
}
......@@ -159,11 +187,176 @@ message CommitTreeProve {
string helpers = 5;
}
message TreePathReq{
message TreeInfoReq{
string rootHash = 1;
string leafHash = 2;
}
message TreeListResp{
repeated string datas = 1;
}
// mix wallet part
// payKey = hash(spendKey) for zk-snark note spend
// 用在note内部的payment key
message PaymentKeyPair {
string payKey = 1;
string spendKey = 2;
}
// pub = priv*G for diff-helman crypto
// out: take spender's tempPrikey*pubkey as password, tempPubkey show in note
// spender: take self prikey*tempPubkey as password to decode
message PubKey {
string X = 1;
string Y = 2;
}
message PrivKey{
string data = 1;
}
message ShareSecretKeyPair {
PrivKey privKey = 1;
PubKey receivingPk = 2;
}
//spend pair for note proof
//crypt pair for DH crypt/decrypt
message AccountPrivacyKey {
PaymentKeyPair paymentKey = 1;
ShareSecretKeyPair shareSecretKey = 2;
}
message WalletAddrPrivacy {
AccountPrivacyKey privacy = 1;
string addr = 2;
}
message SecretData{
string paymentPubKey = 1;
string returnPubKey = 2;
string authorizePubKey = 3;
string amount = 4;
string noteRandom = 5;
}
message EncodedSecretData{
string encoded = 1;
SecretData rawData = 2;
}
message EncryptSecretData{
string secret = 1;
PubKey receivingPk = 2;
}
message DecryptSecretData{
string secret = 1;
PrivKey receivingPriKey = 2;
PubKey epk = 3;
}
enum NoteStatus{
UNDEF = 0;
FROZEN = 1; //未授权
OPEN = 2; //已授权可使用
CLOSE = 3; //已使用
}
message WalletIndexInfo {
string noteHash = 1;
string nullifier = 2;
string authSpendHash = 3;
string spender = 4;
string account = 5; //账户地址
NoteStatus status = 6;
SecretData note = 7;
}
message WalletDbMixInfo {
WalletIndexInfo info = 1;
string txIndex = 2;
}
message WalletMixIndexReq {
string noteHash = 1;
string nullifier = 2;
string authSpendHash = 3;
string spender = 4;
string account = 5;
int32 status = 6;
int32 count = 7;
int32 direction = 8;
}
message WalletIndexResp {
repeated WalletIndexInfo datas = 1;
}
message WalletReqAddrs{
repeated string data = 1;
}
message WalletEnablePrivacyRst{
string addr = 1;
bool isOK = 2;
string msg = 3;
}
message WalletEnablePrivacyResp{
repeated WalletEnablePrivacyRst data = 1;
}
enum MixWalletRescanStatus{
IDLE = 0;
SCANNING = 1;
FINISHED = 2;
}
///////localdb index query
message LocalMixTx {
bytes hash = 1;
int64 height = 2;
int64 index = 3;
}
message MixTxListReq{
string txIndex = 1; //primary direct query
string hash = 2;
int64 height = 3;
int64 index = 4;
int32 count =5;
int32 direction = 6;
}
message MixTxListResp{
repeated LocalMixTx txs = 1;
}
message PrivacyAddrResult{
string addr = 1;
bool isOK = 2;
string msg = 3;
}
message ReqEnablePrivacyRst{
repeated PrivacyAddrResult results = 1;
}
service mixPrivacy {
// 扫描UTXO以及获取扫描UTXO后的状态
rpc GetRescanStatus(ReqNil) returns (ReqString) {}
// 使能隐私账户
rpc RescanNotes(ReqNil) returns (ReqString) {}
// 创建隐私交易
rpc EnablePrivacy(ReqAddrs) returns (ReqEnablePrivacyRst) {}
}
\ 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 (
"encoding/json"
"github.com/33cn/chain33/types"
mixTy "github.com/33cn/plugin/plugin/dapp/mix/types"
"golang.org/x/net/context"
)
// 显示指定地址的公钥对信息,可以作为后续交易参数
//func (g *channelClient) ShowPrivacyKey(ctx context.Context, in *types.ReqString) (*mixTy.AccountPrivacyKey, error) {
// data, err := g.ExecWalletFunc(mixTy.MixX, "ShowPrivacyKey", in)
// if err != nil {
// return nil, err
// }
// return data.(*mixTy.AccountPrivacyKey), nil
//}
func (g *channelClient) GetRescanStatus(ctx context.Context, in *types.ReqNil) (*types.ReqString, error) {
log.Info("GetRescanStatus in")
data, err := g.ExecWalletFunc(mixTy.MixX, "GetRescanStatus", in)
if err != nil {
return nil, err
}
return data.(*types.ReqString), nil
}
//
//// 扫描UTXO以及获取扫描UTXO后的状态
func (g *channelClient) RescanNotes(ctx context.Context, in *types.ReqNil) (*types.ReqString, error) {
log.Info("RescanNotes in")
data, err := g.ExecWalletFunc(mixTy.MixX, "RescanNotes", in)
if err != nil {
return nil, err
}
return data.(*types.ReqString), nil
}
// 使能隐私账户
func (g *channelClient) EnablePrivacy(ctx context.Context, in *types.ReqAddrs) (*mixTy.ReqEnablePrivacyRst, error) {
data, err := g.ExecWalletFunc(mixTy.MixX, "EnablePrivacy", in)
if err != nil {
return nil, err
}
return data.(*mixTy.ReqEnablePrivacyRst), nil
}
// ShowPrivacyAccountInfo display privacy account information for json rpc
func (c *Jrpc) ShowAccountPrivacyInfo(in *types.ReqString, result *json.RawMessage) error {
log.Info("ShowAccountPrivacyInfo jrpc in")
reply, err := c.cli.ExecWalletFunc(mixTy.MixX, "ShowAccountPrivacyInfo", in)
if err != nil {
return err
}
*result, err = types.PBToJSON(reply)
return err
}
/////////////////privacy///////////////
// ShowPrivacyAccountSpend display spend privacy account for json rpc
func (c *Jrpc) ShowAccountNoteInfo(in *types.ReqAddrs, result *json.RawMessage) error {
if 0 == len(in.Addrs) {
return types.ErrInvalidParam
}
reply, err := c.cli.ExecWalletFunc(mixTy.MixX, "ShowAccountNoteInfo", in)
if err != nil {
log.Info("ShowPrivacyAccountSpend", "return err info", err)
return err
}
*result, err = types.PBToJSON(reply)
return err
}
func (c *Jrpc) GetRescanStatus(in *types.ReqNil, result *json.RawMessage) error {
reply, err := c.cli.GetRescanStatus(context.Background(), in)
if err != nil {
return err
}
*result, err = types.PBToJSON(reply)
return err
}
// RescanUtxos rescan utxosl for json rpc
func (c *Jrpc) RescanNotes(in *types.ReqNil, result *json.RawMessage) error {
reply, err := c.cli.RescanNotes(context.Background(), in)
if err != nil {
return err
}
*result, err = types.PBToJSON(reply)
return err
}
// EnablePrivacy enable privacy for json rpc
func (c *Jrpc) EnablePrivacy(in *types.ReqAddrs, result *json.RawMessage) error {
reply, err := c.cli.EnablePrivacy(context.Background(), in)
if err != nil {
return err
}
*result, err = types.PBToJSON(reply)
return err
}
func (c *Jrpc) EncodeSecretData(in *mixTy.SecretData, result *json.RawMessage) error {
reply, err := c.cli.ExecWalletFunc(mixTy.MixX, "EncodeSecretData", in)
if err != nil {
return err
}
*result, err = types.PBToJSON(reply)
return err
}
func (c *Jrpc) EncryptSecretData(in *mixTy.EncryptSecretData, result *json.RawMessage) error {
reply, err := c.cli.ExecWalletFunc(mixTy.MixX, "EncryptSecretData", in)
if err != nil {
return err
}
*result, err = types.PBToJSON(reply)
return err
}
func (c *Jrpc) DecryptSecretData(in *mixTy.DecryptSecretData, result *json.RawMessage) error {
reply, err := c.cli.ExecWalletFunc(mixTy.MixX, "DecryptSecretData", in)
if err != nil {
return err
}
*result, err = types.PBToJSON(reply)
return err
}
// 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/common/log/log15"
"github.com/33cn/chain33/rpc/types"
mixTy "github.com/33cn/plugin/plugin/dapp/mix/types"
)
var log = log15.New("module", "mix.rpc")
// Jrpc json rpc class
type Jrpc struct {
cli *channelClient
}
// Grpc grpc class
type Grpc struct {
*channelClient
}
type channelClient struct {
types.ChannelClient
}
// Init init rpc server
func Init(name string, s types.RPCServer) {
cli := &channelClient{}
grpc := &Grpc{channelClient: cli}
cli.Init(name, s, &Jrpc{cli: cli}, grpc)
mixTy.RegisterMixPrivacyServer(s.GRPC(), grpc)
}
......@@ -23,4 +23,7 @@ var (
//ErrSpendInOutValueNotMatch spend input and output value not match
ErrSpendInOutValueNotMatch = errors.New("ErrSpendInOutValueNotMatch")
//ErrDecryptDataFail decrypt data fail like by wrong prikey
ErrDecryptDataFail = errors.New("ErrDecryptDataFail")
)
......@@ -15,10 +15,10 @@ const (
// 执行器的日志类型
const (
// TyLogParacrossCommit commit log key
TyLogMixDeposit = 750
TyLogMixWithdraw = 751
TyLogMixTransfer = 752
TyLogMixAuth = 753
TyLogMixLocalDeposit = 750
TyLogMixLocalNullifier = 751
TyLogMixLocalAuth = 752
TyLogMixLocalAuthSpend = 753
TyLogMixConfigVk = 754
TyLogMixConfigAuth = 755
TyLogCurrentCommitTreeLeaves = 756
......
This diff is collapsed.
......@@ -5,8 +5,12 @@
package types
import (
"encoding/hex"
"encoding/json"
"reflect"
"github.com/pkg/errors"
log "github.com/33cn/chain33/common/log/log15"
"github.com/33cn/chain33/types"
)
......@@ -84,3 +88,120 @@ func (p *MixType) GetTypeMap() map[string]int32 {
func (p *MixType) GetPayload() types.Message {
return &MixAction{}
}
//
//func DecodeDepositInput(input string) (*DepositPublicInput, error) {
// var v DepositPublicInput
// data, err := hex.DecodeString(input)
// if err != nil {
// return nil, errors.Wrapf(err, "decode string=%s", input)
// }
// err = json.Unmarshal(data, &v)
// if err != nil {
// return nil, errors.Wrapf(err, "unmarshal string=%s", input)
// }
//
// return &v, nil
//}
//
//func DecodeWithdrawInput(input string) (*WithdrawPublicInput, error) {
// var v WithdrawPublicInput
// data, err := hex.DecodeString(input)
// if err != nil {
// return nil, errors.Wrapf(err, "decode string=%s", input)
// }
// err = json.Unmarshal(data, &v)
// if err != nil {
// return nil, errors.Wrapf(err, "unmarshal string=%s", input)
// }
//
// return &v, nil
//}
//
//
//func DecodeTransferInput(input string) (*TransferInputPublicInput, error) {
// var v TransferInputPublicInput
// data, err := hex.DecodeString(input)
// if err != nil {
// return nil, errors.Wrapf(err, "decode string=%s", input)
// }
// err = json.Unmarshal(data, &v)
// if err != nil {
// return nil, errors.Wrapf(err, "unmarshal string=%s", input)
// }
//
// return &v, nil
//}
//
//func DecodeTransferOut(input string) (*TransferOutputPublicInput, error) {
// var v TransferOutputPublicInput
// data, err := hex.DecodeString(input)
// if err != nil {
// return nil, errors.Wrapf(err, "decode string=%s", input)
// }
// err = json.Unmarshal(data, &v)
// if err != nil {
// return nil, errors.Wrapf(err, "unmarshal string=%s", input)
// }
//
// return &v, nil
//}
//
//func DecodeAuthorizeInput(input string) (*AuthorizePublicInput, error) {
// var v AuthorizePublicInput
// data, err := hex.DecodeString(input)
// if err != nil {
// return nil, errors.Wrapf(err, "decode string=%s", input)
// }
// err = json.Unmarshal(data, &v)
// if err != nil {
// return nil, errors.Wrapf(err, "unmarshal string=%s", input)
// }
//
// return &v, nil
//}
func DecodePubInput(ty VerifyType, input string) (interface{}, error) {
data, err := hex.DecodeString(input)
if err != nil {
return nil, errors.Wrapf(err, "decode string=%s", input)
}
switch ty {
case VerifyType_DEPOSIT:
var v DepositPublicInput
err = json.Unmarshal(data, &v)
if err != nil {
return nil, errors.Wrapf(err, "unmarshal string=%s", input)
}
return &v, nil
case VerifyType_WITHDRAW:
var v WithdrawPublicInput
err = json.Unmarshal(data, &v)
if err != nil {
return nil, errors.Wrapf(err, "unmarshal string=%s", input)
}
return &v, nil
case VerifyType_TRANSFERINPUT:
var v TransferInputPublicInput
err = json.Unmarshal(data, &v)
if err != nil {
return nil, errors.Wrapf(err, "unmarshal string=%s", input)
}
return &v, nil
case VerifyType_TRANSFEROUTPUT:
var v TransferOutputPublicInput
err = json.Unmarshal(data, &v)
if err != nil {
return nil, errors.Wrapf(err, "unmarshal string=%s", input)
}
return &v, nil
case VerifyType_AUTHORIZE:
var v AuthorizePublicInput
err = json.Unmarshal(data, &v)
if err != nil {
return nil, errors.Wrapf(err, "unmarshal string=%s", input)
}
return &v, nil
}
return nil, types.ErrInvalidParam
}
package wallet
import (
mixtypes "github.com/33cn/plugin/plugin/dapp/mix/types"
"github.com/consensys/gurvy/bn256/fr"
"github.com/consensys/gurvy/bn256/twistededwards"
)
type curveBn256ECDH struct {
}
// NewCurve25519ECDH creates a new ECDH instance that uses djb's curve25519
// elliptical curve.
func NewCurveBn256ECDH() ECDH {
return &curveBn256ECDH{}
}
func (e *curveBn256ECDH) GenerateKey(generator []byte) (*mixtypes.PrivKey, *mixtypes.PubKey) {
var sk fr.Element
if len(generator) <= 0 {
sk.SetRandom()
} else {
sk.SetBytes(generator)
}
ed := twistededwards.GetEdwardsCurve()
var point twistededwards.Point
point.ScalarMul(&ed.Base, sk)
priv := &mixtypes.PrivKey{
Data: sk.String(),
}
pub := &mixtypes.PubKey{
X: point.X.String(),
Y: point.Y.String(),
}
return priv, pub
}
func (e *curveBn256ECDH) GenerateSharedSecret(priv *mixtypes.PrivKey, pub *mixtypes.PubKey) ([]byte, error) {
var point, pubPoint twistededwards.Point
pubPoint.X.SetString(pub.X)
pubPoint.Y.SetString(pub.Y)
var frPriv fr.Element
frPriv.SetString(priv.Data)
point.ScalarMul(&pubPoint, frPriv)
return point.X.Bytes(), nil
}
package wallet
import (
"testing"
"github.com/stretchr/testify/assert"
)
func TestGenerateSharedSecret(t *testing.T) {
bn256 := NewCurveBn256ECDH()
pri1, pub1 := bn256.GenerateKey(nil)
pri2, pub2 := bn256.GenerateKey(nil)
s1, _ := bn256.GenerateSharedSecret(pri1, pub2)
s2, _ := bn256.GenerateSharedSecret(pri2, pub1)
assert.Equal(t, s1, s2)
}
package wallet
import (
mixtypes "github.com/33cn/plugin/plugin/dapp/mix/types"
)
// The main interface for ECDH key exchange.
type ECDH interface {
GenerateKey([]byte) (*mixtypes.PrivKey, *mixtypes.PubKey)
GenerateSharedSecret(*mixtypes.PrivKey, *mixtypes.PubKey) ([]byte, error)
}
// 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 wallet
import (
"github.com/33cn/chain33/types"
mixTy "github.com/33cn/plugin/plugin/dapp/mix/types"
)
func (policy *mixPolicy) On_ShowAccountPrivacyInfo(req *types.ReqString) (types.Message, error) {
return policy.getAccountPrivacyKey(req.Data)
}
func (policy *mixPolicy) On_ShowAccountNoteInfo(req *types.ReqAddrs) (types.Message, error) {
return policy.showAccountNoteInfo(req.Addrs)
}
func (policy *mixPolicy) On_GetRescanStatus(in *types.ReqNil) (types.Message, error) {
return &types.ReqString{Data: policy.getRescanStatus()}, nil
}
//重新扫描所有notes
func (policy *mixPolicy) On_RescanNotes(in *types.ReqNil) (types.Message, error) {
err := policy.tryRescanNotes()
if err != nil {
bizlog.Error("rescanUTXOs", "err", err.Error())
}
return &types.ReqString{Data: "ok"}, err
}
func (policy *mixPolicy) On_EnablePrivacy(req *types.ReqAddrs) (types.Message, error) {
return policy.enablePrivacy(req.Addrs)
}
func (policy *mixPolicy) On_EncodeSecretData(req *mixTy.SecretData) (types.Message, error) {
return encodeSecretData(req)
}
func (policy *mixPolicy) On_EncryptSecretData(req *mixTy.EncryptSecretData) (types.Message, error) {
return encryptSecretData(req)
}
func (policy *mixPolicy) On_DecryptSecretData(req *mixTy.DecryptSecretData) (types.Message, error) {
return decryptSecretData(req)
}
// 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 wallet
import "fmt"
const (
prefix = "MixCoin-"
// PrivacyDBVersion 隐私交易运行过程中,需要使用到钱包数据库存储的数据库版本信息的KEY值
MixDBVersion = prefix + "DBVersion"
// Privacy4Addr 存储隐私交易保存账户的隐私公钥对信息的KEY值
// KEY值格式为 Privacy4Addr-账号地址
// VALUE值格式为 types.WalletAccountPrivacy, 存储隐私公钥对
Mix4Addr = prefix + "Addr"
//
MixPrivacyEnable = prefix + "PrivacyEnable"
//current rescan notes status
MixRescanStatus = prefix + "RescanStatus"
MixCommitHash = prefix + "CommitHash"
MixNullifier = prefix + "Nullifier"
)
// calcPrivacyAddrKey 获取隐私账户私钥对保存在钱包中的索引串
func calcMixAddrKey(addr string) []byte {
return []byte(fmt.Sprintf("%s-%s", Mix4Addr, addr))
}
func calcMixPrivacyEnable() []byte {
return []byte(MixPrivacyEnable)
}
func calcRescanNoteStatus() []byte {
return []byte(MixRescanStatus)
}
This diff is collapsed.
This diff is collapsed.
package wallet
import (
"encoding/hex"
"testing"
"github.com/33cn/chain33/common"
"github.com/33cn/chain33/types"
mixTy "github.com/33cn/plugin/plugin/dapp/mix/types"
"github.com/stretchr/testify/assert"
)
func TestNewPrivacyWithPrivKey(t *testing.T) {
prikey := "4257D8692EF7FE13C68B65D6A52F03933DB2FA5CE8FAF210B5B8B80C721CED01"
keyByte, err := hex.DecodeString(prikey)
assert.Equal(t, nil, err)
pairs, err := newPrivacyWithPrivKey(keyByte)
assert.Equal(t, nil, err)
t.Log("payPri", pairs.PaymentKey.SpendKey, "payPub", pairs.PaymentKey.PayKey, "crytoPub", pairs.ShareSecretKey.ReceivingPk, "crytoPri", pairs.ShareSecretKey.PrivKey.Data)
prikey2 := "1257D8692EF7FE13C68B65D6A52F03933DB2FA5CE8FAF210B5B8B80C721CED01"
keyByte2, err := hex.DecodeString(prikey2)
assert.Equal(t, nil, err)
pairs2, err := newPrivacyWithPrivKey(keyByte2)
assert.Equal(t, nil, err)
t.Log("payPri", pairs2.PaymentKey.SpendKey, "payPub", pairs2.PaymentKey.PayKey, "crytoPub", pairs2.ShareSecretKey.ReceivingPk, "crytoPri", pairs2.ShareSecretKey.PrivKey.Data)
secret1 := &mixTy.SecretData{
PaymentPubKey: "13735985067536865723202617343666111332145536963656464451727087263423649028705",
ReturnPubKey: "16067249407809359746114321133992130903102335882983385972747813693681808870497",
AuthorizePubKey: "13519883267141251871527102103999205179714486518503885909948192364772977661583",
NoteRandom: "2824204835",
Amount: "28242048",
}
//secret2 := &mixTy.CryptoData{
// SpendPubKey:"18829345085195922012068709111582461121107908772422825655963168999800303848486",
// ReturnPubKey:"16067249407809359746114321133992130903102335882983385972747813693681808870497",
// AuthorizePubKey:"13519883267141251871527102103999205179714486518503885909948192364772977661583",
// NoteRandom:"2824204835",
// Amount:"28242048",
//}
pub1, cryptData1, err := encryptData(pairs.ShareSecretKey.ReceivingPk, types.Encode(secret1))
assert.Nil(t, err)
decryData1, err := decryptData(pairs.ShareSecretKey.PrivKey, pub1, cryptData1)
assert.Nil(t, err)
var val mixTy.SecretData
err = types.Decode(decryData1, &val)
assert.Nil(t, err)
assert.Equal(t, secret1.PaymentPubKey, val.PaymentPubKey)
}
func TestEncrypt(t *testing.T) {
secret1 := &mixTy.SecretData{
PaymentPubKey: "13735985067536865723202617343666111332145536963656464451727087263423649028705",
ReturnPubKey: "16067249407809359746114321133992130903102335882983385972747813693681808870497",
AuthorizePubKey: "13519883267141251871527102103999205179714486518503885909948192364772977661583",
NoteRandom: "2824204835",
Amount: "28242048",
}
password := "1314fuzamei"
cryptData := encryptDataWithPadding([]byte(password), types.Encode(secret1))
decryptData, err := decryptDataWithPading([]byte(password), cryptData)
assert.Nil(t, err)
var raw mixTy.SecretData
err = types.Decode(decryptData, &raw)
assert.Nil(t, err)
assert.Equal(t, raw.PaymentPubKey, secret1.PaymentPubKey)
}
func TestEncodeSecretData(t *testing.T) {
secret := &mixTy.SecretData{
PaymentPubKey: "13735985067536865723202617343666111332145536963656464451727087263423649028705",
ReturnPubKey: "16067249407809359746114321133992130903102335882983385972747813693681808870497",
AuthorizePubKey: "13519883267141251871527102103999205179714486518503885909948192364772977661583",
Amount: "28242048",
}
ret, err := encodeSecretData(secret)
assert.Nil(t, err)
t.Log(ret)
//test encryp data
prikey := "4257D8692EF7FE13C68B65D6A52F03933DB2FA5CE8FAF210B5B8B80C721CED01"
keyByte, err := hex.DecodeString(prikey)
assert.Equal(t, nil, err)
privacy, err := newPrivacyWithPrivKey(keyByte)
assert.Equal(t, nil, err)
req := &mixTy.EncryptSecretData{ReceivingPk: privacy.ShareSecretKey.ReceivingPk, Secret: ret.Encode}
dhSecret, err := encryptSecretData(req)
assert.Nil(t, err)
t.Log(dhSecret)
data, err := common.FromHex(dhSecret.Secret)
assert.Nil(t, err)
rawData, err := decryptData(privacy.ShareSecretKey.PrivKey, dhSecret.Epk, data)
assert.Nil(t, err)
var rawSecret mixTy.SecretData
types.Decode(rawData, &rawSecret)
assert.Equal(t, rawSecret.PaymentPubKey, secret.PaymentPubKey)
}
// Copyright Fuzamei Corp. 2018 All Rights Reserved.
// Use of policy source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package wallet
import (
"sync"
"github.com/33cn/chain33/common/crypto"
"github.com/33cn/chain33/common/db"
"github.com/33cn/chain33/common/log/log15"
"github.com/33cn/chain33/types"
wcom "github.com/33cn/chain33/wallet/common"
mixTy "github.com/33cn/plugin/plugin/dapp/mix/types"
)
var (
bizlog = log15.New("module", "wallet.mix")
// MaxTxHashsPerTime 单词处理的最大哈希书
MaxTxHashsPerTime int64 = 100
// maxTxNumPerBlock 单个区块最大数
maxTxNumPerBlock int64 = types.MaxTxsPerBlock
)
func init() {
wcom.RegisterPolicy(mixTy.MixX, New())
}
// New 创建一盒钱包业务策略
func New() wcom.WalletBizPolicy {
return &mixPolicy{
mtx: &sync.Mutex{},
rescanwg: &sync.WaitGroup{},
}
}
type mixPolicy struct {
mtx *sync.Mutex
store *mixStore
walletOperate wcom.WalletOperate
rescanwg *sync.WaitGroup
}
func (policy *mixPolicy) setWalletOperate(walletBiz wcom.WalletOperate) {
policy.mtx.Lock()
defer policy.mtx.Unlock()
policy.walletOperate = walletBiz
}
func (policy *mixPolicy) getWalletOperate() wcom.WalletOperate {
policy.mtx.Lock()
defer policy.mtx.Unlock()
return policy.walletOperate
}
// Init 初始化处理
func (policy *mixPolicy) Init(walletOperate wcom.WalletOperate, sub []byte) {
policy.setWalletOperate(walletOperate)
policy.store = newStore(walletOperate.GetDBStore())
}
// OnCreateNewAccount 在账号创建时做一些处理
func (policy *mixPolicy) OnCreateNewAccount(acc *types.Account) {
}
// OnImportPrivateKey 在私钥导入时做一些处理
func (policy *mixPolicy) OnImportPrivateKey(acc *types.Account) {
}
// OnAddBlockFinish 在区块被添加成功时做一些处理
func (policy *mixPolicy) OnAddBlockFinish(block *types.BlockDetail) {
}
// OnDeleteBlockFinish 在区块被删除成功时做一些处理
func (policy *mixPolicy) OnDeleteBlockFinish(block *types.BlockDetail) {
}
// OnClose 在钱包关闭时做一些处理
func (policy *mixPolicy) OnClose() {
}
// OnSetQueueClient 在钱包消息队列初始化时做一些处理
func (policy *mixPolicy) OnSetQueueClient() {
}
// OnWalletLocked 在钱包加锁时做一些处理
func (policy *mixPolicy) OnWalletLocked() {
}
// OnWalletUnlocked 在钱包解锁时做一些处理
func (policy *mixPolicy) OnWalletUnlocked(WalletUnLock *types.WalletUnLock) {
}
// OnAddBlockTx 响应区块交易添加的处理
func (policy *mixPolicy) OnAddBlockTx(block *types.BlockDetail, tx *types.Transaction, index int32, dbBatch db.Batch) *types.WalletTxDetail {
dbSet, err := policy.execAutoLocalMix(tx, block.Receipts[index], int(index), block.Block.Height)
if err != nil {
return nil
}
for _, kv := range dbSet.KV {
dbBatch.Set(kv.Key, kv.Value)
}
// 自己处理掉所有事务,部需要外部处理了
return nil
}
// OnDeleteBlockTx 响应删除区块交易的处理
func (policy *mixPolicy) OnDeleteBlockTx(block *types.BlockDetail, tx *types.Transaction, index int32, dbBatch db.Batch) *types.WalletTxDetail {
dbSet, err := policy.execAutoDelLocal(tx)
if err != nil {
return nil
}
for _, kv := range dbSet.KV {
dbBatch.Set(kv.Key, kv.Value)
}
return nil
}
// Call 调用隐私的方法
func (policy *mixPolicy) Call(funName string, in types.Message) (ret types.Message, err error) {
switch funName {
case "GetScanFlag":
isok := policy.store.getRescanNoteStatus() == int32(mixTy.MixWalletRescanStatus_SCANNING)
ret = &types.Reply{IsOk: isok}
default:
err = types.ErrNotSupport
}
return
}
// SignTransaction 对隐私交易进行签名
func (policy *mixPolicy) SignTransaction(key crypto.PrivKey, req *types.ReqSignRawTx) (needSysSign bool, signtxhex string, err error) {
return false, "", types.ErrNotSupport
}
package wallet
import (
"fmt"
"github.com/33cn/chain33/common/db"
"github.com/33cn/chain33/common/db/table"
"github.com/33cn/chain33/types"
mix "github.com/33cn/plugin/plugin/dapp/mix/types"
)
/*
table struct
data: self consens stage
index: status
*/
var boardOpt = &table.Option{
Prefix: "LODB-mixcoin",
Name: "wallet",
Primary: "heightindex",
Index: []string{
"noteHash",
"nullifier",
"authSpendHash",
"spender",
"account",
"status"},
}
//NewStageTable 新建表
func NewMixTable(kvdb db.KV) *table.Table {
rowmeta := NewMixRow()
table, err := table.NewTable(rowmeta, kvdb, boardOpt)
if err != nil {
panic(err)
}
return table
}
//MixRow table meta 结构
type MixRow struct {
*mix.WalletDbMixInfo
}
//NewStageRow 新建一个meta 结构
func NewMixRow() *MixRow {
return &MixRow{WalletDbMixInfo: &mix.WalletDbMixInfo{}}
}
//CreateRow 新建数据行(注意index 数据一定也要保存到数据中,不能就保存heightindex)
func (r *MixRow) CreateRow() *table.Row {
return &table.Row{Data: &mix.WalletDbMixInfo{}}
}
//SetPayload 设置数据
func (r *MixRow) SetPayload(data types.Message) error {
if d, ok := data.(*mix.WalletDbMixInfo); ok {
r.WalletDbMixInfo = d
return nil
}
return types.ErrTypeAsset
}
//Get 按照indexName 查询 indexValue
func (r *MixRow) Get(key string) ([]byte, error) {
switch key {
case "heightindex":
return []byte(r.TxIndex), nil
case "noteHash":
return []byte(r.Info.NoteHash), nil
case "authSpendHash":
return []byte(r.Info.AuthSpendHash), nil
case "spender":
return []byte(r.Info.Spender), nil
case "account":
return []byte(r.Info.Account), nil
case "status":
return []byte(fmt.Sprintf("%2d", r.Info.Status)), nil
default:
return nil, types.ErrNotFound
}
}
// 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 wallet
import (
"github.com/33cn/chain33/common/db"
system "github.com/33cn/chain33/system/dapp"
"github.com/33cn/chain33/types"
wcom "github.com/33cn/chain33/wallet/common"
mixTy "github.com/33cn/plugin/plugin/dapp/mix/types"
)
func newStore(db db.DB) *mixStore {
return &mixStore{Store: wcom.NewStore(db)}
}
// mixStore 隐私交易数据库存储操作类
type mixStore struct {
*wcom.Store
}
//
//func (store *mixStore) getAccountByPrefix(addr string) ([]*types.WalletAccountStore, error) {
// if len(addr) == 0 {
// bizlog.Error("getAccountByPrefix addr is nil")
// return nil, types.ErrInvalidParam
// }
// list := store.NewListHelper()
// accbytes := list.PrefixScan([]byte(addr))
// if len(accbytes) == 0 {
// bizlog.Error("getAccountByPrefix addr not exist")
// return nil, types.ErrAccountNotExist
// }
// WalletAccountStores := make([]*types.WalletAccountStore, len(accbytes))
// for index, accbyte := range accbytes {
// var walletaccount types.WalletAccountStore
// err := proto.Unmarshal(accbyte, &walletaccount)
// if err != nil {
// bizlog.Error("GetAccountByAddr", "proto.Unmarshal err:", err)
// return nil, types.ErrUnmarshal
// }
// WalletAccountStores[index] = &walletaccount
// }
// return WalletAccountStores, nil
//}
func (store *mixStore) getAccountPrivacy(addr string) ([]byte, error) {
if len(addr) == 0 {
return nil, types.ErrInvalidParam
}
return store.Get(calcMixAddrKey(addr))
}
//
//func (store *mixStore) getAccountByAddr(addr string) (*types.WalletAccountStore, error) {
// var account types.WalletAccountStore
// if len(addr) == 0 {
// bizlog.Error("GetAccountByAddr addr is nil")
// return nil, types.ErrInvalidParam
// }
// data, err := store.Get(calcMixAddrKey(addr))
// if data == nil || err != nil {
// if err != db.ErrNotFoundInDb {
// bizlog.Debug("GetAccountByAddr addr", "err", err)
// }
// return nil, types.ErrAddrNotExist
// }
//
// err = types.Decode(data, &account)
// if err != nil {
// bizlog.Error("GetAccountByAddr", "proto.Unmarshal err:", err)
// return nil, types.ErrUnmarshal
// }
// return &account, nil
//}
func (store *mixStore) setAccountPrivacy(addr string, data []byte) error {
if len(addr) == 0 {
bizlog.Error("SetWalletAccountPrivacy addr is nil")
return types.ErrInvalidParam
}
if len(data) == 0 {
bizlog.Error("SetWalletAccountPrivacy privacy is nil")
return types.ErrInvalidParam
}
store.GetDB().Set(calcMixAddrKey(addr), data)
//newbatch := store.NewBatch(true)
//newbatch.Set(calcMixAddrKey(addr), data)
//newbatch.Write()
return nil
}
func (store *mixStore) enablePrivacy() {
newbatch := store.NewBatch(true)
newbatch.Set(calcMixPrivacyEnable(), []byte("true"))
newbatch.Write()
}
func (store *mixStore) getPrivacyEnable() bool {
_, err := store.Get(calcMixPrivacyEnable())
if err != nil {
return false
}
return true
}
func (store *mixStore) setRescanNoteStatus(status int32) {
newbatch := store.NewBatch(true)
newbatch.Set(calcRescanNoteStatus(), []byte(mixTy.MixWalletRescanStatus(status).String()))
newbatch.Write()
}
func (store *mixStore) getRescanNoteStatus() int32 {
v, err := store.Get(calcRescanNoteStatus())
if err != nil {
return int32(mixTy.MixWalletRescanStatus_IDLE)
}
return mixTy.MixWalletRescanStatus_value[string(v)]
}
//AddRollbackKV add rollback kv
func (d *mixStore) AddRollbackKV(tx *types.Transaction, execer []byte, kvs []*types.KeyValue) []*types.KeyValue {
k := types.CalcRollbackKey(types.GetRealExecName(execer), tx.Hash())
kvc := system.NewKVCreator(d.GetDB(), types.CalcLocalPrefix(execer), k)
kvc.AddListNoPrefix(kvs)
kvc.AddRollbackKV()
return kvc.KVList()
}
//DelRollbackKV del rollback kv when exec_del_local
func (d *mixStore) DelRollbackKV(tx *types.Transaction, execer []byte) ([]*types.KeyValue, error) {
krollback := types.CalcRollbackKey(types.GetRealExecName(execer), tx.Hash())
kvc := system.NewKVCreator(d.GetDB(), types.CalcLocalPrefix(execer), krollback)
kvs, err := kvc.GetRollbackKVList()
if err != nil {
return nil, err
}
for _, kv := range kvs {
kvc.AddNoPrefix(kv.Key, kv.Value)
}
kvc.DelRollbackKV()
return kvc.KVList(), nil
}
......@@ -63,4 +63,114 @@
|bindCoins|int|绑定挖矿冻结币的份额,需冻结平行链原生代币,解绑定不需要此配置|
|targetNode|string|绑定目标共识节点,需要是共识账户组的成员|
## 挖矿奖励的转出
1.查询挖矿奖励
>挖矿产生的奖励在平行链的paracross 执行器中
```
{
"method": "Chain33.GetBalance",
"params": [{
"addresses": ["{共识账户地址}"],
"execer": "user.p.para.paracross"
}]
}
1. cli命令方法
./chain33-cli --rpc_laddr http://localhost:8901 account balance -a 1KSBd17H7ZK8iT37aJztFB22XGwsPTdwE4
{
"addr": "1KSBd17H7ZK8iT37aJztFB22XGwsPTdwE4",
"execAccount": [
{
"execer": "user.p.para.paracross",
"account": {
"balance": "2227.0000",
"frozen": "0.0000"
}
}
]
}
2. rpc方法:
curl -ksd '{"method":"Chain33.GetBalance","params":[{"addresses":["1KSBd17H7ZK8iT37aJztFB22XGwsPTdwE4"],"execer":"user.p.para.paracross"}]}' http://172.28.0.2:8901
响应:
{
"result": [{
"currency": 0,
"balance": 227500000000,
"frozen": 0,
"addr": "1KSBd17H7ZK8iT37aJztFB22XGwsPTdwE4"
}],
}
```
2.转出挖矿奖励
>需要从平行链执行器paracross下把奖励 withdraw出到平行链coins合约的签名地址下
```
1. cli命令方式:
./chain33-cli --rpc_laddr http://localhost:8801 --paraName {平行链title} send coins withdraw -a {数量} -e user.p.para.paracross -k ${私钥}
例:
./chain33-cli --rpc_laddr http://localhost:8801 --paraName user.p.para. send coins withdraw -a 2000000000 -e user.p.para.paracross -k ${私钥}
响应:
./chain33-cli --rpc_laddr http://localhost:8901 account balance -a 1KSBd17H7ZK8iT37aJztFB22XGwsPTdwE4
{
"addr": "1KSBd17H7ZK8iT37aJztFB22XGwsPTdwE4",
"execAccount": [
{
"execer": "user.p.para.paracross",
"account": {
"balance": "1032.0000",
"frozen": "0.0000"
}
},
{
"execer": "user.p.para.coins",
"account": {
"balance": "2020.0000",
"frozen": "0.0000"
}
}
]
}
注:user.p.para.coins下就是自己的余额
rpc方法
1.创建交易:
{
"method": "Chain33.CreateRawTransaction",
"params": [{
"to": "19WJJv96nKAU4sHFWqGmsqfjxd37jazqii",
"amount": 2000000000,
"fee": 2000000,
"isWithdraw": true,
"execName": "user.p.para.paracross",
"execer": "user.p.para.coins"
}]
}
注释:
1) "to": "19WJJv96nKAU4sHFWqGmsqfjxd37jazqii", 平行链paracross执行器地址,不需要修改
2) amount,fee需要自己设置
2.签名
{
"method": "Chain33.SignRawTx",
"params": [{
"privkey": "{私钥}",
"txHex": "{交易数据}",
"expire": "120s"
}]
}
3.发送交易
{
"method": "Chain33.SendTransaction",
"params": [{
"data": "{签名数据}"
}]
}
```
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